diff src/ex_docmd.c @ 19181:94eda51ba9ba v8.2.0149

patch 8.2.0149: maintaining a Vim9 branch separately is more work Commit: https://github.com/vim/vim/commit/8a7d6542b33e5d2b352262305c3bfdb2d14e1cf8 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jan 26 15:56:19 2020 +0100 patch 8.2.0149: maintaining a Vim9 branch separately is more work Problem: Maintaining a Vim9 branch separately is more work. Solution: Merge the Vim9 script changes.
author Bram Moolenaar <Bram@vim.org>
date Sun, 26 Jan 2020 16:00:05 +0100
parents 69f0e9b5c107
children 133ef7ba4e4e
line wrap: on
line diff
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -27,7 +27,6 @@ static int	if_level = 0;		// depth in :i
 #endif
 static void	free_cmdmod(void);
 static void	append_command(char_u *cmd);
-static char_u	*find_command(exarg_T *eap, int *full);
 
 #ifndef FEAT_MENU
 # define ex_emenu		ex_ni
@@ -275,6 +274,7 @@ static void	ex_tag_cmd(exarg_T *eap, cha
 # define ex_debug		ex_ni
 # define ex_debuggreedy		ex_ni
 # define ex_delfunction		ex_ni
+# define ex_disassemble		ex_ni
 # define ex_echo		ex_ni
 # define ex_echohl		ex_ni
 # define ex_else		ex_ni
@@ -300,7 +300,10 @@ static void	ex_tag_cmd(exarg_T *eap, cha
 # define ex_try			ex_ni
 # define ex_unlet		ex_ni
 # define ex_unlockvar		ex_ni
+# define ex_vim9script		ex_ni
 # define ex_while		ex_ni
+# define ex_import		ex_ni
+# define ex_export		ex_ni
 #endif
 #ifndef FEAT_SESSION
 # define ex_loadview		ex_ni
@@ -1708,7 +1711,13 @@ do_one_cmd(
     ea.cmd = skip_range(ea.cmd, NULL);
     if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
 	ea.cmd = skipwhite(ea.cmd + 1);
-    p = find_command(&ea, NULL);
+
+#ifdef FEAT_EVAL
+    if (current_sctx.sc_version == SCRIPT_VERSION_VIM9)
+	p = find_ex_command(&ea, NULL, lookup_scriptvar, NULL);
+    else
+#endif
+	p = find_ex_command(&ea, NULL, NULL, NULL);
 
 #ifdef FEAT_EVAL
 # ifdef FEAT_PROFILE
@@ -1876,7 +1885,7 @@ do_one_cmd(
 #ifdef FEAT_EVAL
 		&& !aborting()
 #endif
-		) ? find_command(&ea, NULL) : ea.cmd;
+		) ? find_ex_command(&ea, NULL, NULL, NULL) : ea.cmd;
     }
 
     if (p == NULL)
@@ -2485,6 +2494,10 @@ do_one_cmd(
     }
 
 #ifdef FEAT_EVAL
+    // Set flag that any command was executed, used by ex_vim9script().
+    if (getline_equal(ea.getline, ea.cookie, getsourceline))
+	SCRIPT_ITEM(current_sctx.sc_sid).sn_had_command = TRUE;
+
     /*
      * If the command just executed called do_cmdline(), any throw or ":return"
      * or ":finish" encountered there must also check the cstack of the still
@@ -3108,15 +3121,64 @@ append_command(char_u *cmd)
  * Start of the name can be found at eap->cmd.
  * Sets eap->cmdidx and returns a pointer to char after the command name.
  * "full" is set to TRUE if the whole command name matched.
+ *
+ * If "lookup" is not NULL recognize expression without "eval" or "call" and
+ * assignment without "let".  Sets eap->cmdidx to the command while returning
+ * "eap->cmd".
+ *
  * Returns NULL for an ambiguous user command.
  */
-    static char_u *
-find_command(exarg_T *eap, int *full UNUSED)
+    char_u *
+find_ex_command(
+	exarg_T *eap,
+	int *full UNUSED,
+	int (*lookup)(char_u *, size_t, cctx_T *) UNUSED,
+	cctx_T *cctx UNUSED)
 {
     int		len;
     char_u	*p;
     int		i;
 
+#ifdef FEAT_EVAL
+    /*
+     * Recognize a Vim9 script function/method call and assignment:
+     * "lvar = value", "lvar(arg)", "[1, 2 3]->Func()"
+     */
+    if (lookup != NULL && (p = to_name_const_end(eap->cmd)) > eap->cmd
+								  && *p != NUL)
+    {
+	int oplen;
+	int heredoc;
+
+	// "funcname(" is always a function call.
+	// "varname[]" is an expression.
+	// "g:varname" is an expression.
+	// "varname->expr" is an expression.
+	if (*p == '('
+		|| *p == '['
+		|| p[1] == ':'
+		|| (*p == '-' && p[1] == '>'))
+	{
+	    eap->cmdidx = CMD_eval;
+	    return eap->cmd;
+	}
+
+	oplen = assignment_len(skipwhite(p), &heredoc);
+	if (oplen > 0)
+	{
+	    // Recognize an assignment if we recognize the variable name:
+	    // "g:var = expr"
+	    // "var = expr"  where "var" is a local var name.
+	    if (((p - eap->cmd) > 2 && eap->cmd[1] == ':')
+		    || lookup(eap->cmd, p - eap->cmd, cctx) >= 0)
+	    {
+		eap->cmdidx = CMD_let;
+		return eap->cmd;
+	    }
+	}
+    }
+#endif
+
     /*
      * Isolate the command and search for it in the command table.
      * Exceptions:
@@ -3149,8 +3211,17 @@ find_command(exarg_T *eap, int *full UNU
 	    ++p;
 	// for python 3.x support ":py3", ":python3", ":py3file", etc.
 	if (eap->cmd[0] == 'p' && eap->cmd[1] == 'y')
+	{
 	    while (ASCII_ISALNUM(*p))
 		++p;
+	}
+	else if (*p == '9' && STRNCMP("vim9", eap->cmd, 4) == 0)
+	{
+	    // include "9" for "vim9script"
+	    ++p;
+	    while (ASCII_ISALPHA(*p))
+		++p;
+	}
 
 	// check for non-alpha command
 	if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
@@ -3307,7 +3378,7 @@ cmd_exists(char_u *name)
     // For ":2match" and ":3match" we need to skip the number.
     ea.cmd = (*name == '2' || *name == '3') ? name + 1 : name;
     ea.cmdidx = (cmdidx_T)0;
-    p = find_command(&ea, &full);
+    p = find_ex_command(&ea, &full, NULL, NULL);
     if (p == NULL)
 	return 3;
     if (vim_isdigit(*name) && ea.cmdidx != CMD_match)
@@ -8558,7 +8629,7 @@ ex_folddo(exarg_T *eap)
 }
 #endif
 
-#ifdef FEAT_QUICKFIX
+#if defined(FEAT_QUICKFIX) || defined(PROTO)
 /*
  * Returns TRUE if the supplied Ex cmdidx is for a location list command
  * instead of a quickfix command.