xref: /vim-8.2.3635/src/testdir/test_cmdline.vim (revision 95a9dd1e)
1" Tests for editing the command line.
2
3source check.vim
4source screendump.vim
5
6func Test_complete_tab()
7  call writefile(['testfile'], 'Xtestfile')
8  call feedkeys(":e Xtest\t\r", "tx")
9  call assert_equal('testfile', getline(1))
10  call delete('Xtestfile')
11endfunc
12
13func Test_complete_list()
14  " We can't see the output, but at least we check the code runs properly.
15  call feedkeys(":e test\<C-D>\r", "tx")
16  call assert_equal('test', expand('%:t'))
17endfunc
18
19func Test_complete_wildmenu()
20  call mkdir('Xdir1/Xdir2', 'p')
21  call writefile(['testfile1'], 'Xdir1/Xtestfile1')
22  call writefile(['testfile2'], 'Xdir1/Xtestfile2')
23  call writefile(['testfile3'], 'Xdir1/Xdir2/Xtestfile3')
24  call writefile(['testfile3'], 'Xdir1/Xdir2/Xtestfile4')
25  set wildmenu
26
27  " Pressing <Tab> completes, and moves to next files when pressing again.
28  call feedkeys(":e Xdir1/\<Tab>\<Tab>\<CR>", 'tx')
29  call assert_equal('testfile1', getline(1))
30  call feedkeys(":e Xdir1/\<Tab>\<Tab>\<Tab>\<CR>", 'tx')
31  call assert_equal('testfile2', getline(1))
32
33  " <S-Tab> is like <Tab> but begin with the last match and then go to
34  " previous.
35  call feedkeys(":e Xdir1/Xtest\<S-Tab>\<CR>", 'tx')
36  call assert_equal('testfile2', getline(1))
37  call feedkeys(":e Xdir1/Xtest\<S-Tab>\<S-Tab>\<CR>", 'tx')
38  call assert_equal('testfile1', getline(1))
39
40  " <Left>/<Right> to move to previous/next file.
41  call feedkeys(":e Xdir1/\<Tab>\<Right>\<CR>", 'tx')
42  call assert_equal('testfile1', getline(1))
43  call feedkeys(":e Xdir1/\<Tab>\<Right>\<Right>\<CR>", 'tx')
44  call assert_equal('testfile2', getline(1))
45  call feedkeys(":e Xdir1/\<Tab>\<Right>\<Right>\<Left>\<CR>", 'tx')
46  call assert_equal('testfile1', getline(1))
47
48  " <Up>/<Down> to go up/down directories.
49  call feedkeys(":e Xdir1/\<Tab>\<Down>\<CR>", 'tx')
50  call assert_equal('testfile3', getline(1))
51  call feedkeys(":e Xdir1/\<Tab>\<Down>\<Up>\<Right>\<CR>", 'tx')
52  call assert_equal('testfile1', getline(1))
53
54  " cleanup
55  %bwipe
56  call delete('Xdir1/Xdir2/Xtestfile4')
57  call delete('Xdir1/Xdir2/Xtestfile3')
58  call delete('Xdir1/Xtestfile2')
59  call delete('Xdir1/Xtestfile1')
60  call delete('Xdir1/Xdir2', 'd')
61  call delete('Xdir1', 'd')
62  set nowildmenu
63endfunc
64
65func Test_map_completion()
66  if !has('cmdline_compl')
67    return
68  endif
69  call feedkeys(":map <unique> <si\<Tab>\<Home>\"\<CR>", 'xt')
70  call assert_equal('"map <unique> <silent>', getreg(':'))
71  call feedkeys(":map <script> <un\<Tab>\<Home>\"\<CR>", 'xt')
72  call assert_equal('"map <script> <unique>', getreg(':'))
73  call feedkeys(":map <expr> <sc\<Tab>\<Home>\"\<CR>", 'xt')
74  call assert_equal('"map <expr> <script>', getreg(':'))
75  call feedkeys(":map <buffer> <e\<Tab>\<Home>\"\<CR>", 'xt')
76  call assert_equal('"map <buffer> <expr>', getreg(':'))
77  call feedkeys(":map <nowait> <b\<Tab>\<Home>\"\<CR>", 'xt')
78  call assert_equal('"map <nowait> <buffer>', getreg(':'))
79  call feedkeys(":map <special> <no\<Tab>\<Home>\"\<CR>", 'xt')
80  call assert_equal('"map <special> <nowait>', getreg(':'))
81  call feedkeys(":map <silent> <sp\<Tab>\<Home>\"\<CR>", 'xt')
82  call assert_equal('"map <silent> <special>', getreg(':'))
83
84  map <Middle>x middle
85
86  map ,f commaf
87  map ,g commaf
88  map <Left> left
89  map <A-Left>x shiftleft
90  call feedkeys(":map ,\<Tab>\<Home>\"\<CR>", 'xt')
91  call assert_equal('"map ,f', getreg(':'))
92  call feedkeys(":map ,\<Tab>\<Tab>\<Home>\"\<CR>", 'xt')
93  call assert_equal('"map ,g', getreg(':'))
94  call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt')
95  call assert_equal('"map <Left>', getreg(':'))
96  call feedkeys(":map <A-Left>\<Tab>\<Home>\"\<CR>", 'xt')
97  call assert_equal("\"map <A-Left>\<Tab>", getreg(':'))
98  unmap ,f
99  unmap ,g
100  unmap <Left>
101  unmap <A-Left>x
102
103  set cpo-=< cpo-=B cpo-=k
104  map <Left> left
105  call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt')
106  call assert_equal('"map <Left>', getreg(':'))
107  call feedkeys(":map <M\<Tab>\<Home>\"\<CR>", 'xt')
108  call assert_equal("\"map <M\<Tab>", getreg(':'))
109  unmap <Left>
110
111  set cpo+=<
112  map <Left> left
113  exe "set t_k6=\<Esc>[17~"
114  call feedkeys(":map \<Esc>[17~x f6x\<CR>", 'xt')
115  call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt')
116  call assert_equal('"map <Left>', getreg(':'))
117  if !has('gui_running')
118    call feedkeys(":map \<Esc>[17~\<Tab>\<Home>\"\<CR>", 'xt')
119    call assert_equal("\"map <F6>x", getreg(':'))
120  endif
121  unmap <Left>
122  call feedkeys(":unmap \<Esc>[17~x\<CR>", 'xt')
123  set cpo-=<
124
125  set cpo+=B
126  map <Left> left
127  call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt')
128  call assert_equal('"map <Left>', getreg(':'))
129  unmap <Left>
130  set cpo-=B
131
132  set cpo+=k
133  map <Left> left
134  call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt')
135  call assert_equal('"map <Left>', getreg(':'))
136  unmap <Left>
137  set cpo-=k
138
139  unmap <Middle>x
140  set cpo&vim
141endfunc
142
143func Test_match_completion()
144  if !has('cmdline_compl')
145    return
146  endif
147  hi Aardig ctermfg=green
148  call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt')
149  call assert_equal('"match Aardig', getreg(':'))
150  call feedkeys(":match \<S-Tab>\<Home>\"\<CR>", 'xt')
151  call assert_equal('"match none', getreg(':'))
152endfunc
153
154func Test_highlight_completion()
155  if !has('cmdline_compl')
156    return
157  endif
158  hi Aardig ctermfg=green
159  call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt')
160  call assert_equal('"hi Aardig', getreg(':'))
161  call feedkeys(":hi default \<Tab>\<Home>\"\<CR>", 'xt')
162  call assert_equal('"hi default Aardig', getreg(':'))
163  call feedkeys(":hi clear Aa\<Tab>\<Home>\"\<CR>", 'xt')
164  call assert_equal('"hi clear Aardig', getreg(':'))
165  call feedkeys(":hi li\<S-Tab>\<Home>\"\<CR>", 'xt')
166  call assert_equal('"hi link', getreg(':'))
167  call feedkeys(":hi d\<S-Tab>\<Home>\"\<CR>", 'xt')
168  call assert_equal('"hi default', getreg(':'))
169  call feedkeys(":hi c\<S-Tab>\<Home>\"\<CR>", 'xt')
170  call assert_equal('"hi clear', getreg(':'))
171
172  " A cleared group does not show up in completions.
173  hi Anders ctermfg=green
174  call assert_equal(['Aardig', 'Anders'], getcompletion('A', 'highlight'))
175  hi clear Aardig
176  call assert_equal(['Anders'], getcompletion('A', 'highlight'))
177  hi clear Anders
178  call assert_equal([], getcompletion('A', 'highlight'))
179endfunc
180
181func Test_expr_completion()
182  if !has('cmdline_compl')
183    return
184  endif
185  for cmd in [
186	\ 'let a = ',
187	\ 'const a = ',
188	\ 'if',
189	\ 'elseif',
190	\ 'while',
191	\ 'for',
192	\ 'echo',
193	\ 'echon',
194	\ 'execute',
195	\ 'echomsg',
196	\ 'echoerr',
197	\ 'call',
198	\ 'return',
199	\ 'cexpr',
200	\ 'caddexpr',
201	\ 'cgetexpr',
202	\ 'lexpr',
203	\ 'laddexpr',
204	\ 'lgetexpr']
205    call feedkeys(":" . cmd . " getl\<Tab>\<Home>\"\<CR>", 'xt')
206    call assert_equal('"' . cmd . ' getline(', getreg(':'))
207  endfor
208endfunc
209
210func Test_getcompletion()
211  if !has('cmdline_compl')
212    return
213  endif
214  let groupcount = len(getcompletion('', 'event'))
215  call assert_true(groupcount > 0)
216  let matchcount = len('File'->getcompletion('event'))
217  call assert_true(matchcount > 0)
218  call assert_true(groupcount > matchcount)
219
220  if has('menu')
221    source $VIMRUNTIME/menu.vim
222    let matchcount = len(getcompletion('', 'menu'))
223    call assert_true(matchcount > 0)
224    call assert_equal(['File.'], getcompletion('File', 'menu'))
225    call assert_true(matchcount > 0)
226    let matchcount = len(getcompletion('File.', 'menu'))
227    call assert_true(matchcount > 0)
228  endif
229
230  let l = getcompletion('v:n', 'var')
231  call assert_true(index(l, 'v:null') >= 0)
232  let l = getcompletion('v:notexists', 'var')
233  call assert_equal([], l)
234
235  args a.c b.c
236  let l = getcompletion('', 'arglist')
237  call assert_equal(['a.c', 'b.c'], l)
238  %argdelete
239
240  let l = getcompletion('', 'augroup')
241  call assert_true(index(l, 'END') >= 0)
242  let l = getcompletion('blahblah', 'augroup')
243  call assert_equal([], l)
244
245  let l = getcompletion('', 'behave')
246  call assert_true(index(l, 'mswin') >= 0)
247  let l = getcompletion('not', 'behave')
248  call assert_equal([], l)
249
250  let l = getcompletion('', 'color')
251  call assert_true(index(l, 'default') >= 0)
252  let l = getcompletion('dirty', 'color')
253  call assert_equal([], l)
254
255  let l = getcompletion('', 'command')
256  call assert_true(index(l, 'sleep') >= 0)
257  let l = getcompletion('awake', 'command')
258  call assert_equal([], l)
259
260  let l = getcompletion('', 'dir')
261  call assert_true(index(l, 'samples/') >= 0)
262  let l = getcompletion('NoMatch', 'dir')
263  call assert_equal([], l)
264
265  let l = getcompletion('exe', 'expression')
266  call assert_true(index(l, 'executable(') >= 0)
267  let l = getcompletion('kill', 'expression')
268  call assert_equal([], l)
269
270  let l = getcompletion('tag', 'function')
271  call assert_true(index(l, 'taglist(') >= 0)
272  let l = getcompletion('paint', 'function')
273  call assert_equal([], l)
274
275  let Flambda = {-> 'hello'}
276  let l = getcompletion('', 'function')
277  let l = filter(l, {i, v -> v =~ 'lambda'})
278  call assert_equal([], l)
279
280  let l = getcompletion('run', 'file')
281  call assert_true(index(l, 'runtest.vim') >= 0)
282  let l = getcompletion('walk', 'file')
283  call assert_equal([], l)
284  set wildignore=*.vim
285  let l = getcompletion('run', 'file', 1)
286  call assert_true(index(l, 'runtest.vim') < 0)
287  set wildignore&
288
289  let l = getcompletion('ha', 'filetype')
290  call assert_true(index(l, 'hamster') >= 0)
291  let l = getcompletion('horse', 'filetype')
292  call assert_equal([], l)
293
294  let l = getcompletion('z', 'syntax')
295  call assert_true(index(l, 'zimbu') >= 0)
296  let l = getcompletion('emacs', 'syntax')
297  call assert_equal([], l)
298
299  let l = getcompletion('jikes', 'compiler')
300  call assert_true(index(l, 'jikes') >= 0)
301  let l = getcompletion('break', 'compiler')
302  call assert_equal([], l)
303
304  let l = getcompletion('last', 'help')
305  call assert_true(index(l, ':tablast') >= 0)
306  let l = getcompletion('giveup', 'help')
307  call assert_equal([], l)
308
309  let l = getcompletion('time', 'option')
310  call assert_true(index(l, 'timeoutlen') >= 0)
311  let l = getcompletion('space', 'option')
312  call assert_equal([], l)
313
314  let l = getcompletion('er', 'highlight')
315  call assert_true(index(l, 'ErrorMsg') >= 0)
316  let l = getcompletion('dark', 'highlight')
317  call assert_equal([], l)
318
319  let l = getcompletion('', 'messages')
320  call assert_true(index(l, 'clear') >= 0)
321  let l = getcompletion('not', 'messages')
322  call assert_equal([], l)
323
324  let l = getcompletion('', 'mapclear')
325  call assert_true(index(l, '<buffer>') >= 0)
326  let l = getcompletion('not', 'mapclear')
327  call assert_equal([], l)
328
329  let l = getcompletion('.', 'shellcmd')
330  call assert_equal(['./', '../'], filter(l, 'v:val =~ "\\./"'))
331  call assert_equal(-1, match(l[2:], '^\.\.\?/$'))
332  let root = has('win32') ? 'C:\\' : '/'
333  let l = getcompletion(root, 'shellcmd')
334  let expected = map(filter(glob(root . '*', 0, 1),
335        \ 'isdirectory(v:val) || executable(v:val)'), 'isdirectory(v:val) ? v:val . ''/'' : v:val')
336  call assert_equal(expected, l)
337
338  if has('cscope')
339    let l = getcompletion('', 'cscope')
340    let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show']
341    call assert_equal(cmds, l)
342    " using cmdline completion must not change the result
343    call feedkeys(":cscope find \<c-d>\<c-c>", 'xt')
344    let l = getcompletion('', 'cscope')
345    call assert_equal(cmds, l)
346    let keys = ['a', 'c', 'd', 'e', 'f', 'g', 'i', 's', 't']
347    let l = getcompletion('find ', 'cscope')
348    call assert_equal(keys, l)
349  endif
350
351  if has('signs')
352    sign define Testing linehl=Comment
353    let l = getcompletion('', 'sign')
354    let cmds = ['define', 'jump', 'list', 'place', 'undefine', 'unplace']
355    call assert_equal(cmds, l)
356    " using cmdline completion must not change the result
357    call feedkeys(":sign list \<c-d>\<c-c>", 'xt')
358    let l = getcompletion('', 'sign')
359    call assert_equal(cmds, l)
360    let l = getcompletion('list ', 'sign')
361    call assert_equal(['Testing'], l)
362  endif
363
364  " For others test if the name is recognized.
365  let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user']
366  if has('cmdline_hist')
367    call add(names, 'history')
368  endif
369  if has('gettext')
370    call add(names, 'locale')
371  endif
372  if has('profile')
373    call add(names, 'syntime')
374  endif
375
376  set tags=Xtags
377  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", "word\tfile\tcmd"], 'Xtags')
378
379  for name in names
380    let matchcount = len(getcompletion('', name))
381    call assert_true(matchcount >= 0, 'No matches for ' . name)
382  endfor
383
384  call delete('Xtags')
385  set tags&
386
387  call assert_fails('call getcompletion("", "burp")', 'E475:')
388endfunc
389
390func Test_shellcmd_completion()
391  let save_path = $PATH
392
393  call mkdir('Xpathdir/Xpathsubdir', 'p')
394  call writefile([''], 'Xpathdir/Xfile.exe')
395  call setfperm('Xpathdir/Xfile.exe', 'rwx------')
396
397  " Set PATH to example directory without trailing slash.
398  let $PATH = getcwd() . '/Xpathdir'
399
400  " Test for the ":!<TAB>" case.  Previously, this would include subdirs of
401  " dirs in the PATH, even though they won't be executed.  We check that only
402  " subdirs of the PWD and executables from the PATH are included in the
403  " suggestions.
404  let actual = getcompletion('X', 'shellcmd')
405  let expected = map(filter(glob('*', 0, 1), 'isdirectory(v:val) && v:val[0] == "X"'), 'v:val . "/"')
406  call insert(expected, 'Xfile.exe')
407  call assert_equal(expected, actual)
408
409  call delete('Xpathdir', 'rf')
410  let $PATH = save_path
411endfunc
412
413func Test_expand_star_star()
414  call mkdir('a/b', 'p')
415  call writefile(['asdfasdf'], 'a/b/fileXname')
416  call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt')
417  call assert_equal('find a/b/fileXname', getreg(':'))
418  bwipe!
419  call delete('a', 'rf')
420endfunc
421
422func Test_cmdline_paste()
423  let @a = "def"
424  call feedkeys(":abc \<C-R>a ghi\<C-B>\"\<CR>", 'tx')
425  call assert_equal('"abc def ghi', @:)
426
427  new
428  call setline(1, 'asdf.x /tmp/some verylongword a;b-c*d ')
429
430  call feedkeys(":aaa \<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
431  call assert_equal('"aaa asdf bbb', @:)
432
433  call feedkeys("ft:aaa \<C-R>\<C-F> bbb\<C-B>\"\<CR>", 'tx')
434  call assert_equal('"aaa /tmp/some bbb', @:)
435
436  call feedkeys(":aaa \<C-R>\<C-L> bbb\<C-B>\"\<CR>", 'tx')
437  call assert_equal('"aaa '.getline(1).' bbb', @:)
438
439  set incsearch
440  call feedkeys("fy:aaa veryl\<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
441  call assert_equal('"aaa verylongword bbb', @:)
442
443  call feedkeys("f;:aaa \<C-R>\<C-A> bbb\<C-B>\"\<CR>", 'tx')
444  call assert_equal('"aaa a;b-c*d bbb', @:)
445
446  call feedkeys(":\<C-\>etoupper(getline(1))\<CR>\<C-B>\"\<CR>", 'tx')
447  call assert_equal('"ASDF.X /TMP/SOME VERYLONGWORD A;B-C*D ', @:)
448  bwipe!
449
450  " Error while typing a command used to cause that it was not executed
451  " in the end.
452  new
453  try
454    call feedkeys(":file \<C-R>%Xtestfile\<CR>", 'tx')
455  catch /^Vim\%((\a\+)\)\=:E32/
456    " ignore error E32
457  endtry
458  call assert_equal("Xtestfile", bufname("%"))
459  bwipe!
460endfunc
461
462func Test_cmdline_remove_char()
463  let encoding_save = &encoding
464
465  for e in ['utf8', 'latin1']
466    exe 'set encoding=' . e
467
468    call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx')
469    call assert_equal('"abc ef', @:, e)
470
471    call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx')
472    call assert_equal('"abcdef', @:)
473
474    call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx')
475    call assert_equal('"abc ghi', @:, e)
476
477    call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx')
478    call assert_equal('"def', @:, e)
479  endfor
480
481  let &encoding = encoding_save
482endfunc
483
484func Test_cmdline_keymap_ctrl_hat()
485  if !has('keymap')
486    return
487  endif
488
489  set keymap=esperanto
490  call feedkeys(":\"Jxauxdo \<C-^>Jxauxdo \<C-^>Jxauxdo\<CR>", 'tx')
491  call assert_equal('"Jxauxdo Ĵaŭdo Jxauxdo', @:)
492  set keymap=
493endfunc
494
495func Test_illegal_address1()
496  new
497  2;'(
498  2;')
499  quit
500endfunc
501
502func Test_illegal_address2()
503  call writefile(['c', 'x', '  x', '.', '1;y'], 'Xtest.vim')
504  new
505  source Xtest.vim
506  " Trigger calling validate_cursor()
507  diffsp Xtest.vim
508  quit!
509  bwipe!
510  call delete('Xtest.vim')
511endfunc
512
513func Test_cmdline_complete_wildoptions()
514  help
515  call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
516  let a = join(sort(split(@:)),' ')
517  set wildoptions=tagfile
518  call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
519  let b = join(sort(split(@:)),' ')
520  call assert_equal(a, b)
521  bw!
522endfunc
523
524func Test_cmdline_complete_user_cmd()
525  command! -complete=color -nargs=1 Foo :
526  call feedkeys(":Foo \<Tab>\<Home>\"\<cr>", 'tx')
527  call assert_equal('"Foo blue', @:)
528  call feedkeys(":Foo b\<Tab>\<Home>\"\<cr>", 'tx')
529  call assert_equal('"Foo blue', @:)
530  delcommand Foo
531endfunc
532
533func Test_cmdline_complete_user_names()
534  if has('unix') && executable('whoami')
535    let whoami = systemlist('whoami')[0]
536    let first_letter = whoami[0]
537    if len(first_letter) > 0
538      " Trying completion of  :e ~x  where x is the first letter of
539      " the user name should complete to at least the user name.
540      call feedkeys(':e ~' . first_letter . "\<c-a>\<c-B>\"\<cr>", 'tx')
541      call assert_match('^"e \~.*\<' . whoami . '\>', @:)
542    endif
543  endif
544  if has('win32')
545    " Just in case: check that the system has an Administrator account.
546    let names = system('net user')
547    if names =~ 'Administrator'
548      " Trying completion of  :e ~A  should complete to Administrator.
549      " There could be other names starting with "A" before Administrator.
550      call feedkeys(':e ~A' . "\<c-a>\<c-B>\"\<cr>", 'tx')
551      call assert_match('^"e \~.*Administrator', @:)
552    endif
553  endif
554endfunc
555
556funct Test_cmdline_complete_languages()
557  let lang = substitute(execute('language messages'), '.*"\(.*\)"$', '\1', '')
558
559  call feedkeys(":language \<c-a>\<c-b>\"\<cr>", 'tx')
560  call assert_match('^"language .*\<ctype\>.*\<messages\>.*\<time\>', @:)
561
562  if has('unix')
563    " TODO: these tests don't work on Windows. lang appears to be 'C'
564    " but C does not appear in the completion. Why?
565    call assert_match('^"language .*\<' . lang . '\>', @:)
566
567    call feedkeys(":language messages \<c-a>\<c-b>\"\<cr>", 'tx')
568    call assert_match('^"language .*\<' . lang . '\>', @:)
569
570    call feedkeys(":language ctype \<c-a>\<c-b>\"\<cr>", 'tx')
571    call assert_match('^"language .*\<' . lang . '\>', @:)
572
573    call feedkeys(":language time \<c-a>\<c-b>\"\<cr>", 'tx')
574    call assert_match('^"language .*\<' . lang . '\>', @:)
575  endif
576endfunc
577
578func Test_cmdline_write_alternatefile()
579  new
580  call setline('.', ['one', 'two'])
581  f foo.txt
582  new
583  f #-A
584  call assert_equal('foo.txt-A', expand('%'))
585  f #<-B.txt
586  call assert_equal('foo-B.txt', expand('%'))
587  f %<
588  call assert_equal('foo-B', expand('%'))
589  new
590  call assert_fails('f #<', 'E95')
591  bw!
592  f foo-B.txt
593  f %<-A
594  call assert_equal('foo-B-A', expand('%'))
595  bw!
596  bw!
597endfunc
598
599" using a leading backslash here
600set cpo+=C
601
602func Test_cmdline_search_range()
603  new
604  call setline(1, ['a', 'b', 'c', 'd'])
605  /d
606  1,\/s/b/B/
607  call assert_equal('B', getline(2))
608
609  /a
610  $
611  \?,4s/c/C/
612  call assert_equal('C', getline(3))
613
614  call setline(1, ['a', 'b', 'c', 'd'])
615  %s/c/c/
616  1,\&s/b/B/
617  call assert_equal('B', getline(2))
618
619  bwipe!
620endfunc
621
622" Tests for getcmdline(), getcmdpos() and getcmdtype()
623func Check_cmdline(cmdtype)
624  call assert_equal('MyCmd a', getcmdline())
625  call assert_equal(8, getcmdpos())
626  call assert_equal(a:cmdtype, getcmdtype())
627  return ''
628endfunc
629
630set cpo&
631
632func Test_getcmdtype()
633  call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt")
634
635  let cmdtype = ''
636  debuggreedy
637  call feedkeys(":debug echo 'test'\<CR>", "t")
638  call feedkeys("let cmdtype = \<C-R>=string(getcmdtype())\<CR>\<CR>", "t")
639  call feedkeys("cont\<CR>", "xt")
640  0debuggreedy
641  call assert_equal('>', cmdtype)
642
643  call feedkeys("/MyCmd a\<C-R>=Check_cmdline('/')\<CR>\<Esc>", "xt")
644  call feedkeys("?MyCmd a\<C-R>=Check_cmdline('?')\<CR>\<Esc>", "xt")
645
646  call feedkeys(":call input('Answer?')\<CR>", "t")
647  call feedkeys("MyCmd a\<C-R>=Check_cmdline('@')\<CR>\<C-C>", "xt")
648
649  call feedkeys(":insert\<CR>MyCmd a\<C-R>=Check_cmdline('-')\<CR>\<Esc>", "xt")
650
651  cnoremap <expr> <F6> Check_cmdline('=')
652  call feedkeys("a\<C-R>=MyCmd a\<F6>\<Esc>\<Esc>", "xt")
653  cunmap <F6>
654endfunc
655
656func Test_getcmdwintype()
657  call feedkeys("q/:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
658  call assert_equal('/', a)
659
660  call feedkeys("q?:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
661  call assert_equal('?', a)
662
663  call feedkeys("q::let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
664  call assert_equal(':', a)
665
666  call feedkeys(":\<C-F>:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
667  call assert_equal(':', a)
668
669  call assert_equal('', getcmdwintype())
670endfunc
671
672func Test_getcmdwin_autocmd()
673  let s:seq = []
674  augroup CmdWin
675  au WinEnter * call add(s:seq, 'WinEnter ' .. win_getid())
676  au WinLeave * call add(s:seq, 'WinLeave ' .. win_getid())
677  au BufEnter * call add(s:seq, 'BufEnter ' .. bufnr())
678  au BufLeave * call add(s:seq, 'BufLeave ' .. bufnr())
679  au CmdWinEnter * call add(s:seq, 'CmdWinEnter ' .. win_getid())
680  au CmdWinLeave * call add(s:seq, 'CmdWinLeave ' .. win_getid())
681
682  let org_winid = win_getid()
683  let org_bufnr = bufnr()
684  call feedkeys("q::let a = getcmdwintype()\<CR>:let s:cmd_winid = win_getid()\<CR>:let s:cmd_bufnr = bufnr()\<CR>:q\<CR>", 'x!')
685  call assert_equal(':', a)
686  call assert_equal([
687	\ 'WinLeave ' .. org_winid,
688	\ 'WinEnter ' .. s:cmd_winid,
689	\ 'BufLeave ' .. org_bufnr,
690	\ 'BufEnter ' .. s:cmd_bufnr,
691	\ 'CmdWinEnter ' .. s:cmd_winid,
692	\ 'CmdWinLeave ' .. s:cmd_winid,
693	\ 'BufLeave ' .. s:cmd_bufnr,
694	\ 'WinLeave ' .. s:cmd_winid,
695	\ 'WinEnter ' .. org_winid,
696	\ 'BufEnter ' .. org_bufnr,
697	\ ], s:seq)
698
699  au!
700  augroup END
701endfunc
702
703func Test_verbosefile()
704  set verbosefile=Xlog
705  echomsg 'foo'
706  echomsg 'bar'
707  set verbosefile=
708  let log = readfile('Xlog')
709  call assert_match("foo\nbar", join(log, "\n"))
710  call delete('Xlog')
711endfunc
712
713func Test_verbose_option()
714  CheckScreendump
715
716  let lines =<< trim [SCRIPT]
717    command DoSomething echo 'hello' |set ts=4 |let v = '123' |echo v
718    call feedkeys("\r", 't') " for the hit-enter prompt
719    set verbose=20
720  [SCRIPT]
721  call writefile(lines, 'XTest_verbose')
722
723  let buf = RunVimInTerminal('-S XTest_verbose', {'rows': 12})
724  call term_wait(buf, 100)
725  call term_sendkeys(buf, ":DoSomething\<CR>")
726  call VerifyScreenDump(buf, 'Test_verbose_option_1', {})
727
728  " clean up
729  call StopVimInTerminal(buf)
730  call delete('XTest_verbose')
731endfunc
732
733func Test_setcmdpos()
734  func InsertTextAtPos(text, pos)
735    call assert_equal(0, setcmdpos(a:pos))
736    return a:text
737  endfunc
738
739  " setcmdpos() with position in the middle of the command line.
740  call feedkeys(":\"12\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
741  call assert_equal('"1ab2', @:)
742
743  call feedkeys(":\"12\<C-R>\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
744  call assert_equal('"1b2a', @:)
745
746  " setcmdpos() with position beyond the end of the command line.
747  call feedkeys(":\"12\<C-B>\<C-R>=InsertTextAtPos('a', 10)\<CR>b\<CR>", 'xt')
748  call assert_equal('"12ab', @:)
749
750  " setcmdpos() returns 1 when not editing the command line.
751  call assert_equal(1, 3->setcmdpos())
752endfunc
753
754func Test_cmdline_overstrike()
755  let encodings = ['latin1', 'utf8']
756  let encoding_save = &encoding
757
758  for e in encodings
759    exe 'set encoding=' . e
760
761    " Test overstrike in the middle of the command line.
762    call feedkeys(":\"01234\<home>\<right>\<right>ab\<right>\<insert>cd\<enter>", 'xt')
763    call assert_equal('"0ab1cd4', @:, e)
764
765    " Test overstrike going beyond end of command line.
766    call feedkeys(":\"01234\<home>\<right>\<right>ab\<right>\<insert>cdefgh\<enter>", 'xt')
767    call assert_equal('"0ab1cdefgh', @:, e)
768
769    " Test toggling insert/overstrike a few times.
770    call feedkeys(":\"01234\<home>\<right>ab\<right>\<insert>cd\<right>\<insert>ef\<enter>", 'xt')
771    call assert_equal('"ab0cd3ef4', @:, e)
772  endfor
773
774  " Test overstrike with multi-byte characters.
775  call feedkeys(":\"テキストエディタ\<home>\<right>\<right>ab\<right>\<insert>cd\<enter>", 'xt')
776  call assert_equal('"テabキcdエディタ', @:, e)
777
778  let &encoding = encoding_save
779endfunc
780
781func Test_cmdwin_bug()
782  let winid = win_getid()
783  sp
784  try
785    call feedkeys("q::call win_gotoid(" .. winid .. ")\<CR>:q\<CR>", 'x!')
786  catch /^Vim\%((\a\+)\)\=:E11/
787  endtry
788  bw!
789endfunc
790
791func Test_cmdwin_restore()
792  CheckScreendump
793
794  let lines =<< trim [SCRIPT]
795    call setline(1, range(30))
796    2split
797  [SCRIPT]
798  call writefile(lines, 'XTest_restore')
799
800  let buf = RunVimInTerminal('-S XTest_restore', {'rows': 12})
801  call term_wait(buf, 100)
802  call term_sendkeys(buf, "q:")
803  call VerifyScreenDump(buf, 'Test_cmdwin_restore_1', {})
804
805  " normal restore
806  call term_sendkeys(buf, ":q\<CR>")
807  call VerifyScreenDump(buf, 'Test_cmdwin_restore_2', {})
808
809  " restore after setting 'lines' with one window
810  call term_sendkeys(buf, ":close\<CR>")
811  call term_sendkeys(buf, "q:")
812  call term_sendkeys(buf, ":set lines=18\<CR>")
813  call term_sendkeys(buf, ":q\<CR>")
814  call VerifyScreenDump(buf, 'Test_cmdwin_restore_3', {})
815
816  " clean up
817  call StopVimInTerminal(buf)
818  call delete('XTest_restore')
819endfunc
820
821func Test_buffers_lastused()
822  " check that buffers are sorted by time when wildmode has lastused
823  call test_settime(1550020000)	  " middle
824  edit bufa
825  enew
826  call test_settime(1550030000)	  " newest
827  edit bufb
828  enew
829  call test_settime(1550010000)	  " oldest
830  edit bufc
831  enew
832  call test_settime(0)
833  enew
834
835  call assert_equal(['bufa', 'bufb', 'bufc'],
836	\ getcompletion('', 'buffer'))
837
838  let save_wildmode = &wildmode
839  set wildmode=full:lastused
840
841  let cap = "\<c-r>=execute('let X=getcmdline()')\<cr>"
842  call feedkeys(":b \<tab>" .. cap .. "\<esc>", 'xt')
843  call assert_equal('b bufb', X)
844  call feedkeys(":b \<tab>\<tab>" .. cap .. "\<esc>", 'xt')
845  call assert_equal('b bufa', X)
846  call feedkeys(":b \<tab>\<tab>\<tab>" .. cap .. "\<esc>", 'xt')
847  call assert_equal('b bufc', X)
848  enew
849
850  edit other
851  call feedkeys(":b \<tab>" .. cap .. "\<esc>", 'xt')
852  call assert_equal('b bufb', X)
853  call feedkeys(":b \<tab>\<tab>" .. cap .. "\<esc>", 'xt')
854  call assert_equal('b bufa', X)
855  call feedkeys(":b \<tab>\<tab>\<tab>" .. cap .. "\<esc>", 'xt')
856  call assert_equal('b bufc', X)
857  enew
858
859  let &wildmode = save_wildmode
860
861  bwipeout bufa
862  bwipeout bufb
863  bwipeout bufc
864endfunc
865
866func Test_cmdwin_feedkeys()
867  " This should not generate E488
868  call feedkeys("q:\<CR>", 'x')
869endfunc
870
871" Tests for the issues fixed in 7.4.441.
872" When 'cedit' is set to Ctrl-C, opening the command window hangs Vim
873func Test_cmdwin_cedit()
874  exe "set cedit=\<C-c>"
875  normal! :
876  call assert_equal(1, winnr('$'))
877
878  let g:cmd_wintype = ''
879  func CmdWinType()
880      let g:cmd_wintype = getcmdwintype()
881      return ''
882  endfunc
883
884  call feedkeys("\<C-c>a\<C-R>=CmdWinType()\<CR>\<CR>")
885  echo input('')
886  call assert_equal('@', g:cmd_wintype)
887
888  set cedit&vim
889  delfunc CmdWinType
890endfunc
891
892" vim: shiftwidth=2 sts=2 expandtab
893