Compare commits

...

9 Commits

Author SHA1 Message Date
Bram Moolenaar
1c0aa97827 patch 8.2.2148: Vim9: crash when user command doesn't match
Problem:    Vim9: crash when user command doesn't match.
Solution:   Adjust command index. (closes #7479)
2020-12-16 21:43:54 +01:00
Bram Moolenaar
530bed993e patch 8.2.2147: quickfix window title not updated in all tab pages
Problem:    Quickfix window title not updated in all tab pages.
Solution:   Update the quickfix window title in all tab pages. (Yegappan
            Lakshmanan, closes #7481, closes #7466)
2020-12-16 21:02:56 +01:00
Bram Moolenaar
9987fb0b4b patch 8.2.2146: Vim9: automatic conversion of number to string for dict key
Problem:    Vim9: automatic conversion of number to string for dict key.
Solution:   Do not convert number to string. (closes #7474)
2020-12-15 21:41:56 +01:00
Bram Moolenaar
399ea8108c patch 8.2.2145: Vim9: concatenating lists does not adjust type of result
Problem:    Vim9: concatenating lists does not adjust type of result.
Solution:   When list member types differ use "any" member type.
            (closes #7473)
2020-12-15 21:28:57 +01:00
Bram Moolenaar
025cb1ca86 patch 8.2.2144: Vim9: some corner cases not tested
Problem:    Vim9: some corner cases not tested.
Solution:   Add a few tests.
2020-12-14 18:31:27 +01:00
Bram Moolenaar
ec792290eb patch 8.2.2143: Vim9: dead code in compiling :unlet
Problem:    Vim9: dead code in compiling :unlet.
Solution:   Don't check for "!" a second time.
2020-12-13 21:26:56 +01:00
Bram Moolenaar
fffdf4754f patch 8.2.2142: memory leak when heredoc is not terminated
Problem:    Memory leak when heredoc is not terminated.
Solution:   Free heredoc_trimmed.
2020-12-13 21:16:55 +01:00
Bram Moolenaar
8143a53c53 patch 8.2.2141: a user command with try/catch may not catch an expression error
Problem:    A user command with try/catch may not catch an expression error.
Solution:   When an expression fails check for following "|". (closes #7469)
2020-12-13 20:26:29 +01:00
Bram Moolenaar
2a3cd3af45 patch 8.2.2140: build failure with tiny features
Problem:    Build failure with tiny features.
Solution:   Add #ifdef.
2020-12-13 19:22:27 +01:00
13 changed files with 171 additions and 37 deletions

View File

@@ -951,6 +951,11 @@ eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal)
}
if (evaluate)
{
if (vim9script && check_for_string(&tvkey) == FAIL)
{
clear_tv(&tvkey);
goto failret;
}
key = tv_get_string_buf_chk(&tvkey, buf);
if (key == NULL)
{

View File

@@ -2158,7 +2158,10 @@ eval0(
semsg(_(e_invexpr2), arg);
// Some of the expression may not have been consumed. Do not check for
// a next command to avoid more errors.
// a next command to avoid more errors, unless "|" is following, which
// could only be a command separator.
if (eap != NULL && skipwhite(p)[0] == '|' && skipwhite(p)[1] != '|')
eap->nextcmd = check_nextcmd(p);
return FAIL;
}

View File

@@ -3520,7 +3520,7 @@ find_ex_command(
++p;
p = find_ucmd(eap, p, full, NULL, NULL);
}
if (p == eap->cmd)
if (p == NULL || p == eap->cmd)
eap->cmdidx = CMD_SIZE;
}
@@ -3528,6 +3528,7 @@ find_ex_command(
if (eap->cmdidx == CMD_final && p - eap->cmd == 4)
eap->cmdidx = CMD_finally;
#ifdef FEAT_EVAL
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)
@@ -3535,6 +3536,7 @@ find_ex_command(
semsg(_(e_command_not_followed_by_white_space_str), eap->cmd);
eap->cmdidx = CMD_SIZE;
}
#endif
return p;
}

View File

@@ -4431,21 +4431,26 @@ qf_process_qftf_option(void)
}
/*
* Update the w:quickfix_title variable in the quickfix/location list window
* Update the w:quickfix_title variable in the quickfix/location list window in
* all the tab pages.
*/
static void
qf_update_win_titlevar(qf_info_T *qi)
{
qf_list_T *qfl = qf_get_curlist(qi);
tabpage_T *tp;
win_T *win;
win_T *curwin_save;
win_T *save_curwin = curwin;
if ((win = qf_find_win(qi)) != NULL)
FOR_ALL_TAB_WINDOWS(tp, win)
{
curwin_save = curwin;
curwin = win;
qf_set_title_var(qf_get_curlist(qi));
curwin = curwin_save;
if (is_qf_win(win, qi))
{
curwin = win;
qf_set_title_var(qfl);
}
}
curwin = save_curwin;
}
/*

View File

@@ -4165,6 +4165,30 @@ func Test_qftitle()
call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
call assert_equal('Errors', w:quickfix_title)
cclose
" Switching to another quickfix list in one tab page should update the
" quickfix window title and statusline in all the other tab pages also
call setqflist([], 'f')
%bw!
cgetexpr ['file_one:1:1: error in the first quickfix list']
call setqflist([], 'a', {'title': 'first quickfix list'})
cgetexpr ['file_two:2:1: error in the second quickfix list']
call setqflist([], 'a', {'title': 'second quickfix list'})
copen
wincmd t
tabnew two
copen
wincmd t
colder
call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
call assert_equal(1, tabpagewinnr(1))
call assert_equal(1, tabpagewinnr(2))
tabnew
call setqflist([], 'a', {'title': 'new quickfix title'})
call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
%bw!
endfunc
func Test_lbuffer_with_bwipe()

View File

@@ -2199,5 +2199,30 @@ func Test_BufEnter_exception()
%bwipe!
endfunc
" Test for using try/catch in a user command with a failing expression {{{1
func Test_user_command_try_catch()
let lines =<< trim END
function s:throw() abort
throw 'error'
endfunction
command! Execute
\ try
\ | let s:x = s:throw()
\ | catch
\ | let g:caught = 'caught'
\ | endtry
let g:caught = 'no'
Execute
call assert_equal('caught', g:caught)
END
call writefile(lines, 'XtestTryCatch')
source XtestTryCatch
call delete('XtestTryCatch')
unlet g:caught
endfunc
" Modeline {{{1
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

View File

@@ -20,6 +20,9 @@ def Test_edit_wildcards()
edit X`=filename`xx`=filenr`yy
assert_equal('XXtestxx77yy', bufname())
CheckDefFailure(['edit `=xxx`'], 'E1001:')
CheckDefFailure(['edit `="foo"'], 'E1083:')
enddef
def Test_hardcopy_wildcards()
@@ -626,6 +629,20 @@ def Test_put_command()
assert_equal('aaa', getline(4))
bwipe!
CheckDefFailure(['put =xxx'], 'E1001:')
enddef
def Test_put_with_linebreak()
new
var lines =<< trim END
vim9script
pu =split('abc', '\zs')
->join()
END
CheckScriptSuccess(lines)
getline(2)->assert_equal('a b c')
bwipe!
enddef
def Test_command_star_range()
@@ -684,5 +701,14 @@ def Test_cmd_argument_without_colon()
delete('Xfile')
enddef
def Test_ambiguous_user_cmd()
var lines =<< trim END
com Cmd1 eval 0
com Cmd2 eval 0
Cmd
END
CheckScriptFailure(lines, 'E464:')
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

View File

@@ -1317,6 +1317,23 @@ func Test_expr5_fails_channel()
call CheckDefFailure(["var x = 'a' .. test_null_channel()"], 'E1105:', 1)
endfunc
def Test_expr5_list_add()
# concatenating two lists with same member types is OK
var d = {}
for i in ['a'] + ['b']
d = {[i]: 0}
endfor
# concatenating two lists with different member types results in "any"
var lines =<< trim END
var d = {}
for i in ['a'] + [0]
d = {[i]: 0}
endfor
END
CheckDefExecFailure(lines, 'E1012:')
enddef
" test multiply, divide, modulo
def Test_expr6()
var lines =<< trim END
@@ -1972,6 +1989,14 @@ def Test_expr7_dict()
CheckDefFailure(['var x = ({'], 'E723:', 2)
CheckDefExecFailure(['{}[getftype("file")]'], 'E716: Key not present in Dictionary: ""', 1)
# no automatic conversion from number to string
lines =<< trim END
var n = 123
var d = {[n]: 1}
END
CheckDefFailure(lines, 'E1012:', 2)
CheckScriptFailure(['vim9script'] + lines, 'E928:', 3)
enddef
def Test_expr7_dict_vim9script()

View File

@@ -23,6 +23,11 @@ def Test_range_only()
list
assert_equal('three$', Screenline(&lines))
bwipe!
# won't generate anything
if false
:123
endif
enddef
let g:alist = [7]
@@ -1890,6 +1895,9 @@ def Test_for_loop()
enddef
def Test_for_loop_fails()
CheckDefFailure(['for '], 'E1097:')
CheckDefFailure(['for x'], 'E1097:')
CheckDefFailure(['for x in'], 'E1097:')
CheckDefFailure(['for # in range(5)'], 'E690:')
CheckDefFailure(['for i In range(5)'], 'E690:')
CheckDefFailure(['var x = 5', 'for x in range(5)'], 'E1017:')
@@ -3054,18 +3062,6 @@ def Test_no_unknown_error_after_error()
delete('Xdef')
enddef
def Test_put_with_linebreak()
new
var lines =<< trim END
vim9script
pu =split('abc', '\zs')
->join()
END
CheckScriptSuccess(lines)
getline(2)->assert_equal('a b c')
bwipe!
enddef
def InvokeNormal()
exe "norm! :m+1\r"
enddef

View File

@@ -6825,7 +6825,7 @@ func Test_script_lines()
\ ])
call assert_report("Shouldn't be able to define function")
catch
call assert_exception('Vim(function):E126: Missing :endfunction')
call assert_exception('Vim(function):E1145: Missing heredoc end marker: .')
endtry
" :change
@@ -6845,7 +6845,7 @@ func Test_script_lines()
\ ])
call assert_report("Shouldn't be able to define function")
catch
call assert_exception('Vim(function):E126: Missing :endfunction')
call assert_exception('Vim(function):E1145: Missing heredoc end marker: .')
endtry
" :insert
@@ -6865,7 +6865,7 @@ func Test_script_lines()
\ ])
call assert_report("Shouldn't be able to define function")
catch
call assert_exception('Vim(function):E126: Missing :endfunction')
call assert_exception('Vim(function):E1145: Missing heredoc end marker: .')
endtry
endfunc

View File

@@ -3705,6 +3705,7 @@ errret_2:
ret_free:
ga_clear_strings(&argtypes);
vim_free(skip_until);
vim_free(heredoc_trimmed);
vim_free(line_to_free);
vim_free(fudi.fd_newkey);
if (name != name_arg)

View File

@@ -750,6 +750,24 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2148,
/**/
2147,
/**/
2146,
/**/
2145,
/**/
2144,
/**/
2143,
/**/
2142,
/**/
2141,
/**/
2140,
/**/
2139,
/**/

View File

@@ -538,14 +538,15 @@ generate_add_instr(
type_T *type1,
type_T *type2)
{
isn_T *isn = generate_instr_drop(cctx,
vartype == VAR_NUMBER ? ISN_OPNR
: vartype == VAR_LIST ? ISN_ADDLIST
: vartype == VAR_BLOB ? ISN_ADDBLOB
garray_T *stack = &cctx->ctx_type_stack;
isn_T *isn = generate_instr_drop(cctx,
vartype == VAR_NUMBER ? ISN_OPNR
: vartype == VAR_LIST ? ISN_ADDLIST
: vartype == VAR_BLOB ? ISN_ADDBLOB
#ifdef FEAT_FLOAT
: vartype == VAR_FLOAT ? ISN_OPFLOAT
: vartype == VAR_FLOAT ? ISN_OPFLOAT
#endif
: ISN_OPANY, 1);
: ISN_OPANY, 1);
if (vartype != VAR_LIST && vartype != VAR_BLOB
&& type1->tt_type != VAR_ANY
@@ -556,6 +557,14 @@ generate_add_instr(
if (isn != NULL)
isn->isn_arg.op.op_type = EXPR_ADD;
// When concatenating two lists with different member types the member type
// becomes "any".
if (vartype == VAR_LIST
&& type1->tt_type == VAR_LIST && type2->tt_type == VAR_LIST
&& type1->tt_member != type2->tt_member)
(((type_T **)stack->ga_data)[stack->ga_len - 1]) = &t_list_any;
return isn == NULL ? FAIL : OK;
}
@@ -5993,7 +6002,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
// for "[var, var] = expr" drop the "expr" value
if (var_count > 0 && !semicolon)
{
if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
if (generate_instr_drop(cctx, ISN_DROP, 1) == NULL)
goto theend;
}
@@ -6074,12 +6083,6 @@ compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx)
return NULL;
}
if (*p == '!')
{
p = skipwhite(p + 1);
eap->forceit = TRUE;
}
ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD, compile_unlet, cctx);
return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd;
}
@@ -7178,6 +7181,7 @@ compile_put(char_u *arg, exarg_T *eap, cctx_T *cctx)
// Either no range or a number.
// "errormsg" will not be set because the range is ADDR_LINES.
if (parse_cmd_address(eap, &errormsg, FALSE) == FAIL)
// cannot happen
return NULL;
if (eap->addr_count == 0)
lnum = -1;