Compare commits

..

11 Commits

Author SHA1 Message Date
Bram Moolenaar
956501594e patch 8.2.1248: Netbeans test is flaky in the GUI
Problem:    Netbeans test is flaky in the GUI.
Solution:   Filter out geometry messages. (Taro Muraoka, closes #6487)
2020-07-19 18:24:32 +02:00
Bram Moolenaar
bf9d8c3765 patch 8.2.1247: Vim9: cannot index a character in a string
Problem:    Vim9: cannot index a character in a string.
Solution:   Add ISN_STRINDEX instruction. (closes #6478)
2020-07-19 17:55:44 +02:00
Bram Moolenaar
b209750b5e patch 8.2.1246: Vim9: comment after assignment doesn't work
Problem:    Vim9: comment after assignment doesn't work.
Solution:   Skip over white space. (closes #6481)
2020-07-19 17:17:02 +02:00
Bram Moolenaar
f398238a37 patch 8.2.1245: build failure in tiny version
Problem:    Build failure in tiny version.
Solution:   Add #ifdef.
2020-07-19 16:32:09 +02:00
Bram Moolenaar
6802cce407 patch 8.2.1244: Vim9: in lambda index assumes a list
Problem:    Vim9: in lambda index assumes a list.
Solution:   Use the value type to decide about list or dict. (closes #6479)
2020-07-19 15:49:49 +02:00
Bram Moolenaar
75783bd84e patch 8.2.1243: Vim9: cannot have a comment line halfway a list
Problem:    Vim9: cannot have a comment or empty line halfway a list at script
            level.
Solution:   Skip more than one line if needed.
2020-07-19 14:41:58 +02:00
Bram Moolenaar
65b9545f44 patch 8.2.1242: Vim9: no error if calling a function with wrong type
Problem:    Vim9: no error if calling a function with wrong argument type.
Solution:   Check types of arguments. (closes #6469)
2020-07-19 14:03:09 +02:00
Bram Moolenaar
6434fc574d patch 8.2.1241: cannot use getbufinfo() as a method
Problem:    Cannot use getbufinfo() as a method.
Solution:   Support using getbufinfo() as a method. (closes #6458)
2020-07-18 22:24:22 +02:00
Bram Moolenaar
10e1d01aaf patch 8.2.1240: GUI tests sometimes fail because of translations
Problem:    GUI tests sometimes fail because of translations.
Solution:   Reload the menus without translation. (Taro Muraoka, closes #6486)
2020-07-18 22:03:11 +02:00
Bram Moolenaar
de2396fc87 patch 8.2.1239: "maxwidth" in 'completepopup' not obeyed
Problem:    "maxwidth" in 'completepopup' not obeyed. (Jay Sitter)
Solution:   Add separate field for value from option. (closes #6470)
2020-07-18 21:40:41 +02:00
Bram Moolenaar
d032f34a51 patch 8.2.1238: Vim9: a few remaining errors not caught by try/catch
Problem:    Vim9: a few remaining errors not caught by try/catch.
Solution:   Do not bail out if an error is inside try/catch.
2020-07-18 18:13:02 +02:00
19 changed files with 482 additions and 202 deletions

View File

@@ -4929,8 +4929,11 @@ getbufinfo([{dict}])
<
To get buffer-local options use: >
getbufvar({bufnr}, '&option_name')
<
Can also be used as a |method|: >
GetBufnr()->getbufinfo()
<
*getbufline()*
getbufline({expr}, {lnum} [, {end}])
Return a |List| with the lines starting from {lnum} to {end}

View File

@@ -1913,7 +1913,7 @@ eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
&& evalarg != NULL
&& (evalarg->eval_cookie != NULL || evalarg->eval_cctx != NULL)
&& (*arg == NUL || (VIM_ISWHITE(arg[-1])
&& *arg == '#' && arg[1] != '{')))
&& vim9_comment_start(arg))))
{
char_u *p;

View File

@@ -611,7 +611,7 @@ static funcentry_T global_functions[] =
{"function", 1, 3, FEARG_1, ret_f_function, f_function},
{"garbagecollect", 0, 1, 0, ret_void, f_garbagecollect},
{"get", 2, 3, FEARG_1, ret_any, f_get},
{"getbufinfo", 0, 1, 0, ret_list_dict_any, f_getbufinfo},
{"getbufinfo", 0, 1, FEARG_1, ret_list_dict_any, f_getbufinfo},
{"getbufline", 2, 3, FEARG_1, ret_list_string, f_getbufline},
{"getbufvar", 2, 3, FEARG_1, ret_any, f_getbufvar},
{"getchangelist", 0, 1, FEARG_1, ret_list_any, f_getchangelist},

View File

@@ -642,6 +642,7 @@ pum_position_info_popup(win_T *wp)
int col = pum_col + pum_width + pum_scrollbar + 1;
int row = pum_row;
int botpos = POPPOS_BOTLEFT;
int used_maxwidth_opt = FALSE;
wp->w_popup_pos = POPPOS_TOPLEFT;
if (Columns - col < 20 && Columns - col < pum_col)
@@ -654,6 +655,12 @@ pum_position_info_popup(win_T *wp)
else
wp->w_maxwidth = Columns - col + 1;
wp->w_maxwidth -= popup_extra_width(wp);
if (wp->w_maxwidth_opt > 0 && wp->w_maxwidth > wp->w_maxwidth_opt)
{
// option value overrules computed value
wp->w_maxwidth = wp->w_maxwidth_opt;
used_maxwidth_opt = TRUE;
}
row -= popup_top_extra(wp);
if (wp->w_popup_flags & POPF_INFO_MENU)
@@ -673,7 +680,7 @@ pum_position_info_popup(win_T *wp)
row += pum_selected - pum_first + 1;
wp->w_popup_flags &= ~POPF_HIDDEN;
if (wp->w_maxwidth < 10)
if (wp->w_maxwidth < 10 && !used_maxwidth_opt)
// The popup is not going to fit or will overlap with the cursor
// position, hide the popup.
wp->w_popup_flags |= POPF_HIDDEN;

View File

@@ -1620,6 +1620,7 @@ parse_popup_option(win_T *wp, int is_preview)
if (is_preview)
wp->w_minwidth = x;
wp->w_maxwidth = x;
wp->w_maxwidth_opt = x;
}
}
else if (STRNCMP(s, "highlight:", 10) == 0)

View File

@@ -3,6 +3,7 @@ int check_defined(char_u *p, size_t len, cctx_T *cctx);
void clear_type_list(garray_T *gap);
type_T *typval2type(typval_T *tv);
int check_type(type_T *expected, type_T *actual, int give_msg);
int check_argtype(type_T *expected, typval_T *actual_tv);
int check_compare_types(exptype_T type, typval_T *tv1, typval_T *tv2);
char_u *skip_type(char_u *start);
type_T *parse_type(char_u **arg, garray_T *type_gap);
@@ -10,6 +11,7 @@ char *vartype_name(vartype_T type);
char *type_name(type_T *type, char **tofree);
int get_script_item_idx(int sid, char_u *name, int check_writable);
imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx);
int vim9_comment_start(char_u *p);
char_u *peek_next_line_from_context(cctx_T *cctx);
char_u *next_line_from_context(cctx_T *cctx, int skip_comment);
char_u *to_name_const_end(char_u *arg);

View File

@@ -1763,10 +1763,16 @@ getsourceline(int c UNUSED, void *cookie, int indent UNUSED, int do_concat)
// backslash. We always need to read the next line, keep it in
// sp->nextline.
/* Also check for a comment in between continuation lines: "\ */
// Also check for a Vim9 comment and empty line.
sp->nextline = get_one_sourceline(sp);
if (sp->nextline != NULL
&& (*(p = skipwhite(sp->nextline)) == '\\'
|| (p[0] == '"' && p[1] == '\\' && p[2] == ' ')))
|| (p[0] == '"' && p[1] == '\\' && p[2] == ' ')
#ifdef FEAT_EVAL
|| (in_vim9script()
&& (*p == NUL || vim9_comment_start(p)))
#endif
))
{
garray_T ga;
@@ -1794,8 +1800,14 @@ getsourceline(int c UNUSED, void *cookie, int indent UNUSED, int do_concat)
}
ga_concat(&ga, p + 1);
}
else if (p[0] != '"' || p[1] != '\\' || p[2] != ' ')
else if (!(p[0] == '"' && p[1] == '\\' && p[2] == ' ')
#ifdef FEAT_EVAL
&& !(in_vim9script()
&& (*p == NUL || vim9_comment_start(p)))
#endif
)
break;
/* drop a # comment or "\ comment line */
}
ga_append(&ga, NUL);
vim_free(line);

View File

@@ -3302,6 +3302,7 @@ struct window_S
int w_minwidth; // "minwidth" for popup window
int w_maxheight; // "maxheight" for popup window
int w_maxwidth; // "maxwidth" for popup window
int w_maxwidth_opt; // maxwidth from option
int w_wantline; // "line" for popup window
int w_wantcol; // "col" for popup window
int w_firstline; // "firstline" for popup window

View File

@@ -0,0 +1,14 @@
|a+0&#ffffff0|w|o|r|d| @69
|t|e|s|a|w|o|r|d> @66
|~+0#4040ff13&| | +0#0000001#e0e0e08|w|r|d| @4|W| |e|x|t|r|a| |t|e|x|t| @1| +0#0000000#0000001| +0#0000001#e0e0e08|w|o|r|d|s| |a|r|e| @1| +0#4040ff13#ffffff0@36
|~| | +0#0000001#ffd7ff255|a|n|o|t|w|r|d| |W| |e|x|t|r|a| |t|e|x|t| @1| +0#0000000#0000001| +0#0000001#e0e0e08|c|o@1|l| @6| +0#4040ff13#ffffff0@36
|~| | +0#0000001#ffd7ff255|n|o|a|w|r|d| @1|W| |e|x|t|r|a| |t|e|x|t| @1| +0#0000000#a8a8a8255| +0#4040ff13#ffffff0@48
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |4| +0#0000000&@26

View File

@@ -105,6 +105,13 @@ set nomore
" Output all messages in English.
lang mess C
" suppress menu translation
if has('gui_running') && exists('did_install_default_menus')
source $VIMRUNTIME/delmenu.vim
set langmenu=none
source $VIMRUNTIME/menu.vim
endif
" Always use forward slashes.
set shellslash

View File

@@ -23,6 +23,9 @@ func Test_getbufwintabinfo()
call assert_equal('vim', l[0].variables.editor)
call assert_notequal(-1, index(l[0].windows, '%'->bufwinid()))
let l = '%'->getbufinfo()
call assert_equal(bufnr('%'), l[0].bufnr)
" Test for getbufinfo() with 'bufmodified'
call assert_equal(0, len(getbufinfo({'bufmodified' : 1})))
call setbufline('Xtestfile1', 1, ["Line1"])

View File

@@ -31,6 +31,15 @@ func WaitForError(errcode)
call assert_match(a:errcode, save_exception)
endfunc
" Read the "Xnetbeans" file and filter out geometry messages.
func ReadXnetbeans()
let l = readfile("Xnetbeans")
" Xnetbeans may include '0:geometry=' messages on GUI environment if window
" position, size, or z order are changed. Remove these messages because
" will causes troubles on check.
return filter(l, 'v:val !~ "^0:geometry="')
endfunc
func Nb_basic(port)
call delete("Xnetbeans")
call writefile([], "Xnetbeans")
@@ -42,8 +51,8 @@ func Nb_basic(port)
" Establish the connection with the netbeans server
exe 'nbstart :localhost:' .. a:port .. ':bunny'
call assert_true(has("netbeans_enabled"))
call WaitFor('len(readfile("Xnetbeans")) > (g:last + 2)')
let l = readfile("Xnetbeans")
call WaitFor('len(ReadXnetbeans()) > (g:last + 2)')
let l = ReadXnetbeans()
call assert_equal(['AUTH bunny',
\ '0:version=0 "2.5"',
\ '0:startupDone=0'], l[-3:])
@@ -55,8 +64,8 @@ func Nb_basic(port)
" Open the command buffer to communicate with the server
split Xcmdbuf
let cmdbufnr = bufnr()
call WaitFor('len(readfile("Xnetbeans")) > (g:last + 2)')
let l = readfile("Xnetbeans")
call WaitFor('len(ReadXnetbeans()) > (g:last + 2)')
let l = ReadXnetbeans()
call assert_equal('0:fileOpened=0 "Xcmdbuf" T F',
\ substitute(l[-3], '".*/', '"', ''))
call assert_equal('send: 1:putBufferNumber!15 "Xcmdbuf"',
@@ -75,120 +84,120 @@ func Nb_basic(port)
call cursor(3, 4)
sleep 10m
call appendbufline(cmdbufnr, '$', 'getCursor_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 5)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 5)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:getCursor/30', '30 -1 3 3 19'], l[-2:])
let g:last += 5
" Test for E627
call appendbufline(cmdbufnr, '$', 'E627_Test')
call WaitForError('E627:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0 setReadOnly!31', l[-1])
let g:last += 3
" Test for E628
call appendbufline(cmdbufnr, '$', 'E628_Test')
call WaitForError('E628:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:setReadOnly 32', l[-1])
let g:last += 3
" Test for E632
call appendbufline(cmdbufnr, '$', 'E632_Test')
call WaitForError('E632:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:getLength/33', '33 0'], l[-2:])
let g:last += 4
" Test for E633
call appendbufline(cmdbufnr, '$', 'E633_Test')
call WaitForError('E633:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:getText/34', '34 '], l[-2:])
let g:last += 4
" Test for E634
call appendbufline(cmdbufnr, '$', 'E634_Test')
call WaitForError('E634:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:remove/35 1 1', '35'], l[-2:])
let g:last += 4
" Test for E635
call appendbufline(cmdbufnr, '$', 'E635_Test')
call WaitForError('E635:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:insert/36 0 "line1\n"', '36'], l[-2:])
let g:last += 4
" Test for E636
call appendbufline(cmdbufnr, '$', 'E636_Test')
call WaitForError('E636:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:create!37', l[-1])
let g:last += 3
" Test for E637
call appendbufline(cmdbufnr, '$', 'E637_Test')
call WaitForError('E637:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:startDocumentListen!38', l[-1])
let g:last += 3
" Test for E638
call appendbufline(cmdbufnr, '$', 'E638_Test')
call WaitForError('E638:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:stopDocumentListen!39', l[-1])
let g:last += 3
" Test for E639
call appendbufline(cmdbufnr, '$', 'E639_Test')
call WaitForError('E639:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:setTitle!40 "Title"', l[-1])
let g:last += 3
" Test for E640
call appendbufline(cmdbufnr, '$', 'E640_Test')
call WaitForError('E640:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:initDone!41', l[-1])
let g:last += 3
" Test for E641
call appendbufline(cmdbufnr, '$', 'E641_Test')
call WaitForError('E641:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:putBufferNumber!42 "XSomeBuf"', l[-1])
let g:last += 3
" Test for E642
call appendbufline(cmdbufnr, '$', 'E642_Test')
call WaitForError('E642:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 9:putBufferNumber!43 "XInvalidBuf"', l[-1])
let g:last += 3
" Test for E643
call appendbufline(cmdbufnr, '$', 'E643_Test')
call WaitForError('E643:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:setFullName!44 "XSomeBuf"', l[-1])
let g:last += 3
@@ -197,8 +206,8 @@ func Nb_basic(port)
" Test for E644
call appendbufline(cmdbufnr, '$', 'E644_Test')
call WaitForError('E644:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:editFile!45 "Xfile3"', l[-1])
let g:last += 3
@@ -207,8 +216,8 @@ func Nb_basic(port)
set verbose=1
call WaitForError('E645:')
set verbose&
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:setVisible!46 T', l[-1])
let g:last += 3
@@ -217,56 +226,56 @@ func Nb_basic(port)
set verbose=1
call WaitForError('E646:')
set verbose&
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:setModified!47 T', l[-1])
let g:last += 3
" Test for E647
call appendbufline(cmdbufnr, '$', 'E647_Test')
call WaitForError('E647:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:setDot!48 1/1', l[-1])
let g:last += 3
" Test for E648
call appendbufline(cmdbufnr, '$', 'E648_Test')
call WaitForError('E648:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:close!49', l[-1])
let g:last += 3
" Test for E650
call appendbufline(cmdbufnr, '$', 'E650_Test')
call WaitForError('E650:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:defineAnnoType!50 1 "abc" "a" "a" 1 1', l[-1])
let g:last += 3
" Test for E651
call appendbufline(cmdbufnr, '$', 'E651_Test')
call WaitForError('E651:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:addAnno!51 1 1 1 1', l[-1])
let g:last += 3
" Test for E652
call appendbufline(cmdbufnr, '$', 'E652_Test')
call WaitForError('E652:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:getAnno/52 8', '52 0'], l[-2:])
let g:last += 4
" editFile test
call writefile(['foo bar1', 'foo bar2', 'foo bar3'], 'Xfile3')
call appendbufline(cmdbufnr, '$', 'editFile_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal('send: 2:editFile!53 "Xfile3"', l[-2])
call assert_match('0:fileOpened=0 ".*/Xfile3" T F', l[-1])
call assert_equal('Xfile3', bufname())
@@ -274,37 +283,37 @@ func Nb_basic(port)
" getLength test
call appendbufline(cmdbufnr, '$', 'getLength_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 2:getLength/54', '54 27'], l[-2:])
let g:last += 4
" getModified test
call appendbufline(cmdbufnr, '$', 'getModified_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 2:getModified/55', '55 0'], l[-2:])
let g:last += 4
" getText test
call appendbufline(cmdbufnr, '$', 'getText_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 2:getText/56',
\ '56 "foo bar1\nfoo bar2\nfoo bar3\n"'], l[-2:])
let g:last += 4
" setDot test
call appendbufline(cmdbufnr, '$', 'setDot_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 2:setDot!57 3/6', l[-1])
let g:last += 3
" startDocumentListen test
call appendbufline(cmdbufnr, '$', 'startDocumentListen_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 2:startDocumentListen!58', l[-1])
let g:last += 3
@@ -312,8 +321,8 @@ func Nb_basic(port)
" received the notifications
call append(2, 'blue sky')
1d
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_match('2:insert=\d\+ 18 "blue sky"', l[-3])
call assert_match('2:insert=\d\+ 26 "\\n"', l[-2])
call assert_match('2:remove=\d\+ 0 9', l[-1])
@@ -321,8 +330,8 @@ func Nb_basic(port)
" stopDocumentListen test
call appendbufline(cmdbufnr, '$', 'stopDocumentListen_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 2:stopDocumentListen!59', l[-1])
let g:last += 3
@@ -335,8 +344,8 @@ func Nb_basic(port)
" defineAnnoType test
call appendbufline(cmdbufnr, '$', 'define_anno_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 2:defineAnnoType!60 1 "s1" "x" "=>" blue none', l[-1])
sleep 1m
call assert_equal({'name': '1', 'texthl': 'NB_s1', 'text': '=>'},
@@ -346,15 +355,15 @@ func Nb_basic(port)
" defineAnnoType with a long color name
call appendbufline(cmdbufnr, '$', 'E532_Test')
call WaitForError('E532:')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 2:defineAnnoType!61 1 "s1" "x" "=>" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa none', l[-1])
let g:last += 3
" addAnno test
call appendbufline(cmdbufnr, '$', 'add_anno_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 2:addAnno!62 1 1 2/1 0', l[-1])
sleep 1m
call assert_equal([{'lnum': 2, 'id': 1, 'name': '1', 'priority': 10,
@@ -363,15 +372,15 @@ func Nb_basic(port)
" getAnno test
call appendbufline(cmdbufnr, '$', 'get_anno_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 2:getAnno/63 1', '63 2'], l[-2:])
let g:last += 4
" removeAnno test
call appendbufline(cmdbufnr, '$', 'remove_anno_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 2:removeAnno!64 1', l[-1])
sleep 1m
call assert_equal([], sign_getplaced())
@@ -379,8 +388,8 @@ func Nb_basic(port)
" getModified test to get the number of modified buffers
call appendbufline(cmdbufnr, '$', 'getModifiedAll_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:getModified/65', '65 2'], l[-2:])
let g:last += 4
@@ -388,8 +397,8 @@ func Nb_basic(port)
" create test to create a new buffer
call appendbufline(cmdbufnr, '$', 'create_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:create!66', l[-1])
" Wait for vim to process the previous netbeans message
sleep 10m
@@ -398,15 +407,15 @@ func Nb_basic(port)
" setTitle test
call appendbufline(cmdbufnr, '$', 'setTitle_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:setTitle!67 "Xfile4"', l[-1])
let g:last += 3
" setFullName test
call appendbufline(cmdbufnr, '$', 'setFullName_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 5)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 5)')
let l = ReadXnetbeans()
call assert_equal('send: 3:setFullName!68 "Xfile4"', l[-3])
call assert_match('0:fileOpened=0 ".*/Xfile4" T F', l[-1])
call assert_equal('Xfile4', bufname())
@@ -414,65 +423,65 @@ func Nb_basic(port)
" initDone test
call appendbufline(cmdbufnr, '$', 'initDone_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:initDone!69', l[-1])
let g:last += 3
" setVisible test
hide enew
call appendbufline(cmdbufnr, '$', 'setVisible_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:setVisible!70 T', l[-1])
let g:last += 3
" setModtime test
call appendbufline(cmdbufnr, '$', 'setModtime_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:setModtime!71 6', l[-1])
let g:last += 3
" insert test
call appendbufline(cmdbufnr, '$', 'insert_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 3:insert/72 0 "line1\nline2\n"', '72'], l[-2:])
call assert_equal(['line1', 'line2'], getline(1, '$'))
let g:last += 4
" remove test
call appendbufline(cmdbufnr, '$', 'remove_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 3:remove/73 3 4', '73'], l[-2:])
call assert_equal(['linine2'], getline(1, '$'))
let g:last += 4
" remove with invalid offset
call appendbufline(cmdbufnr, '$', 'remove_invalid_offset_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 3:remove/74 900 4', '74 !bad position'], l[-2:])
let g:last += 4
" remove with invalid count
call appendbufline(cmdbufnr, '$', 'remove_invalid_count_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 3:remove/75 1 800', '75 !bad count'], l[-2:])
let g:last += 4
" guard test
%d
call setline(1, ['foo bar', 'foo bar', 'foo bar'])
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 8)')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 8)')
let g:last += 8
call appendbufline(cmdbufnr, '$', 'guard_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:guard!76 8 7', l[-1])
sleep 1m
" second line is guarded. Try modifying the line
@@ -488,8 +497,8 @@ func Nb_basic(port)
" setModified test
call appendbufline(cmdbufnr, '$', 'setModified_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:setModified!77 T', l[-1])
call assert_equal(1, &modified)
let g:last += 3
@@ -497,8 +506,8 @@ func Nb_basic(port)
" insertDone test
let v:statusmsg = ''
call appendbufline(cmdbufnr, '$', 'insertDone_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:insertDone!78 T F', l[-1])
sleep 1m
call assert_match('.*/Xfile4" 3L, 0B', v:statusmsg)
@@ -507,8 +516,8 @@ func Nb_basic(port)
" saveDone test
let v:statusmsg = ''
call appendbufline(cmdbufnr, '$', 'saveDone_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:saveDone!79', l[-1])
sleep 1m
call assert_match('.*/Xfile4" 3L, 0B', v:statusmsg)
@@ -516,51 +525,51 @@ func Nb_basic(port)
" unimplemented command test
call appendbufline(cmdbufnr, '$', 'invalidcmd_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:invalidcmd!80', l[-1])
let g:last += 3
" unimplemented function test
call appendbufline(cmdbufnr, '$', 'invalidfunc_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 3:invalidfunc/81', '81'], l[-2:])
let g:last += 4
" Test for removeAnno cmd failure
call appendbufline(cmdbufnr, '$', 'removeAnno_fail_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:removeAnno/82 1', '82'], l[-2:])
let g:last += 4
" Test for guard cmd failure
call appendbufline(cmdbufnr, '$', 'guard_fail_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:guard/83 1 1', '83'], l[-2:])
let g:last += 4
" Test for save cmd failure
call appendbufline(cmdbufnr, '$', 'save_fail_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:save/84', '84'], l[-2:])
let g:last += 4
" Test for netbeansBuffer cmd failure
call appendbufline(cmdbufnr, '$', 'netbeansBuffer_fail_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal(['send: 0:netbeansBuffer/85 T', '85'], l[-2:])
let g:last += 4
" nbkey test
call cursor(3, 3)
nbkey "\<C-F2>"
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal(['3:newDotAndMark=85 18 18',
\ '3:keyCommand=85 ""\<C-F2>""',
\ '3:keyAtPos=85 ""\<C-F2>"" 18 3/2'], l[-3:])
@@ -568,22 +577,22 @@ func Nb_basic(port)
" setExitDelay test
call appendbufline(cmdbufnr, '$', 'setExitDelay_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:setExitDelay!86 2', l[-1])
let g:last += 3
" setReadonly test
call appendbufline(cmdbufnr, '$', 'setReadOnly_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 3:setReadOnly!87', l[-1])
let g:last += 3
" close test. Don't use buffer 10 after this
call appendbufline(cmdbufnr, '$', 'close_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 4)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 4)')
let l = ReadXnetbeans()
call assert_equal('send: 3:close!88', l[-2])
call assert_equal('3:killed=88', l[-1])
call assert_equal(1, winnr('$'))
@@ -591,8 +600,8 @@ func Nb_basic(port)
" specialKeys test
call appendbufline(cmdbufnr, '$', 'specialKeys_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 3)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 3)')
let l = ReadXnetbeans()
call assert_equal('send: 0:specialKeys!89 "F12 F13"', l[-1])
sleep 1m
call assert_equal(':nbkey F12<CR>', maparg('<F12>', 'n'))
@@ -602,25 +611,25 @@ func Nb_basic(port)
" Open a buffer not monitored by netbeans
enew | only!
nbkey "\<C-F3>"
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 1)')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 1)')
let l = ReadXnetbeans()
call assert_equal('0:fileOpened=0 "" T F', l[-1])
let g:last += 1
" Test for writing a netbeans buffer
call appendbufline(cmdbufnr, '$', 'nbbufwrite_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 5)')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 5)')
call assert_fails('write', 'E656:')
call setline(1, ['one', 'two'])
call assert_fails('1write!', 'E657:')
write
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 10)')
call WaitFor('len(ReadXnetbeans()) >= (g:last + 10)')
let g:last += 10
" detach
call appendbufline(cmdbufnr, '$', 'detach_Test')
call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 8)')
call WaitForAssert({-> assert_equal('0:disconnect=93', readfile("Xnetbeans")[-1])})
call WaitFor('len(ReadXnetbeans()) >= (g:last + 8)')
call WaitForAssert({-> assert_equal('0:disconnect=93', ReadXnetbeans()[-1])})
" the connection was closed
call assert_false(has("netbeans_enabled"))
@@ -649,9 +658,9 @@ func Nb_file_auth(port)
exe 'nbstart =Xnbauth'
call assert_true(has("netbeans_enabled"))
call WaitFor('len(readfile("Xnetbeans")) > 2')
call WaitFor('len(ReadXnetbeans()) > 2')
nbclose
let lines = readfile("Xnetbeans")
let lines = ReadXnetbeans()
call assert_equal('AUTH bunny', lines[0])
call assert_equal('0:version=0 "2.5"', lines[1])
call assert_equal('0:startupDone=0', lines[2])
@@ -672,19 +681,24 @@ func Nb_quit_with_conn(port)
let after =<< trim END
source shared.vim
func ReadXnetbeans()
let l = readfile("Xnetbeans")
return filter(l, 'v:val !~ "^0:geometry="')
endfunc
" Establish the connection with the netbeans server
exe 'nbstart :localhost:' .. g:port .. ':star'
call assert_true(has("netbeans_enabled"))
call WaitFor('len(readfile("Xnetbeans")) >= 3')
let l = readfile("Xnetbeans")
call WaitFor('len(ReadXnetbeans()) >= 3')
let l = ReadXnetbeans()
call assert_equal(['AUTH star',
\ '0:version=0 "2.5"',
\ '0:startupDone=0'], l[-3:])
" Open the command buffer to communicate with the server
split Xcmdbuf
call WaitFor('len(readfile("Xnetbeans")) >= 6')
let l = readfile("Xnetbeans")
call WaitFor('len(ReadXnetbeans()) >= 6')
let l = ReadXnetbeans()
call assert_equal('0:fileOpened=0 "Xcmdbuf" T F',
\ substitute(l[-3], '".*/', '"', ''))
call assert_equal('send: 1:putBufferNumber!15 "Xcmdbuf"',
@@ -696,8 +710,8 @@ func Nb_quit_with_conn(port)
quit!
END
if RunVim(['let g:port = ' .. a:port], after, '')
call WaitFor('len(readfile("Xnetbeans")) >= 9')
let l = readfile('Xnetbeans')
call WaitFor('len(ReadXnetbeans()) >= 9')
let l = ReadXnetbeans()
call assert_equal('1:unmodified=16', l[-3])
call assert_equal('1:killed=16', l[-2])
call assert_equal('0:disconnect=16', l[-1])

View File

@@ -1115,7 +1115,7 @@ def Test_expr7_list()
call CheckDefExecFailure(["let x = g:anint[3]"], 'E714:')
call CheckDefFailure(["let x = g:list_mixed[xxx]"], 'E1001:')
call CheckDefFailure(["let x = [1,2,3]"], 'E1069:')
call CheckDefExecFailure(["let x = g:list_mixed['xx']"], 'E39:')
call CheckDefExecFailure(["let x = g:list_mixed['xx']"], 'E1029:')
call CheckDefFailure(["let x = g:list_mixed["], 'E1097:')
call CheckDefFailure(["let x = g:list_mixed[0"], 'E1097:')
call CheckDefExecFailure(["let x = g:list_empty[3]"], 'E684:')
@@ -1173,6 +1173,9 @@ def Test_expr7_lambda()
})
assert_equal([111, 222, 111], ll)
let dl = [{'key': 0}, {'key': 22}]->filter({ _, v -> v['key'] })
assert_equal([{'key': 22}], dl)
call CheckDefFailure(["filter([1, 2], {k,v -> 1})"], 'E1069:')
enddef
@@ -1506,6 +1509,15 @@ def Test_expr7_trailing()
assert_equal(123, d.key)
enddef
def Test_expr7_subscript()
let text = 'abcdef'
assert_equal('', text[-1])
assert_equal('a', text[0])
assert_equal('e', text[4])
assert_equal('f', text[5])
assert_equal('', text[6])
enddef
def Test_expr7_subscript_linebreak()
let range = range(
3)

View File

@@ -407,6 +407,17 @@ def Test_vim9script_call_fail_decl()
delete('Xcall_decl.vim')
enddef
def Test_vim9script_call_fail_type()
let lines =<< trim END
vim9script
def MyFunc(arg: string)
echo arg
enddef
MyFunc(1234)
END
CheckScriptFailure(lines, 'E1013: type mismatch, expected string but got number')
enddef
def Test_vim9script_call_fail_const()
let lines =<< trim END
vim9script

View File

@@ -29,7 +29,7 @@ def Test_assignment()
call CheckDefFailure(['let x:string = "x"'], 'E1069:')
call CheckDefFailure(['let a:string = "x"'], 'E1069:')
let a: number = 6
let a: number = 6 #comment
assert_equal(6, a)
if has('channel')
@@ -44,7 +44,7 @@ def Test_assignment()
let Funky2: func = function('len')
let Party2: func = funcref('g:Test_syntax')
g:newvar = 'new'
g:newvar = 'new' #comment
assert_equal('new', g:newvar)
assert_equal('yes', g:existing)
@@ -498,6 +498,10 @@ def Test_cmd_modifier()
call CheckDefFailure(['5tab echo 3'], 'E16:')
enddef
func g:NoSuchFunc()
echo 'none'
endfunc
def Test_try_catch()
let l = []
try # comment
@@ -656,6 +660,57 @@ def Test_try_catch()
n = 344
endtry
assert_equal(344, n)
try
echo len(v:true)
catch /E701:/
n = 355
endtry
assert_equal(355, n)
let P = function('g:NoSuchFunc')
delfunc g:NoSuchFunc
try
echo P()
catch /E117:/
n = 366
endtry
assert_equal(366, n)
try
echo g:NoSuchFunc()
catch /E117:/
n = 377
endtry
assert_equal(377, n)
try
echo g:alist + 4
catch /E745:/
n = 388
endtry
assert_equal(388, n)
try
echo 4 + g:alist
catch /E745:/
n = 399
endtry
assert_equal(399, n)
try
echo g:alist.member
catch /E715:/
n = 400
endtry
assert_equal(400, n)
try
echo d.member
catch /E716:/
n = 411
endtry
assert_equal(411, n)
enddef
def DeletedFunc(): list<any>
@@ -766,6 +821,22 @@ def Test_cexpr_vimscript()
set errorformat&
enddef
def Test_list_vimscript()
# checks line continuation and comments
let lines =<< trim END
vim9script
let mylist = [
'one',
# comment
'two', # empty line follows
'three',
]
assert_equal(['one', 'two', 'three'], mylist)
END
CheckScriptSuccess(lines)
enddef
if has('channel')
let someJob = test_null_job()
@@ -2029,7 +2100,7 @@ def Test_vim9_comment()
CheckScriptFailure([
'vim9script',
'syntax region Word start=/pat/ end=/pat/# comment',
], 'E475:')
], 'E402:')
CheckScriptSuccess([
'vim9script',

View File

@@ -754,6 +754,28 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1248,
/**/
1247,
/**/
1246,
/**/
1245,
/**/
1244,
/**/
1243,
/**/
1242,
/**/
1241,
/**/
1240,
/**/
1239,
/**/
1238,
/**/
1237,
/**/

View File

@@ -111,7 +111,8 @@ typedef enum {
// expression operations
ISN_CONCAT,
ISN_INDEX, // [expr] list index
ISN_STRINDEX, // [expr] string index
ISN_LISTINDEX, // [expr] list index
ISN_SLICE, // drop isn_arg.number items from start of list
ISN_GETITEM, // push list item, isn_arg.number is the index
ISN_MEMBER, // dict[member]

View File

@@ -560,6 +560,50 @@ check_type(type_T *expected, type_T *actual, int give_msg)
return ret;
}
/*
* Return FAIl if "expected" and "actual" don't match.
* TODO: better type comparison
*/
int
check_argtype(type_T *expected, typval_T *actual_tv)
{
type_T actual;
type_T member;
// TODO: should should be done with more levels
CLEAR_FIELD(actual);
actual.tt_type = actual_tv->v_type;
if (actual_tv->v_type == VAR_LIST
&& actual_tv->vval.v_list != NULL
&& actual_tv->vval.v_list->lv_first != NULL)
{
// Use the type of the first member, it is the most specific.
CLEAR_FIELD(member);
member.tt_type = actual_tv->vval.v_list->lv_first->li_tv.v_type;
member.tt_member = &t_any;
actual.tt_member = &member;
}
else if (actual_tv->v_type == VAR_DICT
&& actual_tv->vval.v_dict != NULL
&& actual_tv->vval.v_dict->dv_hashtab.ht_used > 0)
{
dict_iterator_T iter;
typval_T *value;
// Use the type of the first value, it is the most specific.
dict_iterate_start(actual_tv, &iter);
dict_iterate_next(&iter, &value);
CLEAR_FIELD(member);
member.tt_type = value->v_type;
member.tt_member = &t_any;
actual.tt_member = &member;
}
else
actual.tt_member = &t_any;
return check_type(expected, &actual, TRUE);
}
/////////////////////////////////////////////////////////////////////
// Following generate_ functions expect the caller to call ga_grow().
@@ -2419,7 +2463,7 @@ free_imported(cctx_T *cctx)
/*
* Return TRUE if "p" points at a "#" but not at "#{".
*/
static int
int
vim9_comment_start(char_u *p)
{
return p[0] == '#' && p[1] != '{';
@@ -3704,9 +3748,11 @@ compile_subscript(
{
garray_T *stack = &cctx->ctx_type_stack;
type_T **typep;
vartype_T vtype;
// list index: list[123]
// dict member: dict[key]
// string index: text[123]
// TODO: blob index
// TODO: more arguments
// TODO: recognize list or dict at runtime
@@ -3729,22 +3775,44 @@ compile_subscript(
}
*arg = *arg + 1;
// We can index a list and a dict. If we don't know the type
// we can use the index value type.
// TODO: If we don't know use an instruction to figure it out at
// runtime.
typep = ((type_T **)stack->ga_data) + stack->ga_len - 2;
if ((*typep)->tt_type == VAR_LIST || (*typep) == &t_any)
vtype = (*typep)->tt_type;
if (*typep == &t_any)
{
if ((*typep)->tt_type == VAR_LIST)
*typep = (*typep)->tt_member;
if (generate_instr_drop(cctx, ISN_INDEX, 1) == FAIL)
return FAIL;
type_T *valtype = ((type_T **)stack->ga_data)
[stack->ga_len - 1];
if (valtype == &t_string)
vtype = VAR_DICT;
}
else if ((*typep)->tt_type == VAR_DICT)
if (vtype == VAR_DICT)
{
*typep = (*typep)->tt_member;
if ((*typep)->tt_type == VAR_DICT)
*typep = (*typep)->tt_member;
else if (need_type(*typep, &t_dict_any, -2, cctx, FALSE)
== FAIL)
return FAIL;
if (may_generate_2STRING(-1, cctx) == FAIL)
return FAIL;
if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL)
return FAIL;
}
else if (vtype == VAR_STRING)
{
*typep = &t_number;
if (generate_instr_drop(cctx, ISN_STRINDEX, 1) == FAIL)
return FAIL;
}
else if (vtype == VAR_LIST || *typep == &t_any)
{
if ((*typep)->tt_type == VAR_LIST)
*typep = (*typep)->tt_member;
if (generate_instr_drop(cctx, ISN_LISTINDEX, 1) == FAIL)
return FAIL;
}
else
{
emsg(_(e_listdictblobreq));
@@ -5342,7 +5410,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
}
stacktype = stack->ga_len == 0 ? &t_void
: ((type_T **)stack->ga_data)[stack->ga_len - 1];
: ((type_T **)stack->ga_data)[stack->ga_len - 1];
if (lvar != NULL && (is_decl || !has_type))
{
if (new_local && !has_type)
@@ -5645,7 +5713,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
goto theend;
}
ret = end;
ret = skipwhite(end);
theend:
vim_free(name);
@@ -7481,7 +7549,8 @@ delete_instr(isn_T *isn)
case ISN_EXECCONCAT:
case ISN_EXECUTE:
case ISN_FOR:
case ISN_INDEX:
case ISN_LISTINDEX:
case ISN_STRINDEX:
case ISN_GETITEM:
case ISN_SLICE:
case ISN_MEMBER:

View File

@@ -737,6 +737,9 @@ call_def_function(
// Put arguments on the stack.
for (idx = 0; idx < argc; ++idx)
{
if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len
&& check_argtype(ufunc->uf_arg_types[idx], &argv[idx]) == FAIL)
goto failed_early;
copy_tv(&argv[idx], STACK_TV_BOT(0));
++ectx.ec_stack.ga_len;
}
@@ -1512,6 +1515,7 @@ call_def_function(
item->di_tv.v_lock = 0;
if (dict_add(dict, item) == FAIL)
{
// can this ever happen?
dict_unref(dict);
goto failed;
}
@@ -1544,7 +1548,7 @@ call_def_function(
if (call_bfunc(iptr->isn_arg.bfunc.cbf_idx,
iptr->isn_arg.bfunc.cbf_argcount,
&ectx) == FAIL)
goto failed;
goto on_error;
break;
// call a funcref or partial
@@ -1571,7 +1575,7 @@ call_def_function(
if (tv == &partial_tv)
clear_tv(&partial_tv);
if (r == FAIL)
goto failed;
goto on_error;
}
break;
@@ -1592,7 +1596,7 @@ call_def_function(
SOURCING_LNUM = iptr->isn_lnum;
if (call_eval_func(cufunc->cuf_name,
cufunc->cuf_argcount, &ectx, iptr) == FAIL)
goto failed;
goto on_error;
}
break;
@@ -1614,19 +1618,7 @@ call_def_function(
trycmd->tcd_return = TRUE;
}
else
{
// Restore previous function. If the frame pointer
// is zero then there is none and we are done.
if (ectx.ec_frame_idx == initial_frame_idx)
{
if (handle_closure_in_use(&ectx, FALSE) == FAIL)
goto failed;
goto done;
}
if (func_return(&ectx) == FAIL)
goto failed;
}
goto func_return;
}
break;
@@ -1735,8 +1727,6 @@ call_def_function(
{
listitem_T *li = list_find(list, idxtv->vval.v_number);
if (li == NULL)
goto failed;
copy_tv(&li->li_tv, STACK_TV_BOT(0));
++ectx.ec_stack.ga_len;
}
@@ -1814,19 +1804,7 @@ call_def_function(
}
if (trycmd->tcd_return)
{
// Restore previous function. If the frame pointer
// is zero then there is none and we are done.
if (ectx.ec_frame_idx == initial_frame_idx)
{
if (handle_closure_in_use(&ectx, FALSE) == FAIL)
goto failed;
goto done;
}
if (func_return(&ectx) == FAIL)
goto failed;
}
goto func_return;
}
}
break;
@@ -2068,7 +2046,7 @@ call_def_function(
{
n1 = tv_get_number_chk(tv1, &error);
if (error)
goto failed;
goto on_error;
#ifdef FEAT_FLOAT
if (tv2->v_type == VAR_FLOAT)
f1 = n1;
@@ -2085,7 +2063,7 @@ call_def_function(
{
n2 = tv_get_number_chk(tv2, &error);
if (error)
goto failed;
goto on_error;
#ifdef FEAT_FLOAT
if (tv1->v_type == VAR_FLOAT)
f2 = n2;
@@ -2144,7 +2122,44 @@ call_def_function(
}
break;
case ISN_INDEX:
case ISN_STRINDEX:
{
char_u *s;
varnumber_T n;
char_u *res;
// string index: string is at stack-2, index at stack-1
tv = STACK_TV_BOT(-2);
if (tv->v_type != VAR_STRING)
{
emsg(_(e_stringreq));
goto on_error;
}
s = tv->vval.v_string;
tv = STACK_TV_BOT(-1);
if (tv->v_type != VAR_NUMBER)
{
emsg(_(e_number_exp));
goto on_error;
}
n = tv->vval.v_number;
// The resulting variable is a string of a single
// character. If the index is too big or negative the
// result is empty.
if (n < 0 || n >= (varnumber_T)STRLEN(s))
res = NULL;
else
res = vim_strnsave(s + n, 1);
--ectx.ec_stack.ga_len;
tv = STACK_TV_BOT(-1);
vim_free(tv->vval.v_string);
tv->vval.v_string = res;
}
break;
case ISN_LISTINDEX:
{
list_T *list;
varnumber_T n;
@@ -2268,7 +2283,7 @@ call_def_function(
if (tv->v_type != VAR_DICT || tv->vval.v_dict == NULL)
{
emsg(_(e_dictreq));
goto failed;
goto on_error;
}
dict = tv->vval.v_dict;
@@ -2276,7 +2291,7 @@ call_def_function(
== NULL)
{
semsg(_(e_dictkey), iptr->isn_arg.string);
goto failed;
goto on_error;
}
// Clear the dict after getting the item, to avoid that it
// make the item invalid.
@@ -2409,6 +2424,20 @@ call_def_function(
}
continue;
func_return:
// Restore previous function. If the frame pointer is zero then there
// is none and we are done.
if (ectx.ec_frame_idx == initial_frame_idx)
{
if (handle_closure_in_use(&ectx, FALSE) == FAIL)
// only fails when out of memory
goto failed;
goto done;
}
if (func_return(&ectx) == FAIL)
// only fails when out of memory
goto failed;
on_error:
if (trylevel == 0)
goto failed;
@@ -2955,7 +2984,8 @@ ex_disassemble(exarg_T *eap)
// expression operations
case ISN_CONCAT: smsg("%4d CONCAT", current); break;
case ISN_INDEX: smsg("%4d INDEX", current); break;
case ISN_STRINDEX: smsg("%4d STRINDEX", current); break;
case ISN_LISTINDEX: smsg("%4d LISTINDEX", current); break;
case ISN_SLICE: smsg("%4d SLICE %lld",
current, iptr->isn_arg.number); break;
case ISN_GETITEM: smsg("%4d ITEM %lld",