mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.2.2806: Vim9: using "++nr" as a command might not work
Problem: Vim9: using "++nr" as a command might not work. Solution: Do not recognize "++" and "--" in a following line as addition or subtraction.
This commit is contained in:
@@ -2856,12 +2856,15 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
|
|||||||
|
|
||||||
// "." is only string concatenation when scriptversion is 1
|
// "." is only string concatenation when scriptversion is 1
|
||||||
// "+=", "-=" and "..=" are assignments
|
// "+=", "-=" and "..=" are assignments
|
||||||
|
// "++" and "--" on the next line are a separate command.
|
||||||
p = eval_next_non_blank(*arg, evalarg, &getnext);
|
p = eval_next_non_blank(*arg, evalarg, &getnext);
|
||||||
op = *p;
|
op = *p;
|
||||||
concat = op == '.' && (*(p + 1) == '.' || current_sctx.sc_version < 2);
|
concat = op == '.' && (*(p + 1) == '.' || current_sctx.sc_version < 2);
|
||||||
if ((op != '+' && op != '-' && !concat) || p[1] == '='
|
if ((op != '+' && op != '-' && !concat) || p[1] == '='
|
||||||
|| (p[1] == '.' && p[2] == '='))
|
|| (p[1] == '.' && p[2] == '='))
|
||||||
break;
|
break;
|
||||||
|
if (getnext && (op == '+' || op == '-') && p[0] == p[1])
|
||||||
|
break;
|
||||||
|
|
||||||
evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
|
evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
|
||||||
oplen = (concat && p[1] == '.') ? 2 : 1;
|
oplen = (concat && p[1] == '.') ? 2 : 1;
|
||||||
|
@@ -69,4 +69,4 @@ static const unsigned char cmdidxs2[26][26] =
|
|||||||
/* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
/* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int command_count = 577;
|
static const int command_count = 579;
|
||||||
|
@@ -1846,6 +1846,14 @@ EXCMD(CMD_X, "X", ex_X,
|
|||||||
EX_TRLBAR,
|
EX_TRLBAR,
|
||||||
ADDR_NONE),
|
ADDR_NONE),
|
||||||
|
|
||||||
|
// Commands that are recognized only in find_ex_command().
|
||||||
|
EXCMD(CMD_increment, "++", ex_incdec,
|
||||||
|
EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
||||||
|
ADDR_NONE),
|
||||||
|
EXCMD(CMD_decrement, "--", ex_incdec,
|
||||||
|
EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
||||||
|
ADDR_NONE),
|
||||||
|
|
||||||
#undef EXCMD
|
#undef EXCMD
|
||||||
|
|
||||||
#ifndef DO_DECLARE_EXCMD
|
#ifndef DO_DECLARE_EXCMD
|
||||||
|
@@ -3531,6 +3531,13 @@ find_ex_command(
|
|||||||
eap->cmdidx = CMD_eval;
|
eap->cmdidx = CMD_eval;
|
||||||
return eap->cmd;
|
return eap->cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for "++nr" and "--nr".
|
||||||
|
if (p == eap->cmd && p[0] == p[1] && (*p == '+' || *p == '-'))
|
||||||
|
{
|
||||||
|
eap->cmdidx = *p == '+' ? CMD_increment : CMD_decrement;
|
||||||
|
return eap->cmd + 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@ void ex_vim9script(exarg_T *eap);
|
|||||||
int not_in_vim9(exarg_T *eap);
|
int not_in_vim9(exarg_T *eap);
|
||||||
int vim9_bad_comment(char_u *p);
|
int vim9_bad_comment(char_u *p);
|
||||||
int vim9_comment_start(char_u *p);
|
int vim9_comment_start(char_u *p);
|
||||||
|
void ex_incdec(exarg_T *eap);
|
||||||
void ex_export(exarg_T *eap);
|
void ex_export(exarg_T *eap);
|
||||||
void free_imports_and_script_vars(int sid);
|
void free_imports_and_script_vars(int sid);
|
||||||
void mark_imports_for_reload(int sid);
|
void mark_imports_for_reload(int sid);
|
||||||
|
@@ -1837,5 +1837,21 @@ def Test_script_funcref_case()
|
|||||||
CheckScriptFailure(lines, 'E704:')
|
CheckScriptFailure(lines, 'E704:')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_inc_dec()
|
||||||
|
var lines =<< trim END
|
||||||
|
var nr = 7
|
||||||
|
++nr
|
||||||
|
echo nr
|
||||||
|
--nr
|
||||||
|
echo nr
|
||||||
|
|
||||||
|
var ll = [1, 2]
|
||||||
|
--ll[0]
|
||||||
|
++ll[1]
|
||||||
|
echo ll
|
||||||
|
END
|
||||||
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
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
|
||||||
|
@@ -2768,19 +2768,6 @@ def Test_expr7_negate_add()
|
|||||||
echo + +n
|
echo + +n
|
||||||
END
|
END
|
||||||
CheckDefAndScriptFailure(lines, 'E15:')
|
CheckDefAndScriptFailure(lines, 'E15:')
|
||||||
|
|
||||||
lines =<< trim END
|
|
||||||
var n = 12
|
|
||||||
:1
|
|
||||||
++n
|
|
||||||
END
|
|
||||||
CheckDefAndScriptFailure(lines, 'E1050:')
|
|
||||||
lines =<< trim END
|
|
||||||
var n = 12
|
|
||||||
:1
|
|
||||||
--n
|
|
||||||
END
|
|
||||||
CheckDefAndScriptFailure(lines, 'E1050:')
|
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_expr7_legacy_script()
|
def Test_expr7_legacy_script()
|
||||||
|
@@ -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 */
|
||||||
|
/**/
|
||||||
|
2806,
|
||||||
/**/
|
/**/
|
||||||
2805,
|
2805,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -4688,6 +4688,10 @@ compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
|||||||
op = may_peek_next_line(cctx, *arg, &next);
|
op = may_peek_next_line(cctx, *arg, &next);
|
||||||
if (*op != '+' && *op != '-' && !(*op == '.' && *(op + 1) == '.'))
|
if (*op != '+' && *op != '-' && !(*op == '.' && *(op + 1) == '.'))
|
||||||
break;
|
break;
|
||||||
|
if (op[0] == op[1] && *op != '.' && next)
|
||||||
|
// Finding "++" or "--" on the next line is a separate command.
|
||||||
|
// But ".." is concatenation.
|
||||||
|
break;
|
||||||
oplen = (*op == '.' ? 2 : 1);
|
oplen = (*op == '.' ? 2 : 1);
|
||||||
if (next != NULL)
|
if (next != NULL)
|
||||||
{
|
{
|
||||||
@@ -6395,6 +6399,7 @@ compile_assign_unlet(
|
|||||||
* "const name = expr"
|
* "const name = expr"
|
||||||
* "name = expr"
|
* "name = expr"
|
||||||
* "arg" points to "name".
|
* "arg" points to "name".
|
||||||
|
* "++arg" and "--arg"
|
||||||
* Return NULL for an error.
|
* Return NULL for an error.
|
||||||
* Return "arg" if it does not look like a variable list.
|
* Return "arg" if it does not look like a variable list.
|
||||||
*/
|
*/
|
||||||
@@ -6413,6 +6418,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
char_u *op;
|
char_u *op;
|
||||||
int oplen = 0;
|
int oplen = 0;
|
||||||
int heredoc = FALSE;
|
int heredoc = FALSE;
|
||||||
|
int incdec = FALSE;
|
||||||
type_T *rhs_type = &t_any;
|
type_T *rhs_type = &t_any;
|
||||||
char_u *sp;
|
char_u *sp;
|
||||||
int is_decl = is_decl_command(cmdidx);
|
int is_decl = is_decl_command(cmdidx);
|
||||||
@@ -6447,6 +6453,12 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
error_white_both(op, oplen);
|
error_white_both(op, oplen);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (eap->cmdidx == CMD_increment || eap->cmdidx == CMD_decrement)
|
||||||
|
{
|
||||||
|
op = (char_u *)(eap->cmdidx == CMD_increment ? "+=" : "-=");
|
||||||
|
oplen = 2;
|
||||||
|
incdec = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (heredoc)
|
if (heredoc)
|
||||||
{
|
{
|
||||||
@@ -6571,23 +6583,31 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile the expression. Temporarily hide the new local
|
// Compile the expression.
|
||||||
// variable here, it is not available to this expression.
|
|
||||||
if (lhs.lhs_new_local)
|
|
||||||
--cctx->ctx_locals.ga_len;
|
|
||||||
instr_count = instr->ga_len;
|
instr_count = instr->ga_len;
|
||||||
wp = op + oplen;
|
if (incdec)
|
||||||
if (may_get_next_line_error(wp, &p, cctx) == FAIL)
|
|
||||||
{
|
{
|
||||||
|
r = generate_PUSHNR(cctx, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Temporarily hide the new local variable here, it is
|
||||||
|
// not available to this expression.
|
||||||
|
if (lhs.lhs_new_local)
|
||||||
|
--cctx->ctx_locals.ga_len;
|
||||||
|
wp = op + oplen;
|
||||||
|
if (may_get_next_line_error(wp, &p, cctx) == FAIL)
|
||||||
|
{
|
||||||
|
if (lhs.lhs_new_local)
|
||||||
|
++cctx->ctx_locals.ga_len;
|
||||||
|
goto theend;
|
||||||
|
}
|
||||||
|
r = compile_expr0_ext(&p, cctx, &is_const);
|
||||||
if (lhs.lhs_new_local)
|
if (lhs.lhs_new_local)
|
||||||
++cctx->ctx_locals.ga_len;
|
++cctx->ctx_locals.ga_len;
|
||||||
goto theend;
|
if (r == FAIL)
|
||||||
|
goto theend;
|
||||||
}
|
}
|
||||||
r = compile_expr0_ext(&p, cctx, &is_const);
|
|
||||||
if (lhs.lhs_new_local)
|
|
||||||
++cctx->ctx_locals.ga_len;
|
|
||||||
if (r == FAIL)
|
|
||||||
goto theend;
|
|
||||||
}
|
}
|
||||||
else if (semicolon && var_idx == var_count - 1)
|
else if (semicolon && var_idx == var_count - 1)
|
||||||
{
|
{
|
||||||
@@ -9018,9 +9038,11 @@ compile_def_function(
|
|||||||
/*
|
/*
|
||||||
* COMMAND after range
|
* COMMAND after range
|
||||||
* 'text'->func() should not be confused with 'a mark
|
* 'text'->func() should not be confused with 'a mark
|
||||||
|
* "++nr" and "--nr" are eval commands
|
||||||
*/
|
*/
|
||||||
cmd = ea.cmd;
|
cmd = ea.cmd;
|
||||||
if (*cmd != '\'' || starts_with_colon)
|
if (starts_with_colon || !(*cmd == '\''
|
||||||
|
|| (cmd[0] == cmd[1] && (*cmd == '+' || *cmd == '-'))))
|
||||||
{
|
{
|
||||||
ea.cmd = skip_range(ea.cmd, TRUE, NULL);
|
ea.cmd = skip_range(ea.cmd, TRUE, NULL);
|
||||||
if (ea.cmd > cmd)
|
if (ea.cmd > cmd)
|
||||||
@@ -9125,6 +9147,8 @@ compile_def_function(
|
|||||||
case CMD_var:
|
case CMD_var:
|
||||||
case CMD_final:
|
case CMD_final:
|
||||||
case CMD_const:
|
case CMD_const:
|
||||||
|
case CMD_increment:
|
||||||
|
case CMD_decrement:
|
||||||
line = compile_assignment(p, &ea, ea.cmdidx, &cctx);
|
line = compile_assignment(p, &ea, ea.cmdidx, &cctx);
|
||||||
if (line == p)
|
if (line == p)
|
||||||
line = NULL;
|
line = NULL;
|
||||||
|
@@ -159,6 +159,28 @@ vim9_comment_start(char_u *p)
|
|||||||
|
|
||||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "++nr" and "--nr" commands.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ex_incdec(exarg_T *eap)
|
||||||
|
{
|
||||||
|
char_u *cmd = eap->cmd;
|
||||||
|
size_t len = STRLEN(eap->cmd) + 6;
|
||||||
|
|
||||||
|
// This works like "nr += 1" or "nr -= 1".
|
||||||
|
eap->cmd = alloc(len);
|
||||||
|
if (eap->cmd == NULL)
|
||||||
|
return;
|
||||||
|
vim_snprintf((char *)eap->cmd, len, "%s %c= 1", cmd + 2,
|
||||||
|
eap->cmdidx == CMD_increment ? '+' : '-');
|
||||||
|
eap->arg = eap->cmd;
|
||||||
|
eap->cmdidx = CMD_var;
|
||||||
|
ex_let(eap);
|
||||||
|
vim_free(eap->cmd);
|
||||||
|
eap->cmd = cmd;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ":export let Name: type"
|
* ":export let Name: type"
|
||||||
* ":export const Name: type"
|
* ":export const Name: type"
|
||||||
|
Reference in New Issue
Block a user