forked from aniani/vim
patch 8.2.2138: Vim9: "exit_cb" causes Vim to exit
Problem: Vim9: "exit_cb" causes Vim to exit. Solution: Require white space after a command in Vim9 script. (closes #7467) Also fix that Vim9 style heredoc was not always recognized.
This commit is contained in:
@@ -316,4 +316,8 @@ EXTERN char e_indexable_type_required[]
|
|||||||
EXTERN char e_non_empty_string_required[]
|
EXTERN char e_non_empty_string_required[]
|
||||||
INIT(= N_("E1142: Non-empty string required"));
|
INIT(= N_("E1142: Non-empty string required"));
|
||||||
EXTERN char e_empty_expression_str[]
|
EXTERN char e_empty_expression_str[]
|
||||||
INIT(= N_("E1143: empty expression: \"%s\""));
|
INIT(= N_("E1143: Empty expression: \"%s\""));
|
||||||
|
EXTERN char e_command_not_followed_by_white_space_str[]
|
||||||
|
INIT(= N_("E1144: Command is not followed by white space: %s"));
|
||||||
|
EXTERN char e_missing_heredoc_end_marker_str[]
|
||||||
|
INIT(= N_("E1145: Missing heredoc end marker: %s"));
|
||||||
|
@@ -55,6 +55,7 @@
|
|||||||
#define EX_LOCK_OK 0x1000000 // command can be executed when textlock is
|
#define EX_LOCK_OK 0x1000000 // command can be executed when textlock is
|
||||||
// set; when missing disallows editing another
|
// set; when missing disallows editing another
|
||||||
// buffer when curbuf_lock is set
|
// buffer when curbuf_lock is set
|
||||||
|
#define EX_NONWHITE_OK 0x2000000 // command can be followed by non-white
|
||||||
|
|
||||||
#define EX_FILES (EX_XFILE | EX_EXTRA) // multiple extra files allowed
|
#define EX_FILES (EX_XFILE | EX_EXTRA) // multiple extra files allowed
|
||||||
#define EX_FILE1 (EX_FILES | EX_NOSPC) // 1 file, defaults to current file
|
#define EX_FILE1 (EX_FILES | EX_NOSPC) // 1 file, defaults to current file
|
||||||
@@ -632,7 +633,7 @@ EXCMD(CMD_function, "function", ex_function,
|
|||||||
EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
EX_EXTRA|EX_BANG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
||||||
ADDR_NONE),
|
ADDR_NONE),
|
||||||
EXCMD(CMD_global, "global", ex_global,
|
EXCMD(CMD_global, "global", ex_global,
|
||||||
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_EXTRA|EX_DFLALL|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_EXTRA|EX_DFLALL|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_goto, "goto", ex_goto,
|
EXCMD(CMD_goto, "goto", ex_goto,
|
||||||
EX_RANGE|EX_COUNT|EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
EX_RANGE|EX_COUNT|EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
||||||
@@ -1277,7 +1278,7 @@ EXCMD(CMD_rviminfo, "rviminfo", ex_viminfo,
|
|||||||
EX_BANG|EX_FILE1|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
EX_BANG|EX_FILE1|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||||
ADDR_NONE),
|
ADDR_NONE),
|
||||||
EXCMD(CMD_substitute, "substitute", ex_substitute,
|
EXCMD(CMD_substitute, "substitute", ex_substitute,
|
||||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK,
|
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_sNext, "sNext", ex_previous,
|
EXCMD(CMD_sNext, "sNext", ex_previous,
|
||||||
EX_EXTRA|EX_RANGE|EX_COUNT|EX_BANG|EX_CMDARG|EX_ARGOPT|EX_TRLBAR,
|
EX_EXTRA|EX_RANGE|EX_COUNT|EX_BANG|EX_CMDARG|EX_ARGOPT|EX_TRLBAR,
|
||||||
@@ -1652,7 +1653,7 @@ EXCMD(CMD_update, "update", ex_update,
|
|||||||
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_FILE1|EX_ARGOPT|EX_DFLALL|EX_TRLBAR,
|
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_FILE1|EX_ARGOPT|EX_DFLALL|EX_TRLBAR,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_vglobal, "vglobal", ex_global,
|
EXCMD(CMD_vglobal, "vglobal", ex_global,
|
||||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_DFLALL|EX_CMDWIN|EX_LOCK_OK,
|
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_DFLALL|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_var, "var", ex_var,
|
EXCMD(CMD_var, "var", ex_var,
|
||||||
EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
||||||
@@ -1792,16 +1793,16 @@ EXCMD(CMD_z, "z", ex_z,
|
|||||||
|
|
||||||
// commands that don't start with a letter
|
// commands that don't start with a letter
|
||||||
EXCMD(CMD_bang, "!", ex_bang,
|
EXCMD(CMD_bang, "!", ex_bang,
|
||||||
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_FILES|EX_CMDWIN|EX_LOCK_OK,
|
EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_FILES|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_pound, "#", ex_print,
|
EXCMD(CMD_pound, "#", ex_print,
|
||||||
EX_RANGE|EX_WHOLEFOLD|EX_COUNT|EX_FLAGS|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
EX_RANGE|EX_WHOLEFOLD|EX_COUNT|EX_FLAGS|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_and, "&", ex_substitute,
|
EXCMD(CMD_and, "&", ex_substitute,
|
||||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
|
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY|EX_NONWHITE_OK,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_star, "*", ex_at,
|
EXCMD(CMD_star, "*", ex_at,
|
||||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_lshift, "<", ex_operators,
|
EXCMD(CMD_lshift, "<", ex_operators,
|
||||||
EX_RANGE|EX_WHOLEFOLD|EX_COUNT|EX_FLAGS|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
|
EX_RANGE|EX_WHOLEFOLD|EX_COUNT|EX_FLAGS|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
|
||||||
@@ -1813,7 +1814,7 @@ EXCMD(CMD_rshift, ">", ex_operators,
|
|||||||
EX_RANGE|EX_WHOLEFOLD|EX_COUNT|EX_FLAGS|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
|
EX_RANGE|EX_WHOLEFOLD|EX_COUNT|EX_FLAGS|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_at, "@", ex_at,
|
EXCMD(CMD_at, "@", ex_at,
|
||||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_NONWHITE_OK,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
EXCMD(CMD_block, "{{{{{{{{", ex_block, // not found normally
|
EXCMD(CMD_block, "{{{{{{{{", ex_block, // not found normally
|
||||||
0,
|
0,
|
||||||
@@ -1822,7 +1823,7 @@ EXCMD(CMD_endblock, "}", ex_endblock,
|
|||||||
EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||||
ADDR_NONE),
|
ADDR_NONE),
|
||||||
EXCMD(CMD_tilde, "~", ex_substitute,
|
EXCMD(CMD_tilde, "~", ex_substitute,
|
||||||
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY,
|
EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY|EX_NONWHITE_OK,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
|
|
||||||
// commands that start with an uppercase letter
|
// commands that start with an uppercase letter
|
||||||
|
@@ -3528,6 +3528,14 @@ find_ex_command(
|
|||||||
if (eap->cmdidx == CMD_final && p - eap->cmd == 4)
|
if (eap->cmdidx == CMD_final && p - eap->cmd == 4)
|
||||||
eap->cmdidx = CMD_finally;
|
eap->cmdidx = CMD_finally;
|
||||||
|
|
||||||
|
if (eap->cmdidx != CMD_SIZE && in_vim9script()
|
||||||
|
&& !IS_WHITE_OR_NUL(*p) && !ends_excmd(*p) && *p != '!'
|
||||||
|
&& (cmdnames[eap->cmdidx].cmd_argt & EX_NONWHITE_OK) == 0)
|
||||||
|
{
|
||||||
|
semsg(_(e_command_not_followed_by_white_space_str), eap->cmd);
|
||||||
|
eap->cmdidx = CMD_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5114,7 +5122,7 @@ ex_blast(exarg_T *eap)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if "c" ends an Ex command.
|
* Check if "c" ends an Ex command.
|
||||||
* In Vim9 script does not check for white space before # or #{.
|
* In Vim9 script does not check for white space before #.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ends_excmd(int c)
|
ends_excmd(int c)
|
||||||
|
@@ -338,7 +338,7 @@ func Test_let_heredoc_fails()
|
|||||||
endfunc
|
endfunc
|
||||||
END
|
END
|
||||||
call writefile(text, 'XheredocFail')
|
call writefile(text, 'XheredocFail')
|
||||||
call assert_fails('source XheredocFail', 'E126:')
|
call assert_fails('source XheredocFail', 'E1145:')
|
||||||
call delete('XheredocFail')
|
call delete('XheredocFail')
|
||||||
|
|
||||||
let text =<< trim CodeEnd
|
let text =<< trim CodeEnd
|
||||||
@@ -347,7 +347,7 @@ func Test_let_heredoc_fails()
|
|||||||
endfunc
|
endfunc
|
||||||
CodeEnd
|
CodeEnd
|
||||||
call writefile(text, 'XheredocWrong')
|
call writefile(text, 'XheredocWrong')
|
||||||
call assert_fails('source XheredocWrong', 'E126:')
|
call assert_fails('source XheredocWrong', 'E1145:')
|
||||||
call delete('XheredocWrong')
|
call delete('XheredocWrong')
|
||||||
|
|
||||||
let text =<< trim TEXTend
|
let text =<< trim TEXTend
|
||||||
|
@@ -982,6 +982,17 @@ def Test_heredoc()
|
|||||||
var&lines =<< trim END
|
var&lines =<< trim END
|
||||||
x
|
x
|
||||||
x
|
x
|
||||||
|
enddef
|
||||||
|
defcompile
|
||||||
|
[END]
|
||||||
|
CheckScriptFailure(lines, 'E1145: Missing heredoc end marker: END')
|
||||||
|
delfunc! g:Func
|
||||||
|
|
||||||
|
lines =<< trim [END]
|
||||||
|
def Func()
|
||||||
|
var lines =<< trim END
|
||||||
|
x
|
||||||
|
x
|
||||||
x
|
x
|
||||||
x
|
x
|
||||||
x
|
x
|
||||||
@@ -991,7 +1002,7 @@ def Test_heredoc()
|
|||||||
enddef
|
enddef
|
||||||
call Func()
|
call Func()
|
||||||
[END]
|
[END]
|
||||||
CheckScriptFailure(lines, 'E990:')
|
CheckScriptFailure(lines, 'E1145: Missing heredoc end marker: END')
|
||||||
delfunc! g:Func
|
delfunc! g:Func
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
@@ -3058,7 +3058,7 @@ def Test_put_with_linebreak()
|
|||||||
new
|
new
|
||||||
var lines =<< trim END
|
var lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
pu=split('abc', '\zs')
|
pu =split('abc', '\zs')
|
||||||
->join()
|
->join()
|
||||||
END
|
END
|
||||||
CheckScriptSuccess(lines)
|
CheckScriptSuccess(lines)
|
||||||
@@ -3079,6 +3079,13 @@ def Test_invoke_normal_in_visual_mode()
|
|||||||
xunmap <F3>
|
xunmap <F3>
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_white_space_after_command()
|
||||||
|
var lines =<< trim END
|
||||||
|
exit_cb: Func})
|
||||||
|
END
|
||||||
|
CheckDefAndScriptFailure(lines, 'E1144:', 1)
|
||||||
|
enddef
|
||||||
|
|
||||||
" Keep this last, it messes up highlighting.
|
" Keep this last, it messes up highlighting.
|
||||||
def Test_substitute_cmd()
|
def Test_substitute_cmd()
|
||||||
new
|
new
|
||||||
|
@@ -3185,7 +3185,9 @@ define_function(exarg_T *eap, char_u *name_arg)
|
|||||||
lines_left = Rows - 1;
|
lines_left = Rows - 1;
|
||||||
if (theline == NULL)
|
if (theline == NULL)
|
||||||
{
|
{
|
||||||
if (eap->cmdidx == CMD_def)
|
if (skip_until != NULL)
|
||||||
|
semsg(_(e_missing_heredoc_end_marker_str), skip_until);
|
||||||
|
else if (eap->cmdidx == CMD_def)
|
||||||
emsg(_(e_missing_enddef));
|
emsg(_(e_missing_enddef));
|
||||||
else
|
else
|
||||||
emsg(_("E126: Missing :endfunction"));
|
emsg(_("E126: Missing :endfunction"));
|
||||||
@@ -3352,18 +3354,24 @@ define_function(exarg_T *eap, char_u *name_arg)
|
|||||||
|
|
||||||
// Check for ":cmd v =<< [trim] EOF"
|
// Check for ":cmd v =<< [trim] EOF"
|
||||||
// and ":cmd [a, b] =<< [trim] EOF"
|
// and ":cmd [a, b] =<< [trim] EOF"
|
||||||
|
// and "lines =<< [trim] EOF" for Vim9
|
||||||
// Where "cmd" can be "let", "var", "final" or "const".
|
// Where "cmd" can be "let", "var", "final" or "const".
|
||||||
arg = skipwhite(skiptowhite(p));
|
arg = skipwhite(skiptowhite(p));
|
||||||
if (*arg == '[')
|
if (*arg == '[')
|
||||||
arg = vim_strchr(arg, ']');
|
arg = vim_strchr(arg, ']');
|
||||||
if (arg != NULL)
|
if (arg != NULL)
|
||||||
{
|
{
|
||||||
|
int found = (eap->cmdidx == CMD_def && arg[0] == '='
|
||||||
|
&& arg[1] == '<' && arg[2] =='<');
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
// skip over the argument after "cmd"
|
||||||
arg = skipwhite(skiptowhite(arg));
|
arg = skipwhite(skiptowhite(arg));
|
||||||
if (arg[0] == '=' && arg[1] == '<' && arg[2] =='<'
|
if (found || (arg[0] == '=' && arg[1] == '<' && arg[2] =='<'
|
||||||
&& (checkforcmd(&p, "let", 2)
|
&& (checkforcmd(&p, "let", 2)
|
||||||
|| checkforcmd(&p, "var", 3)
|
|| checkforcmd(&p, "var", 3)
|
||||||
|| checkforcmd(&p, "final", 5)
|
|| checkforcmd(&p, "final", 5)
|
||||||
|| checkforcmd(&p, "const", 5)))
|
|| checkforcmd(&p, "const", 5))))
|
||||||
{
|
{
|
||||||
p = skipwhite(arg + 3);
|
p = skipwhite(arg + 3);
|
||||||
if (STRNCMP(p, "trim", 4) == 0)
|
if (STRNCMP(p, "trim", 4) == 0)
|
||||||
|
@@ -750,6 +750,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 */
|
||||||
|
/**/
|
||||||
|
2138,
|
||||||
/**/
|
/**/
|
||||||
2137,
|
2137,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user