mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -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: >
|
Some Ex commands can be confused with assignments in Vim9 script: >
|
||||||
g:name = value # assignment
|
g:name = value # assignment
|
||||||
g:pattern:cmd # invalid command - ERROR
|
|
||||||
:g:pattern:cmd # :global command
|
: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
|
Functions defined with `:def` compile the whole function. Legacy functions
|
||||||
can bail out, and the following lines are not parsed: >
|
can bail out, and the following lines are not parsed: >
|
||||||
func Maybe()
|
func Maybe()
|
||||||
|
@@ -666,3 +666,7 @@ EXTERN char e_invalid_value_for_blob_nr[]
|
|||||||
INIT(= N_("E1239: Invalid value for blob: %d"));
|
INIT(= N_("E1239: Invalid value for blob: %d"));
|
||||||
EXTERN char e_resulting_text_too_long[]
|
EXTERN char e_resulting_text_too_long[]
|
||||||
INIT(= N_("E1240: 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
|
// don't accept alphanumeric for separator
|
||||||
if (check_regexp_delim(*cmd) == FAIL)
|
if (check_regexp_delim(*cmd) == FAIL)
|
||||||
return;
|
return;
|
||||||
|
if (in_vim9script() && check_global_and_subst(eap->cmd, eap->arg)
|
||||||
|
== FAIL)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* undocumented vi feature:
|
* undocumented vi feature:
|
||||||
@@ -4899,6 +4902,9 @@ ex_global(exarg_T *eap)
|
|||||||
cmd = eap->arg;
|
cmd = eap->arg;
|
||||||
which_pat = RE_LAST; // default: use last used regexp
|
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:
|
* undocumented vi feature:
|
||||||
* "\/" and "\?": use previous search pattern.
|
* "\/" 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
|
// 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.
|
// line, if the variable exists it can't be an Ex command.
|
||||||
if (p > eap->cmd && ends_excmd(*skipwhite(p))
|
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);
|
int assignment_len(char_u *p, int *heredoc);
|
||||||
void vim9_declare_error(char_u *name);
|
void vim9_declare_error(char_u *name);
|
||||||
int check_vim9_unlet(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);
|
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 set_function_type(ufunc_T *ufunc);
|
||||||
void delete_instr(isn_T *isn);
|
void delete_instr(isn_T *isn);
|
||||||
|
@@ -1489,5 +1489,54 @@ def Test_cmdwin_block()
|
|||||||
au! justTesting
|
au! justTesting
|
||||||
enddef
|
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
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||||
|
@@ -757,6 +757,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
3503,
|
||||||
/**/
|
/**/
|
||||||
3502,
|
3502,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -9472,6 +9472,26 @@ compile_cexpr(char_u *line, exarg_T *eap, cctx_T *cctx)
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
* Add a function to the list of :def functions.
|
||||||
* This sets "ufunc->uf_dfunc_idx" but the function isn't compiled yet.
|
* This sets "ufunc->uf_dfunc_idx" but the function isn't compiled yet.
|
||||||
@@ -10066,6 +10086,8 @@ compile_def_function(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_substitute:
|
case CMD_substitute:
|
||||||
|
if (check_global_and_subst(ea.cmd, p) == FAIL)
|
||||||
|
goto erret;
|
||||||
if (cctx.ctx_skip == SKIP_YES)
|
if (cctx.ctx_skip == SKIP_YES)
|
||||||
line = (char_u *)"";
|
line = (char_u *)"";
|
||||||
else
|
else
|
||||||
@@ -10132,6 +10154,10 @@ compile_def_function(
|
|||||||
line = compile_script(line, &cctx);
|
line = compile_script(line, &cctx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CMD_global:
|
||||||
|
if (check_global_and_subst(ea.cmd, p) == FAIL)
|
||||||
|
goto erret;
|
||||||
|
// FALLTHROUGH
|
||||||
default:
|
default:
|
||||||
// Not recognized, execute with do_cmdline_cmd().
|
// Not recognized, execute with do_cmdline_cmd().
|
||||||
ea.arg = p;
|
ea.arg = p;
|
||||||
|
Reference in New Issue
Block a user