patch 8.2.0585: Vim9: # comment not recognized after :vim9script

Problem:    Vim9: # comment not recognized after :vim9script.
Solution:   Check script type. Make comment after ":echo" work.  And in
            several other places.
diff --git a/src/eval.c b/src/eval.c
index fbbae63..af22896 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -6061,7 +6061,7 @@
 
     if (eap->skip)
 	++emsg_skip;
-    while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int)
+    while ((!ends_excmd2(eap->cmd, arg) || *arg == '"') && !got_int)
     {
 	// If eval1() causes an error message the text from the command may
 	// still need to be cleared. E.g., "echo 22,44".
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index f908ff3..cc7139d 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -1835,7 +1835,10 @@
      * If we find a '|' or '\n' we set ea.nextcmd.
      */
     if (*ea.cmd == NUL || *ea.cmd == '"'
-			      || (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL)
+#ifdef FEAT_EVAL
+		|| (*ea.cmd == '#' && !starts_with_colon && in_vim9script())
+#endif
+		|| (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL)
     {
 	/*
 	 * strange vi behaviour:
@@ -4761,12 +4764,31 @@
 	do_cmdline_cmd(eap->do_ecmd_cmd);
 }
 
+/*
+ * Check if "c" ends an Ex command.
+ * In Vim9 script does not check for white space before #.
+ */
     int
 ends_excmd(int c)
 {
 #ifdef FEAT_EVAL
     if (c == '#')
-	// TODO: should check for preceding white space
+	return in_vim9script();
+#endif
+    return (c == NUL || c == '|' || c == '"' || c == '\n');
+}
+
+/*
+ * Like ends_excmd() but checks that a # in Vim9 script either has "cmd" equal
+ * to "cmd_start" or has a white space character before it.
+ */
+    int
+ends_excmd2(char_u *cmd_start, char_u *cmd)
+{
+    int c = *cmd;
+
+#ifdef FEAT_EVAL
+    if (c == '#' && (cmd == cmd_start || VIM_ISWHITE(cmd[-1])))
 	return in_vim9script();
 #endif
     return (c == NUL || c == '|' || c == '"' || c == '\n');
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index af70e2d..eba5ee4 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -19,6 +19,7 @@
 char_u *skip_cmd_arg(char_u *p, int rembs);
 int get_bad_opt(char_u *p, exarg_T *eap);
 int ends_excmd(int c);
+int ends_excmd2(char_u *before, char_u *cmd);
 char_u *find_nextcmd(char_u *p);
 char_u *check_nextcmd(char_u *p);
 char_u *get_command_name(expand_T *xp, int idx);
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 5b5d8d9..a96910e 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -10,11 +10,17 @@
   call delete('Xdef')
 endfunc
 
-func CheckScriptFailure(lines, error)
-  call writefile(a:lines, 'Xdef')
-  call assert_fails('so Xdef', a:error, a:lines)
-  call delete('Xdef')
-endfunc
+def CheckScriptFailure(lines: list<string>, error: string)
+  writefile(lines, 'Xdef')
+  assert_fails('so Xdef', error, lines)
+  delete('Xdef')
+enddef
+
+def CheckScriptSuccess(lines: list<string>)
+  writefile(lines, 'Xdef')
+  so Xdef
+  delete('Xdef')
+enddef
 
 def Test_syntax()
   let var = 234
@@ -269,15 +275,15 @@
 
 def Test_try_catch()
   let l = []
-  try
+  try # comment
     add(l, '1')
     throw 'wrong'
     add(l, '2')
-  catch
+  catch # comment
     add(l, v:exception)
-  finally
+  finally # comment
     add(l, '3')
-  endtry
+  endtry # comment
   assert_equal(['1', 'wrong', '3'], l)
 enddef
 
@@ -1003,6 +1009,58 @@
         )
 enddef
 
+def Test_vim9_comment()
+  CheckScriptSuccess([
+      'vim9script',
+      '# something',
+      ])
+  CheckScriptFailure([
+      'vim9script',
+      ':# something',
+      ], 'E488:')
+  CheckScriptFailure([
+      '# something',
+      ], 'E488:')
+  CheckScriptFailure([
+      ':# something',
+      ], 'E488:')
+
+  CheckScriptSuccess([
+      'vim9script',
+      'echo "yes" # something',
+      ])
+  CheckScriptFailure([
+      'vim9script',
+      'echo "yes"# something',
+      ], 'E121:')
+  CheckScriptFailure([
+      'vim9script',
+      'echo# something',
+      ], 'E121:')
+  CheckScriptFailure([
+      'echo "yes" # something',
+      ], 'E121:')
+
+  CheckDefFailure([
+      'try# comment',
+      'echo "yes"',
+      'catch',
+      'endtry',
+      ], 'E488:')
+  CheckDefFailure([
+      'try',
+      'echo "yes"',
+      'catch# comment',
+      'endtry',
+      ], 'E488:')
+  CheckDefFailure([
+      'try',
+      'echo "yes"',
+      'catch',
+      'endtry# comment',
+      ], 'E488:')
+enddef
+
 " Keep this last, it messes up highlighting.
 def Test_substitute_cmd()
   new
diff --git a/src/version.c b/src/version.c
index c8a1d55..ca8d71c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    585,
+/**/
     584,
 /**/
     583,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 4137c56..e8e8598 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -108,6 +108,7 @@
 struct cctx_S {
     ufunc_T	*ctx_ufunc;	    // current function
     int		ctx_lnum;	    // line number in current function
+    char_u	*ctx_line_start;    // start of current line or NULL
     garray_T	ctx_instr;	    // generated instructions
 
     garray_T	ctx_locals;	    // currently visible local variables
@@ -2055,14 +2056,18 @@
     static char_u *
 next_line_from_context(cctx_T *cctx)
 {
-    char_u	*line = NULL;
+    char_u	*line;
 
     do
     {
 	++cctx->ctx_lnum;
 	if (cctx->ctx_lnum >= cctx->ctx_ufunc->uf_lines.ga_len)
+	{
+	    line = NULL;
 	    break;
+	}
 	line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum];
+	cctx->ctx_line_start = line;
 	SOURCING_LNUM = cctx->ctx_ufunc->uf_script_ctx.sc_lnum
 							  + cctx->ctx_lnum + 1;
     } while (line == NULL || *skipwhite(line) == NUL);
@@ -5448,7 +5453,7 @@
     }
 
     p = skipwhite(arg);
-    if (ends_excmd(*p))
+    if (ends_excmd2(arg, p))
     {
 	scope->se_u.se_try.ts_caught_all = TRUE;
 	scope->se_u.se_try.ts_catch_label = 0;
@@ -5782,7 +5787,9 @@
 	if (line != NULL && *line == '|')
 	    // the line continues after a '|'
 	    ++line;
-	else if (line != NULL && *line != NUL)
+	else if (line != NULL && *line != NUL
+		&& !(*line == '#' && (line == cctx.ctx_line_start
+						    || VIM_ISWHITE(line[-1]))))
 	{
 	    semsg(_("E488: Trailing characters: %s"), line);
 	    goto erret;