Compare commits

...

7 Commits

Author SHA1 Message Date
Yegappan Lakshmanan
41a7f82dea patch 8.2.3010: not enough testing for viminfo code
Problem:    Not enough testing for viminfo code.
Solution:   Add a few more tests. (Yegappan Lakshmanan, closes #8390)
2021-06-16 15:53:17 +02:00
Bram Moolenaar
b90ac5e96e patch 8.2.3009: startup test may hang
Problem:    Startup test may hang.
Solution:   Do not run the test in the GUI.
2021-06-16 10:59:36 +02:00
Bram Moolenaar
55b6b60b69 patch 8.2.3008: startup test may hang
Problem:    Startup test may hang.
Solution:   Add quit command in the script.
2021-06-15 23:05:59 +02:00
Bram Moolenaar
61a417b7c1 patch 8.2.3007: Vim9: test for void value fails
Problem:    Vim9: test for void value fails.
Solution:   Adjust expected error.  Do not make a copy of void.
2021-06-15 22:54:28 +02:00
Bram Moolenaar
a97c36310f patch 8.2.3006: crash when echoing a value very early
Problem:    Crash when echoing a value very early. (Naruhiko Nishino)
Solution:   Do not use a NUL to truncate the message, make a copy.
            (closes #8388)
2021-06-15 22:39:11 +02:00
Bram Moolenaar
f57b43c230 patch 8.2.3005: Vim9: using a void value does not give a proper error message
Problem:    Vim9: using a void value does not give a proper error message.
Solution:   Give a clear error message. (clodes #8387)
2021-06-15 22:13:27 +02:00
Bram Moolenaar
8ac681a280 patch 8.2.3004: Vim9: error for missing colon given while skipping
Problem:    Vim9: error for missing colon given while skipping.
Solution:   Do not give the error when skipping. (closes #8385)
2021-06-15 20:06:34 +02:00
16 changed files with 487 additions and 63 deletions

View File

@@ -1844,7 +1844,7 @@ do_one_cmd(
// If a ':' before the range is missing, give a clearer error
// message.
if (ar > ea.cmd)
if (ar > ea.cmd && !ea.skip)
{
semsg(_(e_colon_required_before_range_str), ea.cmd);
goto doend;

View File

@@ -2751,19 +2751,21 @@ msg_puts_printf(char_u *str, int maxlen)
if (*p != NUL && !(silent_mode && p_verbose == 0))
{
int c = -1;
char_u *tofree = NULL;
if (maxlen > 0 && STRLEN(p) > (size_t)maxlen)
{
c = p[maxlen];
p[maxlen] = 0;
tofree = vim_strnsave(p, (size_t)maxlen);
p = tofree;
}
if (p != NULL)
{
if (info_message)
mch_msg((char *)p);
else
mch_errmsg((char *)p);
vim_free(tofree);
}
if (info_message)
mch_msg((char *)p);
else
mch_errmsg((char *)p);
if (c != -1)
p[maxlen] = c;
}
msg_didout = TRUE; // assume that line is not empty

View File

@@ -462,6 +462,9 @@ stuff_yank(int regname, char_u *p)
return OK;
}
/*
* Last executed register (@ command)
*/
static int execreg_lastc = NUL;
int

View File

@@ -1,5 +1,7 @@
" Test for 'fileformat'
source shared.vim
" Test behavior of fileformat after bwipeout of last buffer
func Test_fileformat_after_bw()
bwipeout
@@ -308,4 +310,18 @@ func Test_fileformat_plusplus_read()
call assert_fails('e ++abc1 Xfile1', 'E474:')
endfunc
" When Vim starts up with an empty buffer the first item in 'fileformats' is
" used as the 'fileformat'.
func Test_fileformat_on_startup()
let after =<< trim END
call writefile([&fileformat], 'Xfile', 'a')
quit
END
call RunVim(["set ffs=dos,unix,mac"], after, '')
call RunVim(["set ffs=mac,dos,unix"], after, '')
call RunVim(["set ffs=unix,mac,dos"], after, '')
call assert_equal(['dos', 'mac', 'unix'], readfile('Xfile'))
call delete('Xfile')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -86,13 +86,13 @@ func Test_empty()
endfunc
func Test_test_void()
call assert_fails('echo 1 == test_void()', 'E685:')
call assert_fails('echo 1 == test_void()', 'E1031:')
if has('float')
call assert_fails('echo 1.0 == test_void()', 'E685:')
call assert_fails('echo 1.0 == test_void()', 'E1031:')
endif
call assert_fails('let x = json_encode(test_void())', 'E685:')
call assert_fails('let x = copy(test_void())', 'E685:')
call assert_fails('let x = copy([test_void()])', 'E685:')
call assert_fails('let x = copy([test_void()])', 'E1031:')
endfunc
func Test_len()

View File

@@ -111,4 +111,27 @@ func Test_si_comment_line_continuation()
close!
endfunc
" When 'paste' is set, 'smartindent' should not take effect.
func Test_si_with_paste()
new
setlocal smartindent autoindent
set paste
" insert text that will trigger smartindent
exe "norm! i {\nif (x)\ni = 1;\n#define FOO 1\nj = 2;\n}"
exe "norm! Ok = 3;"
exe "norm! 4G>>"
call assert_equal([' {', 'if (x)', 'i = 1;', '#define FOO 1',
\ 'j = 2;', 'k = 3;', '}'], getline(1, '$'))
call assert_true(&smartindent)
set nopaste
%d _
exe "norm! i {\nif (x)\ni = 1;\n#define FOO 1\nj = 2;\n}"
exe "norm! Ok = 3;"
exe "norm! 4G>>"
call assert_equal([' {', "\t if (x)", "\t\t i = 1;",
\ '#define FOO 1', "\t\t j = 2;", "\t k = 3;", ' }'],
\ getline(1, '$'))
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -1301,4 +1301,20 @@ func Test_write_in_vimrc()
call delete('Xvimrc')
endfunc
func Test_echo_true_in_cmd()
CheckNotGui
let lines =<< trim END
echo v:true
call writefile(['done'], 'Xresult')
quit
END
call writefile(lines, 'Xscript')
if RunVim([], [], '--cmd "source Xscript"')
call assert_equal(['done'], readfile('Xresult'))
endif
call delete('Xscript')
call delete('Xresult')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -117,7 +117,7 @@ def Test_disassemble_exec_expr()
'\d 2STRING stack\[-1\]\_s*' ..
'\d\+ PUSHS ".txt"\_s*' ..
'\d\+ EXECCONCAT 4\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -133,7 +133,7 @@ EOF
assert_match('<SNR>\d*_PyHeredoc.*' ..
" python3 << EOF^@ print('hello')^@EOF\\_s*" ..
'\d EXEC_SPLIT python3 << EOF^@ print(''hello'')^@EOF\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
endif
@@ -153,7 +153,7 @@ def Test_disassemble_substitute()
'\d SUBSTITUTE :%s/a/\\=expr/&g#c\_s*' ..
' 0 LOAD $0\_s*' ..
' -------------\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
@@ -181,7 +181,7 @@ def Test_disassemble_seachpair()
' -------------\_s*' ..
'\d BCALL searchpair(argc 5)\_s*' ..
'\d DROP\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
@@ -209,7 +209,7 @@ def Test_disassemble_redir_var()
'\d REDIR END\_s*' ..
'\d CONCAT\_s*' ..
'\d STORE $0\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
@@ -228,7 +228,7 @@ def Test_disassemble_cexpr()
'\d CEXPR pre cexpr\_s*' ..
'\d LOAD $0\_s*' ..
'\d CEXPR core cexpr "cexpr errors"\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
@@ -244,7 +244,7 @@ def Test_disassemble_yank_range()
'\d EXEC norm! m\[jjm\]\_s*' ..
' :''\[,''\]yank\_s*' ..
'\d EXEC :''\[,''\]yank\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
@@ -258,7 +258,7 @@ def Test_disassemble_put_expr()
' :3put ="text"\_s*' ..
'\d PUSHS "text"\_s*' ..
'\d PUT = 3\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
@@ -272,7 +272,7 @@ def Test_disassemble_put_range()
' :$-2put a\_s*' ..
'\d RANGE $-2\_s*' ..
'\d PUT a range\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
@@ -390,7 +390,7 @@ def Test_disassemble_store_member()
'\d\+ PUSHNR 1\_s*' ..
'\d\+ LOAD $2\_s*' ..
'\d\+ STOREINDEX blob\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -413,7 +413,7 @@ def Test_disassemble_store_index()
'\d LOAD $0\_s*' ..
'\d MEMBER dd\_s*' ..
'\d STOREINDEX any\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -448,7 +448,7 @@ def Test_disassemble_list_assign()
'\d\+ STORE $1\_s*' ..
'\d\+ SLICE 2\_s*' ..
'\d\+ STORE $2\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -476,7 +476,7 @@ def Test_disassemble_list_add()
'\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
'\d\+ LISTAPPEND\_s*' ..
'\d\+ DROP\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -503,7 +503,7 @@ def Test_disassemble_blob_add()
'\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
'\d\+ BLOBAPPEND\_s*' ..
'\d\+ DROP\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -530,7 +530,7 @@ def Test_disassemble_blob_index_slice()
'\d\+ PUSHNR 2\_s*' ..
'\d\+ BLOBSLICE\_s*' ..
'\d\+ ECHO 1\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -720,7 +720,7 @@ def Test_disassemble_closure()
'\d LOAD arg\[-1\]\_s*' ..
'\d CONCAT\_s*' ..
'\d STOREOUTER level 1 $0\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
res = execute('disass g:Get')
@@ -754,7 +754,7 @@ def Test_disassemble_pcall()
'\d PCALL top (argc 1)\_s*' ..
'\d PCALL end\_s*' ..
'\d DROP\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
@@ -1012,7 +1012,7 @@ def Test_disassemble_function()
'\d PUSHS "UserFunc"\_s*' ..
'\d BCALL funcref(argc 1)\_s*' ..
'\d STORE $2\_s*' ..
'\d RETURN 0',
'\d RETURN void',
instr)
enddef
@@ -1039,7 +1039,7 @@ def Test_disassemble_channel()
'var chan1: channel\_s*' ..
'\d PUSHCHANNEL 0\_s*' ..
'\d STORE $2\_s*' ..
'\d RETURN 0',
'\d RETURN void',
instr)
enddef
@@ -1111,7 +1111,7 @@ def Test_disassemble_nested_func()
'echomsg "inner"\_s*' ..
'enddef\_s*' ..
'\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
'\d RETURN 0',
'\d RETURN void',
instr)
enddef
@@ -1133,7 +1133,7 @@ def Test_disassemble_nested_def_list()
'\d DEF /Info\_s*' ..
'def /Info/\_s*' ..
'\d DEF /Info/\_s*' ..
'\d RETURN 0',
'\d RETURN void',
instr)
enddef
@@ -1264,7 +1264,7 @@ def Test_disassemble_for_loop_unpack()
'endfor\_s*' ..
'\d\+ JUMP -> 8\_s*' ..
'\d\+ DROP\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
instr)
enddef
@@ -1321,7 +1321,7 @@ def Test_disassemble_for_loop_continue()
'endfor\_s*' ..
'21 JUMP -> 4\_s*' ..
'\d\+ DROP\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
instr)
enddef
@@ -1341,7 +1341,7 @@ def Test_disassemble_typecast()
'\d NEWLIST size 2\_s*' ..
'\d SETTYPE list<number>\_s*' ..
'\d STORE $0\_s*' ..
'\d RETURN 0\_s*',
'\d RETURN void\_s*',
instr)
enddef
@@ -1828,7 +1828,7 @@ def Test_dsassemble_falsy_op()
'echo "" ?? "empty string"\_s*' ..
'\d\+ PUSHS "empty string"\_s*' ..
'\d\+ ECHO 1\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -1855,7 +1855,7 @@ def Test_disassemble_compare_const()
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
'\d PUSHNR 42.*' ..
'\d ECHO 1.*' ..
'\d RETURN 0',
'\d RETURN void',
instr)
else
# condition false, function just returns
@@ -1863,7 +1863,7 @@ def Test_disassemble_compare_const()
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
'echo 42[ \n]*' ..
'endif[ \n]*' ..
'\d RETURN 0',
'\d RETURN void',
instr)
endif
@@ -1901,7 +1901,7 @@ def Test_disassemble_execute()
'\d\+ LOAD $1\_s*' ..
'\d\+ CONCAT\_s*' ..
'\d\+ EXECUTE 1\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -1920,7 +1920,7 @@ def Test_disassemble_echomsg()
"echoerr 'went' .. 'wrong'\\_s*" ..
'\d PUSHS "wentwrong"\_s*' ..
'\d ECHOERR 1\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
@@ -2029,7 +2029,7 @@ def Test_shuffle()
'\d SHUFFLE 2 up 1\_s*' ..
'\d BCALL append(argc 2)\_s*' ..
'\d DROP\_s*' ..
'\d RETURN 0',
'\d RETURN void',
res)
enddef
@@ -2052,7 +2052,7 @@ def Test_silent()
'\d PUSHS "error"\_s*' ..
'\d ECHOERR 1\_s*' ..
'\d CMDMOD_REV\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -2081,7 +2081,7 @@ def Test_silent_if()
'\d\+ CMDMOD_REV\_s*' ..
'\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
'endif\_s*' ..
'\d\+ RETURN 0',
'\d\+ RETURN void',
res)
enddef
@@ -2104,7 +2104,7 @@ def Test_silent_for()
'endfor\_s*' ..
'\d JUMP -> 5\_s*' ..
'8 DROP\_s*' ..
'\d RETURN 0\_s*',
'\d RETURN void\_s*',
res)
enddef
@@ -2125,7 +2125,7 @@ def Test_silent_while()
'endwhile\_s*' ..
'\d JUMP -> 0\_s*' ..
'6 RETURN 0\_s*',
'6 RETURN void\_s*',
res)
enddef

View File

@@ -2967,6 +2967,20 @@ def Test_expr7_method_call()
assert_equal([1, 2, 3], sorted)
END
CheckDefAndScriptSuccess(lines)
lines =<< trim END
def RetVoid()
enddef
RetVoid()->byte2line()
END
CheckDefExecAndScriptFailure(lines, 'E1031:')
lines =<< trim END
def RetVoid()
enddef
RetVoid()->byteidx(3)
END
CheckDefExecAndScriptFailure(lines, 'E1031:')
enddef

View File

@@ -590,6 +590,19 @@ def Test_try_catch_throw()
return 2
enddef
assert_equal(4, ReturnInFinally())
var lines =<< trim END
vim9script
try
acos('0.5')
->setline(1)
catch
g:caught = v:exception
endtry
END
CheckScriptSuccess(lines)
assert_match('E808: Number or Float required', g:caught)
unlet g:caught
enddef
" :while at the very start of a function that :continue jumps to

View File

@@ -4,7 +4,7 @@ source check.vim
source term_util.vim
source shared.vim
function Test_viminfo_read_and_write()
func Test_viminfo_read_and_write()
" First clear 'history', so that "hislen" is zero. Then set it again,
" simulating Vim starting up.
set history=0
@@ -12,6 +12,7 @@ function Test_viminfo_read_and_write()
set history=1000
call histdel(':')
let @/=''
let lines = [
\ '# comment line',
\ '*encoding=utf-8',
@@ -89,6 +90,36 @@ func Test_global_vars()
call assert_equal(test_null, g:MY_GLOBAL_NULL)
call assert_equal(test_none, g:MY_GLOBAL_NONE)
" When reading global variables from viminfo, if a variable cannot be
" modified, then the value should not be changed.
unlet g:MY_GLOBAL_STRING
unlet g:MY_GLOBAL_NUM
unlet g:MY_GLOBAL_FLOAT
unlet g:MY_GLOBAL_DICT
unlet g:MY_GLOBAL_LIST
unlet g:MY_GLOBAL_BLOB
const g:MY_GLOBAL_STRING = 'New Value'
const g:MY_GLOBAL_NUM = 987
const g:MY_GLOBAL_FLOAT = 1.16
const g:MY_GLOBAL_DICT = {'editor': 'vim'}
const g:MY_GLOBAL_LIST = [5, 7, 13]
const g:MY_GLOBAL_BLOB = 0zDEADBEEF
call assert_fails('rv! Xviminfo', 'E741:')
call assert_equal('New Value', g:MY_GLOBAL_STRING)
call assert_equal(987, g:MY_GLOBAL_NUM)
call assert_equal(1.16, g:MY_GLOBAL_FLOAT)
call assert_equal({'editor': 'vim'}, g:MY_GLOBAL_DICT)
call assert_equal([5, 7 , 13], g:MY_GLOBAL_LIST)
call assert_equal(0zDEADBEEF, g:MY_GLOBAL_BLOB)
unlet g:MY_GLOBAL_STRING
unlet g:MY_GLOBAL_NUM
unlet g:MY_GLOBAL_FLOAT
unlet g:MY_GLOBAL_DICT
unlet g:MY_GLOBAL_LIST
unlet g:MY_GLOBAL_BLOB
" Test for invalid values for a blob, list, dict in a viminfo file
call writefile([
\ "!GLOB_BLOB_1\tBLO\t123",
@@ -510,6 +541,20 @@ func Test_viminfo_bad_syntax()
call delete('Xviminfo')
endfunc
func Test_viminfo_bad_register_syntax()
let lines = []
call add(lines, '|1,4')
call add(lines, '|3') " invalid number of fields for a register type
call add(lines, '|3,1,1,1,1,,1,"x"') " invalid value for the width field
call add(lines, '|3,0,80,1,1,1,1,"x"') " invalid register number
call add(lines, '|3,0,10,5,1,1,1,"x"') " invalid register type
call add(lines, '|3,0,10,1,20,1,1,"x"') " invalid line count
call add(lines, '|3,0,10,1,0,1,1') " zero line count
call writefile(lines, 'Xviminfo')
rviminfo Xviminfo
call delete('Xviminfo')
endfunc
func Test_viminfo_file_marks()
silent! bwipe test_viminfo.vim
silent! bwipe Xviminfo
@@ -664,6 +709,7 @@ func Test_viminfo_bufferlist()
" If there are arguments, then :rviminfo doesn't read the buffer list.
" Need to delete all the arguments for :rviminfo to work.
%argdelete
set viminfo&vim
edit Xfile1
edit Xfile2
@@ -684,9 +730,42 @@ func Test_viminfo_bufferlist()
call assert_equal('Xfile1', bufname(l[1].bufnr))
call assert_equal('Xfile2', bufname(l[2].bufnr))
" The quickfix, terminal, unlisted, unnamed buffers are not stored in the
" viminfo file
%bw!
edit Xfile1
new
setlocal nobuflisted
new
copen
if has('terminal')
terminal
endif
wviminfo! Xviminfo
%bwipe!
rviminfo Xviminfo
let l = getbufinfo()
call assert_equal(2, len(l))
call assert_true(bufexists('Xfile1'))
" If a count is specified for '%', then only that many buffers should be
" stored in the viminfo file.
%bw!
set viminfo&vim
new Xbuf1
new Xbuf2
set viminfo+=%1
wviminfo! Xviminfo
%bwipe!
rviminfo! Xviminfo
let l = getbufinfo()
call assert_equal(2, len(l))
call assert_true(bufexists('Xbuf1'))
call assert_false(bufexists('Xbuf2'))
call delete('Xviminfo')
%bwipe
set viminfo-=%
set viminfo&vim
endfunc
" Test for errors in a viminfo file
@@ -747,6 +826,12 @@ func Test_viminfo_registers_old()
\ ' Vim',
\ '"a CHAR 0',
\ ' red',
\ '"c BLOCK 0',
\ ' a',
\ ' d',
\ '"d LINE 0',
\ ' abc',
\ ' def',
\ '"m@ CHAR 0',
\ " :echo 'Hello'\<CR>",
\ "",
@@ -760,7 +845,12 @@ func Test_viminfo_registers_old()
silent! normal @t
rviminfo! Xviminfo
call assert_equal('red', getreg('a'))
call assert_equal("v", getregtype('a'))
call assert_equal('two', getreg('b'))
call assert_equal("a\nd", getreg('c'))
call assert_equal("\<C-V>1", getregtype('c'))
call assert_equal("abc\ndef\n", getreg('d'))
call assert_equal("V", getregtype('d'))
call assert_equal(":echo 'Hello'\<CR>", getreg('m'))
call assert_equal('Vim', getreg('"'))
call assert_equal("\nHello", execute('normal @@'))
@@ -914,4 +1004,228 @@ func Test_viminfo_oldfiles_newfile()
let &viminfofile = save_viminfofile
endfunc
" When writing CTRL-V or "\n" to a viminfo file, it is converted to CTRL-V
" CTRL-V and CTRL-V n respectively.
func Test_viminfo_with_Ctrl_V()
silent! exe "normal! /\<C-V>\<C-V>\n"
wviminfo Xviminfo
call assert_notequal(-1, readfile('Xviminfo')->index("?/\<C-V>\<C-V>"))
let @/ = 'abc'
rviminfo! Xviminfo
call assert_equal("\<C-V>", @/)
silent! exe "normal! /\<C-V>\<C-J>\n"
wviminfo Xviminfo
call assert_notequal(-1, readfile('Xviminfo')->index("?/\<C-V>n"))
let @/ = 'abc'
rviminfo! Xviminfo
call assert_equal("\n", @/)
call delete('Xviminfo')
endfunc
" Test for the 'r' field in 'viminfo' (removal media)
func Test_viminfo_removable_media()
CheckUnix
if !isdirectory('/tmp') || getftype('/tmp') != 'dir'
return
endif
let save_viminfo = &viminfo
set viminfo+=r/tmp
edit /tmp/Xvima1b2c3
wviminfo Xviminfo
let matches = readfile('Xviminfo')->filter("v:val =~ 'Xvima1b2c3'")
call assert_equal(0, matches->len())
let &viminfo = save_viminfo
call delete('Xviminfo')
endfunc
" Test for the 'h' flag in 'viminfo'. If 'h' is not present, then the last
" search pattern read from 'viminfo' should be highlighted with 'hlsearch'.
" If 'h' is present, then the last search pattern should not be highlighted.
func Test_viminfo_hlsearch()
set viminfo&vim
new
call setline(1, ['one two three'])
" save the screen attribute for the Search highlighted text and the normal
" text for later comparison
set hlsearch
let @/ = 'three'
redraw!
let hiSearch = screenattr(1, 9)
let hiNormal = screenattr(1, 1)
set viminfo-=h
let @/='two'
wviminfo! Xviminfo
let @/='one'
rviminfo! Xviminfo
redraw!
call assert_equal(hiSearch, screenattr(1, 5))
call assert_equal(hiSearch, screenattr(1, 6))
call assert_equal(hiSearch, screenattr(1, 7))
set viminfo+=h
let @/='two'
wviminfo! Xviminfo
let @/='one'
rviminfo! Xviminfo
redraw!
call assert_equal(hiNormal, screenattr(1, 5))
call assert_equal(hiNormal, screenattr(1, 6))
call assert_equal(hiNormal, screenattr(1, 7))
call delete('Xviminfo')
set hlsearch& viminfo&vim
bw!
endfunc
" Test for restoring the magicness of the last search pattern from the viminfo
" file.
func Test_viminfo_last_spat_magic()
set viminfo&vim
new
call setline(1, ' one abc a.c')
" restore 'nomagic'
set nomagic
exe "normal gg/a.c\<CR>"
wviminfo! Xviminfo
set magic
exe "normal gg/one\<CR>"
rviminfo! Xviminfo
exe "normal! gg/\<CR>"
call assert_equal(10, col('.'))
" restore 'magic'
set magic
exe "normal gg/a.c\<CR>"
wviminfo! Xviminfo
set nomagic
exe "normal gg/one\<CR>"
rviminfo! Xviminfo
exe "normal! gg/\<CR>"
call assert_equal(6, col('.'))
call delete('Xviminfo')
set viminfo&vim magic&
bw!
endfunc
" Test for restoring the smartcase of the last search pattern from the viminfo
" file.
func Test_viminfo_last_spat_smartcase()
new
call setline(1, ' one abc Abc')
set ignorecase smartcase
" Searching with * should disable smartcase
exe "normal! gg$b*"
wviminfo! Xviminfo
exe "normal gg/one\<CR>"
rviminfo! Xviminfo
exe "normal! gg/\<CR>"
call assert_equal(6, col('.'))
call delete('Xviminfo')
set ignorecase& smartcase& viminfo&
bw!
endfunc
" Test for restoring the last search pattern with a line or character offset
" from the viminfo file.
func Test_viminfo_last_spat_offset()
new
call setline(1, ['one', 'two', 'three', 'four', 'five'])
" line offset
exe "normal! /two/+2\<CR>"
wviminfo! Xviminfo
exe "normal gg/five\<CR>"
rviminfo! Xviminfo
exe "normal! gg/\<CR>"
call assert_equal(4, line('.'))
" character offset
exe "normal! gg/^th/e+2\<CR>"
wviminfo! Xviminfo
exe "normal gg/two\<CR>"
rviminfo! Xviminfo
exe "normal! gg/\<CR>"
call assert_equal([3, 4], [line('.'), col('.')])
call delete('Xviminfo')
bw!
endfunc
" Test for saving and restoring the last executed register (@ command)
" from the viminfo file
func Test_viminfo_last_exec_reg()
let g:val = 1
let @a = ":let g:val += 1\n"
normal! @a
wviminfo! Xviminfo
let @b = ''
normal! @b
rviminfo! Xviminfo
normal @@
call assert_equal(3, g:val)
call delete('Xviminfo')
endfunc
" Test for merging file marks in a viminfo file
func Test_viminfo_merge_file_marks()
for [f, l, t] in [['a.txt', 5, 10], ['b.txt', 10, 20]]
call test_settime(t)
exe 'edit ' .. f
call setline(1, range(1, 20))
exe l . 'mark a'
wviminfo Xviminfo
bw!
endfor
call test_settime(30)
for [f, l] in [['a.txt', 5], ['b.txt', 10]]
exe 'edit ' .. f
rviminfo! Xviminfo
call assert_equal(l, line("'a"))
bw!
endfor
call delete('Xviminfo')
call test_settime(0)
endfunc
" Test for merging file marks from a old viminfo file
func Test_viminfo_merge_old_filemarks()
let lines = []
call add(lines, '|1,4')
call add(lines, '> ' .. fnamemodify('a.txt', ':p:~'))
call add(lines, "\tb\t7\t0\n")
call writefile(lines, 'Xviminfo')
edit b.txt
call setline(1, range(1, 20))
12mark b
wviminfo Xviminfo
bw!
edit a.txt
rviminfo! Xviminfo
call assert_equal(7, line("'b"))
edit b.txt
rviminfo! Xviminfo
call assert_equal(12, line("'b"))
call delete('Xviminfo')
endfunc
" Test for merging the jump list from a old viminfo file
func Test_viminfo_merge_old_jumplist()
let lines = []
call add(lines, "-' 10 1 " .. fnamemodify('a.txt', ':p:~'))
call add(lines, "-' 20 1 " .. fnamemodify('a.txt', ':p:~'))
call add(lines, "-' 30 1 " .. fnamemodify('b.txt', ':p:~'))
call add(lines, "-' 40 1 " .. fnamemodify('b.txt', ':p:~'))
call writefile(lines, 'Xviminfo')
clearjumps
rviminfo! Xviminfo
let l = getjumplist()[0]
call assert_equal([40, 30, 20, 10], [l[0].lnum, l[1].lnum, l[2].lnum,
\ l[3].lnum])
bw!
call delete('Xviminfo')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -238,9 +238,11 @@ tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool)
case VAR_BLOB:
emsg(_("E974: Using a Blob as a Number"));
break;
case VAR_VOID:
emsg(_(e_cannot_use_void_value));
break;
case VAR_UNKNOWN:
case VAR_ANY:
case VAR_VOID:
case VAR_INSTR:
internal_error_no_abort("tv_get_number(UNKNOWN)");
break;
@@ -294,7 +296,7 @@ tv_get_bool_chk(typval_T *varp, int *denote)
return tv_get_bool_or_number_chk(varp, denote, TRUE);
}
#ifdef FEAT_FLOAT
#if defined(FEAT_FLOAT) || defined(PROTO)
float_T
tv_get_float(typval_T *varp)
{
@@ -336,9 +338,11 @@ tv_get_float(typval_T *varp)
case VAR_BLOB:
emsg(_("E975: Using a Blob as a Float"));
break;
case VAR_VOID:
emsg(_(e_cannot_use_void_value));
break;
case VAR_UNKNOWN:
case VAR_ANY:
case VAR_VOID:
case VAR_INSTR:
internal_error_no_abort("tv_get_float(UNKNOWN)");
break;
@@ -501,9 +505,11 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
return channel_to_string_buf(varp, buf);
#endif
break;
case VAR_VOID:
emsg(_(e_cannot_use_void_value));
break;
case VAR_UNKNOWN:
case VAR_ANY:
case VAR_VOID:
case VAR_INSTR:
semsg(_(e_using_invalid_value_as_string_str),
vartype_name(varp->v_type));
@@ -657,9 +663,11 @@ copy_tv(typval_T *from, typval_T *to)
++to->vval.v_dict->dv_refcount;
}
break;
case VAR_VOID:
emsg(_(e_cannot_use_void_value));
break;
case VAR_UNKNOWN:
case VAR_ANY:
case VAR_VOID:
internal_error_no_abort("copy_tv(UNKNOWN)");
break;
}

View File

@@ -750,6 +750,20 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3010,
/**/
3009,
/**/
3008,
/**/
3007,
/**/
3006,
/**/
3005,
/**/
3004,
/**/
3003,
/**/

View File

@@ -91,7 +91,7 @@ typedef enum {
ISN_PCALL, // call partial, use isn_arg.pfunc
ISN_PCALL_END, // cleanup after ISN_PCALL with cpf_top set
ISN_RETURN, // return, result is on top of stack
ISN_RETURN_ZERO, // Push zero, then return
ISN_RETURN_VOID, // Push void, then return
ISN_FUNCREF, // push a function ref to dfunc isn_arg.funcref
ISN_NEWFUNC, // create a global function from a lambda function
ISN_DEF, // list functions

View File

@@ -9679,8 +9679,8 @@ nextline:
goto erret;
}
// Return zero if there is no return at the end.
generate_instr(&cctx, ISN_RETURN_ZERO);
// Return void if there is no return at the end.
generate_instr(&cctx, ISN_RETURN_VOID);
}
// When compiled with ":silent!" and there was an error don't consider the
@@ -10047,7 +10047,7 @@ delete_instr(isn_T *isn)
case ISN_REDIREND:
case ISN_REDIRSTART:
case ISN_RETURN:
case ISN_RETURN_ZERO:
case ISN_RETURN_VOID:
case ISN_SHUFFLE:
case ISN_SLICE:
case ISN_STORE:

View File

@@ -2815,17 +2815,18 @@ exec_instructions(ectx_T *ectx)
}
break;
// return from a :def function call
case ISN_RETURN_ZERO:
// return from a :def function call without a value
case ISN_RETURN_VOID:
if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
goto theend;
tv = STACK_TV_BOT(0);
++ectx->ec_stack.ga_len;
tv->v_type = VAR_NUMBER;
tv->v_type = VAR_VOID;
tv->vval.v_number = 0;
tv->v_lock = 0;
// FALLTHROUGH
// return from a :def function call with what is on the stack
case ISN_RETURN:
{
garray_T *trystack = &ectx->ec_trystack;
@@ -5076,8 +5077,8 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
case ISN_RETURN:
smsg("%s%4d RETURN", pfx, current);
break;
case ISN_RETURN_ZERO:
smsg("%s%4d RETURN 0", pfx, current);
case ISN_RETURN_VOID:
smsg("%s%4d RETURN void", pfx, current);
break;
case ISN_FUNCREF:
{