Merge remote-tracking branch 'vim/master'

This commit is contained in:
ichizok
2021-07-05 18:19:49 +09:00
56 changed files with 1684 additions and 342 deletions
+13 -1
View File
@@ -8231,6 +8231,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}
@@ -8264,6 +8266,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
@@ -8277,6 +8280,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.
@@ -8287,6 +8292,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()*
@@ -9890,6 +9897,10 @@ sha256({string}) *sha256()*
shellescape({string} [, {special}]) *shellescape()*
Escape {string} for use as a shell command argument.
When the 'shell' contains powershell (MS-Windows) or pwsh
(MS-Windows, Linux, and MacOS) then it will enclose {string}
in single quotes and will double up all internal single
quotes.
On MS-Windows, when 'shellslash' is not set, it will enclose
{string} in double quotes and double all double quotes within
{string}.
@@ -11052,7 +11063,8 @@ tempname() *tempname()* *temp-file-name*
:exe "redir > " . tmpfile
< For Unix, the file will be in a private directory |tempfile|.
For MS-Windows forward slashes are used when the 'shellslash'
option is set or when 'shellcmdflag' starts with '-'.
option is set, or when 'shellcmdflag' starts with '-' and
'shell' does not contain powershell or pwsh.
term_ functions are documented here: |terminal-function-details|
+36 -28
View File
@@ -6726,23 +6726,25 @@ A jump table for the options with a short description can be found at |Q_op|.
*'shellcmdflag'* *'shcf'*
'shellcmdflag' 'shcf' string (default: "-c";
Win32, when 'shell' does not contain "sh"
Win32, when 'shell' contains "powershell":
"-Command", or when it does not contain "sh"
somewhere: "/c")
global
Flag passed to the shell to execute "!" and ":!" commands; e.g.,
"bash.exe -c ls" or "cmd.exe /c dir". For MS-Windows, the default is
set according to the value of 'shell', to reduce the need to set this
option by the user.
"bash.exe -c ls", "powershell.exe -Command dir", or "cmd.exe /c dir".
For MS-Windows, the default is set according to the value of 'shell',
to reduce the need to set this option by the user.
On Unix it can have more than one flag. Each white space separated
part is passed as an argument to the shell command.
See |option-backslash| about including spaces and backslashes.
Also see |dos-shell| for MS-Windows.
Also see |dos-shell| and |dos-powershell| for MS-Windows.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'shellpipe'* *'sp'*
'shellpipe' 'sp' string (default ">", ">%s 2>&1", "| tee", "|& tee" or
"2>&1| tee")
'shellpipe' 'sp' string (default ">", ">%s 2>&1", "| tee", "|& tee"
"2>&1| tee", or
"2>&1 | Out-File -Encoding default")
global
{not available when compiled without the |+quickfix|
feature}
@@ -6752,9 +6754,10 @@ A jump table for the options with a short description can be found at |Q_op|.
The name of the temporary file can be represented by "%s" if necessary
(the file name is appended automatically if no %s appears in the value
of this option).
For the Amiga the default is ">". For MS-Windows the default is
">%s 2>&1". The output is directly saved in a file and not echoed to
the screen.
For the Amiga the default is ">". For MS-Windows using powershell the
default is "2>&1 | Out-File -Encoding default", otherwise the default
is ">%s 2>&1". The output is directly saved in a file and not echoed
to the screen.
For Unix the default is "| tee". The stdout of the compiler is saved
in a file and echoed to the screen. If the 'shell' option is "csh" or
"tcsh" after initializations, the default becomes "|& tee". If the
@@ -6762,6 +6765,8 @@ A jump table for the options with a short description can be found at |Q_op|.
"bash", "fish", "ash" or "dash" the default becomes "2>&1| tee". This
means that stderr is also included. Before using the 'shell' option a
path is removed, thus "/bin/sh" uses "sh".
For Unix and MS-Windows, when the 'shell' option is "pwsh" the default
becomes ">%s 2>&1" and the output is not echoed to the screen.
The initialization of this option is done after reading the ".vimrc"
and the other initializations, so that when the 'shell' option is set
there, the 'shellpipe' option changes automatically, unless it was
@@ -6777,8 +6782,7 @@ A jump table for the options with a short description can be found at |Q_op|.
security reasons.
*'shellquote'* *'shq'*
'shellquote' 'shq' string (default: ""; Win32, when 'shell'
contains "sh" somewhere: "\"")
'shellquote' 'shq' string (default: "")
global
Quoting character(s), put around the command passed to the shell, for
the "!" and ":!" commands. The redirection is kept outside of the
@@ -6786,14 +6790,13 @@ A jump table for the options with a short description can be found at |Q_op|.
probably not useful to set both options.
This is an empty string by default. Only known to be useful for
third-party shells on MS-Windows-like systems, such as the MKS Korn
Shell or bash, where it should be "\"". The default is adjusted
according the value of 'shell', to reduce the need to set this option
by the user. See |dos-shell|.
Shell or bash, where it should be "\"". See |dos-shell|.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'shellredir'* *'srr'*
'shellredir' 'srr' string (default ">", ">&" or ">%s 2>&1")
'shellredir' 'srr' string (default ">", ">&", ">%s 2>&1", or
"2>&1 | Out-File -Encoding default")
global
String to be used to put the output of a filter command in a temporary
file. See also |:!|. See |option-backslash| about including spaces
@@ -6804,10 +6807,12 @@ A jump table for the options with a short description can be found at |Q_op|.
The default is ">". For Unix, if the 'shell' option is "csh" or
"tcsh" during initializations, the default becomes ">&". If the
'shell' option is "sh", "ksh", "mksh", "pdksh", "zsh", "zsh-beta",
"bash" or "fish", the default becomes ">%s 2>&1". This means that
stderr is also included. For Win32, the Unix checks are done and
additionally "cmd" is checked for, which makes the default ">%s 2>&1".
Also, the same names with ".exe" appended are checked for.
"bash", "fish", or "pwsh", the default becomes ">%s 2>&1". This means
that stderr is also included. For Win32, the Unix checks are done and
additionally "cmd" is checked for, which makes the default ">%s 2>&1",
and "powershell" is checked for which makes the default
"2>&1 | Out-File -Encoding default" (see |dos-powershell|). Also, the
same names with ".exe" appended are checked for.
The initialization of this option is done after reading the ".vimrc"
and the other initializations, so that when the 'shell' option is set
there, the 'shellredir' option changes automatically unless it was
@@ -6822,9 +6827,9 @@ A jump table for the options with a short description can be found at |Q_op|.
global
{only for MS-Windows}
When set, a forward slash is used when expanding file names. This is
useful when a Unix-like shell is used instead of cmd.exe. Backward
slashes can still be typed, but they are changed to forward slashes by
Vim.
useful when a Unix-like shell is used instead of cmd.exe, pwsh.exe, or
powershell.exe. Backward slashes can still be typed, but they are
changed to forward slashes by Vim.
Note that setting or resetting this option has no effect for some
existing file names, thus this option needs to be set before opening
any file for best results. This might change in the future.
@@ -6878,6 +6883,8 @@ A jump table for the options with a short description can be found at |Q_op|.
*'shellxquote'* *'sxq'*
'shellxquote' 'sxq' string (default: "";
for Win32, when 'shell' is cmd.exe: "("
for Win32, when 'shell' is
powershell.exe: "\""
for Win32, when 'shell' contains "sh"
somewhere: "\""
for Unix, when using system(): "\"")
@@ -6890,11 +6897,12 @@ A jump table for the options with a short description can be found at |Q_op|.
then ')"' is appended.
When the value is '(' then also see 'shellxescape'.
This is an empty string by default on most systems, but is known to be
useful for on Win32 version, either for cmd.exe which automatically
strips off the first and last quote on a command, or 3rd-party shells
such as the MKS Korn Shell or bash, where it should be "\"". The
default is adjusted according the value of 'shell', to reduce the need
to set this option by the user. See |dos-shell|.
useful for on Win32 version, either for cmd.exe, powershell.exe, or
pwsh.exe which automatically strips off the first and last quote on a
command, or 3rd-party shells such as the MKS Korn Shell or bash, where
it should be "\"". The default is adjusted according the value of
'shell', to reduce the need to set this option by the user. See
|dos-shell|.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
+82 -3
View File
@@ -17,6 +17,7 @@ versions of Vim. Also see |os_win32.txt| and |os_msdos.txt|.
7. Interrupting |dos-CTRL-Break|
8. Temp files |dos-temp-files|
9. Shell option default |dos-shell|
10. PowerShell |dos-powershell|
==============================================================================
1. File locations *dos-locations*
@@ -297,8 +298,86 @@ For Win32 as:
<shell> -c "command name >file"
For DOS 32 bit, DJGPP does this internally somehow.
When starting up, Vim checks for the presence of "sh" anywhere in the 'shell'
option. If it is present, Vim sets the 'shellcmdflag' and 'shellquote' or
'shellxquote' options will be set as described above.
When starting up, if Vim does not recognise a standard Windows shell it checks
for the presence of "sh" anywhere in the 'shell' option. If it is present,
Vim sets the 'shellcmdflag' and 'shellquote' or 'shellxquote' options will be
set as described above.
==============================================================================
10. PowerShell *dos-powershell* *dos-pwsh*
Vim supports PowerShell Desktop and PowerShell Core. PowerShell Desktop is
the version of PowerShell that is installed with Windows, while PowerShell
Core is a separate downloadable version that works cross-platform. To see
which version you are using then enter the following in a PowerShell prompt -
$PSVersionTable.PSEdition
If 'shell' includes "powershell" in the filename at startup then VIM sets
'shellcmdflag', 'shellxquote', 'shellpipe', and 'shellredir' options to the
following values:
'shellcmdflag' -Command
'shellxquote' "
'shellpipe' 2>&1 | Out-File -Encoding default
'shellredir' 2>&1 | Out-File -Encoding default
If 'shell' includes "pwsh" in the filename at startup then VIM sets
'shellcmdflag', 'shellxquote', 'shellpipe', and 'shellredir' options to the
following values:
'shellcmdflag' -c
'shellxquote' "
'shellpipe' >%s 2>&1
'shellredir' >%s 2>&1
If you find that PowerShell commands are taking a long time to run then try
with "-NoProfile" at the beginning of the 'shellcmdflag'. Note this will
prevent any PowerShell environment setup by the profile from taking place.
If you have problems running PowerShell scripts through the 'shell' then try
with "-ExecutionPolicy RemoteSigned -Command" at the beginning of
'shellcmdflag'. See online Windows documentation for more information on
PowerShell Execution Policy settings.
See |option-backslash| about including spaces in 'shellcmdflag' when using
multiple flags.
The 'shellpipe' and 'shellredir' option values re-encode the UTF-16le output
from PowerShell Desktop to your currently configured console codepage. The
output can be forced into a different encoding by changing "default" to one of
the following:
unicode - UTF-16le (default output from PowerShell 5.1)
bigendianunicode - UTF-16
utf8 - UTF-8
utf7 - UTF-7 (no BOM)
utf32 - UTF-32
ascii - 7-bit ASCII character set
default - System's active code page (typically ANSI)
oem - System's current OEM code page
Note The abovce multi-byte Unicode encodings include a leading BOM unless
otherwise indicated.
By default PowerShell Core's output is UTF-8 encoded without a BOM. If you
want to force the output of PowerShell Core into a different encoding then set
'shellredir' and 'shellpipe' to "2>&1 | Out-File -Encoding encoding" where
encoding is one of the following:
ascii - 7-bit ASCII character set
bigendianunicode - UTF-16be
bigendianutf32 - UTF-32be
oem - System's current OEM code page
unicode - UTF-16le
utf7 - UTF-7
utf8 - UTF-8
utf8BOM - UTF-8, with BOM
utf8NoBOM - UTF-8, no BOM (default output from PowerShell Core)
utf32 - UTF-32
Since PowerShell Core 6.2, the Encoding parameter also supports specifying a
numeric ID of a registered code page (-Encoding 1251) or string names of
registered code pages (-Encoding "windows-1251"). The .NET documentation for
Encoding.CodePage has more information
vim:tw=78:ts=8:noet:ft=help:norl:
+1
View File
@@ -30,6 +30,7 @@ File formats |dos-file-formats|
Interrupting |dos-CTRL-Break|
Temp files |dos-temp-files|
Shell option default |dos-shell|
PowerShell defaults |dos-powershell|
Win32 GUI |gui-w32|
+6
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
+5
View File
@@ -1134,7 +1134,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)
+11 -5
View File
@@ -2512,12 +2512,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));
@@ -2571,7 +2576,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);
@@ -2607,7 +2613,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
+37 -2
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)
+12 -3
View File
@@ -147,6 +147,9 @@ edit(
#ifdef FEAT_JOB_CHANNEL
int cmdchar_todo = cmdchar;
#endif
#ifdef FEAT_CONCEAL
int cursor_line_was_concealed;
#endif
// Remember whether editing was restarted after CTRL-O.
did_restart_edit = restart_edit;
@@ -222,9 +225,9 @@ edit(
}
#ifdef FEAT_CONCEAL
// Check if the cursor line needs redrawing before changing State. If
// 'concealcursor' is "n" it needs to be redrawn without concealing.
conceal_check_cursor_line();
// Check if the cursor line was concealed before changing State.
cursor_line_was_concealed = curwin->w_p_cole > 0
&& conceal_cursor_line(curwin);
#endif
/*
@@ -283,6 +286,12 @@ edit(
stop_insert_mode = FALSE;
#ifdef FEAT_CONCEAL
// Check if the cursor line needs redrawing after changing State. If
// 'concealcursor' is "n" it needs to be redrawn without concealing.
conceal_check_cursor_line(cursor_line_was_concealed);
#endif
/*
* Need to recompute the cursor position, it might move when the cursor is
* on a TAB or special character.
+162 -103
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
+12 -2
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
+6 -2
View File
@@ -5257,6 +5257,7 @@ vim_tempname(
WCHAR *chartab = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char_u *retval;
char_u *p;
char_u *shname;
long i;
wcscpy(itmp, L"");
@@ -5280,9 +5281,12 @@ vim_tempname(
// Backslashes in a temp file name cause problems when filtering with
// "sh". NOTE: This also checks 'shellcmdflag' to help those people who
// didn't set 'shellslash'.
// didn't set 'shellslash' but only if not using PowerShell.
retval = utf16_to_enc(itmp, NULL);
if (*p_shcf == '-' || p_ssl)
shname = gettail(p_sh);
if ((*p_shcf == '-' && !(strstr((char *)shname, "powershell") != NULL
|| strstr((char *)shname, "pwsh") != NULL ))
|| p_ssl)
for (p = retval; *p; ++p)
if (*p == '\\')
*p = '/';
+1 -1
View File
@@ -421,7 +421,7 @@ EXTERN type_T t_channel INIT6(VAR_CHANNEL, 0, 0, TTFLAG_STATIC, NULL, NULL);
// Special value used for @#.
EXTERN type_T t_number_or_string INIT6(VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL);
EXTERN type_T t_func_unknown INIT6(VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_unknown, NULL);
EXTERN type_T t_func_unknown INIT6(VAR_FUNC, -1, -1, TTFLAG_STATIC, &t_unknown, NULL);
EXTERN type_T t_func_void INIT6(VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_void, NULL);
EXTERN type_T t_func_any INIT6(VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_any, NULL);
EXTERN type_T t_func_number INIT6(VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_number, NULL);
+2 -1
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);
}
+39 -10
View File
@@ -1396,7 +1396,9 @@ csh_like_shell(void)
/*
* Escape "string" for use as a shell argument with system().
* This uses single quotes, except when we know we need to use double quotes
* (MS-DOS and MS-Windows without 'shellslash' set).
* (MS-DOS and MS-Windows not using PowerShell and without 'shellslash' set).
* PowerShell also uses a novel escaping for enclosed single quotes - double
* them up.
* Escape a newline, depending on the 'shell' option.
* When "do_special" is TRUE also replace "!", "%", "#" and things starting
* with "<" like "<cfile>".
@@ -1412,6 +1414,11 @@ vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
char_u *escaped_string;
int l;
int csh_like;
char_u *shname;
int powershell;
# ifdef MSWIN
int double_quotes;
# endif
// Only csh and similar shells expand '!' within single quotes. For sh and
// the like we must not put a backslash before it, it will be taken
@@ -1419,12 +1426,21 @@ vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
// Csh also needs to have "\n" escaped twice when do_special is set.
csh_like = csh_like_shell();
// PowerShell uses it's own version for quoting single quotes
shname = gettail(p_sh);
powershell = strstr((char *)shname, "pwsh") != NULL;
# ifdef MSWIN
powershell = powershell || strstr((char *)shname, "powershell") != NULL;
// PowerShell only accepts single quotes so override shellslash.
double_quotes = !powershell && !p_ssl;
# endif
// First count the number of extra bytes required.
length = (unsigned)STRLEN(string) + 3; // two quotes and a trailing NUL
for (p = string; *p != NUL; MB_PTR_ADV(p))
{
# ifdef MSWIN
if (!p_ssl)
if (double_quotes)
{
if (*p == '"')
++length; // " -> ""
@@ -1432,7 +1448,12 @@ vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
else
# endif
if (*p == '\'')
length += 3; // ' => '\''
{
if (powershell)
length +=2; // ' => ''
else
length += 3; // ' => '\''
}
if ((*p == '\n' && (csh_like || do_newline))
|| (*p == '!' && (csh_like || do_special)))
{
@@ -1455,7 +1476,7 @@ vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
// add opening quote
# ifdef MSWIN
if (!p_ssl)
if (double_quotes)
*d++ = '"';
else
# endif
@@ -1464,7 +1485,7 @@ vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
for (p = string; *p != NUL; )
{
# ifdef MSWIN
if (!p_ssl)
if (double_quotes)
{
if (*p == '"')
{
@@ -1478,10 +1499,18 @@ vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
# endif
if (*p == '\'')
{
*d++ = '\'';
*d++ = '\\';
*d++ = '\'';
*d++ = '\'';
if (powershell)
{
*d++ = '\'';
*d++ = '\'';
}
else
{
*d++ = '\'';
*d++ = '\\';
*d++ = '\'';
*d++ = '\'';
}
++p;
continue;
}
@@ -1507,7 +1536,7 @@ vim_strsave_shellescape(char_u *string, int do_special, int do_newline)
// add terminating quote and finish with a NUL
# ifdef MSWIN
if (!p_ssl)
if (double_quotes)
*d++ = '"';
else
# endif
+4 -4
View File
@@ -5759,8 +5759,8 @@ may_start_select(int c)
n_start_visual_mode(int c)
{
#ifdef FEAT_CONCEAL
// Check for redraw before changing the state.
conceal_check_cursor_line();
int cursor_line_was_concealed = curwin->w_p_cole > 0
&& conceal_cursor_line(curwin);
#endif
VIsual_mode = c;
@@ -5782,8 +5782,8 @@ n_start_visual_mode(int c)
setmouse();
#ifdef FEAT_CONCEAL
// Check for redraw after changing the state.
conceal_check_cursor_line();
// Check if redraw is needed after changing the state.
conceal_check_cursor_line(cursor_line_was_concealed);
#endif
if (p_smd && msg_silent == 0)
+49 -20
View File
@@ -545,6 +545,8 @@ block_insert(
spaces -= off;
count -= off;
}
if (spaces < 0) // can happen when the cursor was moved
spaces = 0;
newp = alloc(STRLEN(oldp) + s_len + count + 1);
if (newp == NULL)
@@ -1455,6 +1457,9 @@ op_insert(oparg_T *oap, long count1)
struct block_def bd;
int i;
pos_T t1;
pos_T start_insert;
// offset when cursor was moved in insert mode
int offset = 0;
// edit() changes this - record it for OP_APPEND
bd.is_MAX = (curwin->w_curswant == MAXCOL);
@@ -1526,6 +1531,7 @@ op_insert(oparg_T *oap, long count1)
}
t1 = oap->start;
start_insert = curwin->w_cursor;
(void)edit(NUL, FALSE, (linenr_T)count1);
// When a tab was inserted, and the characters in front of the tab
@@ -1564,30 +1570,38 @@ op_insert(oparg_T *oap, long count1)
if (oap->start.lnum == curbuf->b_op_start_orig.lnum
&& !bd.is_MAX && !did_indent)
{
if (oap->op_type == OP_INSERT
&& oap->start.col + oap->start.coladd
!= curbuf->b_op_start_orig.col
+ curbuf->b_op_start_orig.coladd)
int t = getviscol2(curbuf->b_op_start_orig.col,
curbuf->b_op_start_orig.coladd);
if (!bd.is_MAX)
{
int t = getviscol2(curbuf->b_op_start_orig.col,
curbuf->b_op_start_orig.coladd);
oap->start.col = curbuf->b_op_start_orig.col;
pre_textlen -= t - oap->start_vcol;
oap->start_vcol = t;
if (oap->op_type == OP_INSERT
&& oap->start.col + oap->start.coladd
!= curbuf->b_op_start_orig.col
+ curbuf->b_op_start_orig.coladd)
{
oap->start.col = curbuf->b_op_start_orig.col;
pre_textlen -= t - oap->start_vcol;
oap->start_vcol = t;
}
else if (oap->op_type == OP_APPEND
&& oap->end.col + oap->end.coladd
>= curbuf->b_op_start_orig.col
+ curbuf->b_op_start_orig.coladd)
{
oap->start.col = curbuf->b_op_start_orig.col;
// reset pre_textlen to the value of OP_INSERT
pre_textlen += bd.textlen;
pre_textlen -= t - oap->start_vcol;
oap->start_vcol = t;
oap->op_type = OP_INSERT;
}
}
else if (oap->op_type == OP_APPEND
&& oap->end.col + oap->end.coladd
>= curbuf->b_op_start_orig.col
+ curbuf->b_op_start_orig.coladd)
else if (bd.is_MAX && oap->op_type == OP_APPEND)
{
int t = getviscol2(curbuf->b_op_start_orig.col,
curbuf->b_op_start_orig.coladd);
oap->start.col = curbuf->b_op_start_orig.col;
// reset pre_textlen to the value of OP_INSERT
pre_textlen += bd.textlen;
pre_textlen -= t - oap->start_vcol;
oap->start_vcol = t;
oap->op_type = OP_INSERT;
}
}
@@ -1617,13 +1631,28 @@ op_insert(oparg_T *oap, long count1)
len = STRLEN(firstline);
add = bd.textcol;
if (oap->op_type == OP_APPEND)
{
add += bd.textlen;
// account for pressing cursor in insert mode when '$' was used
if (bd.is_MAX
&& (start_insert.lnum == Insstart.lnum
&& start_insert.col > Insstart.col))
{
offset = (start_insert.col - Insstart.col);
add -= offset;
if (oap->end_vcol > offset)
oap->end_vcol -= (offset + 1);
else
// moved outside of the visual block, what to do?
return;
}
}
if ((size_t)add > len)
firstline += len; // short line, point to the NUL
else
firstline += add;
if (pre_textlen >= 0
&& (ins_len = (long)STRLEN(firstline) - pre_textlen) > 0)
if (pre_textlen >= 0 && (ins_len =
(long)STRLEN(firstline) - pre_textlen - offset) > 0)
{
ins_text = vim_strnsave(firstline, ins_len);
if (ins_text != NULL)
+56 -5
View File
@@ -950,6 +950,27 @@ set_init_3(void)
options[idx_srr].def_val[VI_DEFAULT] = p_srr;
}
}
# ifdef MSWIN
// Windows PowerShell output is UTF-16 with BOM so re-encode to the
// current codepage.
else if ( fnamecmp(p, "powershell") == 0
|| fnamecmp(p, "powershell.exe") == 0
)
{
# if defined(FEAT_QUICKFIX)
if (do_sp)
{
p_sp = (char_u *)"2>&1 | Out-File -Encoding default";
options[idx_sp].def_val[VI_DEFAULT] = p_sp;
}
# endif
if (do_srr)
{
p_srr = (char_u *)"2>&1 | Out-File -Encoding default";
options[idx_srr].def_val[VI_DEFAULT] = p_srr;
}
}
#endif
else
// Always use POSIX shell style redirection if we reach this
if ( fnamecmp(p, "sh") == 0
@@ -962,6 +983,7 @@ set_init_3(void)
|| fnamecmp(p, "fish") == 0
|| fnamecmp(p, "ash") == 0
|| fnamecmp(p, "dash") == 0
|| fnamecmp(p, "pwsh") == 0
# ifdef MSWIN
|| fnamecmp(p, "cmd") == 0
|| fnamecmp(p, "sh.exe") == 0
@@ -973,6 +995,7 @@ set_init_3(void)
|| fnamecmp(p, "bash.exe") == 0
|| fnamecmp(p, "cmd.exe") == 0
|| fnamecmp(p, "dash.exe") == 0
|| fnamecmp(p, "pwsh.exe") == 0
# endif
)
{
@@ -982,7 +1005,10 @@ set_init_3(void)
# ifdef MSWIN
p_sp = (char_u *)">%s 2>&1";
# else
p_sp = (char_u *)"2>&1| tee";
if (fnamecmp(p, "pwsh") == 0)
p_sp = (char_u *)">%s 2>&1";
else
p_sp = (char_u *)"2>&1| tee";
# endif
options[idx_sp].def_val[VI_DEFAULT] = p_sp;
}
@@ -1002,11 +1028,36 @@ set_init_3(void)
* Set 'shellcmdflag', 'shellxquote', and 'shellquote' depending on the
* 'shell' option.
* This is done after other initializations, where 'shell' might have been
* set, but only if they have not been set before. Default for p_shcf is
* "/c", for p_shq is "". For "sh" like shells it is changed here to
* "-c" and "\"". And for Win32 we need to set p_sxq instead.
* set, but only if they have not been set before.
* Default values depend on shell (cmd.exe is default shell):
*
* p_shcf p_sxq
* cmd.exe - "/c" "("
* powershell.exe - "-Command" "\""
* pwsh.exe - "-c" "\""
* "sh" like shells - "-c" "\""
*
* For Win32 p_sxq is set instead of p_shq to include shell redirection.
*/
if (strstr((char *)gettail(p_sh), "sh") != NULL)
if (strstr((char *)gettail(p_sh), "powershell") != NULL)
{
int idx_opt;
idx_opt = findoption((char_u *)"shcf");
if (idx_opt >= 0 && !(options[idx_opt].flags & P_WAS_SET))
{
p_shcf = (char_u*)"-Command";
options[idx_opt].def_val[VI_DEFAULT] = p_shcf;
}
idx_opt = findoption((char_u *)"sxq");
if (idx_opt >= 0 && !(options[idx_opt].flags & P_WAS_SET))
{
p_sxq = (char_u*)"\"";
options[idx_opt].def_val[VI_DEFAULT] = p_sxq;
}
}
else if (strstr((char *)gettail(p_sh), "sh") != NULL)
{
int idx3;
+5 -1
View File
@@ -2135,6 +2135,7 @@ executable_exists(char *name, char_u **path, int use_path, int use_pathext)
char_u *pathbuf = NULL;
char_u *pathext = NULL;
char_u *pathextbuf = NULL;
char_u *shname = NULL;
int noext = FALSE;
int retval = FALSE;
@@ -2142,7 +2143,10 @@ executable_exists(char *name, char_u **path, int use_path, int use_pathext)
return FALSE;
// Using the name directly when a Unix-shell like 'shell'.
if (strstr((char *)gettail(p_sh), "sh") != NULL)
shname = gettail(p_sh);
if (strstr((char *)shname, "sh") != NULL &&
!(strstr((char *)shname, "powershell") != NULL
|| strstr((char *)shname, "pwsh") != NULL))
noext = TRUE;
if (use_pathext)
+1 -1
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 : */
+2 -1
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);
+1 -1
View File
@@ -1,6 +1,6 @@
/* screen.c */
int conceal_cursor_line(win_T *wp);
void conceal_check_cursor_line(void);
void conceal_check_cursor_line(int was_concealed);
int get_wcr_attr(win_T *wp);
void win_draw_end(win_T *wp, int c1, int c2, int draw_margin, int row, int endrow, hlf_T hl);
int compute_foldcolumn(win_T *wp, int col);
+3 -1
View File
@@ -1455,6 +1455,8 @@ yank_copy_line(struct block_def *bd, long y_idx, int exclude_trailing_space)
{
char_u *pnew;
if (exclude_trailing_space)
bd->endspaces = 0;
if ((pnew = alloc(bd->startspaces + bd->endspaces + bd->textlen + 1))
== NULL)
return FAIL;
@@ -2747,7 +2749,7 @@ write_reg_contents_lst(
&yank_type) == FAIL)
return;
str_to_reg(y_current, yank_type, (char_u *) strings, -1, block_len, TRUE);
str_to_reg(y_current, yank_type, (char_u *)strings, -1, block_len, TRUE);
finish_write_reg(name, old_y_previous, old_y_current);
}
+12 -2
View File
@@ -83,16 +83,26 @@ conceal_cursor_line(win_T *wp)
/*
* Check if the cursor line needs to be redrawn because of 'concealcursor'.
* To be called after changing the state, "was_concealed" is the value of
* "conceal_cursor_line()" before the change.
* "
*/
void
conceal_check_cursor_line(void)
conceal_check_cursor_line(int was_concealed)
{
if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin))
if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin) != was_concealed)
{
int wcol = curwin->w_wcol;
need_cursor_line_redraw = TRUE;
// Need to recompute cursor column, e.g., when starting Visual mode
// without concealing.
curs_columns(TRUE);
// When concealing now w_wcol will be computed wrong, keep the previous
// value, it will be updated in win_line().
if (!was_concealed)
curwin->w_wcol = wcol;
}
}
#endif
+7 -4
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)
+11
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)
@@ -1,12 +1,12 @@
|-+0&#ffffff0@59| @14
|-@59| @14
|-@25|%|-@16>@|-@14| @14
|-@25|%|-@16|@|-@14| @14
|-@25|f+0#0000001#ffd7ff255|i|R|S|t| |-+0#0000000#ffffff0@6|F+0#0000001#ffd7ff255|i|r|s|t| |-+0#0000000#ffffff0@14| @14
|-@25|s+0#0000001#ffd7ff255|e|C|O|n|d|-+0#0000000#ffffff0@6|S+0#0000001#ffd7ff255|e|c|o|n|D|-+0#0000000#ffffff0@14| @14
|-@59| @14
|-@1|f+0#0000001#ffd7ff255|i|r|s|t| |-+0#0000000#ffffff0@6|F+0#0000001#ffd7ff255|I|r|s|T| |-+0#0000000#ffffff0@38| @14
|-@1|s+0#0000001#ffd7ff255|e|c|o|n|d|-+0#0000000#ffffff0@6|S+0#0000001#ffd7ff255|E|c|o|N|D|-+0#0000000#ffffff0@38| @14
|-@1|#|-@16|&|-@38| @14
|-@1|s+0#0000001#ffd7ff255|e|c|o|n|d|-+0#0000000#ffffff0@6|S+0#0000001#ffd7ff255|E|c|o|N|D|-+0#0000000#ffffff0@6|m+0#0000001#ffd7ff255|a|r|k|-+0#0000000#ffffff0@27| @14
|-@1|#|-@16|&|-@4| @1>X|-@21| @23
|-@59| @14
|-@59| @14
@57|3|,|4|5| @9|T|o|p|
@57|9|,|3|8| @9|T|o|p|
@@ -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|
@@ -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|
+48
View File
@@ -28,4 +28,52 @@ func Test_blockinsert_delete()
bwipe!
endfunc
func Test_blockappend_eol_cursor()
new
" Test 1 Move 1 char left
call setline(1, ['aaa', 'bbb', 'ccc'])
exe "norm! gg$\<c-v>2jA\<left>x\<esc>"
call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
" Test 2 Move 2 chars left
sil %d
call setline(1, ['aaa', 'bbb', 'ccc'])
exe "norm! gg$\<c-v>2jA\<left>\<left>x\<esc>"
call assert_equal(['axaa', 'bxbb', 'cxcc'], getline(1, '$'))
" Test 3 Move 3 chars left (outside of the visual selection)
sil %d
call setline(1, ['aaa', 'bbb', 'ccc'])
exe "norm! ggl$\<c-v>2jA\<left>\<left>\<left>x\<esc>"
call assert_equal(['xaaa', 'bbb', 'ccc'], getline(1, '$'))
bw!
endfunc
func Test_blockappend_eol_cursor2()
new
" Test 1 Move 1 char left
call setline(1, ['aaaaa', 'bbb', 'ccccc'])
exe "norm! gg\<c-v>$2jA\<left>x\<esc>"
call assert_equal(['aaaaxa', 'bbbx', 'ccccxc'], getline(1, '$'))
" Test 2 Move 2 chars left
sil %d
call setline(1, ['aaaaa', 'bbb', 'ccccc'])
exe "norm! gg\<c-v>$2jA\<left>\<left>x\<esc>"
call assert_equal(['aaaxaa', 'bbbx', 'cccxcc'], getline(1, '$'))
" Test 3 Move 3 chars left (to the beginning of the visual selection)
sil %d
call setline(1, ['aaaaa', 'bbb', 'ccccc'])
exe "norm! gg\<c-v>$2jA\<left>\<left>\<left>x\<esc>"
call assert_equal(['aaxaaa', 'bbxb', 'ccxccc'], getline(1, '$'))
" Test 4 Move 3 chars left (outside of the visual selection)
sil %d
call setline(1, ['aaaaa', 'bbb', 'ccccc'])
exe "norm! ggl\<c-v>$2jA\<left>\<left>\<left>x\<esc>"
call assert_equal(['aaxaaa', 'bbxb', 'ccxccc'], getline(1, '$'))
" Test 5 Move 4 chars left (outside of the visual selection)
sil %d
call setline(1, ['aaaaa', 'bbb', 'ccccc'])
exe "norm! ggl\<c-v>$2jA\<left>\<left>\<left>\<left>x\<esc>"
call assert_equal(['axaaaa', 'bxbb', 'cxcccc'], getline(1, '$'))
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+5
View File
@@ -110,6 +110,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))
+12
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)})
+17 -2
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)
+2
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'],
+7 -3
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()
+2 -1
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:')
+2
View File
@@ -1123,6 +1123,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.
+1
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
+18 -2
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))
@@ -1462,6 +1463,13 @@ func Test_popup_atcursor_pos()
\ moved: range(3),
\ mousemoved: range(3),
\ })
normal 9G27|Rconcealed X
syn match Hidden /concealed/ conceal
set conceallevel=2 concealcursor=n
redraw
normal 0fX
call popup_atcursor('mark', {})
END
call writefile(lines, 'XtestPopupAtcursorPos')
let buf = RunVimInTerminal('-S XtestPopupAtcursorPos', #{rows: 12})
@@ -1542,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
+23 -5
View File
@@ -202,10 +202,16 @@ func Test_recover_corrupted_swap_file()
" Not all fields are written in a system-independent manner. Detect whether
" the test is running on a little or big-endian system, so the correct
" corruption values can be set.
let little_endian = b[1008:1015] == 0z33323130.00000000
let little_endian = b[1008:1011] == 0z33323130
" The swap file header fields can be either 32-bit or 64-bit.
let system_64bit = b[1012:1015] == 0z00000000
" clear the B0_MAGIC_LONG field
let b[1008:1015] = 0z0000000000000000
if system_64bit
let b[1008:1015] = 0z00000000.00000000
else
let b[1008:1011] = 0z00000000
endif
call writefile(b, sn)
let msg = execute('recover Xfile1')
call assert_match('the file has been damaged', msg)
@@ -243,7 +249,11 @@ func Test_recover_corrupted_swap_file()
" set the block number in a pointer entry to a negative number
let b = copy(save_b)
let b[4104:4111] = little_endian ? 0z00000000.00000080 : 0z80000000.00000000
if system_64bit
let b[4104:4111] = little_endian ? 0z00000000.00000080 : 0z80000000.00000000
else
let b[4104:4107] = little_endian ? 0z00000080 : 0z80000000
endif
call writefile(b, sn)
call assert_fails('recover Xfile1', 'E312:')
call assert_equal('Xfile1', @%)
@@ -261,7 +271,11 @@ func Test_recover_corrupted_swap_file()
" set the number of lines in the data block to zero
let b = copy(save_b)
let b[8208:8215] = 0z00000000.00000000
if system_64bit
let b[8208:8215] = 0z00000000.00000000
else
let b[8208:8211] = 0z00000000
endif
call writefile(b, sn)
call assert_fails('recover Xfile1', 'E312:')
call assert_equal('Xfile1', @%)
@@ -271,7 +285,11 @@ func Test_recover_corrupted_swap_file()
" use an invalid text start for the lines in a data block
let b = copy(save_b)
let b[8216:8219] = 0z00000000
if system_64bit
let b[8216:8219] = 0z00000000
else
let b[8212:8215] = 0z00000000
endif
call writefile(b, sn)
call assert_fails('recover Xfile1', 'E312:')
call assert_equal('Xfile1', @%)
+44 -6
View File
@@ -19,13 +19,18 @@ func Test_shell_options()
\ ['ash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
\ ['dash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
\ ['csh', '-c', '|& tee', '', '>&', '', ''],
\ ['tcsh', '-c', '|& tee', '', '>&', '', '']]
\ ['tcsh', '-c', '|& tee', '', '>&', '', ''],
\ ['pwsh', '-c', '>%s 2>&1', '', '>%s 2>&1', '', '']]
endif
if has('win32')
let shells += [['cmd', '/c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', ''],
\ ['cmd.exe', '/c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '('],
\ ['powershell.exe', '-c', '>', '', '>', '"&|<>()@^', '"'],
\ ['powershell', '-c', '>', '', '>', '"&|<>()@^', '"'],
\ ['powershell.exe', '-Command', '2>&1 | Out-File -Encoding default',
\ '', '2>&1 | Out-File -Encoding default', '"&|<>()@^', '"'],
\ ['powershell', '-Command', '2>&1 | Out-File -Encoding default', '',
\ '2>&1 | Out-File -Encoding default', '"&|<>()@^', '"'],
\ ['pwsh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
\ ['pwsh', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
\ ['sh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
\ ['ksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
\ ['mksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
@@ -58,6 +63,10 @@ func Test_shell_options()
if e[0] =~# '.*csh$' || e[0] =~# '.*csh.exe$'
let str1 = "'cmd \"arg1\" '\\''arg2'\\'' \\!%#'"
let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\\\!\\%\\#'"
elseif e[0] =~# '.*powershell$' || e[0] =~# '.*powershell.exe$'
\ || e[0] =~# '.*pwsh$' || e[0] =~# '.*pwsh.exe$'
let str1 = "'cmd \"arg1\" ''arg2'' !%#'"
let str2 = "'cmd \"arg1\" ''arg2'' \\!\\%\\#'"
else
let str1 = "'cmd \"arg1\" '\\''arg2'\\'' !%#'"
let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\!\\%\\#'"
@@ -71,9 +80,14 @@ func Test_shell_options()
let [&shellcmdflag, &shellpipe, &shellquote, &shellredir,
\ &shellxescape, &shellxquote] = e[1:6]
new
r !echo hello
call assert_equal('hello', substitute(getline(2), '\W', '', 'g'), e[0])
bwipe!
try
r !echo hello
call assert_equal('hello', substitute(getline(2), '\W', '', 'g'), e[0])
catch
call assert_report('Failed to run shell command, shell: ' .. e[0])
finally
bwipe!
endtry
endif
endfor
set shell& shellcmdflag& shellpipe& shellquote&
@@ -135,6 +149,30 @@ func Test_shellescape()
let &shell = save_shell
endfunc
" Test for 'shellslash'
func Test_shellslash()
CheckOption shellslash
let save_shellslash = &shellslash
" The shell and cmdflag, and expected slash in tempname with shellslash set or
" unset. The assert checks the file separator before the leafname.
" ".*\\\\[^\\\\]*$"
let shells = [['cmd', '/c', '\\', '/'],
\ ['powershell', '-Command', '\\', '/'],
\ ['pwsh', '-Command', '\\', '/'],
\ ['pwsh', '-c', '\\', '/'],
\ ['sh', '-c', '/', '/']]
for e in shells
exe 'set shell=' .. e[0] .. ' | set shellcmdflag=' .. e[1]
set noshellslash
let file = tempname()
call assert_match('^.\+' .. e[2] .. '[^' .. e[2] .. ']\+$', file, e[0] .. ' ' .. e[1] .. ' nossl')
set shellslash
let file = tempname()
call assert_match('^.\+' .. e[3] .. '[^' .. e[3] .. ']\+$', file, e[0] .. ' ' .. e[1] .. ' ssl')
endfor
let &shellslash = save_shellslash
endfunc
" Test for 'shellxquote'
func Test_shellxquote()
CheckUnix
+29 -13
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!
+41
View File
@@ -388,6 +388,16 @@ def Test_assign_linebreak()
->copy()
END
CheckDefFailure(lines, 'E1012:', 2)
lines =<< trim END
var x: any
x.key = 1
+ 2
+ 3
+ 4
+ 5
END
CheckDefExecAndScriptFailure2(lines, 'E1148:', 'E1203:', 2)
enddef
def Test_assign_index()
@@ -650,6 +660,37 @@ 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 PartFuncBool(b: bool): string
return 'done'
enddef
def Test_assignment_partial()
var lines =<< trim END
var Partial: func(): string = function(PartFuncBool, [true])
assert_equal('done', Partial())
END
CheckDefAndScriptSuccess(lines)
lines =<< trim END
vim9script
def Func(b: bool)
enddef
var Ref: func = function(Func, [true])
assert_equal('func()', typename(Ref))
Ref()
END
CheckScriptSuccess(lines)
enddef
def Test_assignment_list_any_index()
+488 -32
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()
+1 -8
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
+7 -1
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
+89
View File
@@ -603,6 +603,52 @@ 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()
var lines =<< trim END
vim9script
var seq = []
def DoIt()
try
seq->add('throw 1')
eval [][0]
seq->add('notreached')
catch
seq->add('catch')
try
seq->add('throw 2')
eval [][0]
seq->add('notreached')
catch /nothing/
seq->add('notreached')
endtry
seq->add('done')
endtry
enddef
DoIt()
assert_equal(['throw 1', 'catch', 'throw 2', 'done'], seq)
END
enddef
def Test_error_in_catch()
var lines =<< trim END
try
eval [][0]
catch /E684:/
eval [][0]
endtry
END
CheckDefExecFailure(lines, 'E684:', 4)
enddef
" :while at the very start of a function that :continue jumps to
@@ -742,6 +788,49 @@ def Test_try_catch_nested()
assert_equal('intry', ReturnFinally())
assert_equal('finally', g:in_finally)
var l = []
try
l->add('1')
throw 'bad'
l->add('x')
catch /bad/
l->add('2')
try
l->add('3')
throw 'one'
l->add('x')
catch /one/
l->add('4')
try
l->add('5')
throw 'more'
l->add('x')
catch /more/
l->add('6')
endtry
endtry
endtry
assert_equal(['1', '2', '3', '4', '5', '6'], l)
l = []
try
try
l->add('1')
throw 'foo'
l->add('x')
catch
l->add('2')
throw 'bar'
l->add('x')
finally
l->add('3')
endtry
l->add('x')
catch /bar/
l->add('4')
endtry
assert_equal(['1', '2', '3', '4'], l)
enddef
def TryOne(): number
+45 -5
View File
@@ -1,6 +1,8 @@
" Tests for various Visual modes.
source shared.vim
source check.vim
source screendump.vim
func Test_block_shift_multibyte()
" Uses double-wide character.
@@ -806,11 +808,7 @@ func Test_visual_block_mode()
%d _
call setline(1, ['aaa', 'bbb', 'ccc'])
exe "normal $\<C-V>2jA\<Left>x"
" BUG: Instead of adding x as the third character in all the three lines,
" 'a' is added in the second and third lines at the end. This bug is not
" reproducible if this operation is performed manually.
"call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
call assert_equal(['aaxa', 'bbba', 'ccca'], getline(1, '$'))
call assert_equal(['aaxa', 'bbxb', 'ccxc'], getline(1, '$'))
" Repeat the previous test but use 'l' to move the cursor instead of '$'
call setline(1, ['aaa', 'bbb', 'ccc'])
exe "normal! gg2l\<C-V>2jA\<Left>x"
@@ -1225,5 +1223,47 @@ func Test_visual_put_in_block_using_zy_and_zp()
bwipe!
endfunc
func Test_visual_put_blockedit_zy_and_zp()
new
call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
exe "normal! gg0\<c-v>2j$zy"
norm! 5gg0zP
call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
"
" now with blockmode editing
sil %d
:set ve=block
call setline(1, ['aa', 'bbbbb', 'ccc', '', 'XX', 'GGHHJ', 'RTZU'])
exe "normal! gg0\<c-v>2j$zy"
norm! 5gg0zP
call assert_equal(['aa', 'bbbbb', 'ccc', '', 'aaXX', 'bbbbbGGHHJ', 'cccRTZU'], getline(1, 7))
set ve&vim
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
+1 -1
View File
@@ -226,7 +226,7 @@ endfunc
func Test_xxd_version()
new
exe 'r! ' . s:xxd_cmd . ' -v'
call assert_match("xxd V1.10 .* by Juergen Weigert", join(getline(1, 3)))
call assert_match('xxd 20\d\d-\d\d-\d\d by Juergen Weigert et al\.', join(getline(1, 3)))
bwipe!
endfunc
+1 -1
View File
@@ -1105,7 +1105,7 @@ ui_cursor_shape_forced(int forced)
# endif
# ifdef FEAT_CONCEAL
conceal_check_cursor_line();
conceal_check_cursor_line(FALSE);
# endif
}
+40 -31
View File
@@ -3103,6 +3103,7 @@ call_func(
int argv_clear = 0;
int argv_base = 0;
partial_T *partial = funcexe->partial;
type_T check_type;
// Initialize rettv so that it is safe for caller to invoke clear_tv(rettv)
// even when call_func() returns FAIL.
@@ -3146,6 +3147,17 @@ call_func(
argv[i + argv_clear] = argvars_in[i];
argvars = argv;
argcount = partial->pt_argc + argcount_in;
if (funcexe->check_type != NULL
&& funcexe->check_type->tt_argcount != -1)
{
// Now funcexe->check_type is missing the added arguments, make
// a copy of the type with the correction.
check_type = *funcexe->check_type;
funcexe->check_type = &check_type;
check_type.tt_argcount += partial->pt_argc;
check_type.tt_min_argcount += partial->pt_argc;
}
}
}
@@ -5478,35 +5490,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 +5524,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 +5547,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 +5556,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 +5571,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;
}
/*
+74
View File
@@ -770,6 +770,80 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3107,
/**/
3106,
/**/
3105,
/**/
3104,
/**/
3103,
/**/
3102,
/**/
3101,
/**/
3100,
/**/
3099,
/**/
3098,
/**/
3097,
/**/
3096,
/**/
3095,
/**/
3094,
/**/
3093,
/**/
3092,
/**/
3091,
/**/
3090,
/**/
3089,
/**/
3088,
/**/
3087,
/**/
3086,
/**/
3085,
/**/
3084,
/**/
3083,
/**/
3082,
/**/
3081,
/**/
3080,
/**/
3079,
/**/
3078,
/**/
3077,
/**/
3076,
/**/
3075,
/**/
3074,
/**/
3073,
/**/
3072,
/**/
3071,
/**/
3070,
/**/
+36 -6
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);
@@ -6726,7 +6726,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
var_start = arg;
for (var_idx = 0; var_idx == 0 || var_idx < var_count; var_idx++)
{
int instr_count = -1;
int instr_count = -1;
int save_lnum;
if (var_start[0] == '_' && !eval_isnamec(var_start[1]))
{
@@ -6979,13 +6980,20 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
goto theend;
}
// Use the line number of the assignment for store instruction.
save_lnum = cctx->ctx_lnum;
cctx->ctx_lnum = start_lnum - 1;
if (lhs.lhs_has_index)
{
// Use the info in "lhs" to store the value at the index in the
// list or dict.
if (compile_assign_unlet(var_start, &lhs, TRUE, rhs_type, cctx)
== FAIL)
{
cctx->ctx_lnum = save_lnum;
goto theend;
}
}
else
{
@@ -7006,8 +7014,12 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
generate_SETTYPE(cctx, lhs.lhs_type);
if (generate_store_lhs(cctx, &lhs, instr_count) == FAIL)
{
cctx->ctx_lnum = save_lnum;
goto theend;
}
}
cctx->ctx_lnum = save_lnum;
if (var_idx + 1 < var_count)
var_start = skipwhite(lhs.lhs_dest_end + 1);
@@ -7747,6 +7759,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 +7787,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 +7951,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;
@@ -8397,10 +8421,17 @@ compile_finally(char_u *arg, cctx_T *cctx)
this_instr = instr->ga_len;
#ifdef FEAT_PROFILE
if (cctx->ctx_compile_type == CT_PROFILE
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
&& ((isn_T *)instr->ga_data)[this_instr - 1]
.isn_type == ISN_PROF_START)
{
// jump to the profile start of the "finally"
--this_instr;
// jump to the profile end above it
if (this_instr > 0 && ((isn_T *)instr->ga_data)[this_instr - 1]
.isn_type == ISN_PROF_END)
--this_instr;
}
#endif
// Fill in the "end" label in jumps at the end of the blocks.
@@ -9153,7 +9184,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);
@@ -9176,12 +9206,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;
@@ -9211,6 +9240,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.
+29 -8
View File
@@ -26,6 +26,8 @@
typedef struct {
int tcd_frame_idx; // ec_frame_idx at ISN_TRY
int tcd_stack_len; // size of ectx.ec_stack at ISN_TRY
int tcd_in_catch; // in catch or finally block
int tcd_did_throw; // set did_throw in :endtry
int tcd_catch_idx; // instruction of the first :catch or :finally
int tcd_finally_idx; // instruction of the :finally block or zero
int tcd_endtry_idx; // instruction of the :endtry
@@ -82,7 +84,6 @@ struct ectx_S {
funclocal_T ec_funclocal;
garray_T ec_trystack; // stack of trycmd_T values
int ec_in_catch; // when TRUE in catch or finally block
int ec_dfunc_idx; // current function index
isn_T *ec_instr; // array with instructions
@@ -1565,20 +1566,38 @@ exec_instructions(ectx_T *ectx)
*msg_list = NULL;
}
if (did_throw && !ectx->ec_in_catch)
if (did_throw)
{
garray_T *trystack = &ectx->ec_trystack;
trycmd_T *trycmd = NULL;
int index = trystack->ga_len;
// An exception jumps to the first catch, finally, or returns from
// the current function.
if (trystack->ga_len > 0)
trycmd = ((trycmd_T *)trystack->ga_data) + trystack->ga_len - 1;
while (index > 0)
{
trycmd = ((trycmd_T *)trystack->ga_data) + index - 1;
if (!trycmd->tcd_in_catch || trycmd->tcd_finally_idx != 0)
break;
// In the catch and finally block of this try we have to go up
// one level.
--index;
trycmd = NULL;
}
if (trycmd != NULL && trycmd->tcd_frame_idx == ectx->ec_frame_idx)
{
// jump to ":catch" or ":finally"
ectx->ec_in_catch = TRUE;
ectx->ec_iidx = trycmd->tcd_catch_idx;
if (trycmd->tcd_in_catch)
{
// exception inside ":catch", jump to ":finally" once
ectx->ec_iidx = trycmd->tcd_finally_idx;
trycmd->tcd_finally_idx = 0;
}
else
// jump to first ":catch"
ectx->ec_iidx = trycmd->tcd_catch_idx;
trycmd->tcd_in_catch = TRUE;
did_throw = FALSE; // don't come back here until :endtry
trycmd->tcd_did_throw = TRUE;
}
else
{
@@ -3202,6 +3221,7 @@ exec_instructions(ectx_T *ectx)
trycmd_T *trycmd = ((trycmd_T *)trystack->ga_data)
+ trystack->ga_len - 1;
trycmd->tcd_caught = TRUE;
trycmd->tcd_did_throw = FALSE;
}
did_emsg = got_int = did_throw = FALSE;
force_abort = need_rethrow = FALSE;
@@ -3263,9 +3283,10 @@ exec_instructions(ectx_T *ectx)
--trystack->ga_len;
--trylevel;
ectx->ec_in_catch = FALSE;
trycmd = ((trycmd_T *)trystack->ga_data)
+ trystack->ga_len;
if (trycmd->tcd_did_throw)
did_throw = TRUE;
if (trycmd->tcd_caught && current_exception != NULL)
{
// discard the exception
+23 -5
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
@@ -355,7 +355,20 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member)
if (ufunc->uf_func_type == NULL)
set_function_type(ufunc);
if (ufunc->uf_func_type != NULL)
{
if (tv->v_type == VAR_PARTIAL
&& tv->vval.v_partial->pt_argc > 0)
{
type = get_type_ptr(type_gap);
if (type == NULL)
return NULL;
*type = *ufunc->uf_func_type;
type->tt_argcount -= tv->vval.v_partial->pt_argc;
type->tt_min_argcount -= tv->vval.v_partial->pt_argc;
return type;
}
return ufunc->uf_func_type;
}
}
}
@@ -364,6 +377,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 +539,10 @@ 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_min_argcount != -1
&& (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 +1047,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
+3 -7
View File
@@ -55,16 +55,12 @@
* 11.01.2019 Add full 64/32 bit range to -o and output by Christer Jensen.
* 04.02.2020 Add -d for decimal offsets by Aapo Rantalainen
*
* (c) 1990-1998 by Juergen Weigert (jnweiger@informatik.uni-erlangen.de)
* (c) 1990-1998 by Juergen Weigert (jnweiger@gmail.com)
*
* I hereby grant permission to distribute and use xxd
* under X11-MIT or GPL-2.0 (at the user's choice).
*
* Small changes made afterwards by Bram Moolenaar et al.
*
* Distribute freely and credit me,
* make money and share with me,
* lose money and don't ask me.
* Contributions by Bram Moolenaar et al.
*/
/* Visual Studio 2005 has 'deprecated' many of the standard CRT functions */
@@ -135,7 +131,7 @@ extern void perror __P((char *));
extern long int strtol();
extern long int ftell();
char version[] = "xxd V1.10 27oct98 by Juergen Weigert";
char version[] = "xxd 2020-02-04 by Juergen Weigert et al.";
#ifdef WIN32
char osver[] = " (Win32)";
#else