diff options
Diffstat (limited to 'src/nvim/testdir/test_cmdline.vim')
| -rw-r--r-- | src/nvim/testdir/test_cmdline.vim | 1733 |
1 files changed, 1591 insertions, 142 deletions
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 35886d42c5..cf1d56ae38 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -3,10 +3,24 @@ source check.vim source screendump.vim source view_util.vim +source shared.vim + +func SetUp() + func SaveLastScreenLine() + let g:Sline = Screenline(&lines - 1) + return '' + endfunc + cnoremap <expr> <F4> SaveLastScreenLine() +endfunc + +func TearDown() + delfunc SaveLastScreenLine + cunmap <F4> +endfunc func Test_complete_tab() call writefile(['testfile'], 'Xtestfile') - call feedkeys(":e Xtestf\t\r", "tx") + call feedkeys(":e Xtest\t\r", "tx") call assert_equal('testfile', getline(1)) " Pressing <Tab> after '%' completes the current file, also on MS-Windows @@ -24,6 +38,47 @@ func Test_complete_list() " used. call feedkeys(":chistory \<C-D>\<C-B>\"\<CR>", 'xt') call assert_equal("\"chistory \<C-D>", @:) + + " Test for displaying the tail of the completion matches + set wildmode=longest,full + call mkdir('Xtest') + call writefile([], 'Xtest/a.c') + call writefile([], 'Xtest/a.h') + let g:Sline = '' + call feedkeys(":e Xtest/\<C-D>\<F4>\<C-B>\"\<CR>", 'xt') + call assert_equal('a.c a.h', g:Sline) + call assert_equal('"e Xtest/', @:) + if has('win32') + " Test for 'completeslash' + set completeslash=backslash + call feedkeys(":e Xtest\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xtest\', @:) + call feedkeys(":e Xtest/\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xtest\a.', @:) + set completeslash=slash + call feedkeys(":e Xtest\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xtest/', @:) + call feedkeys(":e Xtest\\\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xtest/a.', @:) + set completeslash& + endif + + " Test for displaying the tail with wildcards + let g:Sline = '' + call feedkeys(":e Xtes?/\<C-D>\<F4>\<C-B>\"\<CR>", 'xt') + call assert_equal('Xtest/a.c Xtest/a.h', g:Sline) + call assert_equal('"e Xtes?/', @:) + let g:Sline = '' + call feedkeys(":e Xtes*/\<C-D>\<F4>\<C-B>\"\<CR>", 'xt') + call assert_equal('Xtest/a.c Xtest/a.h', g:Sline) + call assert_equal('"e Xtes*/', @:) + let g:Sline = '' + call feedkeys(":e Xtes[/\<C-D>\<F4>\<C-B>\"\<CR>", 'xt') + call assert_equal(':e Xtes[/', g:Sline) + call assert_equal('"e Xtes[/', @:) + + call delete('Xtest', 'rf') + set wildmode& endfunc func Test_complete_wildmenu() @@ -88,14 +143,25 @@ func Test_complete_wildmenu() call assert_equal('"e Xtestfile3 Xtestfile4', @:) cd - + " test for wildmenumode() + cnoremap <expr> <F2> wildmenumode() + call feedkeys(":cd Xdir\<Tab>\<F2>\<C-B>\"\<CR>", 'tx') + call assert_equal('"cd Xdir1/0', @:) + call feedkeys(":e Xdir1/\<Tab>\<F2>\<C-B>\"\<CR>", 'tx') + call assert_equal('"e Xdir1/Xdir2/1', @:) + cunmap <F2> + + " Test for canceling the wild menu by pressing <PageDown> or <PageUp>. + " After this pressing <Left> or <Right> should not change the selection. + call feedkeys(":sign \<Tab>\<PageDown>\<Left>\<Right>\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"sign define', @:) + call histadd('cmd', 'TestWildMenu') + call feedkeys(":sign \<Tab>\<PageUp>\<Left>\<Right>\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"TestWildMenu', @:) + " cleanup %bwipe - call delete('Xdir1/Xdir2/Xtestfile4') - call delete('Xdir1/Xdir2/Xtestfile3') - call delete('Xdir1/Xtestfile2') - call delete('Xdir1/Xtestfile1') - call delete('Xdir1/Xdir2', 'd') - call delete('Xdir1', 'd') + call delete('Xdir1', 'rf') set nowildmenu endfunc @@ -126,13 +192,74 @@ func Test_wildmenu_screendump() call delete('XTest_wildmenu') endfunc +func Test_redraw_in_autocmd() + CheckScreendump + + let lines =<< trim END + set cmdheight=2 + autocmd CmdlineChanged * redraw + END + call writefile(lines, 'XTest_redraw', 'D') + + let buf = RunVimInTerminal('-S XTest_redraw', {'rows': 8}) + call term_sendkeys(buf, ":for i in range(3)\<CR>") + call VerifyScreenDump(buf, 'Test_redraw_in_autocmd_1', {}) + + call term_sendkeys(buf, "let i =") + call VerifyScreenDump(buf, 'Test_redraw_in_autocmd_2', {}) + + " clean up + call term_sendkeys(buf, "\<CR>") + call StopVimInTerminal(buf) +endfunc + +func Test_redrawstatus_in_autocmd() + CheckScreendump + + let lines =<< trim END + set laststatus=2 + set statusline=%=:%{getcmdline()} + autocmd CmdlineChanged * redrawstatus + END + call writefile(lines, 'XTest_redrawstatus', 'D') + + let buf = RunVimInTerminal('-S XTest_redrawstatus', {'rows': 8}) + " :redrawstatus is postponed if messages have scrolled + call term_sendkeys(buf, ":echo \"one\\ntwo\\nthree\\nfour\"\<CR>") + call term_sendkeys(buf, ":foobar") + call VerifyScreenDump(buf, 'Test_redrawstatus_in_autocmd_1', {}) + " it is not postponed if messages have not scrolled + call term_sendkeys(buf, "\<Esc>:for in in range(3)") + call VerifyScreenDump(buf, 'Test_redrawstatus_in_autocmd_2', {}) + " with cmdheight=1 messages have scrolled when typing :endfor + call term_sendkeys(buf, "\<CR>:endfor") + call VerifyScreenDump(buf, 'Test_redrawstatus_in_autocmd_3', {}) + call term_sendkeys(buf, "\<CR>:set cmdheight=2\<CR>") + " with cmdheight=2 messages haven't scrolled when typing :for or :endfor + call term_sendkeys(buf, ":for in in range(3)") + call VerifyScreenDump(buf, 'Test_redrawstatus_in_autocmd_4', {}) + call term_sendkeys(buf, "\<CR>:endfor") + call VerifyScreenDump(buf, 'Test_redrawstatus_in_autocmd_5', {}) + + " clean up + call term_sendkeys(buf, "\<CR>") + call StopVimInTerminal(buf) +endfunc + func Test_changing_cmdheight() CheckScreendump let lines =<< trim END set cmdheight=1 laststatus=2 + func EchoTwo() + set laststatus=2 + set cmdheight=5 + echo 'foo' + echo 'bar' + set cmdheight=1 + endfunc END - call writefile(lines, 'XTest_cmdheight') + call writefile(lines, 'XTest_cmdheight', 'D') let buf = RunVimInTerminal('-S XTest_cmdheight', {'rows': 8}) call term_sendkeys(buf, ":resize -3\<CR>") @@ -150,20 +277,30 @@ func Test_changing_cmdheight() call term_sendkeys(buf, ":set cmdheight-=2\<CR>") call VerifyScreenDump(buf, 'Test_changing_cmdheight_4', {}) - " reducing window size and then setting cmdheight + " reducing window size and then setting cmdheight call term_sendkeys(buf, ":resize -1\<CR>") call term_sendkeys(buf, ":set cmdheight=1\<CR>") call VerifyScreenDump(buf, 'Test_changing_cmdheight_5', {}) + " setting 'cmdheight' works after outputting two messages + call term_sendkeys(buf, ":call EchoTwo()\<CR>") + call VerifyScreenDump(buf, 'Test_changing_cmdheight_6', {}) + + " clean up + call StopVimInTerminal(buf) +endfunc + +func Test_cmdheight_tabline() + CheckScreendump + + let buf = RunVimInTerminal('-c "set ls=2" -c "set stal=2" -c "set cmdheight=1"', {'rows': 6}) + call VerifyScreenDump(buf, 'Test_cmdheight_tabline_1', {}) + " clean up call StopVimInTerminal(buf) - call delete('XTest_cmdheight') endfunc func Test_map_completion() - if !has('cmdline_compl') - return - endif call feedkeys(":map <unique> <si\<Tab>\<Home>\"\<CR>", 'xt') call assert_equal('"map <unique> <silent>', getreg(':')) call feedkeys(":map <script> <un\<Tab>\<Home>\"\<CR>", 'xt') @@ -234,29 +371,30 @@ func Test_map_completion() unmap <Left> " set cpo-=k + call assert_fails('call feedkeys(":map \\\\%(\<Tab>\<Home>\"\<CR>", "xt")', 'E53:') + unmap <Middle>x set cpo&vim endfunc func Test_match_completion() - if !has('cmdline_compl') - return - endif hi Aardig ctermfg=green - call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt') - call assert_equal('"match Aardig', getreg(':')) + " call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt') + call feedkeys(":match A\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"match Aardig', @:) call feedkeys(":match \<S-Tab>\<Home>\"\<CR>", 'xt') - call assert_equal('"match none', getreg(':')) + call assert_equal('"match none', @:) + call feedkeys(":match | chist\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"match | chistory', @:) endfunc func Test_highlight_completion() - if !has('cmdline_compl') - return - endif hi Aardig ctermfg=green - call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt') + " call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt') + call feedkeys(":hi A\<Tab>\<Home>\"\<CR>", 'xt') call assert_equal('"hi Aardig', getreg(':')) - call feedkeys(":hi default \<Tab>\<Home>\"\<CR>", 'xt') + " call feedkeys(":hi default \<Tab>\<Home>\"\<CR>", 'xt') + call feedkeys(":hi default A\<Tab>\<Home>\"\<CR>", 'xt') call assert_equal('"hi default Aardig', getreg(':')) call feedkeys(":hi clear Aa\<Tab>\<Home>\"\<CR>", 'xt') call assert_equal('"hi clear Aardig', getreg(':')) @@ -276,39 +414,7 @@ func Test_highlight_completion() call assert_equal([], getcompletion('A', 'highlight')) endfunc -func Test_expr_completion() - if !has('cmdline_compl') - return - endif - for cmd in [ - \ 'let a = ', - \ 'const a = ', - \ 'if', - \ 'elseif', - \ 'while', - \ 'for', - \ 'echo', - \ 'echon', - \ 'execute', - \ 'echomsg', - \ 'echoerr', - \ 'call', - \ 'return', - \ 'cexpr', - \ 'caddexpr', - \ 'cgetexpr', - \ 'lexpr', - \ 'laddexpr', - \ 'lgetexpr'] - call feedkeys(":" . cmd . " getl\<Tab>\<Home>\"\<CR>", 'xt') - call assert_equal('"' . cmd . ' getline(', getreg(':')) - endfor -endfunc - func Test_getcompletion() - if !has('cmdline_compl') - return - endif let groupcount = len(getcompletion('', 'event')) call assert_true(groupcount > 0) let matchcount = len('File'->getcompletion('event')) @@ -323,6 +429,7 @@ func Test_getcompletion() call assert_true(matchcount > 0) let matchcount = len(getcompletion('File.', 'menu')) call assert_true(matchcount > 0) + source $VIMRUNTIME/delmenu.vim endif let l = getcompletion('v:n', 'var') @@ -333,6 +440,8 @@ func Test_getcompletion() args a.c b.c let l = getcompletion('', 'arglist') call assert_equal(['a.c', 'b.c'], l) + let l = getcompletion('a.', 'buffer') + call assert_equal(['a.c'], l) %argdelete let l = getcompletion('', 'augroup') @@ -388,6 +497,11 @@ func Test_getcompletion() let l = getcompletion('run', 'file', 1) call assert_true(index(l, 'runtest.vim') < 0) set wildignore& + " Directory name with space character + call mkdir('Xdir with space') + call assert_equal(['Xdir with space/'], getcompletion('Xdir\ w', 'shellcmd')) + call assert_equal(['./Xdir with space/'], getcompletion('./Xdir', 'shellcmd')) + call delete('Xdir with space', 'd') let l = getcompletion('ha', 'filetype') call assert_true(index(l, 'hamster') >= 0) @@ -462,11 +576,17 @@ func Test_getcompletion() call assert_equal(cmds, l) let l = getcompletion('list ', 'sign') call assert_equal(['Testing'], l) + let l = getcompletion('de*', 'sign') + call assert_equal(['define'], l) + let l = getcompletion('p?', 'sign') + call assert_equal(['place'], l) + let l = getcompletion('j.', 'sign') + call assert_equal(['jump'], l) endif " Command line completion tests let l = getcompletion('cd ', 'cmdline') - call assert_true(index(l, 'sautest/') >= 0) + call assert_true(index(l, 'samples/') >= 0) let l = getcompletion('cd NoMatch', 'cmdline') call assert_equal([], l) let l = getcompletion('let v:n', 'cmdline') @@ -514,10 +634,39 @@ func Test_getcompletion() call delete('Xtags') set tags& + edit a~b + enew + call assert_equal(['a~b'], getcompletion('a~', 'buffer')) + bw a~b + + if has('unix') + edit Xtest\ + enew + call assert_equal(['Xtest\'], getcompletion('Xtest\', 'buffer')) + bw Xtest\ + endif + + call assert_fails("call getcompletion('\\\\@!\\\\@=', 'buffer')", 'E871:') call assert_fails('call getcompletion("", "burp")', 'E475:') call assert_fails('call getcompletion("abc", [])', 'E475:') endfunc +" Test for getcompletion() with "fuzzy" in 'wildoptions' +func Test_getcompletion_wildoptions() + let save_wildoptions = &wildoptions + set wildoptions& + let l = getcompletion('space', 'option') + call assert_equal([], l) + let l = getcompletion('ier', 'command') + call assert_equal([], l) + set wildoptions=fuzzy + let l = getcompletion('space', 'option') + call assert_true(index(l, 'backspace') >= 0) + let l = getcompletion('ier', 'command') + call assert_true(index(l, 'compiler') >= 0) + let &wildoptions = save_wildoptions +endfunc + func Test_fullcommand() let tests = { \ '': '', @@ -590,7 +739,7 @@ func Test_expand_star_star() call mkdir('a/b', 'p') call writefile(['asdfasdf'], 'a/b/fileXname') call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt') - call assert_equal('find a/b/fileXname', getreg(':')) + call assert_equal('find a/b/fileXname', @:) bwipe! call delete('a', 'rf') endfunc @@ -738,7 +887,31 @@ func Test_cmdline_complete_user_cmd() call assert_equal('"Foo blue', @:) call feedkeys(":Foo b\<Tab>\<Home>\"\<cr>", 'tx') call assert_equal('"Foo blue', @:) + call feedkeys(":Foo a b\<Tab>\<Home>\"\<cr>", 'tx') + call assert_equal('"Foo a blue', @:) + call feedkeys(":Foo b\\\<Tab>\<Home>\"\<cr>", 'tx') + call assert_equal('"Foo b\', @:) + call feedkeys(":Foo b\\x\<Tab>\<Home>\"\<cr>", 'tx') + call assert_equal('"Foo b\x', @:) delcommand Foo + + redraw + call assert_equal('~', Screenline(&lines - 1)) + command! FooOne : + command! FooTwo : + + set nowildmenu + call feedkeys(":Foo\<Tab>\<Home>\"\<cr>", 'tx') + call assert_equal('"FooOne', @:) + call assert_equal('~', Screenline(&lines - 1)) + + call feedkeys(":Foo\<S-Tab>\<Home>\"\<cr>", 'tx') + call assert_equal('"FooTwo', @:) + call assert_equal('~', Screenline(&lines - 1)) + + delcommand FooOne + delcommand FooTwo + set wildmenu& endfunc func Test_complete_user_cmd() @@ -809,7 +982,7 @@ func Test_cmdline_complete_bang() endif endfunc -funct Test_cmdline_complete_languages() +func Test_cmdline_complete_languages() let lang = substitute(execute('language time'), '.*"\(.*\)"$', '\1', '') call assert_equal(lang, v:lc_time) @@ -846,10 +1019,8 @@ endfunc func Test_cmdline_complete_env_variable() let $X_VIM_TEST_COMPLETE_ENV = 'foo' - call feedkeys(":edit $X_VIM_TEST_COMPLETE_E\<C-A>\<C-B>\"\<CR>", 'tx') call assert_match('"edit $X_VIM_TEST_COMPLETE_ENV', @:) - unlet $X_VIM_TEST_COMPLETE_ENV endfunc @@ -926,6 +1097,10 @@ func Test_cmdline_complete_various() call feedkeys(":all abc\<C-A>\<C-B>\"\<CR>", 'xt') call assert_equal("\"all abc\<C-A>", @:) + " completion for :wincmd with :horizontal modifier + call feedkeys(":horizontal wincm\<C-A>\<C-B>\"\<CR>", 'xt') + call assert_equal("\"horizontal wincmd", @:) + " completion for a command with a command modifier call feedkeys(":topleft new\<C-A>\<C-B>\"\<CR>", 'xt') call assert_equal("\"topleft new", @:) @@ -934,14 +1109,6 @@ func Test_cmdline_complete_various() call feedkeys(":match Search /pat/\<C-A>\<C-B>\"\<CR>", 'xt') call assert_equal("\"match Search /pat/\<C-A>", @:) - " completion for the :s command - call feedkeys(":s/from/to/g\<C-A>\<C-B>\"\<CR>", 'xt') - call assert_equal("\"s/from/to/g\<C-A>", @:) - - " completion for the :dlist command - call feedkeys(":dlist 10 /pat/ a\<C-A>\<C-B>\"\<CR>", 'xt') - call assert_equal("\"dlist 10 /pat/ a\<C-A>", @:) - " completion for the :doautocmd command call feedkeys(":doautocmd User MyCmd a.c\<C-A>\<C-B>\"\<CR>", 'xt') call assert_equal("\"doautocmd User MyCmd a.c\<C-A>", @:) @@ -1001,7 +1168,7 @@ func Test_cmdline_complete_various() map <F3> :ls<CR> com -nargs=* -complete=mapping MyCmd call feedkeys(":MyCmd <F\<C-A>\<C-B>\"\<CR>", 'xt') - call assert_equal('"MyCmd <F3>', @:) + call assert_equal('"MyCmd <F3> <F4>', @:) mapclear delcom MyCmd @@ -1025,9 +1192,77 @@ func Test_cmdline_complete_various() call feedkeys(":e `a1b2c\t\<C-B>\"\<CR>", 'xt') call assert_equal('"e `a1b2c', @:) - " completion for the expression register - call feedkeys(":\"\<C-R>=float2\t\"\<C-B>\"\<CR>", 'xt') - call assert_equal('"float2nr("', @=) + " completion for :language command with an invalid argument + call feedkeys(":language dummy \t\<C-B>\"\<CR>", 'xt') + call assert_equal("\"language dummy \t", @:) + + " completion for commands after a :global command + call feedkeys(":g/a\\xb/clearj\t\<C-B>\"\<CR>", 'xt') + call assert_equal('"g/a\xb/clearjumps', @:) + + " completion with ambiguous user defined commands + com TCmd1 echo 'TCmd1' + com TCmd2 echo 'TCmd2' + call feedkeys(":TCmd \t\<C-B>\"\<CR>", 'xt') + call assert_equal('"TCmd ', @:) + delcom TCmd1 + delcom TCmd2 + + " completion after a range followed by a pipe (|) character + call feedkeys(":1,10 | chist\t\<C-B>\"\<CR>", 'xt') + call assert_equal('"1,10 | chistory', @:) + + " completion after a :global command + call feedkeys(":g/a/chist\t\<C-B>\"\<CR>", 'xt') + call assert_equal('"g/a/chistory', @:) + call feedkeys(":g/a\\/chist\t\<C-B>\"\<CR>", 'xt') + call assert_equal("\"g/a\\/chist\t", @:) + + " use <Esc> as the 'wildchar' for completion + set wildchar=<Esc> + call feedkeys(":g/a\\xb/clearj\<Esc>\<C-B>\"\<CR>", 'xt') + call assert_equal('"g/a\xb/clearjumps', @:) + " pressing <esc> twice should cancel the command + call feedkeys(":chist\<Esc>\<Esc>", 'xt') + call assert_equal('"g/a\xb/clearjumps', @:) + set wildchar& + + if has('unix') + " should be able to complete a file name that starts with a '~'. + call writefile([], '~Xtest') + call feedkeys(":e \\~X\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e \~Xtest', @:) + call delete('~Xtest') + + " should be able to complete a file name that has a '*' + call writefile([], 'Xx*Yy') + call feedkeys(":e Xx\*\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xx\*Yy', @:) + call delete('Xx*Yy') + + " use a literal star + call feedkeys(":e \\*\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e \*', @:) + endif + + call feedkeys(":py3f\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"py3file', @:) +endfunc + +" Test for 'wildignorecase' +func Test_cmdline_wildignorecase() + CheckUnix + call writefile([], 'XTEST') + set wildignorecase + call feedkeys(":e xt\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e XTEST', @:) + call assert_equal(['XTEST'], getcompletion('xt', 'file')) + let g:Sline = '' + call feedkeys(":e xt\<C-d>\<F4>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e xt', @:) + call assert_equal('XTEST', g:Sline) + set wildignorecase& + call delete('XTEST') endfunc func Test_cmdline_write_alternatefile() @@ -1051,6 +1286,18 @@ func Test_cmdline_write_alternatefile() bw! endfunc +func Test_cmdline_expand_cur_alt_file() + enew + file http://some.com/file.txt + call feedkeys(":e %\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e http://some.com/file.txt', @:) + edit another + call feedkeys(":e #\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e http://some.com/file.txt', @:) + bwipe + bwipe http://some.com/file.txt +endfunc + " using a leading backslash here set cpo+=C @@ -1072,7 +1319,7 @@ func Test_cmdline_search_range() call assert_equal('B', getline(2)) let @/ = 'apple' - call assert_fails('\/print', 'E486:') + call assert_fails('\/print', ['E486:.*apple']) bwipe! endfunc @@ -1082,7 +1329,7 @@ func Test_tick_mark_in_range() " If only the tick is passed as a range and no command is specified, there " should not be an error call feedkeys(":'\<CR>", 'xt') - call assert_equal("'", getreg(':')) + call assert_equal("'", @:) call assert_fails("',print", 'E78:') endfunc @@ -1188,6 +1435,11 @@ func Test_verbosefile() let log = readfile('Xlog') call assert_match("foo\nbar", join(log, "\n")) call delete('Xlog') + call mkdir('Xdir') + if !has('win32') " FIXME: no error on Windows, libuv bug? + call assert_fails('set verbosefile=Xdir', ['E484:.*Xdir', 'E474:']) + endif + call delete('Xdir', 'd') endfunc func Test_verbose_option() @@ -1260,6 +1512,16 @@ func Test_cmdline_overstrike() let &encoding = encoding_save endfunc +func Test_cmdwin_bug() + let winid = win_getid() + sp + try + call feedkeys("q::call win_gotoid(" .. winid .. ")\<CR>:q\<CR>", 'x!') + catch /^Vim\%((\a\+)\)\=:E11/ + endtry + bw! +endfunc + func Test_cmdwin_restore() CheckScreendump @@ -1414,6 +1676,7 @@ func Test_cmdline_expand_special() call assert_fails('e <afile>', 'E495:') call assert_fails('e <abuf>', 'E496:') call assert_fails('e <amatch>', 'E497:') + call writefile([], 'Xfile.cpp') call writefile([], 'Xfile.java') new Xfile.cpp @@ -1428,7 +1691,7 @@ func Test_cmdwin_jump_to_win() call assert_fails('call feedkeys("q:\<C-W>\<C-W>\<CR>", "xt")', 'E11:') new set modified - call assert_fails('call feedkeys("q/:qall\<CR>", "xt")', 'E162:') + call assert_fails('call feedkeys("q/:qall\<CR>", "xt")', ['E37:', 'E162:']) close! call feedkeys("q/:close\<CR>", "xt") call assert_equal(1, winnr('$')) @@ -1442,16 +1705,36 @@ endfunc func Test_cmdwin_tabpage() tabedit - " v8.2.1919 isn't ported yet, so E492 is thrown after E11 here. - " v8.2.1183 also isn't ported yet, so we also can't assert E11 directly. - " For now, assert E11 and E492 separately. When v8.2.1183 is ported, the - " assert for E492 will fail and this workaround should be removed. - " call assert_fails("silent norm q/g :I\<Esc>", 'E11:') - call assert_fails("silent norm q/g ", 'E11:') - call assert_fails("silent norm q/g :I\<Esc>", 'E492:') + call assert_fails("silent norm q/g :I\<Esc>", 'E11:') tabclose! endfunc +func Test_cmdwin_interrupted() + CheckScreendump + + " aborting the :smile output caused the cmdline window to use the current + " buffer. + let lines =<< trim [SCRIPT] + au WinNew * smile + [SCRIPT] + call writefile(lines, 'XTest_cmdwin') + + let buf = RunVimInTerminal('-S XTest_cmdwin', {'rows': 18}) + " open cmdwin + call term_sendkeys(buf, "q:") + call WaitForAssert({-> assert_match('-- More --', term_getline(buf, 18))}) + " quit more prompt for :smile command + call term_sendkeys(buf, "q") + call WaitForAssert({-> assert_match('^$', term_getline(buf, 18))}) + " execute a simple command + call term_sendkeys(buf, "aecho 'done'\<CR>") + call VerifyScreenDump(buf, 'Test_cmdwin_interrupted', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('XTest_cmdwin') +endfunc + " Test for backtick expression in the command line func Test_cmd_backtick() CheckNotMSWindows " FIXME: see #19297 @@ -1508,6 +1791,53 @@ func Test_cmd_bang_E135() %bwipe! endfunc +func Test_cmd_bang_args() + new + :.! + call assert_equal(0, v:shell_error) + + " Note that below there is one space char after the '!'. This caused a + " shell error in the past, see https://github.com/vim/vim/issues/11495. + :.! + call assert_equal(0, v:shell_error) + bwipe! + + CheckUnix + :.!pwd + call assert_equal(0, v:shell_error) + :.! pwd + call assert_equal(0, v:shell_error) + + " Note there is one space after 'pwd'. + :.! pwd + call assert_equal(0, v:shell_error) + + " Note there are two spaces after 'pwd'. + :.! pwd + call assert_equal(0, v:shell_error) + :.!ls ~ + call assert_equal(0, v:shell_error) + + " Note there is one space char after '~'. + :.!ls ~ + call assert_equal(0, v:shell_error) + + " Note there are two spaces after '~'. + :.!ls ~ + call assert_equal(0, v:shell_error) + + :.!echo "foo" + call assert_equal(getline('.'), "foo") + :.!echo "foo " + call assert_equal(getline('.'), "foo ") + :.!echo " foo " + call assert_equal(getline('.'), " foo ") + :.!echo " foo " + call assert_equal(getline('.'), " foo ") + + %bwipe! +endfunc + " Test for using ~ for home directory in cmdline completion matches func Test_cmdline_expand_home() call mkdir('Xdir') @@ -1543,22 +1873,16 @@ func Test_cmdline_ctrl_g() endfunc " Test for 'wildmode' -func Test_wildmode() +func Wildmode_tests() func T(a, c, p) return "oneA\noneB\noneC" endfunc command -nargs=1 -complete=custom,T MyCmd - func SaveScreenLine() - let g:Sline = Screenline(&lines - 1) - return '' - endfunc - cnoremap <expr> <F2> SaveScreenLine() - set nowildmenu set wildmode=full,list let g:Sline = '' - call feedkeys(":MyCmd \t\t\<F2>\<C-B>\"\<CR>", 'xt') + call feedkeys(":MyCmd \t\t\<F4>\<C-B>\"\<CR>", 'xt') call assert_equal('oneA oneB oneC', g:Sline) call assert_equal('"MyCmd oneA', @:) @@ -1574,7 +1898,7 @@ func Test_wildmode() set wildmode=list:longest let g:Sline = '' - call feedkeys(":MyCmd \t\<F2>\<C-B>\"\<CR>", 'xt') + call feedkeys(":MyCmd \t\<F4>\<C-B>\"\<CR>", 'xt') call assert_equal('oneA oneB oneC', g:Sline) call assert_equal('"MyCmd one', @:) @@ -1585,27 +1909,67 @@ func Test_wildmode() " Test for wildmode=longest with 'fileignorecase' set set wildmode=longest set fileignorecase - argadd AA AAA AAAA - call feedkeys(":buffer \t\<C-B>\"\<CR>", 'xt') - call assert_equal('"buffer AA', @:) + argadd AAA AAAA AAAAA + call feedkeys(":buffer a\t\<C-B>\"\<CR>", 'xt') + call assert_equal('"buffer AAA', @:) set fileignorecase& " Test for listing files with wildmode=list set wildmode=list let g:Sline = '' - call feedkeys(":b A\t\t\<F2>\<C-B>\"\<CR>", 'xt') - call assert_equal('AA AAA AAAA', g:Sline) + call feedkeys(":b A\t\t\<F4>\<C-B>\"\<CR>", 'xt') + call assert_equal('AAA AAAA AAAAA', g:Sline) call assert_equal('"b A', @:) + " when using longest completion match, matches shorter than the argument + " should be ignored (happens with :help) + set wildmode=longest,full + set wildmenu + call feedkeys(":help a*\t\<C-B>\"\<CR>", 'xt') + call assert_equal('"help a', @:) + " non existing file + call feedkeys(":e a1b2y3z4\t\<C-B>\"\<CR>", 'xt') + call assert_equal('"e a1b2y3z4', @:) + set wildmenu& + + " Test for longest file name completion with 'fileignorecase' + " On MS-Windows, file names are case insensitive. + if has('unix') + call writefile([], 'XTESTfoo') + call writefile([], 'Xtestbar') + set nofileignorecase + call feedkeys(":e XT\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e XTESTfoo', @:) + call feedkeys(":e Xt\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xtestbar', @:) + set fileignorecase + call feedkeys(":e XT\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xtest', @:) + call feedkeys(":e Xt\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xtest', @:) + set fileignorecase& + call delete('XTESTfoo') + call delete('Xtestbar') + endif + %argdelete delcommand MyCmd delfunc T - delfunc SaveScreenLine - cunmap <F2> set wildmode& %bwipe! endfunc +func Test_wildmode() + " Test with utf-8 encoding + call Wildmode_tests() + + " Test with latin1 encoding + let save_encoding = &encoding + " set encoding=latin1 + " call Wildmode_tests() + let &encoding = save_encoding +endfunc + " Test for interrupting the command-line completion func Test_interrupt_compl() func F(lead, cmdl, p) @@ -1627,6 +1991,14 @@ func Test_interrupt_compl() endtry call assert_equal(1, interrupted) + let interrupted = 0 + try + call feedkeys(":Tcmd tw\<C-d>\<C-B>\"\<CR>", 'xt') + catch /^Vim:Interrupt$/ + let interrupted = 1 + endtry + call assert_equal(1, interrupted) + delcommand Tcmd delfunc F set wildmode& @@ -1683,6 +2055,11 @@ func Test_cmdline_expr() call assert_equal("\"e \<C-\>\<C-Y>", @:) endfunc +" This was making the insert position negative +func Test_cmdline_expr_register() + exe "sil! norm! ?\<C-\>e0\<C-R>0\<Esc>?\<C-\>e0\<CR>" +endfunc + " Test for 'imcmdline' and 'imsearch' " This test doesn't actually test the input method functionality. func Test_cmdline_inputmethod() @@ -1809,8 +2186,45 @@ func Test_read_shellcmd() endif endfunc +" Test for going up and down the directory tree using 'wildmenu' +func Test_wildmenu_dirstack() + CheckUnix + %bw! + call mkdir('Xdir1/dir2/dir3/dir4', 'p') + call writefile([], 'Xdir1/file1_1.txt') + call writefile([], 'Xdir1/file1_2.txt') + call writefile([], 'Xdir1/dir2/file2_1.txt') + call writefile([], 'Xdir1/dir2/file2_2.txt') + call writefile([], 'Xdir1/dir2/dir3/file3_1.txt') + call writefile([], 'Xdir1/dir2/dir3/file3_2.txt') + call writefile([], 'Xdir1/dir2/dir3/dir4/file4_1.txt') + call writefile([], 'Xdir1/dir2/dir3/dir4/file4_2.txt') + set wildmenu + + cd Xdir1/dir2/dir3/dir4 + call feedkeys(":e \<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e file4_1.txt', @:) + call feedkeys(":e \<Tab>\<Up>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e ../dir4/', @:) + call feedkeys(":e \<Tab>\<Up>\<Up>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e ../../dir3/', @:) + call feedkeys(":e \<Tab>\<Up>\<Up>\<Up>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e ../../../dir2/', @:) + call feedkeys(":e \<Tab>\<Up>\<Up>\<Down>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e ../../dir3/dir4/', @:) + call feedkeys(":e \<Tab>\<Up>\<Up>\<Down>\<Down>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e ../../dir3/dir4/file4_1.txt', @:) + cd - + call feedkeys(":e Xdir1/\<Tab>\<Down>\<Down>\<Down>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xdir1/dir2/dir3/dir4/file4_1.txt', @:) + + call delete('Xdir1', 'rf') + set wildmenu& +endfunc + " Test for recalling newer or older cmdline from history with <Up>, <Down>, -" <S-Up>, <S-Down>, <PageUp>, <PageDown>, <C-p>, or <C-n>. +" <S-Up>, <S-Down>, <PageUp>, <PageDown>, <kPageUp>, <kPageDown>, <C-p>, or +" <C-n>. func Test_recalling_cmdline() CheckFeature cmdline_hist @@ -1818,17 +2232,18 @@ func Test_recalling_cmdline() cnoremap <Plug>(save-cmdline) <Cmd>let g:cmdlines += [getcmdline()]<CR> let histories = [ - \ {'name': 'cmd', 'enter': ':', 'exit': "\<Esc>"}, - \ {'name': 'search', 'enter': '/', 'exit': "\<Esc>"}, - \ {'name': 'expr', 'enter': ":\<C-r>=", 'exit': "\<Esc>\<Esc>"}, - \ {'name': 'input', 'enter': ":call input('')\<CR>", 'exit': "\<CR>"}, + \ #{name: 'cmd', enter: ':', exit: "\<Esc>"}, + \ #{name: 'search', enter: '/', exit: "\<Esc>"}, + \ #{name: 'expr', enter: ":\<C-r>=", exit: "\<Esc>\<Esc>"}, + \ #{name: 'input', enter: ":call input('')\<CR>", exit: "\<CR>"}, "\ TODO: {'name': 'debug', ...} \] let keypairs = [ - \ {'older': "\<Up>", 'newer': "\<Down>", 'prefixmatch': v:true}, - \ {'older': "\<S-Up>", 'newer': "\<S-Down>", 'prefixmatch': v:false}, - \ {'older': "\<PageUp>", 'newer': "\<PageDown>", 'prefixmatch': v:false}, - \ {'older': "\<C-p>", 'newer': "\<C-n>", 'prefixmatch': v:false}, + \ #{older: "\<Up>", newer: "\<Down>", prefixmatch: v:true}, + \ #{older: "\<S-Up>", newer: "\<S-Down>", prefixmatch: v:false}, + \ #{older: "\<PageUp>", newer: "\<PageDown>", prefixmatch: v:false}, + \ #{older: "\<kPageUp>", newer: "\<kPageDown>", prefixmatch: v:false}, + \ #{older: "\<C-p>", newer: "\<C-n>", prefixmatch: v:false}, \] let prefix = 'vi' for h in histories @@ -1857,6 +2272,59 @@ func Test_recalling_cmdline() cunmap <Plug>(save-cmdline) endfunc +func Test_cmd_map_cmdlineChanged() + let g:log = [] + cnoremap <F1> l<Cmd><CR>s + augroup test + autocmd! + autocmd CmdlineChanged : let g:log += [getcmdline()] + augroup END + + call feedkeys(":\<F1>\<CR>", 'xt') + call assert_equal(['l', 'ls'], g:log) + + let @b = 'b' + cnoremap <F1> a<C-R>b + let g:log = [] + call feedkeys(":\<F1>\<CR>", 'xt') + call assert_equal(['a', 'ab'], g:log) + + unlet g:log + cunmap <F1> + augroup test + autocmd! + augroup END +endfunc + +" Test for the 'suffixes' option +func Test_suffixes_opt() + call writefile([], 'Xfile') + call writefile([], 'Xfile.c') + call writefile([], 'Xfile.o') + set suffixes= + call feedkeys(":e Xfi*\<C-A>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xfile Xfile.c Xfile.o', @:) + call feedkeys(":e Xfi*\<Tab>\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xfile.c', @:) + set suffixes=.c + call feedkeys(":e Xfi*\<C-A>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xfile Xfile.o Xfile.c', @:) + call feedkeys(":e Xfi*\<Tab>\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xfile.o', @:) + set suffixes=,, + call feedkeys(":e Xfi*\<C-A>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xfile.c Xfile.o Xfile', @:) + call feedkeys(":e Xfi*\<Tab>\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xfile.o', @:) + set suffixes& + " Test for getcompletion() with different patterns + call assert_equal(['Xfile', 'Xfile.c', 'Xfile.o'], getcompletion('Xfile', 'file')) + call assert_equal(['Xfile'], getcompletion('Xfile$', 'file')) + call delete('Xfile') + call delete('Xfile.c') + call delete('Xfile.o') +endfunc + " Test for using a popup menu for the command line completion matches " (wildoptions=pum) func Test_wildmenu_pum() @@ -1868,39 +2336,63 @@ func Test_wildmenu_pum() set shm+=I set noruler set noshowcmd + + func CmdCompl(a, b, c) + return repeat(['aaaa'], 120) + endfunc + command -nargs=* -complete=customlist,CmdCompl Tcmd + + func MyStatusLine() abort + return 'status' + endfunc + func SetupStatusline() + set statusline=%!MyStatusLine() + set laststatus=2 + endfunc + + func MyTabLine() + return 'my tab line' + endfunc + func SetupTabline() + set statusline= + set tabline=%!My |