Compare commits

...

24 Commits

Author SHA1 Message Date
Bram Moolenaar
f33cae6050 patch 8.2.3103: swap test may fail on some systems
Problem:    Swap test may fail on some systems when jobs take longer to exit.
Solution:   Use different file names.
2021-07-04 17:36:54 +02:00
Bram Moolenaar
3777d6e32b patch 8.2.3102: test for crash fix does not fail without the fix
Problem:    Test for crash fix does not fail without the fix.
Solution:   Adjust the test sequence. (closes #8506)
2021-07-04 17:23:25 +02:00
Bram Moolenaar
26e88ec8e2 patch 8.2.3101: missing function prototype for vim_round()
Problem:    Missing function prototype for vim_round().
Solution:   Add the prototype
2021-07-04 17:21:04 +02:00
Bram Moolenaar
67b17a6fc6 patch 8.2.3101: missing function prototype for vim_round()
Problem:    Missing function prototype for vim_round().
Solution:   Add the prototype.
2021-07-04 16:50:55 +02:00
Bram Moolenaar
7a40ff00ed patch 8.2.3100: Vim9: no error when using type with unknown number of args
Problem:    Vim9: no error when using type with unknown number of arguments.
Solution:   Do not ignore argument count of -1. (closes #8492)
2021-07-04 15:54:08 +02:00
Bram Moolenaar
4197828dc6 patch 8.2.3099: Vim9: missing catch/finally not reported at script level
Problem:    Vim9: missing catch/finally not reported at script level.
Solution:   Give an error. (closes #8487)
2021-07-04 14:47:30 +02:00
Bram Moolenaar
999db2346b patch 8.2.3098: popup window test is flaky on MS-Windows with GUI
Problem:    Popup window test is flaky on MS-Windows with GUI.
Solution:   Skip the check in this situation.
2021-07-04 14:00:55 +02:00
Bram Moolenaar
1d97efce0c patch 8.2.3097: crash when using "quit" at recovery prompt
Problem:    Crash when using "quit" at recovery prompt and autocommands are
            triggered.
Solution:   Block autocommands when creating an empty buffer to use as the
            current buffer. (closes #8506)
2021-07-04 13:27:11 +02:00
Dominique Pelle
6c72fd51a8 patch 8.2.3096: temp files remain after running tests
Problem:    Temp files remain after running tests.
Solution:   Delete the right files. (Dominique Pellé, closes #8509)
2021-07-04 12:30:06 +02:00
Bram Moolenaar
b17ab86e7b patch 8.2.3095: with 'virtualedit' set to "block" block selection is wrong
Problem:    With 'virtualedit' set to "block" block selection is wrong after
            using "$".  (Marco Trosi)
Solution:   Compute the longest selected line. (closes #8495)
2021-07-03 22:15:17 +02:00
Dominique Pelle
c60e959cba patch 8.2.3094: Test_popup_atcursor_pos() fails without the conceal feature
Problem:    Test_popup_atcursor_pos() fails without the conceal feature.
Solution:   Add a check for the conceal feature. (Dominique Pellé,
            closes #8505)
2021-07-03 21:41:38 +02:00
Bram Moolenaar
fb773a3e0a patch 8.2.3093: tablabel_tooltip test fails with Athena
Problem:    tablabel_tooltip test fails with Athena. (Dominique Pellé)
Solution:   Skip the test when using Athena. (closes #8508)
2021-07-03 21:37:59 +02:00
Dominique Pelle
74509239df patch 8.2.3092: Vim9: builtin function test fails without +channel feature
Problem:    Vim9: builtin function test fails without the +channel feature.
Solution:   Check the +channel feature is supported. (Dominique Pellé,
            closes #8507)
2021-07-03 19:27:37 +02:00
Bram Moolenaar
e28d9b3bd4 patch 8.2.3091: Vim9: default argument expr. cannot use previous argument
Problem:    Vim9: default argument expression cannot use previous argument
Solution:   Correct argument index. (closes #8496)
2021-07-03 18:56:53 +02:00
Bram Moolenaar
00aaa512d5 patch 8.2.3090: in rare cases the cursor may be somewhere in a folded line
Problem:    With concealing enabled and indirectly closing a fold the cursor
            may be somewhere in a folded line.
Solution:   Recompute the cursor position when the cursor line can be
            concealed. (closes #8480)
2021-07-03 18:04:11 +02:00
Bram Moolenaar
20cc528320 patch 8.2.3089: garbage collection has useless code
Problem:    Garbage collection has useless code.
Solution:   Bail out when aborting. (closes #8504)
2021-07-03 16:33:16 +02:00
Bram Moolenaar
9cee4a1c9c patch 8.2.3088: with 'virtualedit' set to "block" Visual highlight is wrong
Problem:    With 'virtualedit' set to "block" Visual highlight is wrong after
            using "$".  (Marco Trosi)
Solution:   Do not set w_old_cursor_lcol to MAXCOL. (closes #8495)
2021-07-03 15:08:37 +02:00
Bram Moolenaar
fcde67c99f patch 8.2.3087: Gemtext files are not recognized
Problem:    Gemtext files are not recognized.
Solution:   Recognize .gmi and .gemini files. (closes #8427)
2021-07-03 13:51:44 +02:00
Bram Moolenaar
6fc0161682 patch 8.2.3086: Vim9: breakpoint on "for" does not work
Problem:    Vim9: breakpoint on "for" does not work.
Solution:   Use the right line number in ISN_DEBUG. (closes #8486)
2021-07-03 13:36:31 +02:00
Izhak Jakov
acbb4b5720 patch 8.2.3085: JSONC files are not recognized
Problem:    JSONC files are not recognized.
Solution:   Recognize .jsonc files. (Izhak Jakov, closes #8500)
2021-07-03 13:09:37 +02:00
Yegappan Lakshmanan
a26f56f675 patch 8.2.3084: Vim9: builtin function argument types are not checked
Problem:    Vim9: builtin function argument types are not checked at compile
            time.
Solution:   Add argument types. (Yegappan Lakshmanan, closes #8503)
2021-07-03 11:58:12 +02:00
Christian Brabandt
72463f883c patch 8.2.3083: crash when passing null string to charclass()
Problem:    Crash when passing null string to charclass().
Solution:   Bail out when string pointer is NULL. (Christian Brabandt,
            closes #8498, closes #8260)
2021-07-02 20:19:31 +02:00
Bram Moolenaar
b836f631db patch 8.2.3082: a channel command "echoerr" does not show anything
Problem:    A channel command "echoerr" does not show anything.
Solution:   Do not use silent errors when using an "echoerr" command.
            (closes #8494)
2021-07-01 22:11:28 +02:00
Alisue
11a632d60b patch 8.2.3081: cannot catch errors in a channel command
Problem:    Cannot catch errors in a channel command.
Solution:   Instead of skipping the error make it silent. (closes #8477)
2021-06-30 22:01:02 +02:00
34 changed files with 1003 additions and 221 deletions

View File

@@ -8219,6 +8219,8 @@ prompt_getprompt({buf}) *prompt_getprompt()*
Can also be used as a |method|: >
GetBuffer()->prompt_getprompt()
< {only available when compiled with the |+channel| feature}
prompt_setcallback({buf}, {expr}) *prompt_setcallback()*
Set prompt callback for buffer {buf} to {expr}. When {expr}
@@ -8252,6 +8254,7 @@ prompt_setcallback({buf}, {expr}) *prompt_setcallback()*
< Can also be used as a |method|: >
GetBuffer()->prompt_setcallback(callback)
< {only available when compiled with the |+channel| feature}
prompt_setinterrupt({buf}, {expr}) *prompt_setinterrupt()*
Set a callback for buffer {buf} to {expr}. When {expr} is an
@@ -8265,6 +8268,8 @@ prompt_setinterrupt({buf}, {expr}) *prompt_setinterrupt()*
Can also be used as a |method|: >
GetBuffer()->prompt_setinterrupt(callback)
< {only available when compiled with the |+channel| feature}
prompt_setprompt({buf}, {text}) *prompt_setprompt()*
Set prompt for buffer {buf} to {text}. You most likely want
{text} to end in a space.
@@ -8275,6 +8280,8 @@ prompt_setprompt({buf}, {text}) *prompt_setprompt()*
Can also be used as a |method|: >
GetBuffer()->prompt_setprompt('command: ')
< {only available when compiled with the |+channel| feature}
prop_ functions are documented here: |text-prop-functions|
pum_getpos() *pum_getpos()*

View File

@@ -650,6 +650,9 @@ au BufNewFile,BufRead *.mo,*.gdmo setf gdmo
" Gedcom
au BufNewFile,BufRead *.ged,lltxxxxx.txt setf gedcom
" Gemtext
au BufNewFile,BufRead *.gmi,*.gemini setf gemtext
" Gift (Moodle)
autocmd BufRead,BufNewFile *.gift setf gift
@@ -868,6 +871,9 @@ au BufNewFile,BufRead *.json-patch setf json
" Jupyter Notebook is also json
au BufNewFile,BufRead *.ipynb setf json
" JSONC
au BufNewFile,BufRead *.jsonc setf jsonc
" Kixtart
au BufNewFile,BufRead *.kix setf kix

View File

@@ -1130,7 +1130,12 @@ handle_swap_exists(bufref_T *old_curbuf)
close_buffer(curwin, curbuf, DOBUF_UNLOAD, FALSE, FALSE);
if (old_curbuf == NULL || !bufref_valid(old_curbuf)
|| old_curbuf->br_buf == curbuf)
{
// Block autocommands here because curwin->w_buffer is NULL.
block_autocmds();
buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
unblock_autocmds();
}
else
buf = old_curbuf->br_buf;
if (buf != NULL)

View File

@@ -2486,12 +2486,17 @@ channel_exe_cmd(channel_T *channel, ch_part_T part, typval_T *argv)
if (STRCMP(cmd, "ex") == 0)
{
int called_emsg_before = called_emsg;
int called_emsg_before = called_emsg;
char_u *p = arg;
int do_emsg_silent;
ch_log(channel, "Executing ex command '%s'", (char *)arg);
++emsg_silent;
do_emsg_silent = !checkforcmd(&p, "echoerr", 5);
if (do_emsg_silent)
++emsg_silent;
do_cmdline_cmd(arg);
--emsg_silent;
if (do_emsg_silent)
--emsg_silent;
if (called_emsg > called_emsg_before)
ch_log(channel, "Ex command error: '%s'",
(char *)get_vim_var_str(VV_ERRMSG));
@@ -2545,7 +2550,8 @@ channel_exe_cmd(channel_T *channel, ch_part_T part, typval_T *argv)
char_u *json = NULL;
// Don't pollute the display with errors.
++emsg_skip;
// Do generate the errors so that try/catch works.
++emsg_silent;
if (!is_call)
{
ch_log(channel, "Evaluating expression '%s'", (char *)arg);
@@ -2581,7 +2587,7 @@ channel_exe_cmd(channel_T *channel, ch_part_T part, typval_T *argv)
vim_free(json);
}
}
--emsg_skip;
--emsg_silent;
if (tv == &res_tv)
clear_tv(tv);
else

View File

@@ -1379,6 +1379,12 @@ fold_line(
curwin->w_cline_folded = TRUE;
curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
}
# ifdef FEAT_CONCEAL
// When the line was not folded w_wrow may have been set, recompute it.
if (wp == curwin && lnum == wp->w_cursor.lnum && conceal_cursor_line(wp))
curs_columns(TRUE);
# endif
}
#endif
@@ -2003,12 +2009,41 @@ win_update(win_T *wp)
ve_flags = VE_ALL;
#endif
getvcols(wp, &VIsual, &curwin->w_cursor, &fromc, &toc);
++toc;
#if defined(FEAT_LINEBREAK)
ve_flags = save_ve_flags;
#endif
++toc;
// Highlight to the end of the line, unless 'virtualedit' has
// "block".
if (curwin->w_curswant == MAXCOL)
toc = MAXCOL;
{
if (ve_flags & VE_BLOCK)
{
pos_T pos;
int cursor_above =
curwin->w_cursor.lnum < VIsual.lnum;
// Need to find the longest line.
toc = 0;
pos.coladd = 0;
for (pos.lnum = curwin->w_cursor.lnum; cursor_above
? pos.lnum <= VIsual.lnum
: pos.lnum >= VIsual.lnum;
pos.lnum += cursor_above ? 1 : -1)
{
colnr_T t;
pos.col = STRLEN(ml_get_buf(wp->w_buffer,
pos.lnum, FALSE));
getvvcol(wp, &pos, NULL, NULL, &t);
if (toc < t)
toc = t;
}
++toc;
}
else
toc = MAXCOL;
}
if (fromc != wp->w_old_cursor_fcol
|| toc != wp->w_old_cursor_lcol)

View File

@@ -267,6 +267,33 @@ arg_number(type_T *type, argcontext_T *context)
return check_arg_type(&t_number, type, context);
}
/*
* Check "type" is a dict of 'any'.
*/
static int
arg_dict_any(type_T *type, argcontext_T *context)
{
return check_arg_type(&t_dict_any, type, context);
}
/*
* Check "type" is a list of numbers.
*/
static int
arg_list_number(type_T *type, argcontext_T *context)
{
return check_arg_type(&t_list_number, type, context);
}
/*
* Check "type" is a list of strings.
*/
static int
arg_list_string(type_T *type, argcontext_T *context)
{
return check_arg_type(&t_list_string, type, context);
}
/*
* Check "type" is a string.
*/
@@ -301,6 +328,18 @@ arg_list_or_blob(type_T *type, argcontext_T *context)
return FAIL;
}
/*
* Check "type" is a string or a number
*/
static int
arg_string_or_nr(type_T *type, argcontext_T *context)
{
if (type->tt_type == VAR_ANY
|| type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER)
return OK;
arg_type_mismatch(&t_string, type, context->arg_idx + 1);
return FAIL;
}
/*
* Check "type" is a string or a list of strings.
*/
@@ -404,14 +443,22 @@ arg_extend3(type_T *type, argcontext_T *context)
*/
argcheck_T arg1_string[] = {arg_string};
argcheck_T arg1_number[] = {arg_number};
argcheck_T arg1_dict[] = {arg_dict_any};
argcheck_T arg1_list_number[] = {arg_list_number};
argcheck_T arg1_string_list[] = {arg_list_string};
argcheck_T arg1_float_or_nr[] = {arg_float_or_nr};
argcheck_T arg1_string_or_nr[] = {arg_string_or_nr};
argcheck_T arg1_string_or_list[] = {arg_string_or_list};
argcheck_T arg2_float_or_nr[] = {arg_float_or_nr, arg_float_or_nr};
argcheck_T arg2_number[] = {arg_number, arg_number};
argcheck_T arg2_string[] = {arg_string, arg_string};
argcheck_T arg2_list_number[] = {arg_list_number, arg_list_number};
argcheck_T arg2_listblob_item[] = {arg_list_or_blob, arg_item_of_prev};
argcheck_T arg2_execute[] = {arg_string_or_list, arg_string};
argcheck_T arg23_extend[] = {arg_list_or_dict, arg_same_as_prev, arg_extend3};
argcheck_T arg23_extendnew[] = {arg_list_or_dict, arg_same_struct_as_prev, arg_extend3};
argcheck_T arg3_string[] = {arg_string, arg_string, arg_string};
argcheck_T arg3_number[] = {arg_number, arg_number, arg_number};
argcheck_T arg3_string_nr_bool[] = {arg_string, arg_number, arg_bool};
argcheck_T arg3_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number};
@@ -732,7 +779,7 @@ static funcentry_T global_functions[] =
NULL
#endif
},
{"balloon_show", 1, 1, FEARG_1, NULL,
{"balloon_show", 1, 1, FEARG_1, arg1_string_or_list,
ret_void,
#ifdef FEAT_BEVAL
f_balloon_show
@@ -740,7 +787,7 @@ static funcentry_T global_functions[] =
NULL
#endif
},
{"balloon_split", 1, 1, FEARG_1, NULL,
{"balloon_split", 1, 1, FEARG_1, arg1_string,
ret_list_string,
#if defined(FEAT_BEVAL_TERM)
f_balloon_split
@@ -752,31 +799,31 @@ static funcentry_T global_functions[] =
ret_string, f_browse},
{"browsedir", 2, 2, 0, NULL,
ret_string, f_browsedir},
{"bufadd", 1, 1, FEARG_1, NULL,
{"bufadd", 1, 1, FEARG_1, arg1_string,
ret_number, f_bufadd},
{"bufexists", 1, 1, FEARG_1, NULL,
{"bufexists", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number_bool, f_bufexists},
{"buffer_exists", 1, 1, FEARG_1, NULL, // obsolete
{"buffer_exists", 1, 1, FEARG_1, arg1_string_or_nr, // obsolete
ret_number_bool, f_bufexists},
{"buffer_name", 0, 1, FEARG_1, NULL, // obsolete
{"buffer_name", 0, 1, FEARG_1, arg1_string_or_nr, // obsolete
ret_string, f_bufname},
{"buffer_number", 0, 1, FEARG_1, NULL, // obsolete
ret_number, f_bufnr},
{"buflisted", 1, 1, FEARG_1, NULL,
{"buflisted", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number_bool, f_buflisted},
{"bufload", 1, 1, FEARG_1, NULL,
{"bufload", 1, 1, FEARG_1, arg1_string_or_nr,
ret_void, f_bufload},
{"bufloaded", 1, 1, FEARG_1, NULL,
{"bufloaded", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number_bool, f_bufloaded},
{"bufname", 0, 1, FEARG_1, NULL,
{"bufname", 0, 1, FEARG_1, arg1_string_or_nr,
ret_string, f_bufname},
{"bufnr", 0, 2, FEARG_1, NULL,
ret_number, f_bufnr},
{"bufwinid", 1, 1, FEARG_1, NULL,
{"bufwinid", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_bufwinid},
{"bufwinnr", 1, 1, FEARG_1, NULL,
{"bufwinnr", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_bufwinnr},
{"byte2line", 1, 1, FEARG_1, NULL,
{"byte2line", 1, 1, FEARG_1, arg1_number,
ret_number, f_byte2line},
{"byteidx", 2, 2, FEARG_1, NULL,
ret_number, f_byteidx},
@@ -826,15 +873,15 @@ static funcentry_T global_functions[] =
ret_number, f_changenr},
{"char2nr", 1, 2, FEARG_1, NULL,
ret_number, f_char2nr},
{"charclass", 1, 1, FEARG_1, NULL,
{"charclass", 1, 1, FEARG_1, arg1_string,
ret_number, f_charclass},
{"charcol", 1, 1, FEARG_1, NULL,
ret_number, f_charcol},
{"charidx", 2, 3, FEARG_1, NULL,
ret_number, f_charidx},
{"chdir", 1, 1, FEARG_1, NULL,
{"chdir", 1, 1, FEARG_1, arg1_string,
ret_string, f_chdir},
{"cindent", 1, 1, FEARG_1, NULL,
{"cindent", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_cindent},
{"clearmatches", 0, 1, FEARG_1, arg1_number,
ret_void, f_clearmatches},
@@ -846,7 +893,7 @@ static funcentry_T global_functions[] =
ret_number, f_complete_add},
{"complete_check", 0, 0, 0, NULL,
ret_number_bool, f_complete_check},
{"complete_info", 0, 1, FEARG_1, NULL,
{"complete_info", 0, 1, FEARG_1, arg1_string_list,
ret_dict_any, f_complete_info},
{"confirm", 1, 4, FEARG_1, NULL,
ret_number, f_confirm},
@@ -878,7 +925,7 @@ static funcentry_T global_functions[] =
ret_number_bool, f_deletebufline},
{"did_filetype", 0, 0, 0, NULL,
ret_number_bool, f_did_filetype},
{"diff_filler", 1, 1, FEARG_1, NULL,
{"diff_filler", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_diff_filler},
{"diff_hlID", 2, 2, FEARG_1, NULL,
ret_number, f_diff_hlID},
@@ -888,37 +935,37 @@ static funcentry_T global_functions[] =
ret_number_bool, f_empty},
{"environ", 0, 0, 0, NULL,
ret_dict_string, f_environ},
{"escape", 2, 2, FEARG_1, NULL,
{"escape", 2, 2, FEARG_1, arg2_string,
ret_string, f_escape},
{"eval", 1, 1, FEARG_1, NULL,
{"eval", 1, 1, FEARG_1, arg1_string,
ret_any, f_eval},
{"eventhandler", 0, 0, 0, NULL,
ret_number_bool, f_eventhandler},
{"executable", 1, 1, FEARG_1, NULL,
{"executable", 1, 1, FEARG_1, arg1_string,
ret_number, f_executable},
{"execute", 1, 2, FEARG_1, arg2_execute,
ret_string, f_execute},
{"exepath", 1, 1, FEARG_1, NULL,
{"exepath", 1, 1, FEARG_1, arg1_string,
ret_string, f_exepath},
{"exists", 1, 1, FEARG_1, NULL,
{"exists", 1, 1, FEARG_1, arg1_string,
ret_number_bool, f_exists},
{"exp", 1, 1, FEARG_1, arg1_float_or_nr,
ret_float, FLOAT_FUNC(f_exp)},
{"expand", 1, 3, FEARG_1, NULL,
ret_any, f_expand},
{"expandcmd", 1, 1, FEARG_1, NULL,
{"expandcmd", 1, 1, FEARG_1, arg1_string,
ret_string, f_expandcmd},
{"extend", 2, 3, FEARG_1, arg23_extend,
ret_first_arg, f_extend},
{"extendnew", 2, 3, FEARG_1, arg23_extendnew,
ret_first_cont, f_extendnew},
{"feedkeys", 1, 2, FEARG_1, NULL,
{"feedkeys", 1, 2, FEARG_1, arg2_string,
ret_void, f_feedkeys},
{"file_readable", 1, 1, FEARG_1, NULL, // obsolete
{"file_readable", 1, 1, FEARG_1, arg1_string, // obsolete
ret_number_bool, f_filereadable},
{"filereadable", 1, 1, FEARG_1, NULL,
{"filereadable", 1, 1, FEARG_1, arg1_string,
ret_number_bool, f_filereadable},
{"filewritable", 1, 1, FEARG_1, NULL,
{"filewritable", 1, 1, FEARG_1, arg1_string,
ret_number, f_filewritable},
{"filter", 2, 2, FEARG_1, NULL,
ret_first_arg, f_filter},
@@ -936,19 +983,19 @@ static funcentry_T global_functions[] =
ret_float, FLOAT_FUNC(f_floor)},
{"fmod", 2, 2, FEARG_1, arg2_float_or_nr,
ret_float, FLOAT_FUNC(f_fmod)},
{"fnameescape", 1, 1, FEARG_1, NULL,
{"fnameescape", 1, 1, FEARG_1, arg1_string,
ret_string, f_fnameescape},
{"fnamemodify", 2, 2, FEARG_1, NULL,
{"fnamemodify", 2, 2, FEARG_1, arg2_string,
ret_string, f_fnamemodify},
{"foldclosed", 1, 1, FEARG_1, NULL,
{"foldclosed", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_foldclosed},
{"foldclosedend", 1, 1, FEARG_1, NULL,
{"foldclosedend", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_foldclosedend},
{"foldlevel", 1, 1, FEARG_1, NULL,
{"foldlevel", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_foldlevel},
{"foldtext", 0, 0, 0, NULL,
ret_string, f_foldtext},
{"foldtextresult", 1, 1, FEARG_1, NULL,
{"foldtextresult", 1, 1, FEARG_1, arg1_string_or_nr,
ret_string, f_foldtextresult},
{"foreground", 0, 0, 0, NULL,
ret_void, f_foreground},
@@ -968,7 +1015,7 @@ static funcentry_T global_functions[] =
ret_list_string, f_getbufline},
{"getbufvar", 2, 3, FEARG_1, NULL,
ret_any, f_getbufvar},
{"getchangelist", 0, 1, FEARG_1, NULL,
{"getchangelist", 0, 1, FEARG_1, arg1_string_or_nr,
ret_list_any, f_getchangelist},
{"getchar", 0, 1, 0, NULL,
ret_any, f_getchar},
@@ -996,17 +1043,17 @@ static funcentry_T global_functions[] =
ret_list_number, f_getcursorcharpos},
{"getcwd", 0, 2, FEARG_1, arg2_number,
ret_string, f_getcwd},
{"getenv", 1, 1, FEARG_1, NULL,
{"getenv", 1, 1, FEARG_1, arg1_string,
ret_any, f_getenv},
{"getfontname", 0, 1, 0, NULL,
{"getfontname", 0, 1, 0, arg1_string,
ret_string, f_getfontname},
{"getfperm", 1, 1, FEARG_1, NULL,
{"getfperm", 1, 1, FEARG_1, arg1_string,
ret_string, f_getfperm},
{"getfsize", 1, 1, FEARG_1, NULL,
{"getfsize", 1, 1, FEARG_1, arg1_string,
ret_number, f_getfsize},
{"getftime", 1, 1, FEARG_1, NULL,
{"getftime", 1, 1, FEARG_1, arg1_string,
ret_number, f_getftime},
{"getftype", 1, 1, FEARG_1, NULL,
{"getftype", 1, 1, FEARG_1, arg1_string,
ret_string, f_getftype},
{"getimstatus", 0, 0, 0, NULL,
ret_number_bool, f_getimstatus},
@@ -1016,7 +1063,7 @@ static funcentry_T global_functions[] =
ret_f_getline, f_getline},
{"getloclist", 1, 2, 0, NULL,
ret_list_or_dict_1, f_getloclist},
{"getmarklist", 0, 1, FEARG_1, NULL,
{"getmarklist", 0, 1, FEARG_1, arg1_string_or_nr,
ret_list_dict_any, f_getmarklist},
{"getmatches", 0, 1, 0, arg1_number,
ret_list_dict_any, f_getmatches},
@@ -1024,15 +1071,15 @@ static funcentry_T global_functions[] =
ret_dict_number, f_getmousepos},
{"getpid", 0, 0, 0, NULL,
ret_number, f_getpid},
{"getpos", 1, 1, FEARG_1, NULL,
{"getpos", 1, 1, FEARG_1, arg1_string,
ret_list_number, f_getpos},
{"getqflist", 0, 1, 0, NULL,
{"getqflist", 0, 1, 0, arg1_dict,
ret_list_or_dict_0, f_getqflist},
{"getreg", 0, 3, FEARG_1, NULL,
ret_getreg, f_getreg},
{"getreginfo", 0, 1, FEARG_1, NULL,
{"getreginfo", 0, 1, FEARG_1, arg1_string,
ret_dict_any, f_getreginfo},
{"getregtype", 0, 1, FEARG_1, NULL,
{"getregtype", 0, 1, FEARG_1, arg1_string,
ret_string, f_getregtype},
{"gettabinfo", 0, 1, FEARG_1, arg1_number,
ret_list_dict_any, f_gettabinfo},
@@ -1042,7 +1089,7 @@ static funcentry_T global_functions[] =
ret_any, f_gettabwinvar},
{"gettagstack", 0, 1, FEARG_1, arg1_number,
ret_dict_any, f_gettagstack},
{"gettext", 1, 1, FEARG_1, NULL,
{"gettext", 1, 1, FEARG_1, arg1_string,
ret_string, f_gettext},
{"getwininfo", 0, 1, FEARG_1, arg1_number,
ret_list_dict_any, f_getwininfo},
@@ -1056,7 +1103,7 @@ static funcentry_T global_functions[] =
ret_any, f_getwinvar},
{"glob", 1, 4, FEARG_1, NULL,
ret_any, f_glob},
{"glob2regpat", 1, 1, FEARG_1, NULL,
{"glob2regpat", 1, 1, FEARG_1, arg1_string,
ret_string, f_glob2regpat},
{"globpath", 2, 5, FEARG_2, NULL,
ret_any, f_globpath},
@@ -1072,21 +1119,21 @@ static funcentry_T global_functions[] =
ret_number, f_hlID},
{"highlight_exists",1, 1, FEARG_1, NULL, // obsolete
ret_number_bool, f_hlexists},
{"histadd", 2, 2, FEARG_2, NULL,
{"histadd", 2, 2, FEARG_2, arg2_string,
ret_number_bool, f_histadd},
{"histdel", 1, 2, FEARG_1, NULL,
ret_number_bool, f_histdel},
{"histget", 1, 2, FEARG_1, NULL,
ret_string, f_histget},
{"histnr", 1, 1, FEARG_1, NULL,
{"histnr", 1, 1, FEARG_1, arg1_string,
ret_number, f_histnr},
{"hlID", 1, 1, FEARG_1, NULL,
{"hlID", 1, 1, FEARG_1, arg1_string,
ret_number, f_hlID},
{"hlexists", 1, 1, FEARG_1, NULL,
{"hlexists", 1, 1, FEARG_1, arg1_string,
ret_number_bool, f_hlexists},
{"hostname", 0, 0, 0, NULL,
ret_string, f_hostname},
{"iconv", 3, 3, FEARG_1, NULL,
{"iconv", 3, 3, FEARG_1, arg3_string,
ret_string, f_iconv},
{"indent", 1, 1, FEARG_1, NULL,
ret_number, f_indent},
@@ -1096,13 +1143,13 @@ static funcentry_T global_functions[] =
ret_string, f_input},
{"inputdialog", 1, 3, FEARG_1, NULL,
ret_string, f_inputdialog},
{"inputlist", 1, 1, FEARG_1, NULL,
{"inputlist", 1, 1, FEARG_1, arg1_string_list,
ret_number, f_inputlist},
{"inputrestore", 0, 0, 0, NULL,
ret_number_bool, f_inputrestore},
{"inputsave", 0, 0, 0, NULL,
ret_number_bool, f_inputsave},
{"inputsecret", 1, 2, FEARG_1, NULL,
{"inputsecret", 1, 2, FEARG_1, arg2_string,
ret_string, f_inputsecret},
{"insert", 2, 3, FEARG_1, arg3_insert,
ret_first_arg, f_insert},
@@ -1110,7 +1157,7 @@ static funcentry_T global_functions[] =
ret_void, f_interrupt},
{"invert", 1, 1, FEARG_1, arg1_number,
ret_number, f_invert},
{"isdirectory", 1, 1, FEARG_1, NULL,
{"isdirectory", 1, 1, FEARG_1, arg1_string,
ret_number_bool, f_isdirectory},
{"isinf", 1, 1, FEARG_1, arg1_float_or_nr,
ret_number, MATH_FUNC(f_isinf)},
@@ -1118,7 +1165,7 @@ static funcentry_T global_functions[] =
ret_number_bool, f_islocked},
{"isnan", 1, 1, FEARG_1, arg1_float_or_nr,
ret_number_bool, MATH_FUNC(f_isnan)},
{"items", 1, 1, FEARG_1, NULL,
{"items", 1, 1, FEARG_1, arg1_dict,
ret_list_any, f_items},
{"job_getchannel", 1, 1, FEARG_1, NULL,
ret_channel, JOB_FUNC(f_job_getchannel)},
@@ -1134,15 +1181,15 @@ static funcentry_T global_functions[] =
ret_number_bool, JOB_FUNC(f_job_stop)},
{"join", 1, 2, FEARG_1, NULL,
ret_string, f_join},
{"js_decode", 1, 1, FEARG_1, NULL,
{"js_decode", 1, 1, FEARG_1, arg1_string,
ret_any, f_js_decode},
{"js_encode", 1, 1, FEARG_1, NULL,
ret_string, f_js_encode},
{"json_decode", 1, 1, FEARG_1, NULL,
{"json_decode", 1, 1, FEARG_1, arg1_string,
ret_any, f_json_decode},
{"json_encode", 1, 1, FEARG_1, NULL,
ret_string, f_json_encode},
{"keys", 1, 1, FEARG_1, NULL,
{"keys", 1, 1, FEARG_1, arg1_dict,
ret_list_string, f_keys},
{"last_buffer_nr", 0, 0, 0, NULL, // obsolete
ret_number, f_last_buffer_nr},
@@ -1154,9 +1201,9 @@ static funcentry_T global_functions[] =
ret_number, f_libcallnr},
{"line", 1, 2, FEARG_1, NULL,
ret_number, f_line},
{"line2byte", 1, 1, FEARG_1, NULL,
{"line2byte", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_line2byte},
{"lispindent", 1, 1, FEARG_1, NULL,
{"lispindent", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_lispindent},
{"list2str", 1, 2, FEARG_1, NULL,
ret_string, f_list2str},
@@ -1214,7 +1261,7 @@ static funcentry_T global_functions[] =
ret_list_any, f_matchstrpos},
{"max", 1, 1, FEARG_1, NULL,
ret_number, f_max},
{"menu_info", 1, 2, FEARG_1, NULL,
{"menu_info", 1, 2, FEARG_1, arg2_string,
ret_dict_any,
#ifdef FEAT_MENU
f_menu_info
@@ -1236,7 +1283,7 @@ static funcentry_T global_functions[] =
NULL
#endif
},
{"nextnonblank", 1, 1, FEARG_1, NULL,
{"nextnonblank", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_nextnonblank},
{"nr2char", 1, 2, FEARG_1, NULL,
ret_string, f_nr2char},
@@ -1296,11 +1343,11 @@ static funcentry_T global_functions[] =
ret_void, PROP_FUNC(f_popup_show)},
{"pow", 2, 2, FEARG_1, arg2_float_or_nr,
ret_float, FLOAT_FUNC(f_pow)},
{"prevnonblank", 1, 1, FEARG_1, NULL,
{"prevnonblank", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_prevnonblank},
{"printf", 1, 19, FEARG_2, NULL,
ret_string, f_printf},
{"prompt_getprompt", 1, 1, FEARG_1, NULL,
{"prompt_getprompt", 1, 1, FEARG_1, arg1_string_or_nr,
ret_string, JOB_FUNC(f_prompt_getprompt)},
{"prompt_setcallback", 2, 2, FEARG_1, NULL,
ret_void, JOB_FUNC(f_prompt_setcallback)},
@@ -1356,11 +1403,11 @@ static funcentry_T global_functions[] =
NULL
#endif
},
{"rand", 0, 1, FEARG_1, NULL,
{"rand", 0, 1, FEARG_1, arg1_list_number,
ret_number, f_rand},
{"range", 1, 3, FEARG_1, NULL,
ret_list_number, f_range},
{"readblob", 1, 1, FEARG_1, NULL,
{"readblob", 1, 1, FEARG_1, arg1_string,
ret_blob, f_readblob},
{"readdir", 1, 3, FEARG_1, NULL,
ret_list_string, f_readdir},
@@ -1374,15 +1421,15 @@ static funcentry_T global_functions[] =
ret_string, f_reg_executing},
{"reg_recording", 0, 0, 0, NULL,
ret_string, f_reg_recording},
{"reltime", 0, 2, FEARG_1, NULL,
{"reltime", 0, 2, FEARG_1, arg2_list_number,
ret_list_any, f_reltime},
{"reltimefloat", 1, 1, FEARG_1, NULL,
{"reltimefloat", 1, 1, FEARG_1, arg1_list_number,
ret_float, FLOAT_FUNC(f_reltimefloat)},
{"reltimestr", 1, 1, FEARG_1, NULL,
{"reltimestr", 1, 1, FEARG_1, arg1_list_number,
ret_string, f_reltimestr},
{"remote_expr", 2, 4, FEARG_1, NULL,
ret_string, f_remote_expr},
{"remote_foreground", 1, 1, FEARG_1, NULL,
{"remote_foreground", 1, 1, FEARG_1, arg1_string,
ret_string, f_remote_foreground},
{"remote_peek", 1, 2, FEARG_1, NULL,
ret_number, f_remote_peek},
@@ -1390,15 +1437,15 @@ static funcentry_T global_functions[] =
ret_string, f_remote_read},
{"remote_send", 2, 3, FEARG_1, NULL,
ret_string, f_remote_send},
{"remote_startserver", 1, 1, FEARG_1, NULL,
{"remote_startserver", 1, 1, FEARG_1, arg1_string,
ret_void, f_remote_startserver},
{"remove", 2, 3, FEARG_1, NULL,
ret_remove, f_remove},
{"rename", 2, 2, FEARG_1, NULL,
{"rename", 2, 2, FEARG_1, arg2_string,
ret_number_bool, f_rename},
{"repeat", 2, 2, FEARG_1, NULL,
ret_first_arg, f_repeat},
{"resolve", 1, 1, FEARG_1, NULL,
{"resolve", 1, 1, FEARG_1, arg1_string,
ret_string, f_resolve},
{"reverse", 1, 1, FEARG_1, NULL,
ret_first_arg, f_reverse},
@@ -1420,7 +1467,7 @@ static funcentry_T global_functions[] =
ret_list_number, f_screenchars},
{"screencol", 0, 0, 0, NULL,
ret_number, f_screencol},
{"screenpos", 3, 3, FEARG_1, NULL,
{"screenpos", 3, 3, FEARG_1, arg3_number,
ret_dict_number, f_screenpos},
{"screenrow", 0, 0, 0, NULL,
ret_number, f_screenrow},
@@ -1428,7 +1475,7 @@ static funcentry_T global_functions[] =
ret_string, f_screenstring},
{"search", 1, 5, FEARG_1, NULL,
ret_number, f_search},
{"searchcount", 0, 1, FEARG_1, NULL,
{"searchcount", 0, 1, FEARG_1, arg1_dict,
ret_dict_any, f_searchcount},
{"searchdecl", 1, 3, FEARG_1, NULL,
ret_number_bool, f_searchdecl},
@@ -1450,7 +1497,7 @@ static funcentry_T global_functions[] =
ret_void, f_setcellwidths},
{"setcharpos", 2, 2, FEARG_2, NULL,
ret_number_bool, f_setcharpos},
{"setcharsearch", 1, 1, FEARG_1, NULL,
{"setcharsearch", 1, 1, FEARG_1, arg1_dict,
ret_void, f_setcharsearch},
{"setcmdpos", 1, 1, FEARG_1, arg1_number,
ret_number_bool, f_setcmdpos},
@@ -1458,7 +1505,7 @@ static funcentry_T global_functions[] =
ret_number_bool, f_setcursorcharpos},
{"setenv", 2, 2, FEARG_2, NULL,
ret_void, f_setenv},
{"setfperm", 2, 2, FEARG_1, NULL,
{"setfperm", 2, 2, FEARG_1, arg2_string,
ret_number_bool, f_setfperm},
{"setline", 2, 2, FEARG_2, NULL,
ret_number_bool, f_setline},
@@ -1480,7 +1527,7 @@ static funcentry_T global_functions[] =
ret_number_bool, f_settagstack},
{"setwinvar", 3, 3, FEARG_3, NULL,
ret_void, f_setwinvar},
{"sha256", 1, 1, FEARG_1, NULL,
{"sha256", 1, 1, FEARG_1, arg1_string,
ret_string,
#ifdef FEAT_CRYPT
f_sha256
@@ -1510,7 +1557,7 @@ static funcentry_T global_functions[] =
ret_number_bool, SIGN_FUNC(f_sign_unplace)},
{"sign_unplacelist", 1, 2, FEARG_1, NULL,
ret_list_number, SIGN_FUNC(f_sign_unplacelist)},
{"simplify", 1, 1, FEARG_1, NULL,
{"simplify", 1, 1, FEARG_1, arg1_string,
ret_string, f_simplify},
{"sin", 1, 1, FEARG_1, arg1_float_or_nr,
ret_float, FLOAT_FUNC(f_sin)},
@@ -1526,11 +1573,11 @@ static funcentry_T global_functions[] =
ret_number, SOUND_FUNC(f_sound_playevent)},
{"sound_playfile", 1, 2, FEARG_1, NULL,
ret_number, SOUND_FUNC(f_sound_playfile)},
{"sound_stop", 1, 1, FEARG_1, NULL,
{"sound_stop", 1, 1, FEARG_1, arg1_number,
ret_void, SOUND_FUNC(f_sound_stop)},
{"soundfold", 1, 1, FEARG_1, NULL,
{"soundfold", 1, 1, FEARG_1, arg1_string,
ret_string, f_soundfold},
{"spellbadword", 0, 1, FEARG_1, NULL,
{"spellbadword", 0, 1, FEARG_1, arg1_string,
ret_list_string, f_spellbadword},
{"spellsuggest", 1, 3, FEARG_1, NULL,
ret_list_string, f_spellsuggest},
@@ -1538,9 +1585,9 @@ static funcentry_T global_functions[] =
ret_list_string, f_split},
{"sqrt", 1, 1, FEARG_1, arg1_float_or_nr,
ret_float, FLOAT_FUNC(f_sqrt)},
{"srand", 0, 1, FEARG_1, NULL,
{"srand", 0, 1, FEARG_1, arg1_number,
ret_list_number, f_srand},
{"state", 0, 1, FEARG_1, NULL,
{"state", 0, 1, FEARG_1, arg1_string,
ret_string, f_state},
{"str2float", 1, 1, FEARG_1, arg1_string,
ret_float, FLOAT_FUNC(f_str2float)},
@@ -1570,11 +1617,11 @@ static funcentry_T global_functions[] =
ret_number, f_stridx},
{"string", 1, 1, FEARG_1, NULL,
ret_string, f_string},
{"strlen", 1, 1, FEARG_1, NULL,
{"strlen", 1, 1, FEARG_1, arg1_string_or_nr,
ret_number, f_strlen},
{"strpart", 2, 4, FEARG_1, NULL,
ret_string, f_strpart},
{"strptime", 2, 2, FEARG_1, NULL,
{"strptime", 2, 2, FEARG_1, arg2_string,
ret_number,
#ifdef HAVE_STRPTIME
f_strptime
@@ -1584,23 +1631,23 @@ static funcentry_T global_functions[] =
},
{"strridx", 2, 3, FEARG_1, NULL,
ret_number, f_strridx},
{"strtrans", 1, 1, FEARG_1, NULL,
{"strtrans", 1, 1, FEARG_1, arg1_string,
ret_string, f_strtrans},
{"strwidth", 1, 1, FEARG_1, NULL,
{"strwidth", 1, 1, FEARG_1, arg1_string,
ret_number, f_strwidth},
{"submatch", 1, 2, FEARG_1, NULL,
ret_string, f_submatch},
{"substitute", 4, 4, FEARG_1, NULL,
ret_string, f_substitute},
{"swapinfo", 1, 1, FEARG_1, NULL,
{"swapinfo", 1, 1, FEARG_1, arg1_string,
ret_dict_any, f_swapinfo},
{"swapname", 1, 1, FEARG_1, NULL,
{"swapname", 1, 1, FEARG_1, arg1_string_or_nr,
ret_string, f_swapname},
{"synID", 3, 3, 0, NULL,
ret_number, f_synID},
{"synIDattr", 2, 3, FEARG_1, NULL,
ret_string, f_synIDattr},
{"synIDtrans", 1, 1, FEARG_1, NULL,
{"synIDtrans", 1, 1, FEARG_1, arg1_number,
ret_number, f_synIDtrans},
{"synconcealed", 2, 2, 0, NULL,
ret_list_any, f_synconcealed},
@@ -1610,9 +1657,9 @@ static funcentry_T global_functions[] =
ret_string, f_system},
{"systemlist", 1, 2, FEARG_1, NULL,
ret_list_string, f_systemlist},
{"tabpagebuflist", 0, 1, FEARG_1, NULL,
{"tabpagebuflist", 0, 1, FEARG_1, arg1_number,
ret_list_number, f_tabpagebuflist},
{"tabpagenr", 0, 1, 0, NULL,
{"tabpagenr", 0, 1, 0, arg1_string,
ret_number, f_tabpagenr},
{"tabpagewinnr", 1, 2, FEARG_1, NULL,
ret_number, f_tabpagewinnr},
@@ -1746,13 +1793,13 @@ static funcentry_T global_functions[] =
ret_any, f_test_unknown},
{"test_void", 0, 0, 0, NULL,
ret_void, f_test_void},
{"timer_info", 0, 1, FEARG_1, NULL,
{"timer_info", 0, 1, FEARG_1, arg1_number,
ret_list_dict_any, TIMER_FUNC(f_timer_info)},
{"timer_pause", 2, 2, FEARG_1, NULL,
ret_void, TIMER_FUNC(f_timer_pause)},
{"timer_start", 2, 3, FEARG_1, NULL,
ret_number, TIMER_FUNC(f_timer_start)},
{"timer_stop", 1, 1, FEARG_1, NULL,
{"timer_stop", 1, 1, FEARG_1, arg1_number,
ret_void, TIMER_FUNC(f_timer_stop)},
{"timer_stopall", 0, 0, 0, NULL,
ret_void, TIMER_FUNC(f_timer_stopall)},
@@ -1770,13 +1817,13 @@ static funcentry_T global_functions[] =
ret_number, f_type},
{"typename", 1, 1, FEARG_1, NULL,
ret_string, f_typename},
{"undofile", 1, 1, FEARG_1, NULL,
{"undofile", 1, 1, FEARG_1, arg1_string,
ret_string, f_undofile},
{"undotree", 0, 0, 0, NULL,
ret_dict_any, f_undotree},
{"uniq", 1, 3, FEARG_1, NULL,
ret_list_any, f_uniq},
{"values", 1, 1, FEARG_1, NULL,
{"values", 1, 1, FEARG_1, arg1_dict,
ret_list_any, f_values},
{"virtcol", 1, 1, FEARG_1, NULL,
ret_number, f_virtcol},
@@ -1786,9 +1833,9 @@ static funcentry_T global_functions[] =
ret_number, f_wildmenumode},
{"win_execute", 2, 3, FEARG_2, NULL,
ret_string, f_win_execute},
{"win_findbuf", 1, 1, FEARG_1, NULL,
{"win_findbuf", 1, 1, FEARG_1, arg1_number,
ret_list_number, f_win_findbuf},
{"win_getid", 0, 2, FEARG_1, NULL,
{"win_getid", 0, 2, FEARG_1, arg2_number,
ret_number, f_win_getid},
{"win_gettype", 0, 1, FEARG_1, arg1_number,
ret_string, f_win_gettype},
@@ -1814,11 +1861,11 @@ static funcentry_T global_functions[] =
ret_list_any, f_winlayout},
{"winline", 0, 0, 0, NULL,
ret_number, f_winline},
{"winnr", 0, 1, FEARG_1, NULL,
{"winnr", 0, 1, FEARG_1, arg1_string,
ret_number, f_winnr},
{"winrestcmd", 0, 0, 0, NULL,
ret_string, f_winrestcmd},
{"winrestview", 1, 1, FEARG_1, NULL,
{"winrestview", 1, 1, FEARG_1, arg1_dict,
ret_void, f_winrestview},
{"winsaveview", 0, 0, 0, NULL,
ret_dict_number, f_winsaveview},
@@ -2007,6 +2054,18 @@ internal_func_check_arg_types(
return OK;
}
/*
* Get the argument count for function "idx".
* "argcount" is the total argument count, "min_argcount" the non-optional
* argument count.
*/
void
internal_func_get_argcount(int idx, int *argcount, int *min_argcount)
{
*argcount = global_functions[idx].f_max_argc;
*min_argcount = global_functions[idx].f_min_argc;
}
/*
* Call the "f_retfunc" function to obtain the return type of function "idx".
* "argtypes" is the list of argument types or NULL when there are no

View File

@@ -1670,6 +1670,8 @@ ex_catch(exarg_T *eap)
for (idx = cstack->cs_idx; idx > 0; --idx)
if (cstack->cs_flags[idx] & CSF_TRY)
break;
if (cstack->cs_flags[idx] & CSF_TRY)
cstack->cs_flags[idx] |= CSF_CATCH;
if (cstack->cs_flags[idx] & CSF_FINALLY)
{
// Give up for a ":catch" after ":finally" and ignore it.
@@ -1963,8 +1965,8 @@ ex_endtry(exarg_T *eap)
* made inactive by a ":continue", ":break", ":return", or ":finish" in
* the finally clause. The latter case need not be tested since then
* anything pending has already been discarded. */
skip = did_emsg || got_int || did_throw ||
!(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
skip = did_emsg || got_int || did_throw
|| !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
{
@@ -1992,6 +1994,14 @@ ex_endtry(exarg_T *eap)
{
idx = cstack->cs_idx;
if (in_vim9script()
&& (cstack->cs_flags[idx] & (CSF_CATCH|CSF_FINALLY)) == 0)
{
// try/endtry without any catch or finally: give an error and
// continue.
eap->errmsg = _(e_missing_catch_or_finally);
}
/*
* If we stopped with the exception currently being thrown at this
* try conditional since we didn't know that it doesn't have

View File

@@ -5587,7 +5587,8 @@ f_setcellwidths(typval_T *argvars, typval_T *rettv UNUSED)
void
f_charclass(typval_T *argvars, typval_T *rettv UNUSED)
{
if (check_for_string_arg(argvars, 0) == FAIL)
if (check_for_string_arg(argvars, 0) == FAIL
|| argvars[0].vval.v_string == NULL)
return;
rettv->vval.v_number = mb_get_class(argvars[0].vval.v_string);
}

View File

@@ -6,6 +6,7 @@ int find_internal_func(char_u *name);
int has_internal_func(char_u *name);
char *internal_func_name(int idx);
int internal_func_check_arg_types(type_T **types, int idx, int argcount, cctx_T *cctx);
void internal_func_get_argcount(int idx, int *argcount, int *min_argcount);
type_T *internal_func_ret_type(int idx, int argcount, type_T **argtypes);
int internal_func_is_map(int idx);
int check_internal_func(int idx, int argcount);
@@ -21,7 +22,6 @@ void f_has(typval_T *argvars, typval_T *rettv);
int dynamic_feature(char_u *feature);
void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
void range_list_materialize(list_T *list);
float_T vim_round(float_T f);
long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
void f_string(typval_T *argvars, typval_T *rettv);
/* vim: set ft=c : */

View File

@@ -1,4 +1,4 @@
/* math.c */
/* float.c */
int string2float(char_u *text, float_T *value);
void f_abs(typval_T *argvars, typval_T *rettv);
void f_acos(typval_T *argvars, typval_T *rettv);
@@ -17,6 +17,7 @@ void f_isnan(typval_T *argvars, typval_T *rettv);
void f_log(typval_T *argvars, typval_T *rettv);
void f_log10(typval_T *argvars, typval_T *rettv);
void f_pow(typval_T *argvars, typval_T *rettv);
float_T vim_round(float_T f);
void f_round(typval_T *argvars, typval_T *rettv);
void f_sin(typval_T *argvars, typval_T *rettv);
void f_sinh(typval_T *argvars, typval_T *rettv);

View File

@@ -936,13 +936,14 @@ typedef struct {
# define CSF_TRY 0x0100 // is a ":try"
# define CSF_FINALLY 0x0200 // ":finally" has been passed
# define CSF_THROWN 0x0400 // exception thrown to this try conditional
# define CSF_CAUGHT 0x0800 // exception caught by this try conditional
# define CSF_SILENT 0x1000 // "emsg_silent" reset by ":try"
# define CSF_CATCH 0x0400 // ":catch" has been seen
# define CSF_THROWN 0x0800 // exception thrown to this try conditional
# define CSF_CAUGHT 0x1000 // exception caught by this try conditional
# define CSF_SILENT 0x2000 // "emsg_silent" reset by ":try"
// Note that CSF_ELSE is only used when CSF_TRY and CSF_WHILE are unset
// (an ":if"), and CSF_SILENT is only used when CSF_TRY is set.
//
#define CSF_FUNC_DEF 0x2000 // a function was defined in this block
#define CSF_FUNC_DEF 0x4000 // a function was defined in this block
/*
* What's pending for being reactivated at the ":endtry" of this try
@@ -1610,6 +1611,8 @@ typedef struct
int uf_dfunc_idx; // only valid if uf_def_status is UF_COMPILED
garray_T uf_args; // arguments, including optional arguments
garray_T uf_def_args; // default argument expressions
int uf_args_visible; // normally uf_args.ga_len, less when
// compiling default argument expression.
// for :def (for :function uf_ret_type is NULL)
type_T **uf_arg_types; // argument types (count == uf_args.ga_len)

View File

@@ -14,6 +14,17 @@ func CheckFeature(name)
endif
endfunc
" Command to check for the absence of a feature.
command -nargs=1 CheckNotFeature call CheckNotFeature(<f-args>)
func CheckNotFeature(name)
if !has(a:name, 1)
throw 'Checking for non-existent feature ' .. a:name
endif
if has(a:name)
throw 'Skipped: ' .. a:name .. ' feature present'
endif
endfunc
" Command to check for the presence of a working option.
command -nargs=1 CheckOption call CheckOption(<f-args>)
func CheckOption(name)

View File

@@ -0,0 +1,8 @@
|a+0&#e0e0e08@5> +0&#ffffff0@43
|b+0&#e0e0e08@3| @2| +0&#ffffff0@42
|c+0&#e0e0e08@1| @4| +0&#ffffff0@42
|~+0#4040ff13&| @48
|~| @48
|~| @48
|~| @48
|-+2#0000000&@1| |V|I|S|U|A|L| |B|L|O|C|K| |-@1| +0&&@3|3|x|7| @6|1|,|7| @10|A|l@1|

View File

@@ -0,0 +1,8 @@
|a+0&#e0e0e08@5| | +0&#ffffff0@42
|b+0&#e0e0e08@3| @2| +0&#ffffff0@42
|c+0&#e0e0e08@1> +0&#ffffff0| +0&#e0e0e08@3| +0&#ffffff0@42
|~+0#4040ff13&| @48
|~| @48
|~| @48
|~| @48
|-+2#0000000&@1| |V|I|S|U|A|L| |B|L|O|C|K| |-@1| +0&&@3|3|x|3| @6|3|,|3| @10|A|l@1|

View File

@@ -109,6 +109,11 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
print("sending: {0}".format(cmd))
self.request.sendall(cmd.encode('utf-8'))
response = "ok"
elif decoded[1] == 'echoerr':
cmd = '["ex","echoerr \\\"this is an error\\\""]'
print("sending: {0}".format(cmd))
self.request.sendall(cmd.encode('utf-8'))
response = "ok"
elif decoded[1] == 'bad command':
cmd = '["ex","foo bar"]'
print("sending: {0}".format(cmd))

View File

@@ -115,6 +115,18 @@ func Ch_communicate(port)
call WaitForAssert({-> assert_equal("added2", getline("$"))})
call assert_equal('added1', getline(line('$') - 1))
" Request command "echoerr 'this is an error'".
" This will throw an exception, catch it here.
let caught = 'no'
try
call assert_equal('ok', ch_evalexpr(handle, 'echoerr'))
catch /this is an error/
let caught = 'yes'
endtry
if caught != 'yes'
call assert_report("Expected exception from error message")
endif
" Request command "foo bar", which fails silently.
call assert_equal('ok', ch_evalexpr(handle, 'bad command'))
call WaitForAssert({-> assert_match("E492:.*foo bar", v:errmsg)})

View File

@@ -975,8 +975,7 @@ func Test_debug_def_and_legacy_function()
call RunDbgCmd(buf, 'cont')
call StopVimInTerminal(buf)
call delete('Xtest1.vim')
call delete('Xtest2.vim')
call delete('XtestDebug.vim')
endfunc
func Test_debug_def_function()
@@ -1017,6 +1016,13 @@ func Test_debug_def_function()
# comment
echo "second"
enddef
def g:FuncForLoop()
eval 1
for i in [11, 22, 33]
eval i
endfor
echo "done"
enddef
END
call writefile(file, 'Xtest.vim')
@@ -1062,6 +1068,15 @@ func Test_debug_def_function()
call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"'])
call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
call RunDbgCmd(buf, 'cont')
call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
call RunDbgCmd(buf, 'echo i', ['11'])
call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i'])
call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
call RunDbgCmd(buf, 'echo i', ['22'])
call RunDbgCmd(buf, 'cont')
call StopVimInTerminal(buf)

View File

@@ -192,6 +192,7 @@ let s:filename_checks = {
\ 'gdb': ['.gdbinit'],
\ 'gdmo': ['file.mo', 'file.gdmo'],
\ 'gedcom': ['file.ged', 'lltxxxxx.txt', '/tmp/lltmp', '/tmp/lltmp-file', 'any/tmp/lltmp', 'any/tmp/lltmp-file'],
\ 'gemtext': ['file.gmi', 'file.gemini'],
\ 'gift': ['file.gift'],
\ 'gitcommit': ['COMMIT_EDITMSG', 'MERGE_MSG', 'TAG_EDITMSG'],
\ 'gitconfig': ['file.git/config', '.gitconfig', '.gitmodules', 'file.git/modules//config', '/.config/git/config', '/etc/gitconfig', '/etc/gitconfig.d/file', '/.gitconfig.d/file', 'any/.config/git/config', 'any/.gitconfig.d/file', 'some.git/config', 'some.git/modules/any/config'],
@@ -260,6 +261,7 @@ let s:filename_checks = {
\ 'jovial': ['file.jov', 'file.j73', 'file.jovial'],
\ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file'],
\ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb'],
\ 'jsonc': ['file.jsonc'],
\ 'jsp': ['file.jsp'],
\ 'kconfig': ['Kconfig', 'Kconfig.debug', 'Kconfig.file'],
\ 'kivy': ['file.kv'],

View File

@@ -169,7 +169,8 @@ func Test_strwidth()
if has('float')
call assert_equal(3, strwidth(1.2))
call CheckDefExecAndScriptFailure(['echo strwidth(1.2)'], 'E806:')
call CheckDefFailure(['echo strwidth(1.2)'], 'E1013:')
call CheckScriptFailure(['vim9script', 'echo strwidth(1.2)'], 'E806:')
endif
set ambiwidth&
@@ -236,7 +237,7 @@ func Test_str2nr()
call assert_fails('call str2nr({->2})', 'E729:')
if has('float')
call assert_equal(1, str2nr(1.2))
call CheckDefExecFailure(['echo str2nr(1.2)'], 'E1013:')
call CheckDefFailure(['echo str2nr(1.2)'], 'E1013:')
call CheckScriptFailure(['vim9script', 'echo str2nr(1.2)'], 'E806:')
endif
call assert_fails('call str2nr(10, [])', 'E745:')
@@ -499,7 +500,8 @@ func Test_simplify()
call assert_fails('call simplify({})', 'E731:')
if has('float')
call assert_equal('1.2', simplify(1.2))
call CheckDefExecAndScriptFailure(['echo simplify(1.2)'], 'E806:')
call CheckDefFailure(['echo simplify(1.2)'], 'E1013:')
call CheckScriptFailure(['vim9script', 'echo simplify(1.2)'], 'E806:')
endif
endfunc
@@ -2169,6 +2171,8 @@ func Test_charclass()
call assert_equal(1, charclass('.'))
call assert_equal(2, charclass('x'))
call assert_equal(3, charclass("\u203c"))
" this used to crash vim
call assert_equal(0, "xxx"[-1]->charclass())
endfunc
func Test_eventhandler()

View File

@@ -5,7 +5,8 @@ source vim9.vim
func Test_glob2regpat_invalid()
if has('float')
call assert_equal('^1\.33$', glob2regpat(1.33))
call CheckDefExecAndScriptFailure(['echo glob2regpat(1.33)'], 'E806:')
call CheckDefFailure(['echo glob2regpat(1.2)'], 'E1013:')
call CheckScriptFailure(['vim9script', 'echo glob2regpat(1.2)'], 'E806:')
endif
call assert_fails('call glob2regpat("}")', 'E219:')
call assert_fails('call glob2regpat("{")', 'E220:')

View File

@@ -1118,6 +1118,8 @@ func TestGuiTabToolTip()
endfunc
func Test_gui_tablabel_tooltip()
CheckNotFeature gui_athena
%bw!
" Removing the tabline at the end of this test, reduces the window height by
" one. Save and restore it after the test.

View File

@@ -330,6 +330,7 @@ func Test_closure_error()
let caught_932 = 1
endtry
call assert_equal(1, caught_932)
call delete('Xscript')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -1437,6 +1437,7 @@ endfunc
func Test_popup_atcursor_pos()
CheckScreendump
CheckFeature conceal
let lines =<< trim END
call setline(1, repeat([repeat('-', 60)], 15))
@@ -1549,24 +1550,32 @@ func Test_popup_filter()
redraw
" e is consumed by the filter
let g:eaten = ''
call feedkeys('e', 'xt')
call assert_equal('e', g:eaten)
call feedkeys("\<F9>", 'xt')
call assert_equal("\<F9>", g:eaten)
" 0 is ignored by the filter
let g:ignored = ''
normal $
call assert_equal(9, getcurpos()[2])
call feedkeys('0', 'xt')
call assert_equal('0', g:ignored)
normal! l
call assert_equal(2, getcurpos()[2])
if has('win32') && has('gui_running')
echo "FIXME: this check is very flaky on MS-Windows GUI, the cursor doesn't move"
else
call assert_equal(1, getcurpos()[2])
endif
" x closes the popup
call feedkeys('x', 'xt')
call assert_equal("\<F9>", g:eaten)
call assert_equal(-1, winbufnr(winid))
unlet g:eaten
unlet g:ignored
delfunc MyPopupFilter
call popup_clear()
endfunc

View File

@@ -360,6 +360,7 @@ func Test_swap_prompt_splitwin()
let buf = RunVimInTerminal('', {'rows': 20})
call term_sendkeys(buf, ":set nomore\n")
call term_sendkeys(buf, ":set noruler\n")
call term_sendkeys(buf, ":split Xfile1\n")
call TermWait(buf)
call WaitForAssert({-> assert_match('^\[O\]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: $', term_getline(buf, 20))})
@@ -371,6 +372,21 @@ func Test_swap_prompt_splitwin()
call TermWait(buf)
call WaitForAssert({-> assert_match('^1$', term_getline(buf, 20))})
call StopVimInTerminal(buf)
" This caused Vim to crash when typing "q" at the swap file prompt.
let buf = RunVimInTerminal('-c "au bufadd * let foo_w = wincol()"', {'rows': 18})
call term_sendkeys(buf, ":e Xfile1\<CR>")
call WaitForAssert({-> assert_match('More', term_getline(buf, 18))})
call term_sendkeys(buf, " ")
call WaitForAssert({-> assert_match('^\[O\]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort:', term_getline(buf, 18))})
call term_sendkeys(buf, "q")
call TermWait(buf)
" check that Vim is still running
call term_sendkeys(buf, ":echo 'hello'\<CR>")
call WaitForAssert({-> assert_match('^hello', term_getline(buf, 18))})
call term_sendkeys(buf, ":%bwipe!\<CR>")
call StopVimInTerminal(buf)
%bwipe!
call delete('Xfile1')
endfunc
@@ -486,18 +502,18 @@ endfunc
" Test for renaming a buffer when the swap file is deleted out-of-band
func Test_missing_swap_file()
CheckUnix
new Xfile1
new Xfile2
call delete(swapname(''))
call assert_fails('file Xfile2', 'E301:')
call assert_equal('Xfile2', bufname())
call assert_true(bufexists('Xfile1'))
call assert_fails('file Xfile3', 'E301:')
call assert_equal('Xfile3', bufname())
call assert_true(bufexists('Xfile2'))
call assert_true(bufexists('Xfile3'))
%bw!
endfunc
" Test for :preserve command
func Test_preserve()
new Xfile1
new Xfile4
setlocal noswapfile
call assert_fails('preserve', 'E313:')
bw!
@@ -505,8 +521,8 @@ endfunc
" Test for the v:swapchoice variable
func Test_swapchoice()
call writefile(['aaa', 'bbb'], 'Xfile1')
edit Xfile1
call writefile(['aaa', 'bbb'], 'Xfile5')
edit Xfile5
preserve
let swapfname = swapname('')
let b = readblob(swapfname)
@@ -520,7 +536,7 @@ func Test_swapchoice()
autocmd!
autocmd SwapExists * let v:swapchoice = 'o'
augroup END
edit Xfile1
edit Xfile5
call assert_true(&readonly)
call assert_equal(['aaa', 'bbb'], getline(1, '$'))
%bw!
@@ -532,11 +548,11 @@ func Test_swapchoice()
autocmd SwapExists * let v:swapchoice = 'a'
augroup END
try
edit Xfile1
edit Xfile5
catch /^Vim:Interrupt$/
endtry
call assert_equal('', @%)
call assert_true(bufexists('Xfile1'))
call assert_true(bufexists('Xfile5'))
%bw!
call assert_true(filereadable(swapfname))
@@ -545,12 +561,12 @@ func Test_swapchoice()
autocmd!
autocmd SwapExists * let v:swapchoice = 'd'
augroup END
edit Xfile1
call assert_equal('Xfile1', @%)
edit Xfile5
call assert_equal('Xfile5', @%)
%bw!
call assert_false(filereadable(swapfname))
call delete('Xfile1')
call delete('Xfile5')
call delete(swapfname)
augroup test_swapchoice
autocmd!

View File

@@ -650,6 +650,15 @@ def Test_assignment_list()
d.dd[0] = 0
END
CheckDefExecFailure(lines, 'E1147:', 2)
lines =<< trim END
def OneArg(x: bool)
enddef
def TwoArgs(x: bool, y: bool)
enddef
var fl: list<func(bool, bool, bool)> = [OneArg, TwoArgs]
END
CheckDefExecAndScriptFailure(lines, 'E1012:', 5)
enddef
def Test_assignment_list_any_index()

View File

@@ -180,12 +180,14 @@ def Test_balloon_show()
CheckGui
CheckFeature balloon_eval
assert_fails('balloon_show(10)', 'E1174:')
assert_fails('balloon_show(true)', 'E1174:')
enddef
def Test_balloon_split()
CheckFeature balloon_eval_term
assert_fails('balloon_split([])', 'E1174:')
assert_fails('balloon_split(true)', 'E1174:')
enddef
@@ -206,14 +208,28 @@ def Test_browse()
CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 4')
enddef
def Test_bufadd()
assert_fails('bufadd([])', 'E730:')
enddef
def Test_bufexists()
assert_fails('bufexists(true)', 'E1174')
assert_fails('bufexists(true)', 'E1174:')
enddef
def Test_buflisted()
var res: bool = buflisted('asdf')
assert_equal(false, res)
assert_fails('buflisted(true)', 'E1174')
assert_fails('buflisted(true)', 'E1174:')
assert_fails('buflisted([])', 'E1174:')
enddef
def Test_bufload()
assert_fails('bufload([])', 'E730:')
enddef
def Test_bufloaded()
assert_fails('bufloaded(true)', 'E1174:')
assert_fails('bufloaded([])', 'E1174:')
enddef
def Test_bufname()
@@ -222,6 +238,8 @@ def Test_bufname()
edit OtherFile
bufname('#')->assert_equal('SomeFile')
close
assert_fails('bufname(true)', 'E1138:')
assert_fails('bufname([])', 'E745:')
enddef
def Test_bufnr()
@@ -246,7 +264,19 @@ def Test_bufwinid()
bwipe SomeFile
bwipe OtherFile
assert_fails('bufwinid(true)', 'E1138')
assert_fails('bufwinid(true)', 'E1138:')
assert_fails('bufwinid([])', 'E745:')
enddef
def Test_bufwinnr()
assert_fails('bufwinnr(true)', 'E1138:')
assert_fails('bufwinnr([])', 'E745:')
enddef
def Test_byte2line()
CheckDefFailure(['byte2line("1")'], 'E1013: Argument 1: type mismatch, expected number but got string')
CheckDefFailure(['byte2line([])'], 'E1013: Argument 1: type mismatch, expected number but got list<unknown>')
assert_equal(-1, byte2line(0))
enddef
def Test_call_call()
@@ -259,22 +289,29 @@ def Test_ch_logfile()
if !has('channel')
CheckFeature channel
endif
assert_fails('ch_logfile(true)', 'E1174')
assert_fails('ch_logfile("foo", true)', 'E1174')
assert_fails('ch_logfile(true)', 'E1174:')
assert_fails('ch_logfile("foo", true)', 'E1174:')
enddef
def Test_char2nr()
char2nr('あ', true)->assert_equal(12354)
assert_fails('char2nr(true)', 'E1174')
assert_fails('char2nr(true)', 'E1174:')
enddef
def Test_charclass()
assert_fails('charclass(true)', 'E1174')
assert_fails('charclass(true)', 'E1174:')
enddef
def Test_chdir()
assert_fails('chdir(true)', 'E1174')
assert_fails('chdir(true)', 'E1174:')
enddef
def Test_cindent()
CheckDefFailure(['cindent([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
CheckDefFailure(['cindent(null)'], 'E1013: Argument 1: type mismatch, expected string but got special')
assert_equal(-1, cindent(0))
assert_equal(0, cindent('.'))
enddef
def Test_clearmatches()
@@ -286,7 +323,7 @@ def Test_col()
setline(1, 'asdf')
col([1, '$'])->assert_equal(5)
assert_fails('col(true)', 'E1174')
assert_fails('col(true)', 'E1174:')
enddef
def Test_confirm()
@@ -294,9 +331,16 @@ def Test_confirm()
CheckFeature dialog_con
endif
assert_fails('confirm(true)', 'E1174')
assert_fails('confirm("yes", true)', 'E1174')
assert_fails('confirm("yes", "maybe", 2, true)', 'E1174')
assert_fails('confirm(true)', 'E1174:')
assert_fails('confirm("yes", true)', 'E1174:')
assert_fails('confirm("yes", "maybe", 2, true)', 'E1174:')
enddef
def Test_complete_info()
CheckDefFailure(['complete_info("")'], 'E1013: Argument 1: type mismatch, expected list<string> but got string')
CheckDefFailure(['complete_info({})'], 'E1013: Argument 1: type mismatch, expected list<string> but got dict<unknown>')
assert_equal({'pum_visible': 0, 'mode': '', 'selected': -1, 'items': []}, complete_info())
assert_equal({'mode': '', 'items': []}, complete_info(['mode', 'items']))
enddef
def Test_copy_return_type()
@@ -346,12 +390,32 @@ def Test_delete()
assert_equal(true, res)
enddef
def Test_diff_filler()
CheckDefFailure(['diff_filler([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
CheckDefFailure(['diff_filler(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool')
assert_equal(0, diff_filler(1))
assert_equal(0, diff_filler('.'))
enddef
def Test_escape()
CheckDefFailure(['escape("a", 10)'], 'E1013: Argument 2: type mismatch, expected string but got number')
CheckDefFailure(['escape(10, " ")'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['escape(true, false)'], 'E1013: Argument 1: type mismatch, expected string but got bool')
assert_equal('a\:b', escape("a:b", ":"))
enddef
def Test_eval()
CheckDefFailure(['eval(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['eval(null)'], 'E1013: Argument 1: type mismatch, expected string but got special')
assert_equal(2, eval('1 + 1'))
enddef
def Test_executable()
assert_false(executable(""))
assert_false(executable(test_null_string()))
CheckDefExecFailure(['echo executable(123)'], 'E1174:')
CheckDefExecFailure(['echo executable(true)'], 'E1174:')
CheckDefExecFailure(['echo executable(123)'], 'E1013:')
CheckDefExecFailure(['echo executable(true)'], 'E1013:')
enddef
def Test_execute()
@@ -367,11 +431,16 @@ def Test_execute()
enddef
def Test_exepath()
CheckDefExecFailure(['echo exepath(true)'], 'E1174:')
CheckDefExecFailure(['echo exepath(v:null)'], 'E1174:')
CheckDefExecFailure(['echo exepath(true)'], 'E1013:')
CheckDefExecFailure(['echo exepath(v:null)'], 'E1013:')
CheckDefExecFailure(['echo exepath("")'], 'E1175:')
enddef
def Test_exists()
CheckDefFailure(['exists(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
call assert_equal(1, exists('&tabstop'))
enddef
def Test_expand()
split SomeFile
expand('%', true, true)->assert_equal(['SomeFile'])
@@ -507,6 +576,16 @@ def Test_extend_with_error_function()
CheckScriptFailure(lines, 'E1001: Variable not found: m')
enddef
def Test_feedkeys()
CheckDefFailure(['feedkeys(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['feedkeys("x", 10)'], 'E1013: Argument 2: type mismatch, expected string but got number')
CheckDefFailure(['feedkeys([], {})'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
g:TestVar = 1
feedkeys(":g:TestVar = 789\n", 'xt')
assert_equal(789, g:TestVar)
unlet g:TestVar
enddef
def Test_job_info_return_type()
if has('job')
job_start(&shell)
@@ -521,16 +600,16 @@ def Test_filereadable()
assert_false(filereadable(""))
assert_false(filereadable(test_null_string()))
CheckDefExecFailure(['echo filereadable(123)'], 'E1174:')
CheckDefExecFailure(['echo filereadable(true)'], 'E1174:')
CheckDefExecFailure(['echo filereadable(123)'], 'E1013:')
CheckDefExecFailure(['echo filereadable(true)'], 'E1013:')
enddef
def Test_filewritable()
assert_false(filewritable(""))
assert_false(filewritable(test_null_string()))
CheckDefExecFailure(['echo filewritable(123)'], 'E1174:')
CheckDefExecFailure(['echo filewritable(true)'], 'E1174:')
CheckDefExecFailure(['echo filewritable(123)'], 'E1013:')
CheckDefExecFailure(['echo filewritable(true)'], 'E1013:')
enddef
def Test_finddir()
@@ -620,15 +699,20 @@ def Test_float_funcs_args()
CheckDefFailure(['echo trunc("a")'], 'E1013: Argument 1: type mismatch, expected number but got string')
enddef
def Test_fnameescape()
CheckDefFailure(['fnameescape(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_equal('\+a\%b\|', fnameescape('+a%b|'))
enddef
def Test_fnamemodify()
CheckDefSuccess(['echo fnamemodify(test_null_string(), ":p")'])
CheckDefSuccess(['echo fnamemodify("", ":p")'])
CheckDefSuccess(['echo fnamemodify("file", test_null_string())'])
CheckDefSuccess(['echo fnamemodify("file", "")'])
CheckDefExecFailure(['echo fnamemodify(true, ":p")'], 'E1174: String required for argument 1')
CheckDefExecFailure(['echo fnamemodify(v:null, ":p")'], 'E1174: String required for argument 1')
CheckDefExecFailure(['echo fnamemodify("file", true)'], 'E1174: String required for argument 2')
CheckDefExecFailure(['echo fnamemodify(true, ":p")'], 'E1013: Argument 1: type mismatch, expected string but got bool')
CheckDefExecFailure(['echo fnamemodify(v:null, ":p")'], 'E1013: Argument 1: type mismatch, expected string but got special')
CheckDefExecFailure(['echo fnamemodify("file", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool')
enddef
def Wrong_dict_key_type(items: list<number>): list<number>
@@ -654,6 +738,30 @@ def Test_filter_missing_argument()
res->assert_equal({aa: [1], ac: [3]})
enddef
def Test_foldclosed()
CheckDefFailure(['foldclosed(function("min"))'], 'E1013: Argument 1: type mismatch, expected string but got func(...): any')
assert_equal(-1, foldclosed(1))
assert_equal(-1, foldclosed('$'))
enddef
def Test_foldclosedend()
CheckDefFailure(['foldclosedend(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool')
assert_equal(-1, foldclosedend(1))
assert_equal(-1, foldclosedend('w0'))
enddef
def Test_foldlevel()
CheckDefFailure(['foldlevel(0z10)'], 'E1013: Argument 1: type mismatch, expected string but got blob')
assert_equal(0, foldlevel(1))
assert_equal(0, foldlevel('.'))
enddef
def Test_foldtextresult()
CheckDefFailure(['foldtextresult(1.1)'], 'E1013: Argument 1: type mismatch, expected string but got float')
assert_equal('', foldtextresult(1))
assert_equal('', foldtextresult('.'))
enddef
def Test_fullcommand()
assert_equal('next', fullcommand('n'))
assert_equal('noremap', fullcommand('no'))
@@ -762,36 +870,40 @@ def Test_getloclist_return_type()
d->assert_equal({items: []})
enddef
def Test_getfontname()
CheckDefFailure(['getfontname(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
enddef
def Test_getfperm()
assert_equal('', getfperm(""))
assert_equal('', getfperm(test_null_string()))
CheckDefExecFailure(['echo getfperm(true)'], 'E1174:')
CheckDefExecFailure(['echo getfperm(v:null)'], 'E1174:')
CheckDefExecFailure(['echo getfperm(true)'], 'E1013:')
CheckDefExecFailure(['echo getfperm(v:null)'], 'E1013:')
enddef
def Test_getfsize()
assert_equal(-1, getfsize(""))
assert_equal(-1, getfsize(test_null_string()))
CheckDefExecFailure(['echo getfsize(true)'], 'E1174:')
CheckDefExecFailure(['echo getfsize(v:null)'], 'E1174:')
CheckDefExecFailure(['echo getfsize(true)'], 'E1013:')
CheckDefExecFailure(['echo getfsize(v:null)'], 'E1013:')
enddef
def Test_getftime()
assert_equal(-1, getftime(""))
assert_equal(-1, getftime(test_null_string()))
CheckDefExecFailure(['echo getftime(true)'], 'E1174:')
CheckDefExecFailure(['echo getftime(v:null)'], 'E1174:')
CheckDefExecFailure(['echo getftime(true)'], 'E1013:')
CheckDefExecFailure(['echo getftime(v:null)'], 'E1013:')
enddef
def Test_getftype()
assert_equal('', getftype(""))
assert_equal('', getftype(test_null_string()))
CheckDefExecFailure(['echo getftype(true)'], 'E1174:')
CheckDefExecFailure(['echo getftype(v:null)'], 'E1174:')
CheckDefExecFailure(['echo getftype(true)'], 'E1013:')
CheckDefExecFailure(['echo getftype(v:null)'], 'E1013:')
enddef
def Test_getjumplist()
@@ -800,10 +912,27 @@ def Test_getjumplist()
CheckDefFailure(['echo getjumplist(1, "x")'], 'E1013: Argument 2: type mismatch, expected number but got string')
enddef
def Test_getmarklist()
CheckDefFailure(['getmarklist([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
assert_equal([], getmarklist(10000))
assert_fails('getmarklist("a%b@#")', 'E94:')
enddef
def Test_getmatches()
CheckDefFailure(['echo getmatches("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
enddef
def Test_getpos()
CheckDefFailure(['getpos(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_equal([0, 1, 1, 0], getpos('.'))
assert_equal([0, 0, 0, 0], getpos('a'))
enddef
def Test_getqflist()
CheckDefFailure(['getqflist([])'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>')
call assert_equal({}, getqflist({}))
enddef
def Test_getqflist_return_type()
var l = getqflist()
l->assert_equal([])
@@ -847,6 +976,11 @@ def Test_gettagstack()
CheckDefFailure(['echo gettagstack("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
enddef
def Test_gettext()
CheckDefFailure(['gettext(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_equal('abc', gettext("abc"))
enddef
def Test_getwininfo()
CheckDefFailure(['echo getwininfo("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
enddef
@@ -859,6 +993,11 @@ def Test_glob()
glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim'])
enddef
def Test_glob2regpat()
CheckDefFailure(['glob2regpat(null)'], 'E1013: Argument 1: type mismatch, expected string but got special')
assert_equal('^$', glob2regpat(''))
enddef
def Test_globpath()
globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim'])
enddef
@@ -880,10 +1019,56 @@ def Test_hasmapto()
iunabbrev foo
enddef
def Test_histadd()
CheckDefFailure(['histadd(1, "x")'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['histadd(":", 10)'], 'E1013: Argument 2: type mismatch, expected string but got number')
histadd("search", 'skyblue')
assert_equal('skyblue', histget('/', -1))
enddef
def Test_histnr()
CheckDefFailure(['histnr(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_equal(-1, histnr('abc'))
enddef
def Test_hlID()
CheckDefFailure(['hlID(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_equal(0, hlID('NonExistingHighlight'))
enddef
def Test_hlexists()
CheckDefFailure(['hlexists([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
assert_equal(0, hlexists('NonExistingHighlight'))
enddef
def Test_iconv()
CheckDefFailure(['iconv(1, "from", "to")'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['iconv("abc", 10, "to")'], 'E1013: Argument 2: type mismatch, expected string but got number')
CheckDefFailure(['iconv("abc", "from", 20)'], 'E1013: Argument 3: type mismatch, expected string but got number')
assert_equal('abc', iconv('abc', 'fromenc', 'toenc'))
enddef
def Test_index()
index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3)
enddef
def Test_inputlist()
CheckDefFailure(['inputlist(10)'], 'E1013: Argument 1: type mismatch, expected list<string> but got number')
CheckDefFailure(['inputlist("abc")'], 'E1013: Argument 1: type mismatch, expected list<string> but got string')
CheckDefFailure(['inputlist([1, 2, 3])'], 'E1013: Argument 1: type mismatch, expected list<string> but got list<number>')
feedkeys("2\<CR>", 't')
var r: number = inputlist(['a', 'b', 'c'])
assert_equal(2, r)
enddef
def Test_inputsecret()
CheckDefFailure(['inputsecret(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['inputsecret("Pass:", 20)'], 'E1013: Argument 2: type mismatch, expected string but got number')
feedkeys("\<CR>", 't')
var ans: string = inputsecret('Pass:', '123')
assert_equal('123', ans)
enddef
let s:number_one = 1
let s:number_two = 2
let s:string_keep = 'keep'
@@ -928,13 +1113,51 @@ def Test_invert()
CheckDefFailure(['echo invert("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
enddef
def Test_isdirectory()
CheckDefFailure(['isdirectory(1.1)'], 'E1013: Argument 1: type mismatch, expected string but got float')
assert_false(isdirectory('NonExistingDir'))
enddef
def Test_items()
CheckDefFailure(['[]->items()'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>')
assert_equal([['a', 10], ['b', 20]], {'a': 10, 'b': 20}->items())
assert_equal([], {}->items())
enddef
def Test_js_decode()
CheckDefFailure(['js_decode(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_equal([1, 2], js_decode('[1,2]'))
enddef
def Test_json_decode()
CheckDefFailure(['json_decode(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool')
assert_equal(1.0, json_decode('1.0'))
enddef
def Test_keys()
CheckDefFailure(['keys([])'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>')
assert_equal(['a'], {a: 'v'}->keys())
assert_equal([], {}->keys())
enddef
def Test_keys_return_type()
const var: list<string> = {a: 1, b: 2}->keys()
var->assert_equal(['a', 'b'])
enddef
def Test_line()
assert_fails('line(true)', 'E1174')
assert_fails('line(true)', 'E1174:')
enddef
def Test_line2byte()
CheckDefFailure(['line2byte(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool')
assert_equal(-1, line2byte(1))
assert_equal(-1, line2byte(10000))
enddef
def Test_lispindent()
CheckDefFailure(['lispindent({})'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>')
assert_equal(0, lispindent(1))
enddef
def Test_list2str_str2list_utf8()
@@ -1080,6 +1303,13 @@ def Test_max()
assert_equal([4, 5], l2)
enddef
def Test_menu_info()
CheckDefFailure(['menu_info(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['menu_info(10, "n")'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['menu_info("File", 10)'], 'E1013: Argument 2: type mismatch, expected string but got number')
assert_equal({}, menu_info('aMenu'))
enddef
def Test_min()
g:flag = true
var l1: list<number> = g:flag
@@ -1094,6 +1324,11 @@ def Test_min()
assert_equal([4, 5], l2)
enddef
def Test_nextnonblank()
CheckDefFailure(['nextnonblank(null)'], 'E1013: Argument 1: type mismatch, expected string but got special')
assert_equal(0, nextnonblank(1))
enddef
def Test_nr2char()
nr2char(97, true)->assert_equal('a')
enddef
@@ -1103,6 +1338,25 @@ def Test_or()
CheckDefFailure(['echo or(0x1, "x")'], 'E1013: Argument 2: type mismatch, expected number but got string')
enddef
def Test_prevnonblank()
CheckDefFailure(['prevnonblank(null)'], 'E1013: Argument 1: type mismatch, expected string but got special')
assert_equal(0, prevnonblank(1))
enddef
def Test_prompt_getprompt()
if has('channel')
CheckDefFailure(['prompt_getprompt([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
assert_equal('', prompt_getprompt('NonExistingBuf'))
endif
enddef
def Test_rand()
CheckDefFailure(['rand(10)'], 'E1013: Argument 1: type mismatch, expected list<number> but got number')
CheckDefFailure(['rand(["a"])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<string>')
assert_true(rand() >= 0)
assert_true(rand(srand()) >= 0)
enddef
def Test_readdir()
eval expand('sautest')->readdir((e) => e[0] !=# '.')
eval expand('sautest')->readdirex((e) => e.name[0] !=# '.')
@@ -1134,6 +1388,41 @@ def Test_readfile()
delete('Xreadfile')
enddef
def Test_reltime()
CheckDefFailure(['reltime("x")'], 'E1013: Argument 1: type mismatch, expected list<number> but got string')
CheckDefFailure(['reltime(["x", "y"])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<string>')
CheckDefFailure(['reltime([1, 2], 10)'], 'E1013: Argument 2: type mismatch, expected list<number> but got number')
CheckDefFailure(['reltime([1, 2], ["a", "b"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
var start: list<any> = reltime()
assert_true(type(reltime(start)) == v:t_list)
var end: list<any> = reltime()
assert_true(type(reltime(start, end)) == v:t_list)
enddef
def Test_reltimefloat()
CheckDefFailure(['reltimefloat("x")'], 'E1013: Argument 1: type mismatch, expected list<number> but got string')
CheckDefFailure(['reltimefloat([1.1])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<float>')
assert_true(type(reltimefloat(reltime())) == v:t_float)
enddef
def Test_reltimestr()
CheckDefFailure(['reltimestr(true)'], 'E1013: Argument 1: type mismatch, expected list<number> but got bool')
CheckDefFailure(['reltimestr([true])'], 'E1013: Argument 1: type mismatch, expected list<number> but got list<bool>')
assert_true(type(reltimestr(reltime())) == v:t_string)
enddef
def Test_remote_foreground()
CheckFeature clientserver
# remote_foreground() doesn't fail on MS-Windows
CheckNotMSWindows
CheckDefFailure(['remote_foreground(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_fails('remote_foreground("NonExistingServer")', 'E241:')
enddef
def Test_remote_startserver()
CheckDefFailure(['remote_startserver({})'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>')
enddef
def Test_remove_return_type()
var l = remove({one: [1, 2], two: [3, 4]}, 'one')
var res = 0
@@ -1143,6 +1432,16 @@ def Test_remove_return_type()
res->assert_equal(3)
enddef
def Test_rename()
CheckDefFailure(['rename(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['rename("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
enddef
def Test_resolve()
CheckDefFailure(['resolve([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
assert_equal('SomeFile', resolve('SomeFile'))
enddef
def Test_reverse_return_type()
var l = reverse([1, 2, 3])
var res = 0
@@ -1167,6 +1466,13 @@ def Test_screenchars()
CheckDefFailure(['echo screenchars(1, "x")'], 'E1013: Argument 2: type mismatch, expected number but got string')
enddef
def Test_screenpos()
CheckDefFailure(['screenpos("a", 1, 1)'], 'E1013: Argument 1: type mismatch, expected number but got string')
CheckDefFailure(['screenpos(1, "b", 1)'], 'E1013: Argument 2: type mismatch, expected number but got string')
CheckDefFailure(['screenpos(1, 1, "c")'], 'E1013: Argument 3: type mismatch, expected number but got string')
assert_equal({col: 1, row: 1, endcol: 1, curscol: 1}, screenpos(1, 1, 1))
enddef
def Test_screenstring()
CheckDefFailure(['echo screenstring("x", 1)'], 'E1013: Argument 1: type mismatch, expected number but got string')
CheckDefFailure(['echo screenstring(1, "x")'], 'E1013: Argument 2: type mismatch, expected number but got string')
@@ -1334,10 +1640,23 @@ def Test_setbufvar()
getbufvar('%', 'myvar')->assert_equal(123)
enddef
def Test_setcharsearch()
CheckDefFailure(['setcharsearch("x")'], 'E1013: Argument 1: type mismatch, expected dict<any> but got string')
CheckDefFailure(['setcharsearch([])'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>')
var d: dict<any> = {char: 'x', forward: 1, until: 1}
setcharsearch(d)
assert_equal(d, getcharsearch())
enddef
def Test_setcmdpos()
CheckDefFailure(['echo setcmdpos("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
enddef
def Test_setfperm()
CheckDefFailure(['setfperm(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['setfperm("a", 0z10)'], 'E1013: Argument 2: type mismatch, expected string but got blob')
enddef
def Test_setloclist()
var items = [{filename: '/tmp/file', lnum: 1, valid: true}]
var what = {items: items}
@@ -1353,10 +1672,21 @@ def Test_setreg()
assert_fails('setreg("ab", 0)', 'E1162:')
enddef
def Test_sha256()
CheckDefFailure(['sha256(100)'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['sha256(0zABCD)'], 'E1013: Argument 1: type mismatch, expected string but got blob')
assert_equal('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad', sha256('abc'))
enddef
def Test_shiftwidth()
CheckDefFailure(['echo shiftwidth("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
enddef
def Test_simplify()
CheckDefFailure(['simplify(100)'], 'E1013: Argument 1: type mismatch, expected string but got number')
call assert_equal('NonExistingFile', simplify('NonExistingFile'))
enddef
def Test_slice()
assert_equal('12345', slice('012345', 1))
assert_equal('123', slice('012345', 1, 4))
@@ -1388,6 +1718,16 @@ def Test_spellsuggest()
endif
enddef
def Test_sound_stop()
CheckFeature sound
CheckDefFailure(['sound_stop("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
enddef
def Test_soundfold()
CheckDefFailure(['soundfold(20)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_equal('abc', soundfold('abc'))
enddef
def Test_sort_return_type()
var res: list<number>
res = [1, 2, 3]->sort()
@@ -1408,10 +1748,25 @@ def Test_sort_argument()
CheckDefAndScriptSuccess(lines)
enddef
def Test_spellbadword()
CheckDefFailure(['spellbadword(100)'], 'E1013: Argument 1: type mismatch, expected string but got number')
spellbadword('good')->assert_equal(['', ''])
enddef
def Test_split()
split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', ''])
enddef
def Test_srand()
CheckDefFailure(['srand("a")'], 'E1013: Argument 1: type mismatch, expected number but got string')
type(srand(100))->assert_equal(v:t_list)
enddef
def Test_state()
CheckDefFailure(['state({})'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>')
assert_equal('', state('a'))
enddef
def Run_str2float()
if !has('float')
MissingFeature 'float'
@@ -1439,6 +1794,33 @@ def Test_strchars()
strchars("A\u20dd", true)->assert_equal(1)
enddef
def Test_strlen()
CheckDefFailure(['strlen([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
"abc"->strlen()->assert_equal(3)
strlen(99)->assert_equal(2)
enddef
def Test_strptime()
CheckFunction strptime
CheckDefFailure(['strptime(10, "2021")'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckDefFailure(['strptime("%Y", 2021)'], 'E1013: Argument 2: type mismatch, expected string but got number')
# BUG: Directly calling strptime() in this function gives an "E117: Unknown
# function" error on MS-Windows even with the above CheckFunction call for
# strptime().
#assert_true(strptime('%Y', '2021') != 0)
enddef
def Test_strtrans()
CheckDefFailure(['strtrans(20)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_equal('abc', strtrans('abc'))
enddef
def Test_strwidth()
CheckDefFailure(['strwidth(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
CheckScriptFailure(['vim9script', 'echo strwidth(10)'], 'E1024:')
assert_equal(4, strwidth('abcd'))
enddef
def Test_submatch()
var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
var Rep = () => range(10)->mapnew((_, v) => submatch(v, true))->string()
@@ -1457,6 +1839,16 @@ def Test_substitute()
endif
enddef
def Test_swapinfo()
CheckDefFailure(['swapinfo({})'], 'E1013: Argument 1: type mismatch, expected string but got dict<unknown>')
call assert_equal({error: 'Cannot open file'}, swapinfo('x'))
enddef
def Test_swapname()
CheckDefFailure(['swapname([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
assert_fails('swapname("NonExistingBuf")', 'E94:')
enddef
def Test_synID()
new
setline(1, "text")
@@ -1464,6 +1856,22 @@ def Test_synID()
bwipe!
enddef
def Test_synIDtrans()
CheckDefFailure(['synIDtrans("a")'], 'E1013: Argument 1: type mismatch, expected number but got string')
enddef
def Test_tabpagebuflist()
CheckDefFailure(['tabpagebuflist("t")'], 'E1013: Argument 1: type mismatch, expected number but got string')
assert_equal([bufnr('')], tabpagebuflist())
assert_equal([bufnr('')], tabpagebuflist(1))
enddef
def Test_tabpagenr()
CheckDefFailure(['tabpagenr(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_equal(1, tabpagenr('$'))
assert_equal(1, tabpagenr())
enddef
def Test_term_gettty()
if !has('terminal')
MissingFeature 'terminal'
@@ -1486,6 +1894,12 @@ def Test_term_start()
endif
enddef
def Test_timer_info()
CheckDefFailure(['timer_info("id")'], 'E1013: Argument 1: type mismatch, expected number but got string')
assert_equal([], timer_info(100))
assert_equal([], timer_info())
enddef
def Test_timer_paused()
var id = timer_start(50, () => 0)
timer_pause(id, true)
@@ -1494,6 +1908,11 @@ def Test_timer_paused()
timer_stop(id)
enddef
def Test_timer_stop()
CheckDefFailure(['timer_stop("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
assert_equal(0, timer_stop(100))
enddef
def Test_tolower()
CheckDefFailure(['echo tolower(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
enddef
@@ -1508,17 +1927,46 @@ def Test_tr()
CheckDefFailure(['echo tr("a", "a", 1)'], 'E1013: Argument 3: type mismatch, expected string but got number')
enddef
def Test_undofile()
CheckDefFailure(['undofile(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
assert_equal('.abc.un~', fnamemodify(undofile('abc'), ':t'))
enddef
def Test_values()
CheckDefFailure(['values([])'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>')
assert_equal([], {}->values())
assert_equal(['sun'], {star: 'sun'}->values())
enddef
def Test_win_execute()
assert_equal("\n" .. winnr(), win_execute(win_getid(), 'echo winnr()'))
assert_equal('', win_execute(342343, 'echo winnr()'))
enddef
def Test_win_findbuf()
CheckDefFailure(['win_findbuf("a")'], 'E1013: Argument 1: type mismatch, expected number but got string')
assert_equal([], win_findbuf(1000))
assert_equal([win_getid()], win_findbuf(bufnr('')))
enddef
def Test_win_getid()
CheckDefFailure(['win_getid(".")'], 'E1013: Argument 1: type mismatch, expected number but got string')
CheckDefFailure(['win_getid(1, ".")'], 'E1013: Argument 2: type mismatch, expected number but got string')
assert_equal(win_getid(), win_getid(1, 1))
enddef
def Test_win_splitmove()
split
win_splitmove(1, 2, {vertical: true, rightbelow: true})
close
enddef
def Test_winnr()
CheckDefFailure(['winnr([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
assert_equal(1, winnr())
assert_equal(1, winnr('$'))
enddef
def Test_winrestcmd()
split
var cmd = winrestcmd()
@@ -1528,6 +1976,14 @@ def Test_winrestcmd()
close
enddef
def Test_winrestview()
CheckDefFailure(['winrestview([])'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>')
:%d _
setline(1, 'Hello World')
winrestview({lnum: 1, col: 6})
assert_equal([1, 7], [line('.'), col('.')])
enddef
def Test_winsaveview()
var view: dict<number> = winsaveview()

View File

@@ -57,7 +57,7 @@ def Test_expr1_trinary()
assert_equal(function('len'), Res)
var RetOne: func(string): number = function('len')
var RetTwo: func(string): number = function('winnr')
var RetTwo: func(string): number = function('charcol')
var RetThat: func = g:atrue ? RetOne : RetTwo
assert_equal(function('len'), RetThat)
@@ -2970,13 +2970,6 @@ def Test_expr7_method_call()
END
CheckDefAndScriptSuccess(lines)
lines =<< trim END
def RetVoid()
enddef
RetVoid()->byte2line()
END
CheckDefExecAndScriptFailure(lines, 'E1031:')
lines =<< trim END
def RetVoid()
enddef

View File

@@ -452,6 +452,12 @@ def Test_call_default_args()
MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb')
MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy')
MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy')
def DefArg(mandatory: any, optional = mandatory): string
return mandatory .. optional
enddef
DefArg(1234)->assert_equal('12341234')
DefArg("ok")->assert_equal('okok')
END
CheckDefAndScriptSuccess(lines)
@@ -1024,7 +1030,7 @@ def Test_pass_legacy_lambda_to_def_func()
lines =<< trim END
vim9script
def g:TestFunc(f: func())
def g:TestFunc(f: func)
enddef
legacy call g:TestFunc({-> 0})
delfunc g:TestFunc

View File

@@ -603,6 +603,15 @@ def Test_try_catch_throw()
CheckScriptSuccess(lines)
assert_match('E808: Number or Float required', g:caught)
unlet g:caught
# missing catch and/or finally
lines =<< trim END
vim9script
try
echo 'something'
endtry
END
CheckScriptFailure(lines, 'E1032:')
enddef
def Test_try_in_catch()

View File

@@ -2,6 +2,7 @@
source shared.vim
source check.vim
source screendump.vim
func Test_block_shift_multibyte()
" Uses double-wide character.
@@ -1241,5 +1242,28 @@ func Test_visual_put_blockedit_zy_and_zp()
bw!
endfunc
func Test_visual_block_with_virtualedit()
CheckScreendump
let lines =<< trim END
call setline(1, ['aaaaaa', 'bbbb', 'cc'])
set virtualedit=block
normal G
END
call writefile(lines, 'XTest_block')
let buf = RunVimInTerminal('-S XTest_block', {'rows': 8, 'cols': 50})
call term_sendkeys(buf, "\<C-V>gg$")
call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit', {})
call term_sendkeys(buf, "\<Esc>gg\<C-V>G$")
call VerifyScreenDump(buf, 'Test_visual_block_with_virtualedit2', {})
" clean up
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf)
call delete('XTest_block')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -5478,35 +5478,32 @@ find_var_in_scoped_ht(char_u *name, int no_autoload)
int
set_ref_in_previous_funccal(int copyID)
{
int abort = FALSE;
funccall_T *fc;
for (fc = previous_funccal; !abort && fc != NULL; fc = fc->caller)
for (fc = previous_funccal; fc != NULL; fc = fc->caller)
{
fc->fc_copyID = copyID + 1;
abort = abort
|| set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL)
|| set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL)
|| set_ref_in_list_items(&fc->l_varlist, copyID + 1, NULL);
if (set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL)
|| set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL)
|| set_ref_in_list_items(&fc->l_varlist, copyID + 1, NULL))
return TRUE;
}
return abort;
return FALSE;
}
static int
set_ref_in_funccal(funccall_T *fc, int copyID)
{
int abort = FALSE;
if (fc->fc_copyID != copyID)
{
fc->fc_copyID = copyID;
abort = abort
|| set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL)
|| set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL)
|| set_ref_in_list_items(&fc->l_varlist, copyID, NULL)
|| set_ref_in_func(NULL, fc->func, copyID);
if (set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL)
|| set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL)
|| set_ref_in_list_items(&fc->l_varlist, copyID, NULL)
|| set_ref_in_func(NULL, fc->func, copyID))
return TRUE;
}
return abort;
return FALSE;
}
/*
@@ -5515,19 +5512,19 @@ set_ref_in_funccal(funccall_T *fc, int copyID)
int
set_ref_in_call_stack(int copyID)
{
int abort = FALSE;
funccall_T *fc;
funccal_entry_T *entry;
for (fc = current_funccal; !abort && fc != NULL; fc = fc->caller)
abort = abort || set_ref_in_funccal(fc, copyID);
for (fc = current_funccal; fc != NULL; fc = fc->caller)
if (set_ref_in_funccal(fc, copyID))
return TRUE;
// Also go through the funccal_stack.
for (entry = funccal_stack; !abort && entry != NULL; entry = entry->next)
for (fc = entry->top_funccal; !abort && fc != NULL; fc = fc->caller)
abort = abort || set_ref_in_funccal(fc, copyID);
return abort;
for (entry = funccal_stack; entry != NULL; entry = entry->next)
for (fc = entry->top_funccal; fc != NULL; fc = fc->caller)
if (set_ref_in_funccal(fc, copyID))
return TRUE;
return FALSE;
}
/*
@@ -5538,7 +5535,6 @@ set_ref_in_functions(int copyID)
{
int todo;
hashitem_T *hi = NULL;
int abort = FALSE;
ufunc_T *fp;
todo = (int)func_hashtab.ht_used;
@@ -5548,11 +5544,12 @@ set_ref_in_functions(int copyID)
{
--todo;
fp = HI2UF(hi);
if (!func_name_refcount(fp->uf_name))
abort = abort || set_ref_in_func(NULL, fp, copyID);
if (!func_name_refcount(fp->uf_name)
&& set_ref_in_func(NULL, fp, copyID))
return TRUE;
}
}
return abort;
return FALSE;
}
/*
@@ -5562,12 +5559,12 @@ set_ref_in_functions(int copyID)
set_ref_in_func_args(int copyID)
{
int i;
int abort = FALSE;
for (i = 0; i < funcargs.ga_len; ++i)
abort = abort || set_ref_in_item(((typval_T **)funcargs.ga_data)[i],
copyID, NULL, NULL);
return abort;
if (set_ref_in_item(((typval_T **)funcargs.ga_data)[i],
copyID, NULL, NULL))
return TRUE;
return FALSE;
}
/*

View File

@@ -755,6 +755,52 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3103,
/**/
3102,
/**/
3101,
/**/
3100,
/**/
3099,
/**/
3098,
/**/
3097,
/**/
3096,
/**/
3095,
/**/
3094,
/**/
3093,
/**/
3092,
/**/
3091,
/**/
3090,
/**/
3089,
/**/
3088,
/**/
3087,
/**/
3086,
/**/
3085,
/**/
3084,
/**/
3083,
/**/
3082,
/**/
3081,
/**/
3080,
/**/

View File

@@ -274,7 +274,7 @@ arg_exists(
if (len == 0)
return FAIL;
for (idx = 0; idx < cctx->ctx_ufunc->uf_args.ga_len; ++idx)
for (idx = 0; idx < cctx->ctx_ufunc->uf_args_visible; ++idx)
{
char_u *arg = FUNCARG(cctx->ctx_ufunc, idx);
@@ -7747,6 +7747,7 @@ compile_for(char_u *arg_start, cctx_T *cctx)
type_T *vartype;
type_T *item_type = &t_any;
int idx;
int prev_lnum = cctx->ctx_prev_lnum;
p = skip_var_list(arg_start, TRUE, &var_count, &semicolon, FALSE);
if (p == NULL)
@@ -7774,7 +7775,11 @@ compile_for(char_u *arg_start, cctx_T *cctx)
if (cctx->ctx_compile_type == CT_DEBUG && instr->ga_len > 0
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
.isn_type == ISN_DEBUG)
{
--instr->ga_len;
prev_lnum = ((isn_T *)instr->ga_data)[instr->ga_len]
.isn_arg.debug.dbg_break_lnum;
}
scope = new_scope(cctx, FOR_SCOPE);
if (scope == NULL)
@@ -7934,8 +7939,15 @@ compile_for(char_u *arg_start, cctx_T *cctx)
}
if (cctx->ctx_compile_type == CT_DEBUG)
{
int save_prev_lnum = cctx->ctx_prev_lnum;
// Add ISN_DEBUG here, so that the loop variables can be inspected.
// Use the prev_lnum from the ISN_DEBUG instruction removed above.
cctx->ctx_prev_lnum = prev_lnum;
generate_instr_debug(cctx);
cctx->ctx_prev_lnum = save_prev_lnum;
}
return arg_end;
@@ -9160,7 +9172,6 @@ compile_def_function(
{
int count = ufunc->uf_def_args.ga_len;
int first_def_arg = ufunc->uf_args.ga_len - count;
int uf_args_len = ufunc->uf_args.ga_len;
int i;
char_u *arg;
int off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0);
@@ -9183,12 +9194,11 @@ compile_def_function(
goto erret;
// Make sure later arguments are not found.
ufunc->uf_args.ga_len = i;
ufunc->uf_args_visible = arg_idx;
arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
r = compile_expr0(&arg, &cctx);
ufunc->uf_args.ga_len = uf_args_len;
if (r == FAIL)
goto erret;
@@ -9218,6 +9228,7 @@ compile_def_function(
if (did_set_arg_type)
set_function_type(ufunc);
}
ufunc->uf_args_visible = ufunc->uf_args.ga_len;
/*
* Loop over all the lines of the function and generate instructions.

View File

@@ -260,6 +260,7 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member)
type_T *type;
type_T *member_type = &t_any;
int argcount = 0;
int min_argcount = 0;
if (tv->v_type == VAR_NUMBER)
return &t_number;
@@ -337,8 +338,7 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member)
if (idx >= 0)
{
// TODO: get actual arg count and types
argcount = -1;
internal_func_get_argcount(idx, &argcount, &min_argcount);
member_type = internal_func_ret_type(idx, 0, NULL);
}
else
@@ -364,6 +364,7 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member)
return NULL;
type->tt_type = tv->v_type;
type->tt_argcount = argcount;
type->tt_min_argcount = min_argcount;
type->tt_member = member_type;
return type;
@@ -525,9 +526,9 @@ check_type(type_T *expected, type_T *actual, int give_msg, where_T where)
ret = check_type(expected->tt_member, actual->tt_member,
FALSE, where);
if (ret == OK && expected->tt_argcount != -1
&& actual->tt_argcount != -1
&& (actual->tt_argcount < expected->tt_min_argcount
|| actual->tt_argcount > expected->tt_argcount))
&& (actual->tt_argcount == -1
|| (actual->tt_argcount < expected->tt_min_argcount
|| actual->tt_argcount > expected->tt_argcount)))
ret = FAIL;
if (ret == OK && expected->tt_args != NULL
&& actual->tt_args != NULL)
@@ -1032,7 +1033,10 @@ common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap)
}
}
else
// Use -1 for "tt_argcount" to indicate an unknown number of
// arguments.
*dest = alloc_func_type(common, -1, type_gap);
// Use the minimum of min_argcount.
(*dest)->tt_min_argcount =
type1->tt_min_argcount < type2->tt_min_argcount