xref: /vim-8.2.3635/src/testdir/test_cmdline.vim (revision 5f1920ad)
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_paste_in_cmdline()
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_remove_char_in_cmdline()
463  call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx')
464  call assert_equal('"abc ef', @:)
465
466  call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx')
467  call assert_equal('"abcdef', @:)
468
469  call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx')
470  call assert_equal('"abc ghi', @:)
471
472  call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx')
473  call assert_equal('"def', @:)
474endfunc
475
476func Test_illegal_address1()
477  new
478  2;'(
479  2;')
480  quit
481endfunc
482
483func Test_illegal_address2()
484  call writefile(['c', 'x', '  x', '.', '1;y'], 'Xtest.vim')
485  new
486  source Xtest.vim
487  " Trigger calling validate_cursor()
488  diffsp Xtest.vim
489  quit!
490  bwipe!
491  call delete('Xtest.vim')
492endfunc
493
494func Test_cmdline_complete_wildoptions()
495  help
496  call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
497  let a = join(sort(split(@:)),' ')
498  set wildoptions=tagfile
499  call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
500  let b = join(sort(split(@:)),' ')
501  call assert_equal(a, b)
502  bw!
503endfunc
504
505func Test_cmdline_complete_user_cmd()
506  command! -complete=color -nargs=1 Foo :
507  call feedkeys(":Foo \<Tab>\<Home>\"\<cr>", 'tx')
508  call assert_equal('"Foo blue', @:)
509  call feedkeys(":Foo b\<Tab>\<Home>\"\<cr>", 'tx')
510  call assert_equal('"Foo blue', @:)
511  delcommand Foo
512endfunc
513
514func Test_cmdline_complete_user_names()
515  if has('unix') && executable('whoami')
516    let whoami = systemlist('whoami')[0]
517    let first_letter = whoami[0]
518    if len(first_letter) > 0
519      " Trying completion of  :e ~x  where x is the first letter of
520      " the user name should complete to at least the user name.
521      call feedkeys(':e ~' . first_letter . "\<c-a>\<c-B>\"\<cr>", 'tx')
522      call assert_match('^"e \~.*\<' . whoami . '\>', @:)
523    endif
524  endif
525  if has('win32')
526    " Just in case: check that the system has an Administrator account.
527    let names = system('net user')
528    if names =~ 'Administrator'
529      " Trying completion of  :e ~A  should complete to Administrator.
530      " There could be other names starting with "A" before Administrator.
531      call feedkeys(':e ~A' . "\<c-a>\<c-B>\"\<cr>", 'tx')
532      call assert_match('^"e \~.*Administrator', @:)
533    endif
534  endif
535endfunc
536
537funct Test_cmdline_complete_languages()
538  let lang = substitute(execute('language messages'), '.*"\(.*\)"$', '\1', '')
539
540  call feedkeys(":language \<c-a>\<c-b>\"\<cr>", 'tx')
541  call assert_match('^"language .*\<ctype\>.*\<messages\>.*\<time\>', @:)
542
543  if has('unix')
544    " TODO: these tests don't work on Windows. lang appears to be 'C'
545    " but C does not appear in the completion. Why?
546    call assert_match('^"language .*\<' . lang . '\>', @:)
547
548    call feedkeys(":language messages \<c-a>\<c-b>\"\<cr>", 'tx')
549    call assert_match('^"language .*\<' . lang . '\>', @:)
550
551    call feedkeys(":language ctype \<c-a>\<c-b>\"\<cr>", 'tx')
552    call assert_match('^"language .*\<' . lang . '\>', @:)
553
554    call feedkeys(":language time \<c-a>\<c-b>\"\<cr>", 'tx')
555    call assert_match('^"language .*\<' . lang . '\>', @:)
556  endif
557endfunc
558
559func Test_cmdline_write_alternatefile()
560  new
561  call setline('.', ['one', 'two'])
562  f foo.txt
563  new
564  f #-A
565  call assert_equal('foo.txt-A', expand('%'))
566  f #<-B.txt
567  call assert_equal('foo-B.txt', expand('%'))
568  f %<
569  call assert_equal('foo-B', expand('%'))
570  new
571  call assert_fails('f #<', 'E95')
572  bw!
573  f foo-B.txt
574  f %<-A
575  call assert_equal('foo-B-A', expand('%'))
576  bw!
577  bw!
578endfunc
579
580" using a leading backslash here
581set cpo+=C
582
583func Test_cmdline_search_range()
584  new
585  call setline(1, ['a', 'b', 'c', 'd'])
586  /d
587  1,\/s/b/B/
588  call assert_equal('B', getline(2))
589
590  /a
591  $
592  \?,4s/c/C/
593  call assert_equal('C', getline(3))
594
595  call setline(1, ['a', 'b', 'c', 'd'])
596  %s/c/c/
597  1,\&s/b/B/
598  call assert_equal('B', getline(2))
599
600  bwipe!
601endfunc
602
603" Tests for getcmdline(), getcmdpos() and getcmdtype()
604func Check_cmdline(cmdtype)
605  call assert_equal('MyCmd a', getcmdline())
606  call assert_equal(8, getcmdpos())
607  call assert_equal(a:cmdtype, getcmdtype())
608  return ''
609endfunc
610
611set cpo&
612
613func Test_getcmdtype()
614  call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt")
615
616  let cmdtype = ''
617  debuggreedy
618  call feedkeys(":debug echo 'test'\<CR>", "t")
619  call feedkeys("let cmdtype = \<C-R>=string(getcmdtype())\<CR>\<CR>", "t")
620  call feedkeys("cont\<CR>", "xt")
621  0debuggreedy
622  call assert_equal('>', cmdtype)
623
624  call feedkeys("/MyCmd a\<C-R>=Check_cmdline('/')\<CR>\<Esc>", "xt")
625  call feedkeys("?MyCmd a\<C-R>=Check_cmdline('?')\<CR>\<Esc>", "xt")
626
627  call feedkeys(":call input('Answer?')\<CR>", "t")
628  call feedkeys("MyCmd a\<C-R>=Check_cmdline('@')\<CR>\<C-C>", "xt")
629
630  call feedkeys(":insert\<CR>MyCmd a\<C-R>=Check_cmdline('-')\<CR>\<Esc>", "xt")
631
632  cnoremap <expr> <F6> Check_cmdline('=')
633  call feedkeys("a\<C-R>=MyCmd a\<F6>\<Esc>\<Esc>", "xt")
634  cunmap <F6>
635endfunc
636
637func Test_getcmdwintype()
638  call feedkeys("q/:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
639  call assert_equal('/', a)
640
641  call feedkeys("q?:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
642  call assert_equal('?', a)
643
644  call feedkeys("q::let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
645  call assert_equal(':', a)
646
647  call feedkeys(":\<C-F>:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
648  call assert_equal(':', a)
649
650  call assert_equal('', getcmdwintype())
651endfunc
652
653func Test_getcmdwin_autocmd()
654  let s:seq = []
655  augroup CmdWin
656  au WinEnter * call add(s:seq, 'WinEnter ' .. win_getid())
657  au WinLeave * call add(s:seq, 'WinLeave ' .. win_getid())
658  au BufEnter * call add(s:seq, 'BufEnter ' .. bufnr())
659  au BufLeave * call add(s:seq, 'BufLeave ' .. bufnr())
660  au CmdWinEnter * call add(s:seq, 'CmdWinEnter ' .. win_getid())
661  au CmdWinLeave * call add(s:seq, 'CmdWinLeave ' .. win_getid())
662
663  let org_winid = win_getid()
664  let org_bufnr = bufnr()
665  call feedkeys("q::let a = getcmdwintype()\<CR>:let s:cmd_winid = win_getid()\<CR>:let s:cmd_bufnr = bufnr()\<CR>:q\<CR>", 'x!')
666  call assert_equal(':', a)
667  call assert_equal([
668	\ 'WinLeave ' .. org_winid,
669	\ 'WinEnter ' .. s:cmd_winid,
670	\ 'BufLeave ' .. org_bufnr,
671	\ 'BufEnter ' .. s:cmd_bufnr,
672	\ 'CmdWinEnter ' .. s:cmd_winid,
673	\ 'CmdWinLeave ' .. s:cmd_winid,
674	\ 'BufLeave ' .. s:cmd_bufnr,
675	\ 'WinLeave ' .. s:cmd_winid,
676	\ 'WinEnter ' .. org_winid,
677	\ 'BufEnter ' .. org_bufnr,
678	\ ], s:seq)
679
680  au!
681  augroup END
682endfunc
683
684func Test_verbosefile()
685  set verbosefile=Xlog
686  echomsg 'foo'
687  echomsg 'bar'
688  set verbosefile=
689  let log = readfile('Xlog')
690  call assert_match("foo\nbar", join(log, "\n"))
691  call delete('Xlog')
692endfunc
693
694func Test_verbose_option()
695  CheckScreendump
696
697  let lines =<< trim [SCRIPT]
698    command DoSomething echo 'hello' |set ts=4 |let v = '123' |echo v
699    call feedkeys("\r", 't') " for the hit-enter prompt
700    set verbose=20
701  [SCRIPT]
702  call writefile(lines, 'XTest_verbose')
703
704  let buf = RunVimInTerminal('-S XTest_verbose', {'rows': 12})
705  call term_wait(buf, 100)
706  call term_sendkeys(buf, ":DoSomething\<CR>")
707  call VerifyScreenDump(buf, 'Test_verbose_option_1', {})
708
709  " clean up
710  call StopVimInTerminal(buf)
711  call delete('XTest_verbose')
712endfunc
713
714func Test_setcmdpos()
715  func InsertTextAtPos(text, pos)
716    call assert_equal(0, setcmdpos(a:pos))
717    return a:text
718  endfunc
719
720  " setcmdpos() with position in the middle of the command line.
721  call feedkeys(":\"12\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
722  call assert_equal('"1ab2', @:)
723
724  call feedkeys(":\"12\<C-R>\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
725  call assert_equal('"1b2a', @:)
726
727  " setcmdpos() with position beyond the end of the command line.
728  call feedkeys(":\"12\<C-B>\<C-R>=InsertTextAtPos('a', 10)\<CR>b\<CR>", 'xt')
729  call assert_equal('"12ab', @:)
730
731  " setcmdpos() returns 1 when not editing the command line.
732  call assert_equal(1, 3->setcmdpos())
733endfunc
734
735func Test_cmdline_overstrike()
736  let encodings = ['latin1', 'utf8']
737  let encoding_save = &encoding
738
739  for e in encodings
740    exe 'set encoding=' . e
741
742    " Test overstrike in the middle of the command line.
743    call feedkeys(":\"01234\<home>\<right>\<right>ab\<right>\<insert>cd\<enter>", 'xt')
744    call assert_equal('"0ab1cd4', @:)
745
746    " Test overstrike going beyond end of command line.
747    call feedkeys(":\"01234\<home>\<right>\<right>ab\<right>\<insert>cdefgh\<enter>", 'xt')
748    call assert_equal('"0ab1cdefgh', @:)
749
750    " Test toggling insert/overstrike a few times.
751    call feedkeys(":\"01234\<home>\<right>ab\<right>\<insert>cd\<right>\<insert>ef\<enter>", 'xt')
752    call assert_equal('"ab0cd3ef4', @:)
753  endfor
754
755  " Test overstrike with multi-byte characters.
756  call feedkeys(":\"テキストエディタ\<home>\<right>\<right>ab\<right>\<insert>cd\<enter>", 'xt')
757  call assert_equal('"テabキcdエディタ', @:)
758
759  let &encoding = encoding_save
760endfunc
761
762func Test_cmdwin_bug()
763  let winid = win_getid()
764  sp
765  try
766    call feedkeys("q::call win_gotoid(" .. winid .. ")\<CR>:q\<CR>", 'x!')
767  catch /^Vim\%((\a\+)\)\=:E11/
768  endtry
769  bw!
770endfunc
771
772func Test_cmdwin_restore()
773  CheckScreendump
774
775  let lines =<< trim [SCRIPT]
776    call setline(1, range(30))
777    2split
778  [SCRIPT]
779  call writefile(lines, 'XTest_restore')
780
781  let buf = RunVimInTerminal('-S XTest_restore', {'rows': 12})
782  call term_wait(buf, 100)
783  call term_sendkeys(buf, "q:")
784  call VerifyScreenDump(buf, 'Test_cmdwin_restore_1', {})
785
786  " normal restore
787  call term_sendkeys(buf, ":q\<CR>")
788  call VerifyScreenDump(buf, 'Test_cmdwin_restore_2', {})
789
790  " restore after setting 'lines' with one window
791  call term_sendkeys(buf, ":close\<CR>")
792  call term_sendkeys(buf, "q:")
793  call term_sendkeys(buf, ":set lines=18\<CR>")
794  call term_sendkeys(buf, ":q\<CR>")
795  call VerifyScreenDump(buf, 'Test_cmdwin_restore_3', {})
796
797  " clean up
798  call StopVimInTerminal(buf)
799  call delete('XTest_restore')
800endfunc
801
802func Test_buffers_lastused()
803  " check that buffers are sorted by time when wildmode has lastused
804  call test_settime(1550020000)	  " middle
805  edit bufa
806  enew
807  call test_settime(1550030000)	  " newest
808  edit bufb
809  enew
810  call test_settime(1550010000)	  " oldest
811  edit bufc
812  enew
813  call test_settime(0)
814  enew
815
816  call assert_equal(['bufa', 'bufb', 'bufc'],
817	\ getcompletion('', 'buffer'))
818
819  let save_wildmode = &wildmode
820  set wildmode=full:lastused
821
822  let cap = "\<c-r>=execute('let X=getcmdline()')\<cr>"
823  call feedkeys(":b \<tab>" .. cap .. "\<esc>", 'xt')
824  call assert_equal('b bufb', X)
825  call feedkeys(":b \<tab>\<tab>" .. cap .. "\<esc>", 'xt')
826  call assert_equal('b bufa', X)
827  call feedkeys(":b \<tab>\<tab>\<tab>" .. cap .. "\<esc>", 'xt')
828  call assert_equal('b bufc', X)
829  enew
830
831  edit other
832  call feedkeys(":b \<tab>" .. cap .. "\<esc>", 'xt')
833  call assert_equal('b bufb', X)
834  call feedkeys(":b \<tab>\<tab>" .. cap .. "\<esc>", 'xt')
835  call assert_equal('b bufa', X)
836  call feedkeys(":b \<tab>\<tab>\<tab>" .. cap .. "\<esc>", 'xt')
837  call assert_equal('b bufc', X)
838  enew
839
840  let &wildmode = save_wildmode
841
842  bwipeout bufa
843  bwipeout bufb
844  bwipeout bufc
845endfunc
846
847func Test_cmdwin_feedkeys()
848  " This should not generate E488
849  call feedkeys("q:\<CR>", 'x')
850endfunc
851
852" Tests for the issues fixed in 7.4.441.
853" When 'cedit' is set to Ctrl-C, opening the command window hangs Vim
854func Test_cmdwin_cedit()
855  exe "set cedit=\<C-c>"
856  normal! :
857  call assert_equal(1, winnr('$'))
858
859  let g:cmd_wintype = ''
860  func CmdWinType()
861      let g:cmd_wintype = getcmdwintype()
862      return ''
863  endfunc
864
865  call feedkeys("\<C-c>a\<C-R>=CmdWinType()\<CR>\<CR>")
866  echo input('')
867  call assert_equal('@', g:cmd_wintype)
868
869  set cedit&vim
870  delfunc CmdWinType
871endfunc
872
873" vim: shiftwidth=2 sts=2 expandtab
874