xref: /vim-8.2.3635/src/testdir/test_cmdline.vim (revision 95bafa29)
1" Tests for editing the command line.
2
3func Test_complete_tab()
4  call writefile(['testfile'], 'Xtestfile')
5  call feedkeys(":e Xtest\t\r", "tx")
6  call assert_equal('testfile', getline(1))
7  call delete('Xtestfile')
8endfunc
9
10func Test_complete_list()
11  " We can't see the output, but at least we check the code runs properly.
12  call feedkeys(":e test\<C-D>\r", "tx")
13  call assert_equal('test', expand('%:t'))
14endfunc
15
16func Test_complete_wildmenu()
17  call writefile(['testfile1'], 'Xtestfile1')
18  call writefile(['testfile2'], 'Xtestfile2')
19  set wildmenu
20  call feedkeys(":e Xtest\t\t\r", "tx")
21  call assert_equal('testfile2', getline(1))
22
23  call delete('Xtestfile1')
24  call delete('Xtestfile2')
25  set nowildmenu
26endfunc
27
28func Test_map_completion()
29  if !has('cmdline_compl')
30    return
31  endif
32  call feedkeys(":map <unique> <si\<Tab>\<Home>\"\<CR>", 'xt')
33  call assert_equal('"map <unique> <silent>', getreg(':'))
34  call feedkeys(":map <script> <un\<Tab>\<Home>\"\<CR>", 'xt')
35  call assert_equal('"map <script> <unique>', getreg(':'))
36  call feedkeys(":map <expr> <sc\<Tab>\<Home>\"\<CR>", 'xt')
37  call assert_equal('"map <expr> <script>', getreg(':'))
38  call feedkeys(":map <buffer> <e\<Tab>\<Home>\"\<CR>", 'xt')
39  call assert_equal('"map <buffer> <expr>', getreg(':'))
40  call feedkeys(":map <nowait> <b\<Tab>\<Home>\"\<CR>", 'xt')
41  call assert_equal('"map <nowait> <buffer>', getreg(':'))
42  call feedkeys(":map <special> <no\<Tab>\<Home>\"\<CR>", 'xt')
43  call assert_equal('"map <special> <nowait>', getreg(':'))
44  call feedkeys(":map <silent> <sp\<Tab>\<Home>\"\<CR>", 'xt')
45  call assert_equal('"map <silent> <special>', getreg(':'))
46endfunc
47
48func Test_match_completion()
49  if !has('cmdline_compl')
50    return
51  endif
52  hi Aardig ctermfg=green
53  call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt')
54  call assert_equal('"match Aardig', getreg(':'))
55  call feedkeys(":match \<S-Tab>\<Home>\"\<CR>", 'xt')
56  call assert_equal('"match none', getreg(':'))
57endfunc
58
59func Test_highlight_completion()
60  if !has('cmdline_compl')
61    return
62  endif
63  hi Aardig ctermfg=green
64  call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt')
65  call assert_equal('"hi Aardig', getreg(':'))
66  call feedkeys(":hi default \<Tab>\<Home>\"\<CR>", 'xt')
67  call assert_equal('"hi default Aardig', getreg(':'))
68  call feedkeys(":hi clear Aa\<Tab>\<Home>\"\<CR>", 'xt')
69  call assert_equal('"hi clear Aardig', getreg(':'))
70  call feedkeys(":hi li\<S-Tab>\<Home>\"\<CR>", 'xt')
71  call assert_equal('"hi link', getreg(':'))
72  call feedkeys(":hi d\<S-Tab>\<Home>\"\<CR>", 'xt')
73  call assert_equal('"hi default', getreg(':'))
74  call feedkeys(":hi c\<S-Tab>\<Home>\"\<CR>", 'xt')
75  call assert_equal('"hi clear', getreg(':'))
76
77  " A cleared group does not show up in completions.
78  hi Anders ctermfg=green
79  call assert_equal(['Aardig', 'Anders'], getcompletion('A', 'highlight'))
80  hi clear Aardig
81  call assert_equal(['Anders'], getcompletion('A', 'highlight'))
82  hi clear Anders
83  call assert_equal([], getcompletion('A', 'highlight'))
84endfunc
85
86func Test_expr_completion()
87  if !has('cmdline_compl')
88    return
89  endif
90  for cmd in [
91	\ 'let a = ',
92	\ 'if',
93	\ 'elseif',
94	\ 'while',
95	\ 'for',
96	\ 'echo',
97	\ 'echon',
98	\ 'execute',
99	\ 'echomsg',
100	\ 'echoerr',
101	\ 'call',
102	\ 'return',
103	\ 'cexpr',
104	\ 'caddexpr',
105	\ 'cgetexpr',
106	\ 'lexpr',
107	\ 'laddexpr',
108	\ 'lgetexpr']
109    call feedkeys(":" . cmd . " getl\<Tab>\<Home>\"\<CR>", 'xt')
110    call assert_equal('"' . cmd . ' getline(', getreg(':'))
111  endfor
112endfunc
113
114func Test_getcompletion()
115  if !has('cmdline_compl')
116    return
117  endif
118  let groupcount = len(getcompletion('', 'event'))
119  call assert_true(groupcount > 0)
120  let matchcount = len(getcompletion('File', 'event'))
121  call assert_true(matchcount > 0)
122  call assert_true(groupcount > matchcount)
123
124  if has('menu')
125    source $VIMRUNTIME/menu.vim
126    let matchcount = len(getcompletion('', 'menu'))
127    call assert_true(matchcount > 0)
128    call assert_equal(['File.'], getcompletion('File', 'menu'))
129    call assert_true(matchcount > 0)
130    let matchcount = len(getcompletion('File.', 'menu'))
131    call assert_true(matchcount > 0)
132  endif
133
134  let l = getcompletion('v:n', 'var')
135  call assert_true(index(l, 'v:null') >= 0)
136  let l = getcompletion('v:notexists', 'var')
137  call assert_equal([], l)
138
139  args a.c b.c
140  let l = getcompletion('', 'arglist')
141  call assert_equal(['a.c', 'b.c'], l)
142  %argdelete
143
144  let l = getcompletion('', 'augroup')
145  call assert_true(index(l, 'END') >= 0)
146  let l = getcompletion('blahblah', 'augroup')
147  call assert_equal([], l)
148
149  let l = getcompletion('', 'behave')
150  call assert_true(index(l, 'mswin') >= 0)
151  let l = getcompletion('not', 'behave')
152  call assert_equal([], l)
153
154  let l = getcompletion('', 'color')
155  call assert_true(index(l, 'default') >= 0)
156  let l = getcompletion('dirty', 'color')
157  call assert_equal([], l)
158
159  let l = getcompletion('', 'command')
160  call assert_true(index(l, 'sleep') >= 0)
161  let l = getcompletion('awake', 'command')
162  call assert_equal([], l)
163
164  let l = getcompletion('', 'dir')
165  call assert_true(index(l, 'samples/') >= 0)
166  let l = getcompletion('NoMatch', 'dir')
167  call assert_equal([], l)
168
169  let l = getcompletion('exe', 'expression')
170  call assert_true(index(l, 'executable(') >= 0)
171  let l = getcompletion('kill', 'expression')
172  call assert_equal([], l)
173
174  let l = getcompletion('tag', 'function')
175  call assert_true(index(l, 'taglist(') >= 0)
176  let l = getcompletion('paint', 'function')
177  call assert_equal([], l)
178
179  let Flambda = {-> 'hello'}
180  let l = getcompletion('', 'function')
181  let l = filter(l, {i, v -> v =~ 'lambda'})
182  call assert_equal([], l)
183
184  let l = getcompletion('run', 'file')
185  call assert_true(index(l, 'runtest.vim') >= 0)
186  let l = getcompletion('walk', 'file')
187  call assert_equal([], l)
188  set wildignore=*.vim
189  let l = getcompletion('run', 'file', 1)
190  call assert_true(index(l, 'runtest.vim') < 0)
191  set wildignore&
192
193  let l = getcompletion('ha', 'filetype')
194  call assert_true(index(l, 'hamster') >= 0)
195  let l = getcompletion('horse', 'filetype')
196  call assert_equal([], l)
197
198  let l = getcompletion('z', 'syntax')
199  call assert_true(index(l, 'zimbu') >= 0)
200  let l = getcompletion('emacs', 'syntax')
201  call assert_equal([], l)
202
203  let l = getcompletion('jikes', 'compiler')
204  call assert_true(index(l, 'jikes') >= 0)
205  let l = getcompletion('break', 'compiler')
206  call assert_equal([], l)
207
208  let l = getcompletion('last', 'help')
209  call assert_true(index(l, ':tablast') >= 0)
210  let l = getcompletion('giveup', 'help')
211  call assert_equal([], l)
212
213  let l = getcompletion('time', 'option')
214  call assert_true(index(l, 'timeoutlen') >= 0)
215  let l = getcompletion('space', 'option')
216  call assert_equal([], l)
217
218  let l = getcompletion('er', 'highlight')
219  call assert_true(index(l, 'ErrorMsg') >= 0)
220  let l = getcompletion('dark', 'highlight')
221  call assert_equal([], l)
222
223  let l = getcompletion('', 'messages')
224  call assert_true(index(l, 'clear') >= 0)
225  let l = getcompletion('not', 'messages')
226  call assert_equal([], l)
227
228  let l = getcompletion('', 'mapclear')
229  call assert_true(index(l, '<buffer>') >= 0)
230  let l = getcompletion('not', 'mapclear')
231  call assert_equal([], l)
232
233  let l = getcompletion('.', 'shellcmd')
234  call assert_equal(['./', '../'], filter(l, 'v:val =~ "\\./"'))
235  call assert_equal(-1, match(l[2:], '^\.\.\?/$'))
236  let root = has('win32') ? 'C:\\' : '/'
237  let l = getcompletion(root, 'shellcmd')
238  let expected = map(filter(glob(root . '*', 0, 1),
239        \ 'isdirectory(v:val) || executable(v:val)'), 'isdirectory(v:val) ? v:val . ''/'' : v:val')
240  call assert_equal(expected, l)
241
242  if has('cscope')
243    let l = getcompletion('', 'cscope')
244    let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show']
245    call assert_equal(cmds, l)
246    " using cmdline completion must not change the result
247    call feedkeys(":cscope find \<c-d>\<c-c>", 'xt')
248    let l = getcompletion('', 'cscope')
249    call assert_equal(cmds, l)
250    let keys = ['a', 'c', 'd', 'e', 'f', 'g', 'i', 's', 't']
251    let l = getcompletion('find ', 'cscope')
252    call assert_equal(keys, l)
253  endif
254
255  if has('signs')
256    sign define Testing linehl=Comment
257    let l = getcompletion('', 'sign')
258    let cmds = ['define', 'jump', 'list', 'place', 'undefine', 'unplace']
259    call assert_equal(cmds, l)
260    " using cmdline completion must not change the result
261    call feedkeys(":sign list \<c-d>\<c-c>", 'xt')
262    let l = getcompletion('', 'sign')
263    call assert_equal(cmds, l)
264    let l = getcompletion('list ', 'sign')
265    call assert_equal(['Testing'], l)
266  endif
267
268  " For others test if the name is recognized.
269  let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user']
270  if has('cmdline_hist')
271    call add(names, 'history')
272  endif
273  if has('gettext')
274    call add(names, 'locale')
275  endif
276  if has('profile')
277    call add(names, 'syntime')
278  endif
279
280  set tags=Xtags
281  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", "word\tfile\tcmd"], 'Xtags')
282
283  for name in names
284    let matchcount = len(getcompletion('', name))
285    call assert_true(matchcount >= 0, 'No matches for ' . name)
286  endfor
287
288  call delete('Xtags')
289
290  call assert_fails('call getcompletion("", "burp")', 'E475:')
291endfunc
292
293func Test_shellcmd_completion()
294  let save_path = $PATH
295
296  call mkdir('Xpathdir/Xpathsubdir', 'p')
297  call writefile([''], 'Xpathdir/Xfile.exe')
298  call setfperm('Xpathdir/Xfile.exe', 'rwx------')
299
300  " Set PATH to example directory without trailing slash.
301  let $PATH = getcwd() . '/Xpathdir'
302
303  " Test for the ":!<TAB>" case.  Previously, this would include subdirs of
304  " dirs in the PATH, even though they won't be executed.  We check that only
305  " subdirs of the PWD and executables from the PATH are included in the
306  " suggestions.
307  let actual = getcompletion('X', 'shellcmd')
308  let expected = map(filter(glob('*', 0, 1), 'isdirectory(v:val) && v:val[0] == "X"'), 'v:val . "/"')
309  call insert(expected, 'Xfile.exe')
310  call assert_equal(expected, actual)
311
312  call delete('Xpathdir', 'rf')
313  let $PATH = save_path
314endfunc
315
316func Test_expand_star_star()
317  call mkdir('a/b', 'p')
318  call writefile(['asdfasdf'], 'a/b/fileXname')
319  call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt')
320  call assert_equal('find a/b/fileXname', getreg(':'))
321  bwipe!
322  call delete('a', 'rf')
323endfunc
324
325func Test_paste_in_cmdline()
326  let @a = "def"
327  call feedkeys(":abc \<C-R>a ghi\<C-B>\"\<CR>", 'tx')
328  call assert_equal('"abc def ghi', @:)
329
330  new
331  call setline(1, 'asdf.x /tmp/some verylongword a;b-c*d ')
332
333  call feedkeys(":aaa \<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
334  call assert_equal('"aaa asdf bbb', @:)
335
336  call feedkeys("ft:aaa \<C-R>\<C-F> bbb\<C-B>\"\<CR>", 'tx')
337  call assert_equal('"aaa /tmp/some bbb', @:)
338
339  call feedkeys(":aaa \<C-R>\<C-L> bbb\<C-B>\"\<CR>", 'tx')
340  call assert_equal('"aaa '.getline(1).' bbb', @:)
341
342  set incsearch
343  call feedkeys("fy:aaa veryl\<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
344  call assert_equal('"aaa verylongword bbb', @:)
345
346  call feedkeys("f;:aaa \<C-R>\<C-A> bbb\<C-B>\"\<CR>", 'tx')
347  call assert_equal('"aaa a;b-c*d bbb', @:)
348
349  call feedkeys(":\<C-\>etoupper(getline(1))\<CR>\<C-B>\"\<CR>", 'tx')
350  call assert_equal('"ASDF.X /TMP/SOME VERYLONGWORD A;B-C*D ', @:)
351  bwipe!
352
353  " Error while typing a command used to cause that it was not executed
354  " in the end.
355  new
356  try
357    call feedkeys(":file \<C-R>%Xtestfile\<CR>", 'tx')
358  catch /^Vim\%((\a\+)\)\=:E32/
359    " ignore error E32
360  endtry
361  call assert_equal("Xtestfile", bufname("%"))
362  bwipe!
363endfunc
364
365func Test_remove_char_in_cmdline()
366  call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx')
367  call assert_equal('"abc ef', @:)
368
369  call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx')
370  call assert_equal('"abcdef', @:)
371
372  call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx')
373  call assert_equal('"abc ghi', @:)
374
375  call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx')
376  call assert_equal('"def', @:)
377endfunc
378
379func Test_illegal_address1()
380  new
381  2;'(
382  2;')
383  quit
384endfunc
385
386func Test_illegal_address2()
387  call writefile(['c', 'x', '  x', '.', '1;y'], 'Xtest.vim')
388  new
389  source Xtest.vim
390  " Trigger calling validate_cursor()
391  diffsp Xtest.vim
392  quit!
393  bwipe!
394  call delete('Xtest.vim')
395endfunc
396
397func Test_cmdline_complete_wildoptions()
398  help
399  call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
400  let a = join(sort(split(@:)),' ')
401  set wildoptions=tagfile
402  call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
403  let b = join(sort(split(@:)),' ')
404  call assert_equal(a, b)
405  bw!
406endfunc
407
408func Test_cmdline_complete_user_cmd()
409  command! -complete=color -nargs=1 Foo :
410  call feedkeys(":Foo \<Tab>\<Home>\"\<cr>", 'tx')
411  call assert_equal('"Foo blue', @:)
412  call feedkeys(":Foo b\<Tab>\<Home>\"\<cr>", 'tx')
413  call assert_equal('"Foo blue', @:)
414  delcommand Foo
415endfunc
416
417func Test_cmdline_complete_user_names()
418  if has('unix') && executable('whoami')
419    let whoami = systemlist('whoami')[0]
420    let first_letter = whoami[0]
421    if len(first_letter) > 0
422      " Trying completion of  :e ~x  where x is the first letter of
423      " the user name should complete to at least the user name.
424      call feedkeys(':e ~' . first_letter . "\<c-a>\<c-B>\"\<cr>", 'tx')
425      call assert_match('^"e \~.*\<' . whoami . '\>', @:)
426    endif
427  endif
428  if has('win32')
429    " Just in case: check that the system has an Administrator account.
430    let names = system('net user')
431    if names =~ 'Administrator'
432      " Trying completion of  :e ~A  should complete to Administrator.
433      call feedkeys(':e ~A' . "\<c-a>\<c-B>\"\<cr>", 'tx')
434      call assert_match('^"e \~Administrator', @:)
435    endif
436  endif
437endfunc
438
439funct Test_cmdline_complete_languages()
440  let lang = substitute(execute('language messages'), '.*"\(.*\)"$', '\1', '')
441
442  call feedkeys(":language \<c-a>\<c-b>\"\<cr>", 'tx')
443  call assert_match('^"language .*\<ctype\>.*\<messages\>.*\<time\>', @:)
444
445  if has('unix')
446    " TODO: these tests don't work on Windows. lang appears to be 'C'
447    " but C does not appear in the completion. Why?
448    call assert_match('^"language .*\<' . lang . '\>', @:)
449
450    call feedkeys(":language messages \<c-a>\<c-b>\"\<cr>", 'tx')
451    call assert_match('^"language .*\<' . lang . '\>', @:)
452
453    call feedkeys(":language ctype \<c-a>\<c-b>\"\<cr>", 'tx')
454    call assert_match('^"language .*\<' . lang . '\>', @:)
455
456    call feedkeys(":language time \<c-a>\<c-b>\"\<cr>", 'tx')
457    call assert_match('^"language .*\<' . lang . '\>', @:)
458  endif
459endfunc
460
461func Test_cmdline_write_alternatefile()
462  new
463  call setline('.', ['one', 'two'])
464  f foo.txt
465  new
466  f #-A
467  call assert_equal('foo.txt-A', expand('%'))
468  f #<-B.txt
469  call assert_equal('foo-B.txt', expand('%'))
470  f %<
471  call assert_equal('foo-B', expand('%'))
472  new
473  call assert_fails('f #<', 'E95')
474  bw!
475  f foo-B.txt
476  f %<-A
477  call assert_equal('foo-B-A', expand('%'))
478  bw!
479  bw!
480endfunc
481
482" using a leading backslash here
483set cpo+=C
484
485func Test_cmdline_search_range()
486  new
487  call setline(1, ['a', 'b', 'c', 'd'])
488  /d
489  1,\/s/b/B/
490  call assert_equal('B', getline(2))
491
492  /a
493  $
494  \?,4s/c/C/
495  call assert_equal('C', getline(3))
496
497  call setline(1, ['a', 'b', 'c', 'd'])
498  %s/c/c/
499  1,\&s/b/B/
500  call assert_equal('B', getline(2))
501
502  bwipe!
503endfunc
504
505" Tests for getcmdline(), getcmdpos() and getcmdtype()
506func Check_cmdline(cmdtype)
507  call assert_equal('MyCmd a', getcmdline())
508  call assert_equal(8, getcmdpos())
509  call assert_equal(a:cmdtype, getcmdtype())
510  return ''
511endfunc
512
513func Test_getcmdtype()
514  call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt")
515
516  let cmdtype = ''
517  debuggreedy
518  call feedkeys(":debug echo 'test'\<CR>", "t")
519  call feedkeys("let cmdtype = \<C-R>=string(getcmdtype())\<CR>\<CR>", "t")
520  call feedkeys("cont\<CR>", "xt")
521  0debuggreedy
522  call assert_equal('>', cmdtype)
523
524  call feedkeys("/MyCmd a\<C-R>=Check_cmdline('/')\<CR>\<Esc>", "xt")
525  call feedkeys("?MyCmd a\<C-R>=Check_cmdline('?')\<CR>\<Esc>", "xt")
526
527  call feedkeys(":call input('Answer?')\<CR>", "t")
528  call feedkeys("MyCmd a\<C-R>=Check_cmdline('@')\<CR>\<C-C>", "xt")
529
530  call feedkeys(":insert\<CR>MyCmd a\<C-R>=Check_cmdline('-')\<CR>\<Esc>", "xt")
531
532  cnoremap <expr> <F6> Check_cmdline('=')
533  call feedkeys("a\<C-R>=MyCmd a\<F6>\<Esc>\<Esc>", "xt")
534  cunmap <F6>
535endfunc
536
537func Test_getcmdwintype()
538  call feedkeys("q/:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
539  call assert_equal('/', a)
540
541  call feedkeys("q?:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
542  call assert_equal('?', a)
543
544  call feedkeys("q::let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
545  call assert_equal(':', a)
546
547  call feedkeys(":\<C-F>:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
548  call assert_equal(':', a)
549
550  call assert_equal('', getcmdwintype())
551endfunc
552
553func Test_verbosefile()
554  set verbosefile=Xlog
555  echomsg 'foo'
556  echomsg 'bar'
557  set verbosefile=
558  let log = readfile('Xlog')
559  call assert_match("foo\nbar", join(log, "\n"))
560  call delete('Xlog')
561endfunc
562
563func Test_setcmdpos()
564  func InsertTextAtPos(text, pos)
565    call assert_equal(0, setcmdpos(a:pos))
566    return a:text
567  endfunc
568
569  " setcmdpos() with position in the middle of the command line.
570  call feedkeys(":\"12\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
571  call assert_equal('"1ab2', @:)
572
573  call feedkeys(":\"12\<C-R>\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
574  call assert_equal('"1b2a', @:)
575
576  " setcmdpos() with position beyond the end of the command line.
577  call feedkeys(":\"12\<C-B>\<C-R>=InsertTextAtPos('a', 10)\<CR>b\<CR>", 'xt')
578  call assert_equal('"12ab', @:)
579
580  " setcmdpos() returns 1 when not editing the command line.
581  call assert_equal(1, setcmdpos(3))
582endfunc
583
584set cpo&
585