diff options
Diffstat (limited to 'test/old/testdir/test_cmdline.vim')
| -rw-r--r-- | test/old/testdir/test_cmdline.vim | 3914 |
1 files changed, 3914 insertions, 0 deletions
diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim new file mode 100644 index 0000000000..3f13218c5b --- /dev/null +++ b/test/old/testdir/test_cmdline.vim @@ -0,0 +1,3914 @@ +" Tests for editing the command line. + +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 Xtest\t\r", "tx") + call assert_equal('testfile', getline(1)) + + " Pressing <Tab> after '%' completes the current file, also on MS-Windows + call feedkeys(":e %\t\r", "tx") + call assert_equal('e Xtestfile', @:) + call delete('Xtestfile') +endfunc + +func Test_complete_list() + " We can't see the output, but at least we check the code runs properly. + call feedkeys(":e test\<C-D>\r", "tx") + call assert_equal('test', expand('%:t')) + + " If a command doesn't support completion, then CTRL-D should be literally + " 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() + call mkdir('Xwilddir1/Xdir2', 'pR') + call writefile(['testfile1'], 'Xwilddir1/Xtestfile1') + call writefile(['testfile2'], 'Xwilddir1/Xtestfile2') + call writefile(['testfile3'], 'Xwilddir1/Xdir2/Xtestfile3') + call writefile(['testfile3'], 'Xwilddir1/Xdir2/Xtestfile4') + set wildmenu + + " Pressing <Tab> completes, and moves to next files when pressing again. + call feedkeys(":e Xwilddir1/\<Tab>\<Tab>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) + call feedkeys(":e Xwilddir1/\<Tab>\<Tab>\<Tab>\<CR>", 'tx') + call assert_equal('testfile2', getline(1)) + + " <S-Tab> is like <Tab> but begin with the last match and then go to + " previous. + call feedkeys(":e Xwilddir1/Xtest\<S-Tab>\<CR>", 'tx') + call assert_equal('testfile2', getline(1)) + call feedkeys(":e Xwilddir1/Xtest\<S-Tab>\<S-Tab>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) + + " <Left>/<Right> to move to previous/next file. + call feedkeys(":e Xwilddir1/\<Tab>\<Right>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) + call feedkeys(":e Xwilddir1/\<Tab>\<Right>\<Right>\<CR>", 'tx') + call assert_equal('testfile2', getline(1)) + call feedkeys(":e Xwilddir1/\<Tab>\<Right>\<Right>\<Left>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) + + " <Up>/<Down> to go up/down directories. + call feedkeys(":e Xwilddir1/\<Tab>\<Down>\<CR>", 'tx') + call assert_equal('testfile3', getline(1)) + call feedkeys(":e Xwilddir1/\<Tab>\<Down>\<Up>\<Right>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) + + " this fails in some Unix GUIs, not sure why + if !has('unix') || !has('gui_running') + " <C-J>/<C-K> mappings to go up/down directories when 'wildcharm' is + " different than 'wildchar'. + set wildcharm=<C-Z> + cnoremap <C-J> <Down><C-Z> + cnoremap <C-K> <Up><C-Z> + call feedkeys(":e Xwilddir1/\<Tab>\<C-J>\<CR>", 'tx') + call assert_equal('testfile3', getline(1)) + call feedkeys(":e Xwilddir1/\<Tab>\<C-J>\<C-K>\<CR>", 'tx') + call assert_equal('testfile1', getline(1)) + set wildcharm=0 + cunmap <C-J> + cunmap <C-K> + endif + + " Test for canceling the wild menu by adding a character + redrawstatus + call feedkeys(":e Xwilddir1/\<Tab>x\<C-B>\"\<CR>", 'xt') + call assert_equal('"e Xwilddir1/Xdir2/x', @:) + + " Completion using a relative path + cd Xwilddir1/Xdir2 + call feedkeys(":e ../\<Tab>\<Right>\<Down>\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"e Xtestfile3 Xtestfile4', @:) + cd - + + " test for wildmenumode() + cnoremap <expr> <F2> wildmenumode() + call feedkeys(":cd Xwilddir\<Tab>\<F2>\<C-B>\"\<CR>", 'tx') + call assert_equal('"cd Xwilddir1/0', @:) + call feedkeys(":e Xwilddir1/\<Tab>\<F2>\<C-B>\"\<CR>", 'tx') + call assert_equal('"e Xwilddir1/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', @:) + + " Test for Ctrl-E/Ctrl-Y being able to cancel / accept a match + call feedkeys(":sign un zz\<Left>\<Left>\<Left>\<Tab>\<C-E> yy\<C-B>\"\<CR>", 'tx') + call assert_equal('"sign un yy zz', @:) + + call feedkeys(":sign un zz\<Left>\<Left>\<Left>\<Tab>\<Tab>\<C-Y> yy\<C-B>\"\<CR>", 'tx') + call assert_equal('"sign unplace yy zz', @:) + + " cleanup + %bwipe + set nowildmenu +endfunc + +func Test_wildmenu_screendump() + CheckScreendump + + let lines =<< trim [SCRIPT] + set wildmenu hlsearch + [SCRIPT] + call writefile(lines, 'XTest_wildmenu', 'D') + + " Test simple wildmenu + let buf = RunVimInTerminal('-S XTest_wildmenu', {'rows': 8}) + call term_sendkeys(buf, ":vim\<Tab>") + call VerifyScreenDump(buf, 'Test_wildmenu_1', {}) + + call term_sendkeys(buf, "\<Tab>") + call VerifyScreenDump(buf, 'Test_wildmenu_2', {}) + + call term_sendkeys(buf, "\<Tab>") + call VerifyScreenDump(buf, 'Test_wildmenu_3', {}) + + " Looped back to the original value + call term_sendkeys(buf, "\<Tab>\<Tab>") + call VerifyScreenDump(buf, 'Test_wildmenu_4', {}) + + " Test that the wild menu is cleared properly + call term_sendkeys(buf, " ") + call VerifyScreenDump(buf, 'Test_wildmenu_5', {}) + + " Test that a different wildchar still works + call term_sendkeys(buf, "\<Esc>:set wildchar=<Esc>\<CR>") + call term_sendkeys(buf, ":vim\<Esc>") + call VerifyScreenDump(buf, 'Test_wildmenu_1', {}) + + " Double-<Esc> is a hard-coded method to escape while wildchar=<Esc>. Make + " sure clean up is properly done in edge case like this. + call term_sendkeys(buf, "\<Esc>") + call VerifyScreenDump(buf, 'Test_wildmenu_6', {}) + + " clean up + call StopVimInTerminal(buf) +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', 'D') + + let buf = RunVimInTerminal('-S XTest_cmdheight', {'rows': 8}) + call term_sendkeys(buf, ":resize -3\<CR>") + call VerifyScreenDump(buf, 'Test_changing_cmdheight_1', {}) + + " using the space available doesn't change the status line + call term_sendkeys(buf, ":set cmdheight+=3\<CR>") + call VerifyScreenDump(buf, 'Test_changing_cmdheight_2', {}) + + " using more space moves the status line up + call term_sendkeys(buf, ":set cmdheight+=1\<CR>") + call VerifyScreenDump(buf, 'Test_changing_cmdheight_3', {}) + + " reducing cmdheight moves status line down + call term_sendkeys(buf, ":set cmdheight-=2\<CR>") + call VerifyScreenDump(buf, 'Test_changing_cmdheight_4', {}) + + " 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) +endfunc + +func Test_map_completion() + 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') + call assert_equal('"map <script> <unique>', getreg(':')) + call feedkeys(":map <expr> <sc\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <expr> <script>', getreg(':')) + call feedkeys(":map <buffer> <e\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <buffer> <expr>', getreg(':')) + call feedkeys(":map <nowait> <b\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <nowait> <buffer>', getreg(':')) + call feedkeys(":map <special> <no\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <special> <nowait>', getreg(':')) + call feedkeys(":map <silent> <sp\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <silent> <special>', getreg(':')) + + map <Middle>x middle + + map ,f commaf + map ,g commaf + map <Left> left + map <A-Left>x shiftleft + call feedkeys(":map ,\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map ,f', getreg(':')) + call feedkeys(":map ,\<Tab>\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map ,g', getreg(':')) + call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <Left>', getreg(':')) + call feedkeys(":map <A-Left>\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal("\"map <A-Left>\<Tab>", getreg(':')) + call feedkeys(":map <M-Left>\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal("\"map <M-Left>x", getreg(':')) + unmap ,f + unmap ,g + unmap <Left> + unmap <A-Left>x + + set cpo-=< cpo-=k + map <Left> left + call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <Left>', getreg(':')) + call feedkeys(":map <M\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal("\"map <M\<Tab>", getreg(':')) + call feedkeys(":map \<C-V>\<C-V><M\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal("\"map \<C-V><Middle>x", getreg(':')) + unmap <Left> + + " set cpo+=< + map <Left> left + exe "set t_k6=\<Esc>[17~" + call feedkeys(":map \<Esc>[17~x f6x\<CR>", 'xt') + call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <Left>', getreg(':')) + if !has('gui_running') + call feedkeys(":map \<Esc>[17~\<Tab>\<Home>\"\<CR>", 'xt') + " call assert_equal("\"map <F6>x", getreg(':')) + endif + unmap <Left> + call feedkeys(":unmap \<Esc>[17~x\<CR>", 'xt') + set cpo-=< + + set cpo+=B + map <Left> left + call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <Left>', getreg(':')) + unmap <Left> + set cpo-=B + + " set cpo+=k + map <Left> left + call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <Left>', getreg(':')) + 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() + hi Aardig ctermfg=green + " 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', @:) + call feedkeys(":match | chist\<Tab>\<C-B>\"\<CR>", 'xt') + call assert_equal('"match | chistory', @:) +endfunc + +func Test_highlight_completion() + hi Aardig ctermfg=green + " 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 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(':')) + call feedkeys(":hi li\<S-Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"hi link', getreg(':')) + call feedkeys(":hi d\<S-Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"hi default', getreg(':')) + call feedkeys(":hi c\<S-Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"hi clear', getreg(':')) + + " A cleared group does not show up in completions. + hi Anders ctermfg=green + call assert_equal(['Aardig', 'Anders'], getcompletion('A', 'highlight')) + hi clear Aardig + call assert_equal(['Anders'], getcompletion('A', 'highlight')) + hi clear Anders + call assert_equal([], getcompletion('A', 'highlight')) +endfunc + +func Test_getcompletion() + let groupcount = len(getcompletion('', 'event')) + call assert_true(groupcount > 0) + let matchcount = len('File'->getcompletion('event')) + call assert_true(matchcount > 0) + call assert_true(groupcount > matchcount) + + if has('menu') + source $VIMRUNTIME/menu.vim + let matchcount = len(getcompletion('', 'menu')) + call assert_true(matchcount > 0) + call assert_equal(['File.'], getcompletion('File', 'menu')) + 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') + call assert_true(index(l, 'v:null') >= 0) + let l = getcompletion('v:notexists', 'var') + call assert_equal([], l) + + 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') + call assert_true(index(l, 'END') >= 0) + let l = getcompletion('blahblah', 'augroup') + call assert_equal([], l) + + " let l = getcompletion('', 'behave') + " call assert_true(index(l, 'mswin') >= 0) + " let l = getcompletion('not', 'behave') + " call assert_equal([], l) + + let l = getcompletion('', 'color') + call assert_true(index(l, 'default') >= 0) + let l = getcompletion('dirty', 'color') + call assert_equal([], l) + + let l = getcompletion('', 'command') + call assert_true(index(l, 'sleep') >= 0) + let l = getcompletion('awake', 'command') + call assert_equal([], l) + + let l = getcompletion('', 'dir') + call assert_true(index(l, 'sautest/') >= 0) + let l = getcompletion('NoMatch', 'dir') + call assert_equal([], l) + + if glob('~/*') !=# '' + let l = getcompletion('~/', 'dir') + call assert_true(l[0][0] ==# '~') + endif + + let l = getcompletion('exe', 'expression') + call assert_true(index(l, 'executable(') >= 0) + let l = getcompletion('kill', 'expression') + call assert_equal([], l) + + let l = getcompletion('tag', 'function') + call assert_true(index(l, 'taglist(') >= 0) + let l = getcompletion('paint', 'function') + call assert_equal([], l) + + let Flambda = {-> 'hello'} + let l = getcompletion('', 'function') + let l = filter(l, {i, v -> v =~ 'lambda'}) + call assert_equal(0, len(l)) + + let l = getcompletion('run', 'file') + call assert_true(index(l, 'runtest.vim') >= 0) + let l = getcompletion('walk', 'file') + call assert_equal([], l) + set wildignore=*.vim + 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) + let l = getcompletion('horse', 'filetype') + call assert_equal([], l) + + let l = getcompletion('z', 'syntax') + call assert_true(index(l, 'zimbu') >= 0) + let l = getcompletion('emacs', 'syntax') + call assert_equal([], l) + + let l = getcompletion('jikes', 'compiler') + call assert_true(index(l, 'jikes') >= 0) + let l = getcompletion('break', 'compiler') + call assert_equal([], l) + + let l = getcompletion('last', 'help') + call assert_true(index(l, ':tablast') >= 0) + let l = getcompletion('giveup', 'help') + call assert_equal([], l) + + let l = getcompletion('time', 'option') + call assert_true(index(l, 'timeoutlen') >= 0) + let l = getcompletion('space', 'option') + call assert_equal([], l) + + let l = getcompletion('er', 'highlight') + call assert_true(index(l, 'ErrorMsg') >= 0) + let l = getcompletion('dark', 'highlight') + call assert_equal([], l) + + let l = getcompletion('', 'messages') + call assert_true(index(l, 'clear') >= 0) + let l = getcompletion('not', 'messages') + call assert_equal([], l) + + let l = getcompletion('', 'mapclear') + call assert_true(index(l, '<buffer>') >= 0) + let l = getcompletion('not', 'mapclear') + call assert_equal([], l) + + let l = getcompletion('.', 'shellcmd') + call assert_equal(['./', '../'], filter(l, 'v:val =~ "\\./"')) + call assert_equal(-1, match(l[2:], '^\.\.\?/$')) + let root = has('win32') ? 'C:\\' : '/' + let l = getcompletion(root, 'shellcmd') + let expected = map(filter(glob(root . '*', 0, 1), + \ 'isdirectory(v:val) || executable(v:val)'), 'isdirectory(v:val) ? v:val . ''/'' : v:val') + call assert_equal(expected, l) + + if has('cscope') + let l = getcompletion('', 'cscope') + let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show'] + call assert_equal(cmds, l) + " using cmdline completion must not change the result + call feedkeys(":cscope find \<c-d>\<c-c>", 'xt') + let l = getcompletion('', 'cscope') + call assert_equal(cmds, l) + let keys = ['a', 'c', 'd', 'e', 'f', 'g', 'i', 's', 't'] + let l = getcompletion('find ', 'cscope') + call assert_equal(keys, l) + endif + + if has('signs') + sign define Testing linehl=Comment + let l = getcompletion('', 'sign') + let cmds = ['define', 'jump', 'list', 'place', 'undefine', 'unplace'] + call assert_equal(cmds, l) + " using cmdline completion must not change the result + call feedkeys(":sign list \<c-d>\<c-c>", 'xt') + let l = getcompletion('', 'sign') + 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, 'samples/') >= 0) + let l = getcompletion('cd NoMatch', 'cmdline') + call assert_equal([], l) + let l = getcompletion('let v:n', 'cmdline') + call assert_true(index(l, 'v:null') >= 0) + let l = getcompletion('let v:notexists', 'cmdline') + call assert_equal([], l) + let l = getcompletion('call tag', 'cmdline') + call assert_true(index(l, 'taglist(') >= 0) + let l = getcompletion('call paint', 'cmdline') + call assert_equal([], l) + let l = getcompletion('autocmd BufEnter * map <bu', 'cmdline') + call assert_equal(['<buffer>'], l) + + func T(a, c, p) + let g:cmdline_compl_params = [a:a, a:c, a:p] + return "oneA\noneB\noneC" + endfunc + command -nargs=1 -complete=custom,T MyCmd + let l = getcompletion('MyCmd ', 'cmdline') + call assert_equal(['oneA', 'oneB', 'oneC'], l) + call assert_equal(['', 'MyCmd ', 6], g:cmdline_compl_params) + + delcommand MyCmd + delfunc T + unlet g:cmdline_compl_params + + " For others test if the name is recognized. + let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user'] + if has('cmdline_hist') + call add(names, 'history') + endif + if has('gettext') + call add(names, 'locale') + endif + if has('profile') + call add(names, 'syntime') + endif + + set tags=Xtags + call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", "word\tfile\tcmd"], 'Xtags') + + for name in names + let matchcount = len(getcompletion('', name)) + call assert_true(matchcount >= 0, 'No matches for ' . name) + endfor + + 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", [])', 'E1174:') +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 = { + \ '': '', + \ ':': '', + \ ':::': '', + \ ':::5': '', + \ 'not_a_cmd': '', + \ 'Check': '', + \ 'syntax': 'syntax', + \ ':syntax': 'syntax', + \ '::::syntax': 'syntax', + \ 'sy': 'syntax', + \ 'syn': 'syntax', + \ 'synt': 'syntax', + \ ':sy': 'syntax', + \ '::::sy': 'syntax', + \ 'match': 'match', + \ '2match': 'match', + \ '3match': 'match', + \ 'aboveleft': 'aboveleft', + \ 'abo': 'aboveleft', + \ 's': 'substitute', + \ '5s': 'substitute', + \ ':5s': 'substitute', + \ "'<,'>s": 'substitute', + \ ":'<,'>s": 'substitute', + \ 'CheckUni': 'CheckUnix', + \ 'CheckUnix': 'CheckUnix', + \ } + + for [in, want] in items(tests) + call assert_equal(want, fullcommand(in)) + endfor + call assert_equal('', fullcommand(v:_null_string)) + + call assert_equal('syntax', 'syn'->fullcommand()) + + command -buffer BufferLocalCommand : + command GlobalCommand : + call assert_equal('GlobalCommand', fullcommand('GlobalCom')) + call assert_equal('BufferLocalCommand', fullcommand('BufferL')) + delcommand BufferLocalCommand + delcommand GlobalCommand +endfunc + +func Test_shellcmd_completion() + let save_path = $PATH + + call mkdir('Xpathdir/Xpathsubdir', 'pR') + call writefile([''], 'Xpathdir/Xfile.exe') + call setfperm('Xpathdir/Xfile.exe', 'rwx------') + + " Set PATH to example directory without trailing slash. + let $PATH = getcwd() . '/Xpathdir' + + " Test for the ":!<TAB>" case. Previously, this would include subdirs of + " dirs in the PATH, even though they won't be executed. We check that only + " subdirs of the PWD and executables from the PATH are included in the + " suggestions. + let actual = getcompletion('X', 'shellcmd') + let expected = map(filter(glob('*', 0, 1), 'isdirectory(v:val) && v:val[0] == "X"'), 'v:val . "/"') + call insert(expected, 'Xfile.exe') + call assert_equal(expected, actual) + + let $PATH = save_path +endfunc + +func Test_expand_star_star() + call mkdir('a/b/c', 'pR') + call writefile(['asdfasdf'], 'a/b/c/fileXname') + call feedkeys(":find a/**/fileXname\<Tab>\<CR>", 'xt') + call assert_equal('find a/b/c/fileXname', @:) + bwipe! +endfunc + +func Test_cmdline_paste() + let @a = "def" + call feedkeys(":abc \<C-R>a ghi\<C-B>\"\<CR>", 'tx') + call assert_equal('"abc def ghi', @:) + + new + call setline(1, 'asdf.x /tmp/some verylongword a;b-c*d ') + + call feedkeys(":aaa \<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx') + call assert_equal('"aaa asdf bbb', @:) + + call feedkeys("ft:aaa \<C-R>\<C-F> bbb\<C-B>\"\<CR>", 'tx') + call assert_equal('"aaa /tmp/some bbb', @:) + + call feedkeys(":aaa \<C-R>\<C-L> bbb\<C-B>\"\<CR>", 'tx') + call assert_equal('"aaa '.getline(1).' bbb', @:) + + set incsearch + call feedkeys("fy:aaa veryl\<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx') + call assert_equal('"aaa verylongword bbb', @:) + + call feedkeys("f;:aaa \<C-R>\<C-A> bbb\<C-B>\"\<CR>", 'tx') + call assert_equal('"aaa a;b-c*d bbb', @:) + + call feedkeys(":\<C-\>etoupper(getline(1))\<CR>\<C-B>\"\<CR>", 'tx') + call assert_equal('"ASDF.X /TMP/SOME VERYLONGWORD A;B-C*D ', @:) + bwipe! + + " Error while typing a command used to cause that it was not executed + " in the end. + new + try + call feedkeys(":file \<C-R>%Xtestfile\<CR>", 'tx') + catch /^Vim\%((\a\+)\)\=:E32/ + " ignore error E32 + endtry + call assert_equal("Xtestfile", bufname("%")) + + " Try to paste an invalid register using <C-R> + call feedkeys(":\"one\<C-R>\<C-X>two\<CR>", 'xt') + call assert_equal('"onetwo', @:) + + " Test for pasting register containing CTRL-H using CTRL-R and CTRL-R CTRL-R + let @a = "xy\<C-H>z" + call feedkeys(":\"\<C-R>a\<CR>", 'xt') + call assert_equal('"xz', @:) + call feedkeys(":\"\<C-R>\<C-R>a\<CR>", 'xt') + call assert_equal("\"xy\<C-H>z", @:) + call feedkeys(":\"\<C-R>\<C-O>a\<CR>", 'xt') + call assert_equal("\"xy\<C-H>z", @:) + + " Test for pasting register containing CTRL-V using CTRL-R and CTRL-R CTRL-R + let @a = "xy\<C-V>z" + call feedkeys(":\"\<C-R>=@a\<CR>\<cr>", 'xt') + call assert_equal('"xyz', @:) + call feedkeys(":\"\<C-R>\<C-R>=@a\<CR>\<cr>", 'xt') + call assert_equal("\"xy\<C-V>z", @:) + + call assert_beeps('call feedkeys(":\<C-R>=\<C-R>=\<Esc>", "xt")') + + bwipe! +endfunc + +func Test_cmdline_remove_char() + let encoding_save = &encoding + + " for e in ['utf8', 'latin1'] + for e in ['utf8'] + exe 'set encoding=' . e + + call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx') + call assert_equal('"abc ef', @:, e) + + call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx') + call assert_equal('"abcdef', @:) + + call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx') + call assert_equal('"abc ghi', @:, e) + + call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx') + call assert_equal('"def', @:, e) + + " This was going before the start in latin1. + call feedkeys(": \<C-W>\<CR>", 'tx') + endfor + + let &encoding = encoding_save +endfunc + +func Test_cmdline_keymap_ctrl_hat() + if !has('keymap') + return + endif + + set keymap=esperanto + call feedkeys(":\"Jxauxdo \<C-^>Jxauxdo \<C-^>Jxauxdo\<CR>", 'tx') + call assert_equal('"Jxauxdo Ĵaŭdo Jxauxdo', @:) + set keymap= +endfunc + +func Test_illegal_address1() + new + 2;'( + 2;') + quit +endfunc + +func Test_illegal_address2() + call writefile(['c', 'x', ' x', '.', '1;y'], 'Xtest.vim') + new + source Xtest.vim + " Trigger calling validate_cursor() + diffsp Xtest.vim + quit! + bwipe! + call delete('Xtest.vim') +endfunc + +func Test_mark_from_line_zero() + " this was reading past the end of the first (empty) line + new + norm oxxxx + call assert_fails("0;'(", 'E20:') + bwipe! +endfunc + +func Test_cmdline_complete_wildoptions() + help + call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx') + let a = join(sort(split(@:)),' ') + set wildoptions=tagfile + call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx') + let b = join(sort(split(@:)),' ') + call assert_equal(a, b) + bw! +endfunc + +func Test_cmdline_complete_user_cmd() + command! -complete=color -nargs=1 Foo : + call feedkeys(":Foo \<Tab>\<Home>\"\<cr>", 'tx') + 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() + command FooBar echo 'global' + command -buffer FooBar echo 'local' + call feedkeys(":Foo\<C-A>\<Home>\"\<CR>", 'tx') + call assert_equal('"FooBar', @:) + + delcommand -buffer FooBar + delcommand FooBar +endfunc + +func s:ScriptLocalFunction() + echo 'yes' +endfunc + +func Test_cmdline_complete_user_func() + call feedkeys(":func Test_cmdline_complete_user\<Tab>\<Home>\"\<cr>", 'tx') + call assert_match('"func Test_cmdline_complete_user_', @:) + call feedkeys(":func s:ScriptL\<Tab>\<Home>\"\<cr>", 'tx') + call assert_match('"func <SNR>\d\+_ScriptLocalFunction', @:) + + " g: prefix also works + call feedkeys(":echo g:Test_cmdline_complete_user_f\<Tab>\<Home>\"\<cr>", 'tx') + call assert_match('"echo g:Test_cmdline_complete_user_func', @:) + + " using g: prefix does not result in just "g:" matches from a lambda + let Fx = { a -> a } + call feedkeys(":echo g:\<Tab>\<Home>\"\<cr>", 'tx') + call assert_match('"echo g:[A-Z]', @:) + + " existence of script-local dict function does not break user function name + " completion + function s:a_dict_func() dict + endfunction + call feedkeys(":call Test_cmdline_complete_user\<Tab>\<Home>\"\<cr>", 'tx') + call assert_match('"call Test_cmdline_complete_user_', @:) + delfunction s:a_dict_func +endfunc + +func Test_cmdline_complete_user_names() + if has('unix') && executable('whoami') + let whoami = systemlist('whoami')[0] + let first_letter = whoami[0] + if len(first_letter) > 0 + " Trying completion of :e ~x where x is the first letter of + " the user name should complete to at least the user name. + call feedkeys(':e ~' . first_letter . "\<c-a>\<c-B>\"\<cr>", 'tx') + call assert_match('^"e \~.*\<' . whoami . '\>', @:) + endif + endif + if has('win32') + " Just in case: check that the system has an Administrator account. + let names = system('net user') + if names =~ 'Administrator' + " Trying completion of :e ~A should complete to Administrator. + " There could be other names starting with "A" before Administrator. + call feedkeys(':e ~A' . "\<c-a>\<c-B>\"\<cr>", 'tx') + call assert_match('^"e \~.*Administrator', @:) + endif + endif +endfunc + +func Test_cmdline_complete_bang() + if executable('whoami') + call feedkeys(":!whoam\<C-A>\<C-B>\ |