mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.3503: Vim9: using g:pat:cmd is confusing
Problem: Vim9: using g:pat:cmd is confusing. Solution: Do not recognize g: as the :global command. Also for s:pat:repl. (closes #8982)
This commit is contained in:
@@ -942,9 +942,22 @@ Ex command ranges need to be prefixed with a colon. >
|
||||
|
||||
Some Ex commands can be confused with assignments in Vim9 script: >
|
||||
g:name = value # assignment
|
||||
g:pattern:cmd # invalid command - ERROR
|
||||
:g:pattern:cmd # :global command
|
||||
|
||||
To avoid confusion between a `:global` or `:substitute` command and an
|
||||
expression or assignment, a few separators cannot be used when these commands
|
||||
are abbreviated to a single character: ':', '-' and '.'. >
|
||||
g:pattern:cmd # invalid command - ERROR
|
||||
s:pattern:repl # invalid command - ERROR
|
||||
g-pattern-cmd # invalid command - ERROR
|
||||
s-pattern-repl # invalid command - ERROR
|
||||
g.pattern.cmd # invalid command - ERROR
|
||||
s.pattern.repl # invalid command - ERROR
|
||||
|
||||
Also, there cannot be a space between the command and the separator: >
|
||||
g /pattern/cmd # invalid command - ERROR
|
||||
s /pattern/repl # invalid command - ERROR
|
||||
|
||||
Functions defined with `:def` compile the whole function. Legacy functions
|
||||
can bail out, and the following lines are not parsed: >
|
||||
func Maybe()
|
||||
|
@@ -666,3 +666,7 @@ EXTERN char e_invalid_value_for_blob_nr[]
|
||||
INIT(= N_("E1239: Invalid value for blob: %d"));
|
||||
EXTERN char e_resulting_text_too_long[]
|
||||
INIT(= N_("E1240: Resulting text too long"));
|
||||
EXTERN char e_separator_not_supported_str[]
|
||||
INIT(= N_("E1241: Separator not supported: %s"));
|
||||
EXTERN char e_no_white_space_allowed_before_separator_str[]
|
||||
INIT(= N_("E1242: No white space allowed before separator: %s"));
|
||||
|
@@ -3724,6 +3724,9 @@ ex_substitute(exarg_T *eap)
|
||||
// don't accept alphanumeric for separator
|
||||
if (check_regexp_delim(*cmd) == FAIL)
|
||||
return;
|
||||
if (in_vim9script() && check_global_and_subst(eap->cmd, eap->arg)
|
||||
== FAIL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* undocumented vi feature:
|
||||
@@ -4899,6 +4902,9 @@ ex_global(exarg_T *eap)
|
||||
cmd = eap->arg;
|
||||
which_pat = RE_LAST; // default: use last used regexp
|
||||
|
||||
if (in_vim9script() && check_global_and_subst(eap->cmd, eap->arg) == FAIL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* undocumented vi feature:
|
||||
* "\/" and "\?": use previous search pattern.
|
||||
|
@@ -3600,6 +3600,15 @@ find_ex_command(
|
||||
}
|
||||
}
|
||||
|
||||
// "g:", "s:" and "l:" are always assumed to be a variable, thus start
|
||||
// an expression. A global/substitute/list command needs to use a
|
||||
// longer name.
|
||||
if (vim_strchr((char_u *)"gsl", *p) != NULL && p[1] == ':')
|
||||
{
|
||||
eap->cmdidx = CMD_eval;
|
||||
return eap->cmd;
|
||||
}
|
||||
|
||||
// If it is an ID it might be a variable with an operator on the next
|
||||
// line, if the variable exists it can't be an Ex command.
|
||||
if (p > eap->cmd && ends_excmd(*skipwhite(p))
|
||||
|
@@ -17,6 +17,7 @@ void fill_exarg_from_cctx(exarg_T *eap, cctx_T *cctx);
|
||||
int assignment_len(char_u *p, int *heredoc);
|
||||
void vim9_declare_error(char_u *name);
|
||||
int check_vim9_unlet(char_u *name);
|
||||
int check_global_and_subst(char_u *cmd, char_u *arg);
|
||||
int compile_def_function(ufunc_T *ufunc, int check_return_type, compiletype_T compile_type, cctx_T *outer_cctx);
|
||||
void set_function_type(ufunc_T *ufunc);
|
||||
void delete_instr(isn_T *isn);
|
||||
|
@@ -1489,5 +1489,54 @@ def Test_cmdwin_block()
|
||||
au! justTesting
|
||||
enddef
|
||||
|
||||
def Test_var_not_cmd()
|
||||
var lines =<< trim END
|
||||
g:notexist:cmd
|
||||
END
|
||||
CheckDefAndScriptFailure2(lines, 'E488: Trailing characters: :cmd', 'E121: Undefined variable: g:notexist', 1)
|
||||
|
||||
lines =<< trim END
|
||||
g-pat-cmd
|
||||
END
|
||||
CheckDefAndScriptFailure(lines, 'E1241:', 1)
|
||||
|
||||
lines =<< trim END
|
||||
s:notexist:repl
|
||||
END
|
||||
CheckDefAndScriptFailure2(lines, 'E488: Trailing characters: :repl', 'E121: Undefined variable: s:notexist', 1)
|
||||
|
||||
lines =<< trim END
|
||||
s-pat-repl
|
||||
END
|
||||
CheckDefAndScriptFailure(lines, 'E1241:', 1)
|
||||
|
||||
lines =<< trim END
|
||||
w:notexist->len()
|
||||
END
|
||||
CheckDefExecAndScriptFailure(lines, 'E121: Undefined variable: w:notexist', 1)
|
||||
|
||||
lines =<< trim END
|
||||
b:notexist->len()
|
||||
END
|
||||
CheckDefExecAndScriptFailure(lines, 'E121: Undefined variable: b:notexist', 1)
|
||||
|
||||
lines =<< trim END
|
||||
t:notexist->len()
|
||||
END
|
||||
CheckDefExecAndScriptFailure(lines, 'E121: Undefined variable: t:notexist', 1)
|
||||
enddef
|
||||
|
||||
def Test_no_space_after_command()
|
||||
var lines =<< trim END
|
||||
g /pat/cmd
|
||||
END
|
||||
CheckDefAndScriptFailure(lines, 'E1242:', 1)
|
||||
|
||||
lines =<< trim END
|
||||
s /pat/repl
|
||||
END
|
||||
CheckDefAndScriptFailure(lines, 'E1242:', 1)
|
||||
enddef
|
||||
|
||||
|
||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||
|
@@ -757,6 +757,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
3503,
|
||||
/**/
|
||||
3502,
|
||||
/**/
|
||||
|
@@ -9472,6 +9472,26 @@ compile_cexpr(char_u *line, exarg_T *eap, cctx_T *cctx)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check if the separator for a :global or :substitute command is OK.
|
||||
*/
|
||||
int
|
||||
check_global_and_subst(char_u *cmd, char_u *arg)
|
||||
{
|
||||
if (arg == cmd + 1 && vim_strchr(":-.", *arg) != NULL)
|
||||
{
|
||||
semsg(_(e_separator_not_supported_str), arg);
|
||||
return FAIL;
|
||||
}
|
||||
if (VIM_ISWHITE(cmd[1]))
|
||||
{
|
||||
semsg(_(e_no_white_space_allowed_before_separator_str), cmd);
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add a function to the list of :def functions.
|
||||
* This sets "ufunc->uf_dfunc_idx" but the function isn't compiled yet.
|
||||
@@ -10066,6 +10086,8 @@ compile_def_function(
|
||||
break;
|
||||
|
||||
case CMD_substitute:
|
||||
if (check_global_and_subst(ea.cmd, p) == FAIL)
|
||||
goto erret;
|
||||
if (cctx.ctx_skip == SKIP_YES)
|
||||
line = (char_u *)"";
|
||||
else
|
||||
@@ -10132,6 +10154,10 @@ compile_def_function(
|
||||
line = compile_script(line, &cctx);
|
||||
break;
|
||||
|
||||
case CMD_global:
|
||||
if (check_global_and_subst(ea.cmd, p) == FAIL)
|
||||
goto erret;
|
||||
// FALLTHROUGH
|
||||
default:
|
||||
// Not recognized, execute with do_cmdline_cmd().
|
||||
ea.arg = p;
|
||||
|
Reference in New Issue
Block a user