xref: /vim-8.2.3635/src/testdir/test_cmdline.vim (revision 2e693a88)
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	\ 'if',
188	\ 'elseif',
189	\ 'while',
190	\ 'for',
191	\ 'echo',
192	\ 'echon',
193	\ 'execute',
194	\ 'echomsg',
195	\ 'echoerr',
196	\ 'call',
197	\ 'return',
198	\ 'cexpr',
199	\ 'caddexpr',
200	\ 'cgetexpr',
201	\ 'lexpr',
202	\ 'laddexpr',
203	\ 'lgetexpr']
204    call feedkeys(":" . cmd . " getl\<Tab>\<Home>\"\<CR>", 'xt')
205    call assert_equal('"' . cmd . ' getline(', getreg(':'))
206  endfor
207endfunc
208
209func Test_getcompletion()
210  if !has('cmdline_compl')
211    return
212  endif
213  let groupcount = len(getcompletion('', 'event'))
214  call assert_true(groupcount > 0)
215  let matchcount = len('File'->getcompletion('event'))
216  call assert_true(matchcount > 0)
217  call assert_true(groupcount > matchcount)
218
219  if has('menu')
220    source $VIMRUNTIME/menu.vim
221    let matchcount = len(getcompletion('', 'menu'))
222    call assert_true(matchcount > 0)
223    call assert_equal(['File.'], getcompletion('File', 'menu'))
224    call assert_true(matchcount > 0)
225    let matchcount = len(getcompletion('File.', 'menu'))
226    call assert_true(matchcount > 0)
227  endif
228
229  let l = getcompletion('v:n', 'var')
230  call assert_true(index(l, 'v:null') >= 0)
231  let l = getcompletion('v:notexists', 'var')
232  call assert_equal([], l)
233
234  args a.c b.c
235  let l = getcompletion('', 'arglist')
236  call assert_equal(['a.c', 'b.c'], l)
237  %argdelete
238
239  let l = getcompletion('', 'augroup')
240  call assert_true(index(l, 'END') >= 0)
241  let l = getcompletion('blahblah', 'augroup')
242  call assert_equal([], l)
243
244  let l = getcompletion('', 'behave')
245  call assert_true(index(l, 'mswin') >= 0)
246  let l = getcompletion('not', 'behave')
247  call assert_equal([], l)
248
249  let l = getcompletion('', 'color')
250  call assert_true(index(l, 'default') >= 0)
251  let l = getcompletion('dirty', 'color')
252  call assert_equal([], l)
253
254  let l = getcompletion('', 'command')
255  call assert_true(index(l, 'sleep') >= 0)
256  let l = getcompletion('awake', 'command')
257  call assert_equal([], l)
258
259  let l = getcompletion('', 'dir')
260  call assert_true(index(l, 'samples/') >= 0)
261  let l = getcompletion('NoMatch', 'dir')
262  call assert_equal([], l)
263
264  let l = getcompletion('exe', 'expression')
265  call assert_true(index(l, 'executable(') >= 0)
266  let l = getcompletion('kill', 'expression')
267  call assert_equal([], l)
268
269  let l = getcompletion('tag', 'function')
270  call assert_true(index(l, 'taglist(') >= 0)
271  let l = getcompletion('paint', 'function')
272  call assert_equal([], l)
273
274  let Flambda = {-> 'hello'}
275  let l = getcompletion('', 'function')
276  let l = filter(l, {i, v -> v =~ 'lambda'})
277  call assert_equal([], l)
278
279  let l = getcompletion('run', 'file')
280  call assert_true(index(l, 'runtest.vim') >= 0)
281  let l = getcompletion('walk', 'file')
282  call assert_equal([], l)
283  set wildignore=*.vim
284  let l = getcompletion('run', 'file', 1)
285  call assert_true(index(l, 'runtest.vim') < 0)
286  set wildignore&
287
288  let l = getcompletion('ha', 'filetype')
289  call assert_true(index(l, 'hamster') >= 0)
290  let l = getcompletion('horse', 'filetype')
291  call assert_equal([], l)
292
293  let l = getcompletion('z', 'syntax')
294  call assert_true(index(l, 'zimbu') >= 0)
295  let l = getcompletion('emacs', 'syntax')
296  call assert_equal([], l)
297
298  let l = getcompletion('jikes', 'compiler')
299  call assert_true(index(l, 'jikes') >= 0)
300  let l = getcompletion('break', 'compiler')
301  call assert_equal([], l)
302
303  let l = getcompletion('last', 'help')
304  call assert_true(index(l, ':tablast') >= 0)
305  let l = getcompletion('giveup', 'help')
306  call assert_equal([], l)
307
308  let l = getcompletion('time', 'option')
309  call assert_true(index(l, 'timeoutlen') >= 0)
310  let l = getcompletion('space', 'option')
311  call assert_equal([], l)
312
313  let l = getcompletion('er', 'highlight')
314  call assert_true(index(l, 'ErrorMsg') >= 0)
315  let l = getcompletion('dark', 'highlight')
316  call assert_equal([], l)
317
318  let l = getcompletion('', 'messages')
319  call assert_true(index(l, 'clear') >= 0)
320  let l = getcompletion('not', 'messages')
321  call assert_equal([], l)
322
323  let l = getcompletion('', 'mapclear')
324  call assert_true(index(l, '<buffer>') >= 0)
325  let l = getcompletion('not', 'mapclear')
326  call assert_equal([], l)
327
328  let l = getcompletion('.', 'shellcmd')
329  call assert_equal(['./', '../'], filter(l, 'v:val =~ "\\./"'))
330  call assert_equal(-1, match(l[2:], '^\.\.\?/$'))
331  let root = has('win32') ? 'C:\\' : '/'
332  let l = getcompletion(root, 'shellcmd')
333  let expected = map(filter(glob(root . '*', 0, 1),
334        \ 'isdirectory(v:val) || executable(v:val)'), 'isdirectory(v:val) ? v:val . ''/'' : v:val')
335  call assert_equal(expected, l)
336
337  if has('cscope')
338    let l = getcompletion('', 'cscope')
339    let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show']
340    call assert_equal(cmds, l)
341    " using cmdline completion must not change the result
342    call feedkeys(":cscope find \<c-d>\<c-c>", 'xt')
343    let l = getcompletion('', 'cscope')
344    call assert_equal(cmds, l)
345    let keys = ['a', 'c', 'd', 'e', 'f', 'g', 'i', 's', 't']
346    let l = getcompletion('find ', 'cscope')
347    call assert_equal(keys, l)
348  endif
349
350  if has('signs')
351    sign define Testing linehl=Comment
352    let l = getcompletion('', 'sign')
353    let cmds = ['define', 'jump', 'list', 'place', 'undefine', 'unplace']
354    call assert_equal(cmds, l)
355    " using cmdline completion must not change the result
356    call feedkeys(":sign list \<c-d>\<c-c>", 'xt')
357    let l = getcompletion('', 'sign')
358    call assert_equal(cmds, l)
359    let l = getcompletion('list ', 'sign')
360    call assert_equal(['Testing'], l)
361  endif
362
363  " For others test if the name is recognized.
364  let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user']
365  if has('cmdline_hist')
366    call add(names, 'history')
367  endif
368  if has('gettext')
369    call add(names, 'locale')
370  endif
371  if has('profile')
372    call add(names, 'syntime')
373  endif
374
375  set tags=Xtags
376  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", "word\tfile\tcmd"], 'Xtags')
377
378  for name in names
379    let matchcount = len(getcompletion('', name))
380    call assert_true(matchcount >= 0, 'No matches for ' . name)
381  endfor
382
383  call delete('Xtags')
384  set tags&
385
386  call assert_fails('call getcompletion("", "burp")', 'E475:')
387endfunc
388
389func Test_shellcmd_completion()
390  let save_path = $PATH
391
392  call mkdir('Xpathdir/Xpathsubdir', 'p')
393  call writefile([''], 'Xpathdir/Xfile.exe')
394  call setfperm('Xpathdir/Xfile.exe', 'rwx------')
395
396  " Set PATH to example directory without trailing slash.
397  let $PATH = getcwd() . '/Xpathdir'
398
399  " Test for the ":!<TAB>" case.  Previously, this would include subdirs of
400  " dirs in the PATH, even though they won't be executed.  We check that only
401  " subdirs of the PWD and executables from the PATH are included in the
402  " suggestions.
403  let actual = getcompletion('X', 'shellcmd')
404  let expected = map(filter(glob('*', 0, 1), 'isdirectory(v:val) && v:val[0] == "X"'), 'v:val . "/"')
405  call insert(expected, 'Xfile.exe')
406  call assert_equal(expected, actual)
407
408  call delete('Xpathdir', 'rf')
409  let $PATH = save_path
410endfunc
411
412func Test_expand_star_star()
413  call mkdir('a/b', 'p')
414  call writefile(['asdfasdf'], 'a/b/fileXname')
415  call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt')
416  call assert_equal('find a/b/fileXname', getreg(':'))
417  bwipe!
418  call delete('a', 'rf')
419endfunc
420
421func Test_paste_in_cmdline()
422  let @a = "def"
423  call feedkeys(":abc \<C-R>a ghi\<C-B>\"\<CR>", 'tx')
424  call assert_equal('"abc def ghi', @:)
425
426  new
427  call setline(1, 'asdf.x /tmp/some verylongword a;b-c*d ')
428
429  call feedkeys(":aaa \<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
430  call assert_equal('"aaa asdf bbb', @:)
431
432  call feedkeys("ft:aaa \<C-R>\<C-F> bbb\<C-B>\"\<CR>", 'tx')
433  call assert_equal('"aaa /tmp/some bbb', @:)
434
435  call feedkeys(":aaa \<C-R>\<C-L> bbb\<C-B>\"\<CR>", 'tx')
436  call assert_equal('"aaa '.getline(1).' bbb', @:)
437
438  set incsearch
439  call feedkeys("fy:aaa veryl\<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
440  call assert_equal('"aaa verylongword bbb', @:)
441
442  call feedkeys("f;:aaa \<C-R>\<C-A> bbb\<C-B>\"\<CR>", 'tx')
443  call assert_equal('"aaa a;b-c*d bbb', @:)
444
445  call feedkeys(":\<C-\>etoupper(getline(1))\<CR>\<C-B>\"\<CR>", 'tx')
446  call assert_equal('"ASDF.X /TMP/SOME VERYLONGWORD A;B-C*D ', @:)
447  bwipe!
448
449  " Error while typing a command used to cause that it was not executed
450  " in the end.
451  new
452  try
453    call feedkeys(":file \<C-R>%Xtestfile\<CR>", 'tx')
454  catch /^Vim\%((\a\+)\)\=:E32/
455    " ignore error E32
456  endtry
457  call assert_equal("Xtestfile", bufname("%"))
458  bwipe!
459endfunc
460
461func Test_remove_char_in_cmdline()
462  call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx')
463  call assert_equal('"abc ef', @:)
464
465  call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx')
466  call assert_equal('"abcdef', @:)
467
468  call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx')
469  call assert_equal('"abc ghi', @:)
470
471  call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx')
472  call assert_equal('"def', @:)
473endfunc
474
475func Test_illegal_address1()
476  new
477  2;'(
478  2;')
479  quit
480endfunc
481
482func Test_illegal_address2()
483  call writefile(['c', 'x', '  x', '.', '1;y'], 'Xtest.vim')
484  new
485  source Xtest.vim
486  " Trigger calling validate_cursor()
487  diffsp Xtest.vim
488  quit!
489  bwipe!
490  call delete('Xtest.vim')
491endfunc
492
493func Test_cmdline_complete_wildoptions()
494  help
495  call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
496  let a = join(sort(split(@:)),' ')
497  set wildoptions=tagfile
498  call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
499  let b = join(sort(split(@:)),' ')
500  call assert_equal(a, b)
501  bw!
502endfunc
503
504func Test_cmdline_complete_user_cmd()
505  command! -complete=color -nargs=1 Foo :
506  call feedkeys(":Foo \<Tab>\<Home>\"\<cr>", 'tx')
507  call assert_equal('"Foo blue', @:)
508  call feedkeys(":Foo b\<Tab>\<Home>\"\<cr>", 'tx')
509  call assert_equal('"Foo blue', @:)
510  delcommand Foo
511endfunc
512
513func Test_cmdline_complete_user_names()
514  if has('unix') && executable('whoami')
515    let whoami = systemlist('whoami')[0]
516    let first_letter = whoami[0]
517    if len(first_letter) > 0
518      " Trying completion of  :e ~x  where x is the first letter of
519      " the user name should complete to at least the user name.
520      call feedkeys(':e ~' . first_letter . "\<c-a>\<c-B>\"\<cr>", 'tx')
521      call assert_match('^"e \~.*\<' . whoami . '\>', @:)
522    endif
523  endif
524  if has('win32')
525    " Just in case: check that the system has an Administrator account.
526    let names = system('net user')
527    if names =~ 'Administrator'
528      " Trying completion of  :e ~A  should complete to Administrator.
529      " There could be other names starting with "A" before Administrator.
530      call feedkeys(':e ~A' . "\<c-a>\<c-B>\"\<cr>", 'tx')
531      call assert_match('^"e \~.*Administrator', @:)
532    endif
533  endif
534endfunc
535
536funct Test_cmdline_complete_languages()
537  let lang = substitute(execute('language messages'), '.*"\(.*\)"$', '\1', '')
538
539  call feedkeys(":language \<c-a>\<c-b>\"\<cr>", 'tx')
540  call assert_match('^"language .*\<ctype\>.*\<messages\>.*\<time\>', @:)
541
542  if has('unix')
543    " TODO: these tests don't work on Windows. lang appears to be 'C'
544    " but C does not appear in the completion. Why?
545    call assert_match('^"language .*\<' . lang . '\>', @:)
546
547    call feedkeys(":language messages \<c-a>\<c-b>\"\<cr>", 'tx')
548    call assert_match('^"language .*\<' . lang . '\>', @:)
549
550    call feedkeys(":language ctype \<c-a>\<c-b>\"\<cr>", 'tx')
551    call assert_match('^"language .*\<' . lang . '\>', @:)
552
553    call feedkeys(":language time \<c-a>\<c-b>\"\<cr>", 'tx')
554    call assert_match('^"language .*\<' . lang . '\>', @:)
555  endif
556endfunc
557
558func Test_cmdline_write_alternatefile()
559  new
560  call setline('.', ['one', 'two'])
561  f foo.txt
562  new
563  f #-A
564  call assert_equal('foo.txt-A', expand('%'))
565  f #<-B.txt
566  call assert_equal('foo-B.txt', expand('%'))
567  f %<
568  call assert_equal('foo-B', expand('%'))
569  new
570  call assert_fails('f #<', 'E95')
571  bw!
572  f foo-B.txt
573  f %<-A
574  call assert_equal('foo-B-A', expand('%'))
575  bw!
576  bw!
577endfunc
578
579" using a leading backslash here
580set cpo+=C
581
582func Test_cmdline_search_range()
583  new
584  call setline(1, ['a', 'b', 'c', 'd'])
585  /d
586  1,\/s/b/B/
587  call assert_equal('B', getline(2))
588
589  /a
590  $
591  \?,4s/c/C/
592  call assert_equal('C', getline(3))
593
594  call setline(1, ['a', 'b', 'c', 'd'])
595  %s/c/c/
596  1,\&s/b/B/
597  call assert_equal('B', getline(2))
598
599  bwipe!
600endfunc
601
602" Tests for getcmdline(), getcmdpos() and getcmdtype()
603func Check_cmdline(cmdtype)
604  call assert_equal('MyCmd a', getcmdline())
605  call assert_equal(8, getcmdpos())
606  call assert_equal(a:cmdtype, getcmdtype())
607  return ''
608endfunc
609
610set cpo&
611
612func Test_getcmdtype()
613  call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt")
614
615  let cmdtype = ''
616  debuggreedy
617  call feedkeys(":debug echo 'test'\<CR>", "t")
618  call feedkeys("let cmdtype = \<C-R>=string(getcmdtype())\<CR>\<CR>", "t")
619  call feedkeys("cont\<CR>", "xt")
620  0debuggreedy
621  call assert_equal('>', cmdtype)
622
623  call feedkeys("/MyCmd a\<C-R>=Check_cmdline('/')\<CR>\<Esc>", "xt")
624  call feedkeys("?MyCmd a\<C-R>=Check_cmdline('?')\<CR>\<Esc>", "xt")
625
626  call feedkeys(":call input('Answer?')\<CR>", "t")
627  call feedkeys("MyCmd a\<C-R>=Check_cmdline('@')\<CR>\<C-C>", "xt")
628
629  call feedkeys(":insert\<CR>MyCmd a\<C-R>=Check_cmdline('-')\<CR>\<Esc>", "xt")
630
631  cnoremap <expr> <F6> Check_cmdline('=')
632  call feedkeys("a\<C-R>=MyCmd a\<F6>\<Esc>\<Esc>", "xt")
633  cunmap <F6>
634endfunc
635
636func Test_getcmdwintype()
637  call feedkeys("q/:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
638  call assert_equal('/', a)
639
640  call feedkeys("q?:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
641  call assert_equal('?', a)
642
643  call feedkeys("q::let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
644  call assert_equal(':', a)
645
646  call feedkeys(":\<C-F>:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
647  call assert_equal(':', a)
648
649  call assert_equal('', getcmdwintype())
650endfunc
651
652func Test_getcmdwin_autocmd()
653  let s:seq = []
654  augroup CmdWin
655  au WinEnter * call add(s:seq, 'WinEnter ' .. win_getid())
656  au WinLeave * call add(s:seq, 'WinLeave ' .. win_getid())
657  au BufEnter * call add(s:seq, 'BufEnter ' .. bufnr())
658  au BufLeave * call add(s:seq, 'BufLeave ' .. bufnr())
659  au CmdWinEnter * call add(s:seq, 'CmdWinEnter ' .. win_getid())
660  au CmdWinLeave * call add(s:seq, 'CmdWinLeave ' .. win_getid())
661
662  let org_winid = win_getid()
663  let org_bufnr = bufnr()
664  call feedkeys("q::let a = getcmdwintype()\<CR>:let s:cmd_winid = win_getid()\<CR>:let s:cmd_bufnr = bufnr()\<CR>:q\<CR>", 'x!')
665  call assert_equal(':', a)
666  call assert_equal([
667	\ 'WinLeave ' .. org_winid,
668	\ 'WinEnter ' .. s:cmd_winid,
669	\ 'BufLeave ' .. org_bufnr,
670	\ 'BufEnter ' .. s:cmd_bufnr,
671	\ 'CmdWinEnter ' .. s:cmd_winid,
672	\ 'CmdWinLeave ' .. s:cmd_winid,
673	\ 'BufLeave ' .. s:cmd_bufnr,
674	\ 'WinLeave ' .. s:cmd_winid,
675	\ 'WinEnter ' .. org_winid,
676	\ 'BufEnter ' .. org_bufnr,
677	\ ], s:seq)
678
679  au!
680  augroup END
681endfunc
682
683func Test_verbosefile()
684  set verbosefile=Xlog
685  echomsg 'foo'
686  echomsg 'bar'
687  set verbosefile=
688  let log = readfile('Xlog')
689  call assert_match("foo\nbar", join(log, "\n"))
690  call delete('Xlog')
691endfunc
692
693func Test_verbose_option()
694  CheckScreendump
695
696  let lines =<< trim [SCRIPT]
697    command DoSomething echo 'hello' |set ts=4 |let v = '123' |echo v
698    call feedkeys("\r", 't') " for the hit-enter prompt
699    set verbose=20
700  [SCRIPT]
701  call writefile(lines, 'XTest_verbose')
702
703  let buf = RunVimInTerminal('-S XTest_verbose', {'rows': 12})
704  call term_wait(buf, 100)
705  call term_sendkeys(buf, ":DoSomething\<CR>")
706  call VerifyScreenDump(buf, 'Test_verbose_option_1', {})
707
708  " clean up
709  call StopVimInTerminal(buf)
710  call delete('XTest_verbose')
711endfunc
712
713func Test_setcmdpos()
714  func InsertTextAtPos(text, pos)
715    call assert_equal(0, setcmdpos(a:pos))
716    return a:text
717  endfunc
718
719  " setcmdpos() with position in the middle of the command line.
720  call feedkeys(":\"12\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
721  call assert_equal('"1ab2', @:)
722
723  call feedkeys(":\"12\<C-R>\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
724  call assert_equal('"1b2a', @:)
725
726  " setcmdpos() with position beyond the end of the command line.
727  call feedkeys(":\"12\<C-B>\<C-R>=InsertTextAtPos('a', 10)\<CR>b\<CR>", 'xt')
728  call assert_equal('"12ab', @:)
729
730  " setcmdpos() returns 1 when not editing the command line.
731  call assert_equal(1, 3->setcmdpos())
732endfunc
733
734func Test_cmdline_overstrike()
735  let encodings = ['latin1', 'utf8']
736  let encoding_save = &encoding
737
738  for e in encodings
739    exe 'set encoding=' . e
740
741    " Test overstrike in the middle of the command line.
742    call feedkeys(":\"01234\<home>\<right>\<right>ab\<right>\<insert>cd\<enter>", 'xt')
743    call assert_equal('"0ab1cd4', @:)
744
745    " Test overstrike going beyond end of command line.
746    call feedkeys(":\"01234\<home>\<right>\<right>ab\<right>\<insert>cdefgh\<enter>", 'xt')
747    call assert_equal('"0ab1cdefgh', @:)
748
749    " Test toggling insert/overstrike a few times.
750    call feedkeys(":\"01234\<home>\<right>ab\<right>\<insert>cd\<right>\<insert>ef\<enter>", 'xt')
751    call assert_equal('"ab0cd3ef4', @:)
752  endfor
753
754  " Test overstrike with multi-byte characters.
755  call feedkeys(":\"テキストエディタ\<home>\<right>\<right>ab\<right>\<insert>cd\<enter>", 'xt')
756  call assert_equal('"テabキcdエディタ', @:)
757
758  let &encoding = encoding_save
759endfunc
760
761func Test_cmdwin_bug()
762  let winid = win_getid()
763  sp
764  try
765    call feedkeys("q::call win_gotoid(" .. winid .. ")\<CR>:q\<CR>", 'x!')
766  catch /^Vim\%((\a\+)\)\=:E11/
767  endtry
768  bw!
769endfunc
770