Merge remote-tracking branch 'vim/master'

This commit is contained in:
ichizok
2021-05-30 19:55:29 +09:00
46 changed files with 855 additions and 91 deletions
+1 -1
View File
@@ -152,7 +152,7 @@ MINOR = 2
# > cd src
# > msvc2015.bat
# - Build the console binary:
# > nmake -f Mae_mvc.mak
# > nmake -f Make_mvc.mak
# - Run the tests and check the output:
# > nmake -f Make_mvc.mak testclean
# > nmake -f Make_mvc.mak test
+14 -6
View File
@@ -11,7 +11,11 @@ sed -e "s/@<<$/@<< | sed -e 's#.*\\\\r.*##'/" Make_mvc.mak > Make_mvc2.mak
echo "Building MSVC 64bit console Version"
nmake -f Make_mvc2.mak CPU=AMD64 ^
OLE=no GUI=no IME=yes ICONV=yes DEBUG=no ^
FEATURES=%FEATURE% || exit 1
FEATURES=%FEATURE%
if not exist vim.exe (
echo Build failure.
exit 1
)
:: build MSVC huge version with python and channel support
:: GUI needs to be last, so that testing works
@@ -21,16 +25,20 @@ if "%FEATURE%" == "HUGE" (
OLE=no GUI=yes IME=yes ICONV=yes DEBUG=no POSTSCRIPT=yes ^
PYTHON_VER=27 DYNAMIC_PYTHON=yes PYTHON=C:\Python27-x64 ^
PYTHON3_VER=35 DYNAMIC_PYTHON3=yes PYTHON3=C:\Python35-x64 ^
FEATURES=%FEATURE% || exit 1
FEATURES=%FEATURE%
) ELSE (
nmake -f Make_mvc2.mak CPU=AMD64 ^
OLE=no GUI=yes IME=yes ICONV=yes DEBUG=no ^
FEATURES=%FEATURE% || exit 1
FEATURES=%FEATURE%
)
.\gvim -u NONE -c "redir @a | ver |0put a | wq" ver_msvc.txt
if not exist gvim.exe (
echo Build failure.
exit 1
)
.\gvim -u NONE -c "redir @a | ver |0put a | wq" ver_msvc.txt || exit 1
echo "version output MSVC console"
.\vim --version
.\vim --version || exit 1
echo "version output MSVC GUI"
type ver_msvc.txt
type ver_msvc.txt || exit 1
cd ..
+1 -1
View File
@@ -1037,7 +1037,7 @@ giving the mapping.
Defaults without a .vimrc file ~
*defaults.vim*
*defaults.vim* *E1187*
If Vim is started normally and no user vimrc file is found, the
$VIMRUNTIME/defaults.vim script is loaded. This will set 'compatible' off,
switch on syntax highlighting and a few more things. See the script for
+6
View File
@@ -1981,6 +1981,12 @@ win_line(
// TODO: is passing p for start of the line OK?
n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol,
NULL) - 1;
// We have just drawn the showbreak value, no need to add
// space for it again
if (vcol == vcol_sbr)
n_extra -= MB_CHARLEN(get_showbreak_value(wp));
if (c == TAB && n_extra + col > wp->w_width)
# ifdef FEAT_VARTABS
n_extra = tabstop_padding(vcol, wp->w_buffer->b_p_ts,
+2
View File
@@ -413,3 +413,5 @@ EXTERN char e_missing_redir_end[]
INIT(= N_("E1185: Missing :redir END"));
EXTERN char e_expression_does_not_result_in_value_str[]
INIT(= N_("E1186: Expression does not result in a value: %s"));
EXTERN char e_failed_to_source_defaults[]
INIT(= N_("E1187: Failed to source defaults.vim"));
+14 -8
View File
@@ -1309,6 +1309,9 @@ set_var_lval(
{
cc = *endp;
*endp = NUL;
if (in_vim9script() && check_reserved_name(lp->ll_name) == FAIL)
return;
if (lp->ll_blob != NULL)
{
int error = FALSE, val;
@@ -2358,7 +2361,7 @@ eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
++*arg;
if (evaluate && vim9script && !IS_WHITE_OR_NUL((*arg)[1]))
{
error_white_both(p, op_falsy ? 2 : 1);
error_white_both(*arg - (op_falsy ? 1 : 0), op_falsy ? 2 : 1);
clear_tv(rettv);
return FAIL;
}
@@ -2406,7 +2409,7 @@ eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
*/
if (evaluate && vim9script && !IS_WHITE_OR_NUL((*arg)[1]))
{
error_white_both(p, 1);
error_white_both(*arg, 1);
clear_tv(rettv);
evalarg_used->eval_flags = orig_flags;
return FAIL;
@@ -2511,7 +2514,7 @@ eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
*/
if (evaluate && in_vim9script() && !IS_WHITE_OR_NUL((*arg)[2]))
{
error_white_both(p, 2);
error_white_both(*arg, 2);
clear_tv(rettv);
return FAIL;
}
@@ -2637,7 +2640,7 @@ eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
*/
if (evaluate && in_vim9script() && !IS_WHITE_OR_NUL((*arg)[2]))
{
error_white_both(p, 2);
error_white_both(*arg, 2);
clear_tv(rettv);
return FAIL;
}
@@ -2735,10 +2738,13 @@ eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
if (getnext)
{
*arg = eval_next_line(evalarg);
p = *arg;
}
else if (evaluate && vim9script && !VIM_ISWHITE(**arg))
{
error_white_both(p, len);
error_white_both(*arg, len);
clear_tv(rettv);
return FAIL;
}
@@ -2898,7 +2904,7 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
{
if (evaluate && vim9script && !VIM_ISWHITE(**arg))
{
error_white_both(p, oplen);
error_white_both(*arg, oplen);
clear_tv(rettv);
return FAIL;
}
@@ -2934,7 +2940,7 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
*/
if (evaluate && vim9script && !IS_WHITE_OR_NUL((*arg)[oplen]))
{
error_white_both(p, oplen);
error_white_both(*arg, oplen);
clear_tv(rettv);
return FAIL;
}
@@ -3130,7 +3136,7 @@ eval6(
{
if (evaluate && in_vim9script() && !VIM_ISWHITE(**arg))
{
error_white_both(p, 1);
error_white_both(*arg, 1);
clear_tv(rettv);
return FAIL;
}
+37 -18
View File
@@ -3398,8 +3398,11 @@ find_ex_command(
int len;
char_u *p;
int i;
#ifndef FEAT_EVAL
int vim9 = FALSE;
#else
int vim9 = in_vim9script();
#ifdef FEAT_EVAL
/*
* Recognize a Vim9 script function/method call and assignment:
* "lvar = value", "lvar(arg)", "[1, 2 3]->Func()"
@@ -3562,12 +3565,13 @@ find_ex_command(
* - the "d" command can directly be followed by 'l' or 'p' flag.
*/
p = eap->cmd;
if (*p == 'k')
if (!vim9 && *p == 'k')
{
eap->cmdidx = CMD_k;
++p;
}
else if (p[0] == 's'
else if (!vim9
&& p[0] == 's'
&& ((p[1] == 'c' && (p[2] == NUL || (p[2] != 's' && p[2] != 'r'
&& (p[3] == NUL || (p[3] != 'i' && p[4] != 'p')))))
|| p[1] == 'g'
@@ -3600,7 +3604,7 @@ find_ex_command(
if (p == eap->cmd && vim_strchr((char_u *)"@*!=><&~#}", *p) != NULL)
++p;
len = (int)(p - eap->cmd);
if (*eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p'))
if (!vim9 && *eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p'))
{
// Check for ":dl", ":dell", etc. to ":deletel": that's
// :delete with the 'l' flag. Same for 'p'.
@@ -3677,7 +3681,7 @@ find_ex_command(
#ifdef FEAT_EVAL
if (eap->cmdidx < CMD_SIZE
&& in_vim9script()
&& vim9
&& !IS_WHITE_OR_NUL(*p) && *p != '\n' && *p != '!'
&& (eap->cmdidx < 0 ||
(cmdnames[eap->cmdidx].cmd_argt & EX_NONWHITE_OK) == 0))
@@ -3797,17 +3801,32 @@ f_fullcommand(typval_T *argvars, typval_T *rettv)
char_u *name = argvars[0].vval.v_string;
char_u *p;
while (name[0] != NUL && name[0] == ':')
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
if (name == NULL)
return;
while (*name != NUL && *name == ':')
name++;
name = skip_range(name, TRUE, NULL);
rettv->v_type = VAR_STRING;
ea.cmd = (*name == '2' || *name == '3') ? name + 1 : name;
ea.cmdidx = (cmdidx_T)0;
ea.addr_count = 0;
p = find_ex_command(&ea, NULL, NULL, NULL);
if (p == NULL || ea.cmdidx == CMD_SIZE)
return;
if (in_vim9script())
{
int res;
++emsg_silent;
res = not_in_vim9(&ea);
--emsg_silent;
if (res == FAIL)
return;
}
rettv->vval.v_string = vim_strsave(IS_USER_CMDIDX(ea.cmdidx)
? get_user_commands(NULL, ea.useridx)
@@ -5485,7 +5504,7 @@ not_exiting(void)
settmode(TMODE_RAW);
}
static int
int
before_quit_autocmds(win_T *wp, int quit_all, int forceit)
{
apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, wp->w_buffer);
@@ -5559,7 +5578,7 @@ ex_quit(exarg_T *eap)
#endif
/*
* If there are more files or windows we won't exit.
* If there is only one relevant window we will exit.
*/
if (check_more(FALSE, eap->forceit) == OK && only_one_window())
exiting = TRUE;
@@ -6076,7 +6095,7 @@ ex_stop(exarg_T *eap)
}
/*
* ":exit", ":xit" and ":wq": Write file and quite the current window.
* ":exit", ":xit" and ":wq": Write file and quit the current window.
*/
static void
ex_exit(exarg_T *eap)
@@ -6099,17 +6118,17 @@ ex_exit(exarg_T *eap)
return;
}
if (before_quit_autocmds(curwin, FALSE, eap->forceit))
return;
/*
* if more files or windows we won't exit
* we plan to exit if there is only one relevant window
*/
if (check_more(FALSE, eap->forceit) == OK && only_one_window())
exiting = TRUE;
if ( ((eap->cmdidx == CMD_wq
|| curbufIsChanged())
&& do_write(eap) == FAIL)
// Write the buffer for ":wq" or when it was changed.
// Trigger QuitPre and ExitPre.
// Check if we can exit now, after autocommands have changed things.
if (((eap->cmdidx == CMD_wq || curbufIsChanged()) && do_write(eap) == FAIL)
|| before_quit_autocmds(curwin, FALSE, eap->forceit)
|| check_more(TRUE, eap->forceit) == FAIL
|| (only_one_window() && check_changed_any(eap->forceit, FALSE)))
{
+3 -2
View File
@@ -866,9 +866,10 @@ gui_exit(int rc)
void
gui_shell_closed(void)
{
cmdmod_T save_cmdmod;
cmdmod_T save_cmdmod = cmdmod;
save_cmdmod = cmdmod;
if (before_quit_autocmds(curwin, TRUE, FALSE))
return;
// Only exit when there are no changed files
exiting = TRUE;
+30 -1
View File
@@ -700,12 +700,41 @@ S_POPMARK(pTHX)
/* perl-5.32 needs Perl_POPMARK */
# if (PERL_REVISION == 5) && (PERL_VERSION >= 32)
# define Perl_POPMARK S_POPMARK
# endif
/* perl-5.34 needs Perl_SvTRUE_common; used in SvTRUE_nomg_NN */
# if (PERL_REVISION == 5) && (PERL_VERSION >= 34)
PERL_STATIC_INLINE bool
Perl_SvTRUE_common(pTHX_ SV * sv, const bool sv_2bool_is_fallback)
{
if (UNLIKELY(SvIMMORTAL_INTERP(sv)))
return SvIMMORTAL_TRUE(sv);
if (! SvOK(sv))
return FALSE;
if (SvPOK(sv))
return SvPVXtrue(sv);
if (SvIOK(sv))
return SvIVX(sv) != 0; /* casts to bool */
if (SvROK(sv) && !(SvOBJECT(SvRV(sv)) && HvAMAGIC(SvSTASH(SvRV(sv)))))
return TRUE;
if (sv_2bool_is_fallback)
return sv_2bool_nomg(sv);
return isGV_with_GP(sv);
}
# endif
/* perl-5.32 needs Perl_SvTRUE */
# if (PERL_REVISION == 5) && (PERL_VERSION >= 32)
PERL_STATIC_INLINE bool
Perl_SvTRUE(pTHX_ SV *sv) {
if (!LIKELY(sv))
return FALSE;
return FALSE;
SvGETMAGIC(sv);
return SvTRUE_nomg_NN(sv);
}
+8 -2
View File
@@ -3213,7 +3213,11 @@ source_startup_scripts(mparm_T *parmp)
if (parmp->use_vimrc != NULL)
{
if (STRCMP(parmp->use_vimrc, "DEFAULTS") == 0)
do_source((char_u *)VIM_DEFAULTS_FILE, FALSE, DOSO_NONE, NULL);
{
if (do_source((char_u *)VIM_DEFAULTS_FILE, FALSE, DOSO_NONE, NULL)
!= OK)
emsg(e_failed_to_source_defaults);
}
else if (STRCMP(parmp->use_vimrc, "NONE") == 0
|| STRCMP(parmp->use_vimrc, "NORC") == 0)
{
@@ -3285,7 +3289,9 @@ source_startup_scripts(mparm_T *parmp)
&& !has_dash_c_arg)
{
// When no .vimrc file was found: source defaults.vim.
do_source((char_u *)VIM_DEFAULTS_FILE, FALSE, DOSO_NONE, NULL);
if (do_source((char_u *)VIM_DEFAULTS_FILE, FALSE, DOSO_NONE,
NULL) == FAIL)
emsg(e_failed_to_source_defaults);
}
}
+7 -2
View File
@@ -2772,7 +2772,8 @@ ml_append_int(
len = (colnr_T)STRLEN(line) + 1; // space needed for the text
#ifdef FEAT_PROP_POPUP
if (curbuf->b_has_textprop && lnum > 0 && !(flags & ML_APPEND_UNDO))
if (curbuf->b_has_textprop && lnum > 0
&& !(flags & (ML_APPEND_UNDO | ML_APPEND_NOPROP)))
// Add text properties that continue from the previous line.
add_text_props_for_append(buf, lnum, &line, &len, &tofree);
#endif
@@ -3992,7 +3993,11 @@ ml_flush_line(buf_T *buf)
*/
// How about handling errors???
(void)ml_append_int(buf, lnum, new_line, new_len,
(dp->db_index[idx] & DB_MARKED) ? ML_APPEND_MARK : 0);
((dp->db_index[idx] & DB_MARKED) ? ML_APPEND_MARK : 0)
#ifdef FEAT_PROP_POPUP
| ML_APPEND_NOPROP
#endif
);
(void)ml_delete_int(buf, lnum, 0);
}
}
+32
View File
@@ -120,6 +120,37 @@ test_trunc_string(void)
vim_free(s);
}
/*
* Test trunc_string() with mbyte chars.
*/
static void
test_trunc_string_mbyte(void)
{
char_u *buf; // allocated every time to find uninit errors
char_u *s;
buf = alloc(40);
s = vim_strsave((char_u *)"Ä text tha just fits");
trunc_string(s, buf, 20, 40);
assert(STRCMP(buf, "Ä text tha just fits") == 0);
vim_free(buf);
vim_free(s);
buf = alloc(40);
s = vim_strsave((char_u *)"a text ÄÖÜä nott fits");
trunc_string(s, buf, 20, 40);
assert(STRCMP(buf, "a text Ä...nott fits") == 0);
vim_free(buf);
vim_free(s);
buf = alloc(40);
s = vim_strsave((char_u *)"a text that not fitsÄ");
trunc_string(s, buf, 20, 40);
assert(STRCMP(buf, "a text t...not fitsÄ") == 0);
vim_free(buf);
vim_free(s);
}
/*
* Test vim_snprintf() with a focus on checking that truncation is
* correct when buffer is small, since it cannot be tested from
@@ -286,6 +317,7 @@ main(int argc, char **argv)
set_option_value((char_u *)"encoding", 0, (char_u *)"utf-8", 0);
init_chartab();
test_trunc_string();
test_trunc_string_mbyte();
test_vim_snprintf();
set_option_value((char_u *)"encoding", 0, (char_u *)"latin1", 0);
+11
View File
@@ -6156,6 +6156,17 @@ nv_g_cmd(cmdarg_T *cap)
i = curwin->w_leftcol + curwin->w_width - col_off - 1;
coladvance((colnr_T)i);
// if the character doesn't fit move one back
if (curwin->w_cursor.col > 0
&& (*mb_ptr2cells)(ml_get_cursor()) > 1)
{
colnr_T vcol;
getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol);
if (vcol >= curwin->w_leftcol + curwin->w_width - col_off)
--curwin->w_cursor.col;
}
// Make sure we stick in this column.
validate_virtcol();
curwin->w_curswant = curwin->w_virtcol;
+20 -8
View File
@@ -3822,17 +3822,29 @@ update_popups(void (*win_update)(win_T *wp))
title_wincol = wp->w_wincol + 1;
if (wp->w_popup_title != NULL)
{
char_u *title_text;
title_len = (int)MB_CHARLEN(wp->w_popup_title);
title_len = (int)STRLEN(wp->w_popup_title);
title_text = alloc(title_len + 1);
trunc_string(wp->w_popup_title, title_text,
total_width - 2, title_len + 1);
screen_puts(title_text, wp->w_winrow, title_wincol,
wp->w_popup_border[0] > 0 ? border_attr[0] : popup_attr);
vim_free(title_text);
// truncate the title if too long
if (title_len > total_width - 2)
{
int title_byte_len = (int)STRLEN(wp->w_popup_title);
char_u *title_text = alloc(title_byte_len + 1);
if (title_text != NULL)
{
trunc_string(wp->w_popup_title, title_text,
total_width - 2, title_byte_len + 1);
screen_puts(title_text, wp->w_winrow, title_wincol,
wp->w_popup_border[0] > 0
? border_attr[0] : popup_attr);
vim_free(title_text);
}
title_len = total_width - 2;
}
else
screen_puts(wp->w_popup_title, wp->w_winrow, title_wincol,
wp->w_popup_border[0] > 0 ? border_attr[0] : popup_attr);
}
wincol = wp->w_wincol - wp->w_popup_leftoff;
+2 -1
View File
@@ -7,13 +7,13 @@ int getline_equal(char_u *(*fgetline)(int, void *, int, getline_opt_T), void *co
void *getline_cookie(char_u *(*fgetline)(int, void *, int, getline_opt_T), void *cookie);
char_u *getline_peek(char_u *(*fgetline)(int, void *, int, getline_opt_T), void *cookie);
char *ex_errmsg(char *msg, char_u *arg);
int checkforcmd(char_u **pp, char *cmd, int len);
int parse_command_modifiers(exarg_T *eap, char **errormsg, cmdmod_T *cmod, int skip_only);
int has_cmdmod(cmdmod_T *cmod);
int cmdmod_error(void);
void apply_cmdmod(cmdmod_T *cmod);
void undo_cmdmod(cmdmod_T *cmod);
int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
int checkforcmd(char_u **pp, char *cmd, int len);
char_u *skip_option_env_lead(char_u *start);
char_u *find_ex_command(exarg_T *eap, int *full, int (*lookup)(char_u *, size_t, int cmd, cctx_T *), cctx_T *cctx);
int modifier_len(char_u *cmd);
@@ -33,6 +33,7 @@ char_u *find_nextcmd(char_u *p);
char_u *check_nextcmd(char_u *p);
char_u *get_command_name(expand_T *xp, int idx);
void not_exiting(void);
int before_quit_autocmds(win_T *wp, int quit_all, int forceit);
void ex_quit(exarg_T *eap);
void tabpage_close(int forceit);
void tabpage_close_other(tabpage_T *tp, int forceit);
+1
View File
@@ -18,4 +18,5 @@ void hide_script_var(scriptitem_T *si, int idx, int func_defined);
void free_all_script_vars(scriptitem_T *si);
svar_T *find_typval_in_script(typval_T *dest);
int check_script_var_type(typval_T *dest, typval_T *value, char_u *name, where_T where);
int check_reserved_name(char_u *name);
/* vim: set ft=c : */
+1
View File
@@ -774,6 +774,7 @@ typedef struct memline
#define ML_APPEND_NEW 1 // starting to edit a new file
#define ML_APPEND_MARK 2 // mark the new line
#define ML_APPEND_UNDO 4 // called from undo
#define ML_APPEND_NOPROP 8 // do not continue textprop from previous line
/*
+1
View File
@@ -4254,6 +4254,7 @@ add_termcode(char_u *name, char_u *string, int flags)
if (new_tc == NULL)
{
tc_max_len -= 20;
vim_free(s);
return;
}
for (i = 0; i < tc_len; ++i)
+1 -1
View File
@@ -40,7 +40,7 @@ tiny: nolog tinytests report
benchmark: $(SCRIPTS_BENCH)
report:
# without the +eval feature test_result.log is a copy of test.log
@# without the +eval feature test_result.log is a copy of test.log
@/bin/sh -c "if test -f test.log; \
then cp test.log test_result.log; \
else echo No failures reported > test_result.log; \
@@ -0,0 +1,10 @@
>1+0&#ffffff0| @73
|2| @73
|3| @73
|4| @25|╔+0#0000001#ffd7ff255|▶|Ä|Ö|Ü|◀|═@12|╗| +0#0000000#ffffff0@27
|5| @25|║+0#0000001#ffd7ff255| |T+0&#e0e0e08|h|i|s| |i|s| |a| |l|i|n|e| @1| +0&#ffd7ff255|║| +0#0000000#ffffff0@27
|6| @25|║+0#0000001#ffd7ff255| |a|n|d| |a|n|o|t|h|e|r| |l|i|n|e| |║| +0#0000000#ffffff0@27
|7| @25|╚+0#0000001#ffd7ff255|═@17|╝| +0#0000000#ffffff0@27
|8| @73
|9| @73
@57|1|,|1| @10|T|o|p|
+1
View File
@@ -475,6 +475,7 @@ func Test_fullcommand()
for [in, want] in items(tests)
call assert_equal(want, fullcommand(in))
endfor
call assert_equal('', fullcommand(test_null_string()))
call assert_equal('syntax', 'syn'->fullcommand())
endfunc
+1
View File
@@ -167,6 +167,7 @@ func Test_cpo_E()
call assert_beeps('normal "ayl')
" change an empty line
call assert_beeps('normal lcTa')
call assert_beeps('normal 0c0')
" delete an empty line
call assert_beeps('normal D')
call assert_beeps('normal dl')
+17
View File
@@ -334,4 +334,21 @@ func Test_fold_fillchars()
set fillchars& fdc& foldmethod& foldenable&
endfunc
func Test_display_linebreak_breakat()
new
vert resize 25
let _breakat = &breakat
setl signcolumn=yes linebreak breakat=) showbreak=+\
call setline(1, repeat('x', winwidth(0) - 2) .. ')abc')
let lines = ScreenLines([1, 2], 25)
let expected = [
\ ' xxxxxxxxxxxxxxxxxxxxxxx',
\ ' + )abc '
\ ]
call assert_equal(expected, lines)
%bw!
let &breakat=_breakat
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+1
View File
@@ -127,6 +127,7 @@ func Test_getreg_empty_list()
let y = x
call add(x, 'foo')
call assert_equal(['foo'], y)
call assert_fails('call getreg([])', 'E730:')
endfunc
func Test_loop_over_null_list()
+7
View File
@@ -141,6 +141,7 @@ func Test_min()
call assert_fails('call min(1)', 'E712:')
call assert_fails('call min(v:none)', 'E712:')
call assert_fails('call min([1, {}])', 'E728:')
" check we only get one error
call assert_fails('call min([[1], #{}])', ['E745:', 'E745:'])
@@ -715,6 +716,7 @@ func Test_tr()
call assert_fails("let s=tr('abcd', 'abcd', 'def')", 'E475:')
call assert_equal('hEllO', tr('hello', 'eo', 'EO'))
call assert_equal('hello', tr('hello', 'xy', 'ab'))
call assert_fails('call tr("abc", "123", "₁₂")', 'E475:')
set encoding=utf8
endfunc
@@ -2674,4 +2676,9 @@ func Test_default_arg_value()
call assert_equal('msg', HasDefault())
endfunc
" Test for gettext()
func Test_gettext()
call assert_fails('call gettext(1)', 'E475:')
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+17
View File
@@ -876,4 +876,21 @@ func Test_normal_increment_with_virtualedit()
set virtualedit&
endfunc
" Test for incrementing a signed hexadecimal and octal number
func Test_normal_increment_signed_hexoct_nr()
new
" negative sign before a hex number should be ignored
call setline(1, ["-0x9"])
exe "norm \<C-A>"
call assert_equal(["-0xa"], getline(1, '$'))
exe "norm \<C-X>"
call assert_equal(["-0x9"], getline(1, '$'))
call setline(1, ["-007"])
exe "norm \<C-A>"
call assert_equal(["-010"], getline(1, '$'))
exe "norm \<C-X>"
call assert_equal(["-007"], getline(1, '$'))
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+5
View File
@@ -513,6 +513,11 @@ func Test_list_locked_var_unlet()
call assert_equal(expected[depth][u][1], ps)
endfor
endfor
" Deleting a list range should fail if the range is locked
let l = [1, 2, 3, 4]
lockvar l[1:2]
call assert_fails('unlet l[1:2]', 'E741:')
unlet l
endfunc
" Locked variables and :unlet or list / dict functions
+56 -3
View File
@@ -1986,6 +1986,16 @@ func Test_normal30_changecase()
call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
set whichwrap&
" try changing the case with a double byte encoding (DBCS)
%bw!
let enc = &enc
set encoding=cp932
call setline(1, "\u8470")
normal ~
normal gU$gu$gUgUg~g~gugu
call assert_equal("\u8470", getline(1))
let &encoding = enc
" clean up
bw!
endfunc
@@ -2191,9 +2201,9 @@ func Test_normal33_g_cmd2()
%d
15vsp
set wrap listchars= sbr=
let lineA='abcdefghijklmnopqrstuvwxyz'
let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
let lineC='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
let lineA = 'abcdefghijklmnopqrstuvwxyz'
let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
$put =lineA
$put =lineB
@@ -2228,6 +2238,28 @@ func Test_normal33_g_cmd2()
call assert_equal('l', getreg(0))
call assert_beeps('normal 5g$')
" Test for g$ with double-width character half displayed
vsplit
9wincmd |
setlocal nowrap nonumber
call setline(2, 'asdfasdfヨ')
2
normal 0g$
call assert_equal(8, col('.'))
10wincmd |
normal 0g$
call assert_equal(9, col('.'))
setlocal signcolumn=yes
11wincmd |
normal 0g$
call assert_equal(8, col('.'))
12wincmd |
normal 0g$
call assert_equal(9, col('.'))
close
" Test for g_
call assert_beeps('normal! 100g_')
call setline(2, [' foo ', ' foobar '])
@@ -3324,4 +3356,25 @@ func Test_normal_percent_jump()
close!
endfunc
" Test for << and >> commands to shift text by 'shiftwidth'
func Test_normal_shift_rightleft()
new
call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
set shiftwidth=2 tabstop=8
normal gg6>>
call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
\ getline(1, '$'))
normal ggVG2>>
call assert_equal([' one', '', "\t ", "\ttwo",
\ "\t three", "\t four"], getline(1, '$'))
normal gg6<<
call assert_equal([' one', '', "\t ", ' two', "\t three",
\ "\t four"], getline(1, '$'))
normal ggVG2<<
call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
\ getline(1, '$'))
set shiftwidth& tabstop&
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+5
View File
@@ -1799,6 +1799,11 @@ func Test_popup_title()
call term_sendkeys(buf, ":\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_longtitle_4', {})
call term_sendkeys(buf, ":call popup_clear()\<CR>")
call term_sendkeys(buf, ":call popup_menu(['This is a line', 'and another line'], #{title: '▶ÄÖÜ◀', })\<CR>")
call VerifyScreenDump(buf, 'Test_popupwin_multibytetitle', {})
call term_sendkeys(buf, "x")
" clean up
call StopVimInTerminal(buf)
call delete('XtestPopupTitle')
+9
View File
@@ -281,6 +281,7 @@ endfunc
func Test_set_register()
call assert_fails("call setreg('#', 200)", 'E86:')
call assert_fails("call setreg('a', test_unknown())", 'E908:')
edit Xfile_alt_1
let b1 = bufnr('')
@@ -470,6 +471,14 @@ func Test_get_reginfo()
let info = getreginfo('"')
call assert_equal('z', info.points_to)
let @a="a1b2"
nnoremap <F2> <Cmd>let g:RegInfo = getreginfo()<CR>
exe "normal \"a\<F2>"
call assert_equal({'regcontents': ['a1b2'], 'isunnamed': v:false,
\ 'regtype': 'v'}, g:RegInfo)
nunmap <F2>
unlet g:RegInfo
bwipe!
endfunc
+157
View File
@@ -583,6 +583,13 @@ func Test_mkspell()
call assert_fails('mkspell! Xtest.spl Xtest.dic', 'E17:')
call delete('Xtest.spl', 'rf')
" can't write the .spl file as its directory does not exist
call writefile([], 'Xtest.aff')
call writefile([], 'Xtest.dic')
call assert_fails('mkspell DOES_NOT_EXIT/Xtest.spl Xtest.dic', 'E484:')
call delete('Xtest.aff')
call delete('Xtest.dic')
call assert_fails('mkspell en en_US abc_xyz', 'E755:')
endfunc
@@ -842,6 +849,156 @@ func Test_spell_add_word()
%bw!
endfunc
func Test_spellfile_verbose()
call writefile(['1', 'one'], 'XtestVerbose.dic')
call writefile([], 'XtestVerbose.aff')
mkspell! XtestVerbose-utf8.spl XtestVerbose
set spell
" First time: the spl file should be read.
let a = execute('3verbose set spelllang=XtestVerbose-utf8.spl')
call assert_match('Reading spell file "XtestVerbose-utf8.spl"', a)
" Second time time: the spl file should not be read (already read).
let a = execute('3verbose set spelllang=XtestVerbose-utf8.spl')
call assert_notmatch('Reading spell file "XtestVerbose-utf8.spl"', a)
set spell& spelllang&
call delete('XtestVerbose.dic')
call delete('XtestVerbose.aff')
call delete('XtestVerbose-utf8.spl')
endfunc
" Test NOBREAK (see :help spell-NOBREAK)
func Test_NOBREAK()
call writefile(['3', 'one', 'two', 'three' ], 'XtestNOBREAK.dic')
call writefile(['NOBREAK' ], 'XtestNOBREAK.aff')
mkspell! XtestNOBREAK-utf8.spl XtestNOBREAK
set spell spelllang=XtestNOBREAK-utf8.spl
call assert_equal(['', ''], spellbadword('One two three onetwo onetwothree threetwoone'))
call assert_equal(['x', 'bad'], spellbadword('x'))
call assert_equal(['y', 'bad'], spellbadword('yone'))
call assert_equal(['z', 'bad'], spellbadword('onez'))
call assert_equal(['zero', 'bad'], spellbadword('Onetwozerothree'))
set spell& spelllang&
call delete('XtestNOBREAK.dic')
call delete('XtestNOBREAK.aff')
call delete('XtestNOBREAK-utf8.spl')
endfunc
" Test CHECKCOMPOUNDPATTERN (see :help spell-CHECKCOMPOUNDPATTERN)
func Test_spellfile_CHECKCOMPOUNDPATTERN()
call writefile(['4',
\ 'one/c',
\ 'two/c',
\ 'three/c',
\ 'four'], 'XtestCHECKCOMPOUNDPATTERN.dic')
" Forbid compound words where first word ends with 'wo' and second starts with 'on'.
call writefile(['CHECKCOMPOUNDPATTERN 1',
\ 'CHECKCOMPOUNDPATTERN wo on',
\ 'COMPOUNDFLAG c'], 'XtestCHECKCOMPOUNDPATTERN.aff')
mkspell! XtestCHECKCOMPOUNDPATTERN-utf8.spl XtestCHECKCOMPOUNDPATTERN
set spell spelllang=XtestCHECKCOMPOUNDPATTERN-utf8.spl
" Check valid words with and without valid compounds.
for goodword in ['one', 'two', 'three', 'four',
\ 'oneone', 'onetwo', 'onethree',
\ 'twotwo', 'twothree',
\ 'threeone', 'threetwo', 'threethree',
\ 'onetwothree', 'onethreetwo', 'twothreeone', 'oneoneone']
call assert_equal(['', ''], spellbadword(goodword), goodword)
endfor
" Compounds 'twoone' or 'threetwoone' should be forbidden by CHECKCOMPOUNPATTERN.
" 'four' does not have the 'c' flag in *.aff file so no compound.
" 'five' is not in the *.dic file.
for badword in ['five', 'onetwox',
\ 'twoone', 'threetwoone',
\ 'fourone', 'onefour']
call assert_equal([badword, 'bad'], spellbadword(badword))
endfor
set spell& spelllang&
call delete('XtestCHECKCOMPOUNDPATTERN.dic')
call delete('XtestCHECKCOMPOUNDPATTERN.aff')
call delete('XtestCHECKCOMPOUNDPATTERN-utf8.spl')
endfunc
" Test COMMON (better suggestions with common words, see :help spell-COMMON)
func Test_spellfile_COMMON()
call writefile(['7',
\ 'and',
\ 'ant',
\ 'end',
\ 'any',
\ 'tee',
\ 'the',
\ 'ted'], 'XtestCOMMON.dic')
call writefile(['COMMON the and'], 'XtestCOMMON.aff')
mkspell! XtestCOMMON-utf8.spl XtestCOMMON
set spell spelllang=XtestCOMMON-utf8.spl
" COMMON words 'and' and 'the' should be the top suggestions.
call assert_equal(['and', 'ant'], spellsuggest('anr', 2))
call assert_equal(['and', 'end'], spellsuggest('ond', 2))
call assert_equal(['the', 'ted'], spellsuggest('tha', 2))
call assert_equal(['the', 'tee'], spellsuggest('dhe', 2))
set spell& spelllang&
call delete('XtestCOMMON.dic')
call delete('XtestCOMMON.aff')
call delete('XtestCOMMON-utf8.spl')
endfunc
" Test CIRCUMFIX (see: :help spell-CIRCUMFIX)
func Test_spellfile_CIRCUMFIX()
" Example taken verbatim from https://github.com/hunspell/hunspell/tree/master/tests
call writefile(['1',
\ 'nagy/C po:adj'], 'XtestCIRCUMFIX.dic')
call writefile(['# circumfixes: ~ obligate prefix/suffix combinations',
\ '# superlative in Hungarian: leg- (prefix) AND -bb (suffix)',
\ '',
\ 'CIRCUMFIX X',
\ '',
\ 'PFX A Y 1',
\ 'PFX A 0 leg/X .',
\ '',
\ 'PFX B Y 1',
\ 'PFX B 0 legesleg/X .',
\ '',
\ 'SFX C Y 3',
\ 'SFX C 0 obb . is:COMPARATIVE',
\ 'SFX C 0 obb/AX . is:SUPERLATIVE',
\ 'SFX C 0 obb/BX . is:SUPERSUPERLATIVE'], 'XtestCIRCUMFIX.aff')
mkspell! XtestCIRCUMFIX-utf8.spl XtestCIRCUMFIX
set spell spelllang=XtestCIRCUMFIX-utf8.spl
" From https://catalog.ldc.upenn.edu/docs/LDC2008T01/acta04.pdf:
" Hungarian English
" --------- -------
" nagy great
" nagyobb greater
" legnagyobb greatest
" legeslegnagyob most greatest
call assert_equal(['', ''], spellbadword('nagy nagyobb legnagyobb legeslegnagyobb'))
for badword in ['legnagy', 'legeslegnagy', 'legobb', 'legeslegobb']
call assert_equal([badword, 'bad'], spellbadword(badword))
endfor
set spell& spelllang&
call delete('XtestCIRCUMFIX.dic')
call delete('XtestCIRCUMFIX.aff')
call delete('XtestCIRCUMFIX-utf8.spl')
endfunc
" When 'spellfile' is not set, adding a new good word will automatically set
" the 'spellfile'
func Test_init_spellfile()
+14
View File
@@ -276,6 +276,20 @@ func Test_V_arg()
call assert_match("sourcing \"$VIMRUNTIME[\\/]defaults\.vim\"\r\nline 1: \" The default vimrc file\..* verbose=15\n", out)
endfunc
" Test that an error is shown when the defaults.vim file could not be read
" TODO: disabled - this causes ASAN errors for unknown reasons
"func Test_defaults_error()
" " Can't catch the output of gvim.
" CheckNotGui
" CheckNotMSWindows
"
" let out = system('VIMRUNTIME=/tmp ' .. GetVimCommand() .. ' --clean -cq')
" call assert_match("E1187: Failed to source defaults.vim", out)
"
" let out = system('VIMRUNTIME=/tmp ' .. GetVimCommand() .. ' -u DEFAULTS -cq')
" call assert_match("E1187: Failed to source defaults.vim", out)
"endfunc
" Test the '-q [errorfile]' argument.
func Test_q_arg()
CheckFeature quickfix
+19
View File
@@ -1469,5 +1469,24 @@ func Test_prop_one_line_window()
bwipe!
endfunc
" This was calling ml_append_int() and copy a text property from a previous
" line at the wrong moment. Exact text length matters.
def Test_prop_splits_data_block()
new
var lines: list<string> = [repeat('x', 35)]->repeat(41)
+ [repeat('!', 35)]
+ [repeat('x', 35)]->repeat(56)
lines->setline(1)
prop_type_add('someprop', {highlight: 'ErrorMsg'})
prop_add(1, 27, {end_lnum: 1, end_col: 70, type: 'someprop'})
prop_remove({type: 'someprop'}, 1)
prop_add(35, 22, {end_lnum: 43, end_col: 43, type: 'someprop'})
prop_remove({type: 'someprop'}, 35, 43)
assert_equal([], prop_list(42))
bwipe!
prop_type_delete('someprop')
enddef
" vim: shiftwidth=2 sts=2 expandtab
+10
View File
@@ -160,6 +160,16 @@ func Test_default_arg()
\ .. "1 return deepcopy(a:)\n"
\ .. " endfunction",
\ execute('func Args2'))
" Error in default argument expression
let l =<< trim END
func F1(x = y)
return a:x * 2
endfunc
echo F1()
END
let @a = l->join("\n")
call assert_fails("exe @a", 'E121:')
endfunc
func s:addFoo(lead)
+7
View File
@@ -249,6 +249,13 @@ def Test_assignment()
END
enddef
def Test_reserved_name()
for name in ['true', 'false', 'null']
CheckDefExecAndScriptFailure(['var ' .. name .. ' = 0'], 'E1034:')
CheckDefExecAndScriptFailure(['var ' .. name .. ': bool'], 'E1034:')
endfor
enddef
def Test_skipped_assignment()
var lines =<< trim END
for x in []
+31
View File
@@ -363,6 +363,7 @@ def Test_extend_arg_types()
END
CheckDefAndScriptSuccess(lines)
CheckDefFailure(['extend("a", 1)'], 'E1013: Argument 1: type mismatch, expected list<any> but got string')
CheckDefFailure(['extend([1, 2], 3)'], 'E1013: Argument 2: type mismatch, expected list<number> but got number')
CheckDefFailure(['extend([1, 2], ["x"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
CheckDefFailure(['extend([1, 2], [3], "x")'], 'E1013: Argument 3: type mismatch, expected number but got string')
@@ -553,6 +554,29 @@ def Test_filter_missing_argument()
res->assert_equal({aa: [1], ac: [3]})
enddef
def Test_fullcommand()
assert_equal('next', fullcommand('n'))
assert_equal('noremap', fullcommand('no'))
assert_equal('noremap', fullcommand('nor'))
assert_equal('normal', fullcommand('norm'))
assert_equal('', fullcommand('k'))
assert_equal('keepmarks', fullcommand('ke'))
assert_equal('keepmarks', fullcommand('kee'))
assert_equal('keepmarks', fullcommand('keep'))
assert_equal('keepjumps', fullcommand('keepj'))
assert_equal('dlist', fullcommand('dl'))
assert_equal('', fullcommand('dp'))
assert_equal('delete', fullcommand('del'))
assert_equal('', fullcommand('dell'))
assert_equal('', fullcommand('delp'))
assert_equal('srewind', fullcommand('sre'))
assert_equal('scriptnames', fullcommand('scr'))
assert_equal('', fullcommand('scg'))
enddef
def Test_garbagecollect()
garbagecollect(true)
enddef
@@ -726,6 +750,12 @@ def Test_insert()
endfor
res->assert_equal(6)
var m: any = []
insert(m, 4)
call assert_equal([4], m)
extend(m, [6], 0)
call assert_equal([6, 4], m)
var lines =<< trim END
insert(test_null_list(), 123)
END
@@ -743,6 +773,7 @@ def Test_insert()
assert_equal(['a', 'b', 'c'], insert(['b', 'c'], 'a'))
assert_equal(0z1234, insert(0z34, 0x12))
CheckDefFailure(['insert("a", 1)'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 1)
CheckDefFailure(['insert([2, 3], "a")'], 'E1013: Argument 2: type mismatch, expected number but got string', 1)
CheckDefFailure(['insert([2, 3], 1, "x")'], 'E1013: Argument 3: type mismatch, expected number but got string', 1)
enddef
+61 -2
View File
@@ -172,11 +172,23 @@ func Test_expr1_trinary_fails()
call CheckDefAndScriptFailure(["var x = 1? 'one' : 'two'"], msg, 1)
call CheckDefAndScriptFailure(["var x = 1 ?'one' : 'two'"], msg, 1)
call CheckDefAndScriptFailure(["var x = 1?'one' : 'two'"], msg, 1)
let lines =<< trim END
var x = 1
?'one' : 'two'
# comment
END
call CheckDefAndScriptFailure(lines, 'E1004: White space required before and after ''?'' at "?''one'' : ''two''"', 2)
let msg = "White space required before and after ':'"
call CheckDefAndScriptFailure(["var x = 1 ? 'one': 'two'"], msg, 1)
call CheckDefAndScriptFailure(["var x = 1 ? 'one' :'two'"], msg, 1)
call CheckDefAndScriptFailure(["var x = 1 ? 'one':'two'"], msg, 1)
let lines =<< trim END
var x = 1 ? 'one'
:'two'
# Comment
END
call CheckDefAndScriptFailure(lines, 'E1004: White space required before and after '':'' at ":''two''"', 2)
call CheckDefAndScriptFailure(["var x = 'x' ? 'one' : 'two'"], 'E1135:', 1)
call CheckDefAndScriptFailure(["var x = 0z1234 ? 'one' : 'two'"], 'E974:', 1)
@@ -229,6 +241,12 @@ def Test_expr1_falsy()
call CheckDefAndScriptFailure(["var x = 1?? 'one' : 'two'"], msg, 1)
call CheckDefAndScriptFailure(["var x = 1 ??'one' : 'two'"], msg, 1)
call CheckDefAndScriptFailure(["var x = 1??'one' : 'two'"], msg, 1)
lines =<< trim END
var x = 1
??'one' : 'two'
#comment
END
CheckDefAndScriptFailure(lines, 'E1004: White space required before and after ''??'' at "??''one'' : ''two''"', 2)
enddef
def Record(val: any): any
@@ -376,6 +394,13 @@ def Test_expr2_fails()
call CheckDefAndScriptFailure2(["var x = [] || false"], 'E1012: Type mismatch; expected bool but got list<unknown>', 'E745:', 1)
var lines =<< trim END
vim9script
echo false
||true
# comment
END
CheckScriptFailure(lines, 'E1004: White space required before and after ''||'' at "||true"', 3)
enddef
" test &&
@@ -476,13 +501,19 @@ def Test_expr3_fails()
CheckDefAndScriptFailure(["var x = 1&&2"], msg, 1)
CheckDefAndScriptFailure(["var x = 1 &&2"], msg, 1)
CheckDefAndScriptFailure(["var x = 1&& 2"], msg, 1)
var lines =<< trim END
var x = 1
&&2
# comment
END
CheckDefAndScriptFailure(lines, 'E1004: White space required before and after ''&&'' at "&&2"', 2)
g:vals = []
CheckDefAndScriptFailure2(["if 'yes' && 0", 'echo 0', 'endif'], 'E1012: Type mismatch; expected bool but got string', 'E1135: Using a String as a Bool', 1)
CheckDefExecAndScriptFailure(['assert_equal(false, Record(1) && Record(4) && Record(0))'], 'E1023: Using a Number as a Bool: 4', 1)
var lines =<< trim END
lines =<< trim END
if 3
&& true
endif
@@ -976,6 +1007,12 @@ def Test_expr4_vim9script()
END
CheckDefAndScriptFailure(lines, 'E1004:', 1)
for op in ['==', '>', '>=', '<', '<=', '=~', '!~', 'is', 'isnot']
lines = ["echo 'aaa'", op .. "'bbb'", '# comment']
var msg = printf("E1004: White space required before and after '%s'", op)
CheckDefAndScriptFailure(lines, msg, 2)
endfor
lines =<< trim END
echo len('xxx') == 3
END
@@ -1220,7 +1257,14 @@ def Test_expr5_vim9script()
lines =<< trim END
echo 'a'.. 'b'
END
CheckDefAndScriptFailure(lines, 'E1004:', 1)
CheckDefAndScriptFailure(lines, 'E1004: White space required before and after ''..'' at ".. ''b''"', 1)
lines =<< trim END
echo 'a'
..'b'
# comment
END
CheckDefAndScriptFailure(lines, 'E1004: White space required before and after ''..'' at "..''b''"', 2)
# check invalid string concatenation
lines =<< trim END
@@ -1257,6 +1301,12 @@ def Test_expr5_vim9script()
bwipe!
END
CheckDefAndScriptFailure(lines, "E1004: White space required before and after '/' at \"/pattern", 3)
for op in ['+', '-']
lines = ['var x = 1', op .. '2', '# comment']
var msg = printf("E1004: White space required before and after '%s' at \"%s2\"", op, op)
CheckDefAndScriptFailure(lines, msg, 2)
endfor
enddef
def Test_expr5_vim9script_channel()
@@ -1538,6 +1588,12 @@ func Test_expr6_fails()
if has('float')
call CheckDefAndScriptFailure2(["var x = 0.7[1]"], 'E1107:', 'E806:', 1)
endif
for op in ['*', '/', '%']
let lines = ['var x = 1', op .. '2', '# comment']
let msg = printf("E1004: White space required before and after '%s' at \"%s2\"", op, op)
call CheckDefAndScriptFailure(lines, msg, 2)
endfor
endfunc
func Test_expr6_float_fails()
@@ -1580,6 +1636,8 @@ def Test_expr7t()
var ln: list<number> = [<number>g:anint, <number>g:thefour]
var nr = <number>234
assert_equal(234, nr)
var b: bool = <bool>1
assert_equal(true, b)
var text =
<string>
'text'
@@ -1591,6 +1649,7 @@ def Test_expr7t()
CheckDefAndScriptFailure(["var x = <nr>123"], 'E1010:', 1)
CheckDefFailure(["var x = <number>"], 'E1097:', 3)
CheckDefFailure(["var x = <number>string(1)"], 'E1012:', 1)
CheckScriptFailure(['vim9script', "var x = <number>"], 'E15:', 2)
CheckDefAndScriptFailure(["var x = <number >123"], 'E1068:', 1)
CheckDefAndScriptFailure(["var x = <number 123"], 'E1104:', 1)
+8
View File
@@ -397,6 +397,7 @@ def Test_call_default_args()
delfunc g:Func
CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
delfunc g:Func
CheckDefFailure(['def Func(x: number = )', 'enddef'], 'E15:')
lines =<< trim END
vim9script
@@ -1315,6 +1316,8 @@ def Test_arg_type_wrong()
CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
CheckScriptFailure(['def Func6(...x:list<number>)', 'echo "a"', 'enddef'], 'E1069:')
CheckScriptFailure(['def Func7(...x: int)', 'echo "a"', 'enddef'], 'E1010:')
enddef
def Test_white_space_before_comma()
@@ -2717,6 +2720,11 @@ def Test_ignored_argument()
var _ = 1
END
CheckDefAndScriptFailure(lines, 'E1181:', 1)
lines =<< trim END
var x = _
END
CheckDefAndScriptFailure(lines, 'E1181:', 1)
enddef
def Test_too_many_arguments()
+4 -2
View File
@@ -3844,12 +3844,14 @@ def Test_unsupported_commands()
var lines =<< trim END
ka
END
CheckDefAndScriptFailure(lines, 'E1100:')
CheckDefFailure(lines, 'E476:')
CheckScriptFailure(['vim9script'] + lines, 'E492:')
lines =<< trim END
:1ka
END
CheckDefAndScriptFailure(lines, 'E481:')
CheckDefFailure(lines, 'E476:')
CheckScriptFailure(['vim9script'] + lines, 'E492:')
lines =<< trim END
t
+27
View File
@@ -80,6 +80,10 @@ func Test_edit_change()
call setline(1, "\t⒌")
normal Cx
call assert_equal('x', getline(1))
" Do a visual block change
call setline(1, ['a', 'b', 'c'])
exe "normal gg3l\<C-V>2jcx"
call assert_equal(['a x', 'b x', 'c x'], getline(1, '$'))
bwipe!
set virtualedit=
endfunc
@@ -289,6 +293,16 @@ func Test_replace_after_eol()
call append(0, '"r"')
normal gg$5lrxa
call assert_equal('"r" x', getline(1))
" visual block replace
%d _
call setline(1, ['a', '', 'b'])
exe "normal 2l\<C-V>2jrx"
call assert_equal(['a x', ' x', 'b x'], getline(1, '$'))
" visual characterwise selection replace after eol
%d _
call setline(1, 'a')
normal 4lv2lrx
call assert_equal('a xxx', getline(1))
bwipe!
set virtualedit=
endfunc
@@ -375,4 +389,17 @@ func Test_ve_backspace()
close!
endfunc
" Test for delete (x) on EOL character and after EOL
func Test_delete_past_eol()
new
call setline(1, "ab")
set virtualedit=all
exe "normal 2lx"
call assert_equal('ab', getline(1))
exe "normal 10lx"
call assert_equal('ab', getline(1))
set virtualedit&
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+89 -12
View File
@@ -81,12 +81,11 @@ func Test_visual_mode_reset()
" thus preventing the problem:
exe "normal! GV:call TriggerTheProblem()\<CR>"
call assert_equal("Everything's fine.", g:msg)
endfunc
" Test for visual block shift and tab characters.
func Test_block_shift_tab()
enew!
new
call append(0, repeat(['one two three'], 5))
call cursor(1,1)
exe "normal i\<C-G>u"
@@ -95,7 +94,7 @@ func Test_block_shift_tab()
call assert_equal('on1 two three', getline(2))
call assert_equal('on1 two three', getline(5))
enew!
%d _
call append(0, repeat(['abcdefghijklmnopqrstuvwxyz'], 5))
call cursor(1,1)
exe "normal \<C-V>4jI \<Esc>j<<11|D"
@@ -120,12 +119,26 @@ func Test_block_shift_tab()
call assert_equal(" abc\<Tab>\<Tab>defghijklmnopqrstuvwxyz", getline(4))
call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(5))
enew!
" Test for block shift with space characters at the beginning and with
" 'noexpandtab' and 'expandtab'
%d _
call setline(1, [" 1", " 2", " 3"])
setlocal shiftwidth=2 noexpandtab
exe "normal gg\<C-V>3j>"
call assert_equal(["\t1", "\t2", "\t3"], getline(1, '$'))
%d _
call setline(1, [" 1", " 2", " 3"])
setlocal shiftwidth=2 expandtab
exe "normal gg\<C-V>3j>"
call assert_equal([" 1", " 2", " 3"], getline(1, '$'))
setlocal shiftwidth&
bw!
endfunc
" Tests Blockwise Visual when there are TABs before the text.
func Test_blockwise_visual()
enew!
new
call append(0, ['123456',
\ '234567',
\ '345678',
@@ -147,12 +160,12 @@ func Test_blockwise_visual()
\ "\t\tsomext",
\ "\t\ttesext"], getline(1, 7))
enew!
bw!
endfunc
" Test swapping corners in blockwise visual mode with o and O
func Test_blockwise_visual_o_O()
enew!
new
exe "norm! 10i.\<Esc>Y4P3lj\<C-V>4l2jr "
exe "norm! gvO\<Esc>ra"
@@ -171,7 +184,7 @@ func Test_blockwise_visual_o_O()
\ '...a bf.',
\ '..........'], getline(1, '$'))
enew!
bw!
endfun
" Test Virtual replace mode.
@@ -459,15 +472,13 @@ endfunc
" Test for 'p'ut in visual block mode
func Test_visual_block_put()
enew
new
call append(0, ['One', 'Two', 'Three'])
normal gg
yank
call feedkeys("jl\<C-V>ljp", 'xt')
call assert_equal(['One', 'T', 'Tee', 'One', ''], getline(1, '$'))
enew!
bw!
endfunc
" Visual modes (v V CTRL-V) followed by an operator; count; repeating
@@ -646,6 +657,12 @@ func Test_characterwise_visual_mode()
norm! G1vy
call assert_equal('four', @")
" characterwise visual mode: replace a single character line and the eol
%d _
call setline(1, "a")
normal v$rx
call assert_equal(['x'], getline(1, '$'))
bwipe!
endfunc
@@ -741,6 +758,66 @@ func Test_visual_block_mode()
exe "normal! \<C-V>j2lD"
call assert_equal(['ax', 'ax'], getline(3, 4))
" Test block insert with a short line that ends before the block
%d _
call setline(1, [" one", "a", " two"])
exe "normal gg\<C-V>2jIx"
call assert_equal([" xone", "a", " xtwo"], getline(1, '$'))
" Test block append at EOL with '$' and without '$'
%d _
call setline(1, ["one", "a", "two"])
exe "normal gg$\<C-V>2jAx"
call assert_equal(["onex", "ax", "twox"], getline(1, '$'))
%d _
call setline(1, ["one", "a", "two"])
exe "normal gg3l\<C-V>2jAx"
call assert_equal(["onex", "a x", "twox"], getline(1, '$'))
" Test block replace with an empty line in the middle and use $ to jump to
" the end of the line.
%d _
call setline(1, ['one', '', 'two'])
exe "normal gg$\<C-V>2jrx"
call assert_equal(["onx", "", "twx"], getline(1, '$'))
" Test block replace with an empty line in the middle and move cursor to the
" end of the line
%d _
call setline(1, ['one', '', 'two'])
exe "normal gg2l\<C-V>2jrx"
call assert_equal(["onx", "", "twx"], getline(1, '$'))
" Replace odd number of characters with a multibyte character
%d _
call setline(1, ['abcd', 'efgh'])
exe "normal ggl\<C-V>2ljr\u1100"
call assert_equal(["a\u1100 ", "e\u1100 "], getline(1, '$'))
" During visual block append, if the cursor moved outside of the selected
" range, then the edit should not be applied to the block.
%d _
call setline(1, ['aaa', 'bbb', 'ccc'])
exe "normal 2G\<C-V>jAx\<Up>"
call assert_equal(['aaa', 'bxbb', 'ccc'], getline(1, '$'))
" During visual block append, if the cursor is moved before the start of the
" block, then the new text should be appended there.
%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, '$'))
" Change a characterwise motion to a blockwise motion using CTRL-V
%d _
call setline(1, ['123', '456', '789'])
exe "normal ld\<C-V>j"
call assert_equal(['13', '46', '789'], getline(1, '$'))
bwipe!
endfunc
+21
View File
@@ -915,4 +915,25 @@ func Test_write_binary_file()
call delete('Xfile3')
endfunc
" Check that buffer is written before triggering QuitPre
func Test_wq_quitpre_autocommand()
edit Xsomefile
call setline(1, 'hello')
split
let g:seq = []
augroup Testing
au QuitPre * call add(g:seq, 'QuitPre - ' .. (&modified ? 'modified' : 'not modified'))
au BufWritePost * call add(g:seq, 'written')
augroup END
wq
call assert_equal(['written', 'QuitPre - not modified'], g:seq)
augroup Testing
au!
augroup END
bwipe!
unlet g:seq
call delete('Xsomefile')
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+15 -1
View File
@@ -252,7 +252,6 @@ f_reltimestr(typval_T *argvars UNUSED, typval_T *rettv)
void
f_strftime(typval_T *argvars, typval_T *rettv)
{
char_u result_buf[256];
struct tm tmval;
struct tm *curtime;
time_t seconds;
@@ -271,6 +270,20 @@ f_strftime(typval_T *argvars, typval_T *rettv)
rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
else
{
# ifdef MSWIN
WCHAR result_buf[256];
WCHAR *wp;
wp = enc_to_utf16(p, NULL);
if (wp != NULL)
(void)wcsftime(result_buf, sizeof(result_buf) / sizeof(WCHAR),
wp, curtime);
else
result_buf[0] = NUL;
rettv->vval.v_string = utf16_to_enc(result_buf, NULL);
vim_free(wp);
# else
char_u result_buf[256];
vimconv_T conv;
char_u *enc;
@@ -296,6 +309,7 @@ f_strftime(typval_T *argvars, typval_T *rettv)
// Release conversion descriptors
convert_setup(&conv, NULL, NULL);
vim_free(enc);
# endif
}
}
# endif
+44
View File
@@ -765,6 +765,50 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2907,
/**/
2906,
/**/
2905,
/**/
2904,
/**/
2903,
/**/
2902,
/**/
2901,
/**/
2900,
/**/
2899,
/**/
2898,
/**/
2897,
/**/
2896,
/**/
2895,
/**/
2894,
/**/
2893,
/**/
2892,
/**/
2891,
/**/
2890,
/**/
2889,
/**/
2888,
/**/
2887,
/**/
2886,
/**/
2885,
/**/
+3 -18
View File
@@ -5187,7 +5187,7 @@ compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1 + op_falsy]))
{
semsg(_(e_white_space_required_before_and_after_str_at_str),
op_falsy ? "??" : "?", *arg);
op_falsy ? "??" : "?", p);
return FAIL;
}
@@ -5594,14 +5594,6 @@ assignment_len(char_u *p, int *heredoc)
return 0;
}
// words that cannot be used as a variable
static char *reserved[] = {
"true",
"false",
"null",
NULL
};
/*
* Generate the load instruction for "name".
*/
@@ -5995,16 +5987,9 @@ compile_lhs(
}
else
{
int idx;
// No specific kind of variable recognized, just a name.
for (idx = 0; reserved[idx] != NULL; ++idx)
if (STRCMP(reserved[idx], lhs->lhs_name) == 0)
{
semsg(_(e_cannot_use_reserved_name), lhs->lhs_name);
return FAIL;
}
if (check_reserved_name(lhs->lhs_name) == FAIL)
return FAIL;
if (lookup_local(var_start, lhs->lhs_varlen,
&lhs->lhs_local_lvar, cctx) == OK)
+24 -2
View File
@@ -709,10 +709,10 @@ vim9_declare_scriptvar(exarg_T *eap, char_u *arg)
}
name = vim_strnsave(arg, p - arg);
// parse type
// parse type, check for reserved name
p = skipwhite(p + 1);
type = parse_type(&p, &si->sn_type_list, TRUE);
if (type == NULL)
if (type == NULL || check_reserved_name(name) == FAIL)
{
vim_free(name);
return p;
@@ -974,4 +974,26 @@ check_script_var_type(
return OK; // not really
}
// words that cannot be used as a variable
static char *reserved[] = {
"true",
"false",
"null",
NULL
};
int
check_reserved_name(char_u *name)
{
int idx;
for (idx = 0; reserved[idx] != NULL; ++idx)
if (STRCMP(reserved[idx], name) == 0)
{
semsg(_(e_cannot_use_reserved_name), name);
return FAIL;
}
return OK;
}
#endif // FEAT_EVAL