xref: /vim-8.2.3635/src/testdir/test_tagjump.vim (revision 489d6099)
1" Tests for tagjump (tags and special searches)
2
3source check.vim
4source screendump.vim
5
6" SEGV occurs in older versions.  (At least 7.4.1748 or older)
7func Test_ptag_with_notagstack()
8  CheckFeature quickfix
9
10  set notagstack
11  call assert_fails('ptag does_not_exist_tag_name', 'E433:')
12  set tagstack&vim
13endfunc
14
15func Test_ptjump()
16  CheckFeature quickfix
17
18  set tags=Xtags
19  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
20        \ "one\tXfile\t1",
21        \ "three\tXfile\t3",
22        \ "two\tXfile\t2"],
23        \ 'Xtags')
24  call writefile(['one', 'two', 'three'], 'Xfile')
25
26  %bw!
27  ptjump two
28  call assert_equal(2, winnr())
29  wincmd p
30  call assert_equal(1, &previewwindow)
31  call assert_equal('Xfile', expand("%:p:t"))
32  call assert_equal(2, line('.'))
33  call assert_equal(2, winnr('$'))
34  call assert_equal(1, winnr())
35  close
36  call setline(1, ['one', 'two', 'three'])
37  exe "normal 3G\<C-W>g}"
38  call assert_equal(2, winnr())
39  wincmd p
40  call assert_equal(1, &previewwindow)
41  call assert_equal('Xfile', expand("%:p:t"))
42  call assert_equal(3, line('.'))
43  call assert_equal(2, winnr('$'))
44  call assert_equal(1, winnr())
45  close
46  exe "normal 3G5\<C-W>\<C-G>}"
47  wincmd p
48  call assert_equal(5, winheight(0))
49  close
50
51  call delete('Xtags')
52  call delete('Xfile')
53  set tags&
54endfunc
55
56func Test_cancel_ptjump()
57  CheckFeature quickfix
58
59  set tags=Xtags
60  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
61        \ "word\tfile1\tcmd1",
62        \ "word\tfile2\tcmd2"],
63        \ 'Xtags')
64
65  only!
66  call feedkeys(":ptjump word\<CR>\<CR>", "xt")
67  help
68  call assert_equal(2, winnr('$'))
69
70  call delete('Xtags')
71  set tags&
72  quit
73endfunc
74
75func Test_static_tagjump()
76  set tags=Xtags
77  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
78        \ "one\tXfile1\t/^one/;\"\tf\tfile:\tsignature:(void)",
79        \ "word\tXfile2\tcmd2"],
80        \ 'Xtags')
81  new Xfile1
82  call setline(1, ['empty', 'one()', 'empty'])
83  write
84  tag one
85  call assert_equal(2, line('.'))
86
87  bwipe!
88  set tags&
89  call delete('Xtags')
90  call delete('Xfile1')
91endfunc
92
93func Test_duplicate_tagjump()
94  set tags=Xtags
95  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
96        \ "thesame\tXfile1\t1;\"\td\tfile:",
97        \ "thesame\tXfile1\t2;\"\td\tfile:",
98        \ "thesame\tXfile1\t3;\"\td\tfile:",
99        \ ],
100        \ 'Xtags')
101  new Xfile1
102  call setline(1, ['thesame one', 'thesame two', 'thesame three'])
103  write
104  tag thesame
105  call assert_equal(1, line('.'))
106  tnext
107  call assert_equal(2, line('.'))
108  tnext
109  call assert_equal(3, line('.'))
110
111  bwipe!
112  set tags&
113  call delete('Xtags')
114  call delete('Xfile1')
115endfunc
116
117func Test_tagjump_switchbuf()
118  CheckFeature quickfix
119
120  set tags=Xtags
121  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
122        \ "second\tXfile1\t2",
123        \ "third\tXfile1\t3",],
124        \ 'Xtags')
125  call writefile(['first', 'second', 'third'], 'Xfile1')
126
127  enew | only
128  set switchbuf=
129  stag second
130  call assert_equal(2, winnr('$'))
131  call assert_equal(2, line('.'))
132  stag third
133  call assert_equal(3, winnr('$'))
134  call assert_equal(3, line('.'))
135
136  enew | only
137  set switchbuf=useopen
138  stag second
139  call assert_equal(2, winnr('$'))
140  call assert_equal(2, line('.'))
141  stag third
142  call assert_equal(2, winnr('$'))
143  call assert_equal(3, line('.'))
144
145  enew | only
146  set switchbuf=usetab
147  tab stag second
148  call assert_equal(2, tabpagenr('$'))
149  call assert_equal(2, line('.'))
150  1tabnext | stag third
151  call assert_equal(2, tabpagenr('$'))
152  call assert_equal(3, line('.'))
153
154  tabclose!
155  enew | only
156  call delete('Xfile1')
157  call delete('Xtags')
158  set tags&
159  set switchbuf&vim
160endfunc
161
162" Tests for [ CTRL-I and CTRL-W CTRL-I commands
163function Test_keyword_jump()
164  call writefile(["#include Xinclude", "",
165	      \ "",
166	      \ "/* test text test tex start here",
167	      \ "		some text",
168	      \ "		test text",
169	      \ "		start OK if found this line",
170	      \ "	start found wrong line",
171	      \ "test text"], 'Xtestfile')
172  call writefile(["/* test text test tex start here",
173	      \ "		some text",
174	      \ "		test text",
175	      \ "		start OK if found this line",
176	      \ "	start found wrong line",
177	      \ "test text"], 'Xinclude')
178  new Xtestfile
179  call cursor(1,1)
180  call search("start")
181  exe "normal! 5[\<C-I>"
182  call assert_equal("		start OK if found this line", getline('.'))
183  call cursor(1,1)
184  call search("start")
185  exe "normal! 5\<C-W>\<C-I>"
186  call assert_equal("		start OK if found this line", getline('.'))
187
188  " invalid tag search pattern
189  call assert_fails('tag /\%(/', 'E426:')
190
191  enew! | only
192  call delete('Xtestfile')
193  call delete('Xinclude')
194endfunction
195
196" Test for jumping to a tag with 'hidden' set, with symbolic link in path of
197" tag.  This only works for Unix, because of the symbolic link.
198func Test_tag_symbolic()
199  CheckUnix
200
201  set hidden
202  call delete("Xtest.dir", "rf")
203  call system("ln -s . Xtest.dir")
204  " Create a tags file with the current directory name inserted.
205  call writefile([
206        \ "SECTION_OFF	" . getcwd() . "/Xtest.dir/Xtest.c	/^#define  SECTION_OFF  3$/",
207        \ '',
208        \ ], 'Xtags')
209  call writefile(['#define  SECTION_OFF  3',
210        \ '#define  NUM_SECTIONS 3'], 'Xtest.c')
211
212  " Try jumping to a tag, but with a path that contains a symbolic link.  When
213  " wrong, this will give the ATTENTION message.  The next space will then be
214  " eaten by hit-return, instead of moving the cursor to 'd'.
215  set tags=Xtags
216  enew!
217  call append(0, 'SECTION_OFF')
218  call cursor(1,1)
219  exe "normal \<C-]> "
220  call assert_equal('Xtest.c', expand('%:t'))
221  call assert_equal(2, col('.'))
222
223  set hidden&
224  set tags&
225  enew!
226  call delete('Xtags')
227  call delete('Xtest.c')
228  call delete("Xtest.dir", "rf")
229  %bwipe!
230endfunc
231
232" Tests for tag search with !_TAG_FILE_ENCODING.
233" Depends on the test83-tags2 and test83-tags3 files.
234func Test_tag_file_encoding()
235  if has('vms')
236    throw 'Skipped: does not work on VMS'
237  endif
238
239  if !has('iconv') || iconv("\x82\x60", "cp932", "utf-8") != "\uff21"
240    throw 'Skipped: iconv does not work'
241  endif
242
243  let save_enc = &encoding
244  set encoding=utf8
245
246  let content = ['text for tags1', 'abcdefghijklmnopqrs']
247  call writefile(content, 'Xtags1.txt')
248  let content = ['text for tags2', 'ABC']
249  call writefile(content, 'Xtags2.txt')
250  let content = ['text for tags3', 'ABC']
251  call writefile(content, 'Xtags3.txt')
252  let content = ['!_TAG_FILE_ENCODING	utf-8	//', 'abcdefghijklmnopqrs	Xtags1.txt	/abcdefghijklmnopqrs']
253  call writefile(content, 'Xtags1')
254
255  " case1:
256  new
257  set tags=Xtags1
258  tag abcdefghijklmnopqrs
259  call assert_equal('Xtags1.txt', expand('%:t'))
260  call assert_equal('abcdefghijklmnopqrs', getline('.'))
261  close
262
263  " case2:
264  new
265  set tags=test83-tags2
266  tag /.BC
267  call assert_equal('Xtags2.txt', expand('%:t'))
268  call assert_equal('ABC', getline('.'))
269  close
270
271  " case3:
272  new
273  set tags=test83-tags3
274  tag abc50
275  call assert_equal('Xtags3.txt', expand('%:t'))
276  call assert_equal('ABC', getline('.'))
277  close
278
279  set tags&
280  let &encoding = save_enc
281  call delete('Xtags1.txt')
282  call delete('Xtags2.txt')
283  call delete('Xtags3.txt')
284  call delete('Xtags1')
285endfunc
286
287" Test for emacs-style tags file (TAGS)
288func Test_tagjump_etags()
289  CheckFeature emacs_tags
290
291  call writefile([
292        \ "void foo() {}",
293        \ "int main(int argc, char **argv)",
294        \ "{",
295        \ "\tfoo();",
296        \ "\treturn 0;",
297        \ "}",
298        \ ], 'Xmain.c')
299
300  call writefile([
301	\ "\x0c",
302        \ "Xmain.c,64",
303        \ "void foo() {}\x7ffoo\x011,0",
304        \ "int main(int argc, char **argv)\x7fmain\x012,14",
305	\ ], 'Xtags')
306  set tags=Xtags
307  ta foo
308  call assert_equal('void foo() {}', getline('.'))
309
310  " Test for including another tags file
311  call writefile([
312        \ "\x0c",
313        \ "Xmain.c,64",
314        \ "void foo() {}\x7ffoo\x011,0",
315        \ "\x0c",
316        \ "Xnonexisting,include",
317        \ "\x0c",
318        \ "Xtags2,include"
319        \ ], 'Xtags')
320  call writefile([
321        \ "\x0c",
322        \ "Xmain.c,64",
323        \ "int main(int argc, char **argv)\x7fmain\x012,14",
324        \ ], 'Xtags2')
325  tag main
326  call assert_equal(2, line('.'))
327
328  " corrupted tag line
329  call writefile([
330        \ "\x0c",
331        \ "Xmain.c,8",
332        \ "int main"
333        \ ], 'Xtags', 'b')
334  call assert_fails('tag foo', 'E426:')
335
336  " invalid line number
337  call writefile([
338	\ "\x0c",
339        \ "Xmain.c,64",
340        \ "void foo() {}\x7ffoo\x0abc,0",
341	\ ], 'Xtags')
342  call assert_fails('tag foo', 'E426:')
343
344  " invalid tag name
345  call writefile([
346	\ "\x0c",
347        \ "Xmain.c,64",
348        \ ";;;;\x7f1,0",
349	\ ], 'Xtags')
350  call assert_fails('tag foo', 'E431:')
351
352  call delete('Xtags')
353  call delete('Xtags2')
354  call delete('Xmain.c')
355  set tags&
356  bwipe!
357endfunc
358
359" Test for getting and modifying the tag stack
360func Test_getsettagstack()
361  call writefile(['line1', 'line2', 'line3'], 'Xfile1')
362  call writefile(['line1', 'line2', 'line3'], 'Xfile2')
363  call writefile(['line1', 'line2', 'line3'], 'Xfile3')
364
365  enew | only
366  call settagstack(1, {'items' : []})
367  call assert_equal(0, gettagstack(1).length)
368  call assert_equal([], 1->gettagstack().items)
369  " Error cases
370  call assert_equal({}, gettagstack(100))
371  call assert_equal(-1, settagstack(100, {'items' : []}))
372  call assert_fails('call settagstack(1, [1, 10])', 'E715:')
373  call assert_fails("call settagstack(1, {'items' : 10})", 'E714:')
374  call assert_fails("call settagstack(1, {'items' : []}, 10)", 'E928:')
375  call assert_fails("call settagstack(1, {'items' : []}, 'b')", 'E962:')
376  call assert_equal(-1, settagstack(0, test_null_dict()))
377
378  set tags=Xtags
379  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
380        \ "one\tXfile1\t1",
381        \ "three\tXfile3\t3",
382        \ "two\tXfile2\t2"],
383        \ 'Xtags')
384
385  let stk = []
386  call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'one',
387	\ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1})
388  tag one
389  call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'two',
390	\ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1})
391  tag two
392  call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'three',
393	\ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1})
394  tag three
395  call assert_equal(3, gettagstack(1).length)
396  call assert_equal(stk, gettagstack(1).items)
397  " Check for default - current window
398  call assert_equal(3, gettagstack().length)
399  call assert_equal(stk, gettagstack().items)
400
401  " Try to set current index to invalid values
402  call settagstack(1, {'curidx' : -1})
403  call assert_equal(1, gettagstack().curidx)
404  eval {'curidx' : 50}->settagstack(1)
405  call assert_equal(4, gettagstack().curidx)
406
407  " Try pushing invalid items onto the stack
408  call settagstack(1, {'items' : []})
409  call settagstack(1, {'items' : ["plate"]}, 'a')
410  call assert_equal(0, gettagstack().length)
411  call assert_equal([], gettagstack().items)
412  call settagstack(1, {'items' : [{"tagname" : "abc"}]}, 'a')
413  call assert_equal(0, gettagstack().length)
414  call assert_equal([], gettagstack().items)
415  call settagstack(1, {'items' : [{"from" : 100}]}, 'a')
416  call assert_equal(0, gettagstack().length)
417  call assert_equal([], gettagstack().items)
418  call settagstack(1, {'items' : [{"from" : [2, 1, 0, 0]}]}, 'a')
419  call assert_equal(0, gettagstack().length)
420  call assert_equal([], gettagstack().items)
421
422  " Push one item at a time to the stack
423  call settagstack(1, {'items' : []})
424  call settagstack(1, {'items' : [stk[0]]}, 'a')
425  call settagstack(1, {'items' : [stk[1]]}, 'a')
426  call settagstack(1, {'items' : [stk[2]]}, 'a')
427  call settagstack(1, {'curidx' : 4})
428  call assert_equal({'length' : 3, 'curidx' : 4, 'items' : stk},
429        \ gettagstack(1))
430
431  " Try pushing items onto a full stack
432  for i in range(7)
433    call settagstack(1, {'items' : stk}, 'a')
434  endfor
435  call assert_equal(20, gettagstack().length)
436  call settagstack(1,
437        \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 'a')
438  call assert_equal('abc', gettagstack().items[19].tagname)
439
440  " truncate the tag stack
441  call settagstack(1,
442        \ {'curidx' : 9,
443        \  'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 't')
444  let t = gettagstack()
445  call assert_equal(9, t.length)
446  call assert_equal(10, t.curidx)
447
448  " truncate the tag stack without pushing any new items
449  call settagstack(1, {'curidx' : 5}, 't')
450  let t = gettagstack()
451  call assert_equal(4, t.length)
452  call assert_equal(5, t.curidx)
453
454  " truncate an empty tag stack and push new items
455  call settagstack(1, {'items' : []})
456  call settagstack(1,
457        \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 't')
458  let t = gettagstack()
459  call assert_equal(1, t.length)
460  call assert_equal(2, t.curidx)
461
462  " Tag with multiple matches
463  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
464        \ "two\tXfile1\t1",
465        \ "two\tXfile2\t3",
466        \ "two\tXfile3\t2"],
467        \ 'Xtags')
468  call settagstack(1, {'items' : []})
469  tag two
470  tnext
471  tnext
472  call assert_equal(1, gettagstack().length)
473  call assert_equal(3, gettagstack().items[0].matchnr)
474
475  " Memory allocation failures
476  call test_alloc_fail(GetAllocId('tagstack_items'), 0, 0)
477  call assert_fails('call gettagstack()', 'E342:')
478  call test_alloc_fail(GetAllocId('tagstack_from'), 0, 0)
479  call assert_fails('call gettagstack()', 'E342:')
480  call test_alloc_fail(GetAllocId('tagstack_details'), 0, 0)
481  call assert_fails('call gettagstack()', 'E342:')
482
483  call settagstack(1, {'items' : []})
484  call delete('Xfile1')
485  call delete('Xfile2')
486  call delete('Xfile3')
487  call delete('Xtags')
488  set tags&
489endfunc
490
491func Test_tag_with_count()
492  call writefile([
493	\ 'test	Xtest.h	/^void test();$/;"	p	typeref:typename:void	signature:()',
494	\ ], 'Xtags')
495  call writefile([
496	\ 'main	Xtest.c	/^int main()$/;"	f	typeref:typename:int	signature:()',
497	\ 'test	Xtest.c	/^void test()$/;"	f	typeref:typename:void	signature:()',
498	\ ], 'Ytags')
499  cal writefile([
500	\ 'int main()',
501	\ 'void test()',
502	\ ], 'Xtest.c')
503  cal writefile([
504	\ 'void test();',
505	\ ], 'Xtest.h')
506  set tags=Xtags,Ytags
507
508  new Xtest.c
509  let tl = taglist('test', 'Xtest.c')
510  call assert_equal(tl[0].filename, 'Xtest.c')
511  call assert_equal(tl[1].filename, 'Xtest.h')
512
513  tag test
514  call assert_equal(bufname('%'), 'Xtest.c')
515  1tag test
516  call assert_equal(bufname('%'), 'Xtest.c')
517  2tag test
518  call assert_equal(bufname('%'), 'Xtest.h')
519
520  set tags&
521  call delete('Xtags')
522  call delete('Ytags')
523  bwipe Xtest.h
524  bwipe Xtest.c
525  call delete('Xtest.h')
526  call delete('Xtest.c')
527endfunc
528
529func Test_tagnr_recall()
530  call writefile([
531	\ 'test	Xtest.h	/^void test();$/;"	p',
532	\ 'main	Xtest.c	/^int main()$/;"	f',
533	\ 'test	Xtest.c	/^void test()$/;"	f',
534	\ ], 'Xtags')
535  cal writefile([
536	\ 'int main()',
537	\ 'void test()',
538	\ ], 'Xtest.c')
539  cal writefile([
540	\ 'void test();',
541	\ ], 'Xtest.h')
542  set tags=Xtags
543
544  new Xtest.c
545  let tl = taglist('test', 'Xtest.c')
546  call assert_equal(tl[0].filename, 'Xtest.c')
547  call assert_equal(tl[1].filename, 'Xtest.h')
548
549  2tag test
550  call assert_equal(bufname('%'), 'Xtest.h')
551  pop
552  call assert_equal(bufname('%'), 'Xtest.c')
553  tag
554  call assert_equal(bufname('%'), 'Xtest.h')
555
556  set tags&
557  call delete('Xtags')
558  bwipe Xtest.h
559  bwipe Xtest.c
560  call delete('Xtest.h')
561  call delete('Xtest.c')
562endfunc
563
564func Test_tag_line_toolong()
565  call writefile([
566	\ '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678	django/contrib/admin/templates/admin/edit_inline/stacked.html	16;"	j	line:16	language:HTML'
567	\ ], 'Xtags')
568  set tags=Xtags
569  let old_vbs = &verbose
570  set verbose=5
571  " ":tjump" should give "tag not found" not "Format error in tags file"
572  call assert_fails('tj /foo', 'E426:')
573  try
574    tj /foo
575  catch /^Vim\%((\a\+)\)\=:E431/
576    call assert_report(v:exception)
577  catch /.*/
578  endtry
579  call assert_equal('Searching tags file Xtags', split(execute('messages'), '\n')[-1])
580
581  call writefile([
582	\ '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567	django/contrib/admin/templates/admin/edit_inline/stacked.html	16;"	j	line:16	language:HTML'
583	\ ], 'Xtags')
584  call assert_fails('tj /foo', 'E426:')
585  try
586    tj /foo
587  catch /^Vim\%((\a\+)\)\=:E431/
588    call assert_report(v:exception)
589  catch /.*/
590  endtry
591  call assert_equal('Searching tags file Xtags', split(execute('messages'), '\n')[-1])
592
593  " binary search works in file with long line
594  call writefile([
595        \ 'asdfasfd	nowhere	16',
596	\ 'foobar	Xsomewhere	3; " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567',
597        \ 'zasdfasfd	nowhere	16',
598	\ ], 'Xtags')
599  call writefile([
600        \ 'one',
601        \ 'two',
602        \ 'trhee',
603        \ 'four',
604        \ ], 'Xsomewhere')
605  tag foobar
606  call assert_equal('Xsomewhere', expand('%'))
607  call assert_equal(3, getcurpos()[1])
608
609  " expansion on command line works with long lines when &wildoptions contains
610  " 'tagfile'
611  set wildoptions=tagfile
612  call writefile([
613	\ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa	file	/^pattern$/;"	f'
614	\ ], 'Xtags')
615  call feedkeys(":tag \<Tab>", 'tx')
616  " Should not crash
617  call assert_true(v:true)
618
619  call delete('Xtags')
620  call delete('Xsomewhere')
621  set tags&
622  let &verbose = old_vbs
623endfunc
624
625" Check that using :tselect does not run into the hit-enter prompt.
626" Requires a terminal to trigger that prompt.
627func Test_tselect()
628  CheckScreendump
629
630  call writefile([
631	\ 'main	Xtest.h	/^void test();$/;"	f',
632	\ 'main	Xtest.c	/^int main()$/;"	f',
633	\ 'main	Xtest.x	/^void test()$/;"	f',
634	\ ], 'Xtags')
635  cal writefile([
636	\ 'int main()',
637	\ 'void test()',
638	\ ], 'Xtest.c')
639
640  let lines =<< trim [SCRIPT]
641    set tags=Xtags
642  [SCRIPT]
643  call writefile(lines, 'XTest_tselect')
644  let buf = RunVimInTerminal('-S XTest_tselect', {'rows': 10, 'cols': 50})
645
646  call TermWait(buf, 50)
647  call term_sendkeys(buf, ":tselect main\<CR>2\<CR>")
648  call VerifyScreenDump(buf, 'Test_tselect_1', {})
649
650  call StopVimInTerminal(buf)
651  call delete('Xtags')
652  call delete('Xtest.c')
653  call delete('XTest_tselect')
654endfunc
655
656func Test_tagline()
657  call writefile([
658	\ 'provision	Xtest.py	/^    def provision(self, **kwargs):$/;"	m	line:1	language:Python class:Foo',
659	\ 'provision	Xtest.py	/^    def provision(self, **kwargs):$/;"	m	line:3	language:Python class:Bar',
660	\], 'Xtags')
661  call writefile([
662	\ '    def provision(self, **kwargs):',
663	\ '        pass',
664	\ '    def provision(self, **kwargs):',
665	\ '        pass',
666	\], 'Xtest.py')
667
668  set tags=Xtags
669
670  1tag provision
671  call assert_equal(line('.'), 1)
672  2tag provision
673  call assert_equal(line('.'), 3)
674
675  call delete('Xtags')
676  call delete('Xtest.py')
677  set tags&
678endfunc
679
680" Test for expanding environment variable in a tag file name
681func Test_tag_envvar()
682  call writefile(["Func1\t$FOO\t/^Func1/"], 'Xtags')
683  set tags=Xtags
684
685  let $FOO='TagTestEnv'
686
687  let caught_exception = v:false
688  try
689    tag Func1
690  catch /E429:/
691    call assert_match('E429:.*"TagTestEnv".*', v:exception)
692    let caught_exception = v:true
693  endtry
694  call assert_true(caught_exception)
695
696  set tags&
697  call delete('Xtags')
698  unlet $FOO
699endfunc
700
701" Test for :ptag
702func Test_tag_preview()
703  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
704        \ "second\tXfile1\t2",
705        \ "third\tXfile1\t3",],
706        \ 'Xtags')
707  set tags=Xtags
708  call writefile(['first', 'second', 'third'], 'Xfile1')
709
710  enew | only
711  ptag third
712  call assert_equal(2, winnr())
713  call assert_equal(2, winnr('$'))
714  call assert_equal(1, getwinvar(1, '&previewwindow'))
715  call assert_equal(0, getwinvar(2, '&previewwindow'))
716  wincmd P
717  call assert_equal(3, line('.'))
718
719  " jump to the tag again
720  wincmd w
721  ptag third
722  wincmd P
723  call assert_equal(3, line('.'))
724
725  " jump to the newer tag
726  wincmd w
727  ptag
728  wincmd P
729  call assert_equal(3, line('.'))
730
731  " close the preview window
732  pclose
733  call assert_equal(1, winnr('$'))
734
735  call delete('Xfile1')
736  call delete('Xtags')
737  set tags&
738endfunc
739
740" Tests for guessing the tag location
741func Test_tag_guess()
742  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
743        \ "func1\tXfoo\t/^int func1(int x)/",
744        \ "func2\tXfoo\t/^int func2(int y)/",
745        \ "func3\tXfoo\t/^func3/",
746        \ "func4\tXfoo\t/^func4/"],
747        \ 'Xtags')
748  set tags=Xtags
749  let code =<< trim [CODE]
750
751    int FUNC1  (int x) { }
752    int
753    func2   (int y) { }
754    int * func3 () { }
755
756  [CODE]
757  call writefile(code, 'Xfoo')
758
759  let v:statusmsg = ''
760  ta func1
761  call assert_match('E435:', v:statusmsg)
762  call assert_equal(2, line('.'))
763  let v:statusmsg = ''
764  ta func2
765  call assert_match('E435:', v:statusmsg)
766  call assert_equal(4, line('.'))
767  let v:statusmsg = ''
768  ta func3
769  call assert_match('E435:', v:statusmsg)
770  call assert_equal(5, line('.'))
771  call assert_fails('ta func4', 'E434:')
772
773  call delete('Xtags')
774  call delete('Xfoo')
775  set tags&
776endfunc
777
778" Test for an unsorted tags file
779func Test_tag_sort()
780  call writefile([
781        \ "first\tXfoo\t1",
782        \ "ten\tXfoo\t3",
783        \ "six\tXfoo\t2"],
784        \ 'Xtags')
785  set tags=Xtags
786  let code =<< trim [CODE]
787    int first() {}
788    int six() {}
789    int ten() {}
790  [CODE]
791  call writefile(code, 'Xfoo')
792
793  call assert_fails('tag first', 'E432:')
794
795  call delete('Xtags')
796  call delete('Xfoo')
797  set tags&
798  %bwipe
799endfunc
800
801" Test for an unsorted tags file
802func Test_tag_fold()
803  call writefile([
804        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
805        \ "!_TAG_FILE_SORTED\t2\t/0=unsorted, 1=sorted, 2=foldcase/",
806        \ "first\tXfoo\t1",
807        \ "second\tXfoo\t2",
808        \ "third\tXfoo\t3"],
809        \ 'Xtags')
810  set tags=Xtags
811  let code =<< trim [CODE]
812    int first() {}
813    int second() {}
814    int third() {}
815  [CODE]
816  call writefile(code, 'Xfoo')
817
818  enew
819  tag second
820  call assert_equal('Xfoo', bufname(''))
821  call assert_equal(2, line('.'))
822
823  call delete('Xtags')
824  call delete('Xfoo')
825  set tags&
826  %bwipe
827endfunc
828
829" Test for the :ltag command
830func Test_ltag()
831  call writefile([
832        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
833        \ "first\tXfoo\t1",
834        \ "second\tXfoo\t/^int second() {}$/",
835        \ "third\tXfoo\t3"],
836        \ 'Xtags')
837  set tags=Xtags
838  let code =<< trim [CODE]
839    int first() {}
840    int second() {}
841    int third() {}
842  [CODE]
843  call writefile(code, 'Xfoo')
844
845  enew
846  call setloclist(0, [], 'f')
847  ltag third
848  call assert_equal('Xfoo', bufname(''))
849  call assert_equal(3, line('.'))
850  call assert_equal([{'lnum': 3, 'end_lnum': 0, 'bufnr': bufnr('Xfoo'),
851        \ 'col': 0, 'end_col': 0, 'pattern': '', 'valid': 1, 'vcol': 0,
852        \ 'nr': 0, 'type': '', 'module': '', 'text': 'third'}], getloclist(0))
853
854  ltag second
855  call assert_equal(2, line('.'))
856  call assert_equal([{'lnum': 0, 'end_lnum': 0, 'bufnr': bufnr('Xfoo'),
857        \ 'col': 0, 'end_col': 0, 'pattern': '^\Vint second() {}\$',
858        \ 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'module': '',
859        \ 'text': 'second'}], getloclist(0))
860
861  call delete('Xtags')
862  call delete('Xfoo')
863  set tags&
864  %bwipe
865endfunc
866
867" Test for setting the last search pattern to the tag search pattern
868" when cpoptions has 't'
869func Test_tag_last_search_pat()
870  call writefile([
871        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
872        \ "first\tXfoo\t/^int first() {}/",
873        \ "second\tXfoo\t/^int second() {}/",
874        \ "third\tXfoo\t/^int third() {}/"],
875        \ 'Xtags')
876  set tags=Xtags
877  let code =<< trim [CODE]
878    int first() {}
879    int second() {}
880    int third() {}
881  [CODE]
882  call writefile(code, 'Xfoo')
883
884  enew
885  let save_cpo = &cpo
886  set cpo+=t
887  let @/ = ''
888  tag second
889  call assert_equal('^int second() {}', @/)
890  let &cpo = save_cpo
891
892  call delete('Xtags')
893  call delete('Xfoo')
894  set tags&
895  %bwipe
896endfunc
897
898" Tag stack tests
899func Test_tag_stack()
900  let l = []
901  for i in range(10, 31)
902    let l += ["var" .. i .. "\tXfoo\t/^int var" .. i .. ";$/"]
903  endfor
904  call writefile(l, 'Xtags')
905  set tags=Xtags
906
907  let l = []
908  for i in range(10, 31)
909    let l += ["int var" .. i .. ";"]
910  endfor
911  call writefile(l, 'Xfoo')
912
913  " Jump to a tag when the tag stack is full. Oldest entry should be removed.
914  enew
915  for i in range(10, 30)
916    exe "tag var" .. i
917  endfor
918  let l = gettagstack()
919  call assert_equal(20, l.length)
920  call assert_equal('var11', l.items[0].tagname)
921  tag var31
922  let l = gettagstack()
923  call assert_equal('var12', l.items[0].tagname)
924  call assert_equal('var31', l.items[19].tagname)
925
926  " Use tnext with a single match
927  call assert_fails('tnext', 'E427:')
928
929  " Jump to newest entry from the top of the stack
930  call assert_fails('tag', 'E556:')
931
932  " Pop with zero count from the top of the stack
933  call assert_fails('0pop', 'E556:')
934
935  " Pop from an unsaved buffer
936  enew!
937  call append(1, "sample text")
938  call assert_fails('pop', 'E37:')
939  call assert_equal(21, gettagstack().curidx)
940  enew!
941
942  " Pop all the entries in the tag stack
943  call assert_fails('30pop', 'E555:')
944
945  " Pop with a count when already at the bottom of the stack
946  call assert_fails('exe "normal 4\<C-T>"', 'E555:')
947  call assert_equal(1, gettagstack().curidx)
948
949  " Jump to newest entry from the bottom of the stack with zero count
950  call assert_fails('0tag', 'E555:')
951
952  " Pop the tag stack when it is empty
953  call settagstack(1, {'items' : []})
954  call assert_fails('pop', 'E73:')
955
956  call delete('Xtags')
957  call delete('Xfoo')
958  set tags&
959  %bwipe
960endfunc
961
962" Test for browsing multiple matching tags
963func Test_tag_multimatch()
964  call writefile([
965        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
966        \ "first\tXfoo\t1",
967        \ "first\tXfoo\t2",
968        \ "first\tXfoo\t3"],
969        \ 'Xtags')
970  set tags=Xtags
971  let code =<< trim [CODE]
972    int first() {}
973    int first() {}
974    int first() {}
975  [CODE]
976  call writefile(code, 'Xfoo')
977
978  call settagstack(1, {'items' : []})
979  tag first
980  tlast
981  call assert_equal(3, line('.'))
982  call assert_fails('tnext', 'E428:')
983  tfirst
984  call assert_equal(1, line('.'))
985  call assert_fails('tprev', 'E425:')
986
987  tlast
988  call feedkeys("5\<CR>", 't')
989  tselect first
990  call assert_equal(2, gettagstack().curidx)
991
992  set ignorecase
993  tag FIRST
994  tnext
995  call assert_equal(2, line('.'))
996  tlast
997  tprev
998  call assert_equal(2, line('.'))
999  tNext
1000  call assert_equal(1, line('.'))
1001  set ignorecase&
1002
1003  call delete('Xtags')
1004  call delete('Xfoo')
1005  set tags&
1006  %bwipe
1007endfunc
1008
1009" Test for previewing multiple matching tags
1010func Test_preview_tag_multimatch()
1011  call writefile([
1012        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
1013        \ "first\tXfoo\t1",
1014        \ "first\tXfoo\t2",
1015        \ "first\tXfoo\t3"],
1016        \ 'Xtags')
1017  set tags=Xtags
1018  let code =<< trim [CODE]
1019    int first() {}
1020    int first() {}
1021    int first() {}
1022  [CODE]
1023  call writefile(code, 'Xfoo')
1024
1025  enew | only
1026  ptag first
1027  ptlast
1028  wincmd P
1029  call assert_equal(3, line('.'))
1030  wincmd w
1031  call assert_fails('ptnext', 'E428:')
1032  ptprev
1033  wincmd P
1034  call assert_equal(2, line('.'))
1035  wincmd w
1036  ptfirst
1037  wincmd P
1038  call assert_equal(1, line('.'))
1039  wincmd w
1040  call assert_fails('ptprev', 'E425:')
1041  ptnext
1042  wincmd P
1043  call assert_equal(2, line('.'))
1044  wincmd w
1045  ptlast
1046  call feedkeys("5\<CR>", 't')
1047  ptselect first
1048  wincmd P
1049  call assert_equal(3, line('.'))
1050
1051  pclose
1052
1053  call delete('Xtags')
1054  call delete('Xfoo')
1055  set tags&
1056  %bwipe
1057endfunc
1058
1059" Test for jumping to multiple matching tags across multiple :tags commands
1060func Test_tnext_multimatch()
1061  call writefile([
1062        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
1063        \ "first\tXfoo1\t1",
1064        \ "first\tXfoo2\t1",
1065        \ "first\tXfoo3\t1"],
1066        \ 'Xtags')
1067  set tags=Xtags
1068  let code =<< trim [CODE]
1069    int first() {}
1070  [CODE]
1071  call writefile(code, 'Xfoo1')
1072  call writefile(code, 'Xfoo2')
1073  call writefile(code, 'Xfoo3')
1074
1075  tag first
1076  tag first
1077  pop
1078  tnext
1079  tnext
1080  call assert_fails('tnext', 'E428:')
1081
1082  call delete('Xtags')
1083  call delete('Xfoo1')
1084  call delete('Xfoo2')
1085  call delete('Xfoo3')
1086  set tags&
1087  %bwipe
1088endfunc
1089
1090" Test for jumping to multiple matching tags in non-existing files
1091func Test_multimatch_non_existing_files()
1092  call writefile([
1093        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
1094        \ "first\tXfoo1\t1",
1095        \ "first\tXfoo2\t1",
1096        \ "first\tXfoo3\t1"],
1097        \ 'Xtags')
1098  set tags=Xtags
1099
1100  call settagstack(1, {'items' : []})
1101  call assert_fails('tag first', 'E429:')
1102  call assert_equal(3, gettagstack().items[0].matchnr)
1103
1104  call delete('Xtags')
1105  set tags&
1106  %bwipe
1107endfunc
1108
1109func Test_tselect_listing()
1110  call writefile([
1111        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
1112        \ "first\tXfoo\t1" .. ';"' .. "\tv\ttyperef:typename:int\tfile:",
1113        \ "first\tXfoo\t2" .. ';"' .. "\tkind:v\ttyperef:typename:char\tfile:"],
1114        \ 'Xtags')
1115  set tags=Xtags
1116
1117  let code =<< trim [CODE]
1118    static int first;
1119    static char first;
1120  [CODE]
1121  call writefile(code, 'Xfoo')
1122
1123  call feedkeys("\<CR>", "t")
1124  let l = split(execute("tselect first"), "\n")
1125  let expected =<< [DATA]
1126  # pri kind tag               file
1127  1 FS  v    first             Xfoo
1128               typeref:typename:int
1129               1
1130  2 FS  v    first             Xfoo
1131               typeref:typename:char
1132               2
1133Type number and <Enter> (q or empty cancels):
1134[DATA]
1135  call assert_equal(expected, l)
1136
1137  call delete('Xtags')
1138  call delete('Xfoo')
1139  set tags&
1140  %bwipe
1141endfunc
1142
1143" Test for :isearch, :ilist, :ijump and :isplit commands
1144" Test for [i, ]i, [I, ]I, [ CTRL-I, ] CTRL-I and CTRL-W i commands
1145func Test_inc_search()
1146  new
1147  call setline(1, ['1:foo', '2:foo', 'foo', '3:foo', '4:foo', '==='])
1148  call cursor(3, 1)
1149
1150  " Test for [i and ]i
1151  call assert_equal('1:foo', execute('normal [i'))
1152  call assert_equal('2:foo', execute('normal 2[i'))
1153  call assert_fails('normal 3[i', 'E387:')
1154  call assert_equal('3:foo', execute('normal ]i'))
1155  call assert_equal('4:foo', execute('normal 2]i'))
1156  call assert_fails('normal 3]i', 'E389:')
1157  call assert_fails('normal G]i', 'E349:')
1158  call assert_fails('normal [i', 'E349:')
1159  call cursor(3, 1)
1160
1161  " Test for :isearch
1162  call assert_equal('1:foo', execute('isearch foo'))
1163  call assert_equal('3:foo', execute('isearch 4 /foo/'))
1164  call assert_fails('isearch 3 foo', 'E387:')
1165  call assert_equal('3:foo', execute('+1,$isearch foo'))
1166  call assert_fails('1,.-1isearch 3 foo', 'E389:')
1167  call assert_fails('isearch bar', 'E389:')
1168  call assert_fails('isearch /foo/3', 'E488:')
1169
1170  " Test for [I and ]I
1171  call assert_equal([
1172        \ '  1:    1 1:foo',
1173        \ '  2:    2 2:foo',
1174        \ '  3:    3 foo',
1175        \ '  4:    4 3:foo',
1176        \ '  5:    5 4:foo'], split(execute('normal [I'), "\n"))
1177  call assert_equal([
1178        \ '  1:    4 3:foo',
1179        \ '  2:    5 4:foo'], split(execute('normal ]I'), "\n"))
1180  call assert_fails('normal G]I', 'E349:')
1181  call assert_fails('normal [I', 'E349:')
1182  call cursor(3, 1)
1183
1184  " Test for :ilist
1185  call assert_equal([
1186        \ '  1:    1 1:foo',
1187        \ '  2:    2 2:foo',
1188        \ '  3:    3 foo',
1189        \ '  4:    4 3:foo',
1190        \ '  5:    5 4:foo'], split(execute('ilist foo'), "\n"))
1191  call assert_equal([
1192        \ '  1:    4 3:foo',
1193        \ '  2:    5 4:foo'], split(execute('+1,$ilist /foo/'), "\n"))
1194  call assert_fails('ilist bar', 'E389:')
1195
1196  " Test for [ CTRL-I and ] CTRL-I
1197  exe "normal [\t"
1198  call assert_equal([1, 3], [line('.'), col('.')])
1199  exe "normal 2j4[\t"
1200  call assert_equal([4, 3], [line('.'), col('.')])
1201  call assert_fails("normal k3[\t", 'E387:')
1202  call assert_fails("normal 6[\t", 'E389:')
1203  exe "normal ]\t"
1204  call assert_equal([4, 3], [line('.'), col('.')])
1205  exe "normal k2]\t"
1206  call assert_equal([5, 3], [line('.'), col('.')])
1207  call assert_fails("normal 2k3]\t", 'E389:')
1208  call assert_fails("normal G[\t", 'E349:')
1209  call assert_fails("normal ]\t", 'E349:')
1210  call cursor(3, 1)
1211
1212  " Test for :ijump
1213  call cursor(3, 1)
1214  ijump foo
1215  call assert_equal([1, 3], [line('.'), col('.')])
1216  call cursor(3, 1)
1217  ijump 4 /foo/
1218  call assert_equal([4, 3], [line('.'), col('.')])
1219  call cursor(3, 1)
1220  call assert_fails('ijump 3 foo', 'E387:')
1221  +,$ijump 2 foo
1222  call assert_equal([5, 3], [line('.'), col('.')])
1223  call assert_fails('ijump bar', 'E389:')
1224
1225  " Test for CTRL-W i
1226  call cursor(3, 1)
1227  wincmd i
1228  call assert_equal([1, 3, 3], [line('.'), col('.'), winnr('$')])
1229  close
1230  5wincmd i
1231  call assert_equal([5, 3, 3], [line('.'), col('.'), winnr('$')])
1232  close
1233  call assert_fails('3wincmd i', 'E387:')
1234  call assert_fails('6wincmd i', 'E389:')
1235  call assert_fails("normal G\<C-W>i", 'E349:')
1236  call cursor(3, 1)
1237
1238  " Test for :isplit
1239  isplit foo
1240  call assert_equal([1, 3, 3], [line('.'), col('.'), winnr('$')])
1241  close
1242  isplit 5 /foo/
1243  call assert_equal([5, 3, 3], [line('.'), col('.'), winnr('$')])
1244  close
1245  call assert_fails('isplit 3 foo', 'E387:')
1246  call assert_fails('isplit 6 foo', 'E389:')
1247  call assert_fails('isplit bar', 'E389:')
1248
1249  close!
1250endfunc
1251
1252" Test for :dsearch, :dlist, :djump and :dsplit commands
1253" Test for [d, ]d, [D, ]D, [ CTRL-D, ] CTRL-D and CTRL-W d commands
1254func Test_macro_search()
1255  new
1256  call setline(1, ['#define FOO 1', '#define FOO 2', '#define FOO 3',
1257        \ '#define FOO 4', '#define FOO 5'])
1258  call cursor(3, 9)
1259
1260  " Test for [d and ]d
1261  call assert_equal('#define FOO 1', execute('normal [d'))
1262  call assert_equal('#define FOO 2', execute('normal 2[d'))
1263  call assert_fails('normal 3[d', 'E387:')
1264  call assert_equal('#define FOO 4', execute('normal ]d'))
1265  call assert_equal('#define FOO 5', execute('normal 2]d'))
1266  call assert_fails('normal 3]d', 'E388:')
1267
1268  " Test for :dsearch
1269  call assert_equal('#define FOO 1', execute('dsearch FOO'))
1270  call assert_equal('#define FOO 5', execute('dsearch 5 /FOO/'))
1271  call assert_fails('dsearch 3 FOO', 'E387:')
1272  call assert_equal('#define FOO 4', execute('+1,$dsearch FOO'))
1273  call assert_fails('1,.-1dsearch 3 FOO', 'E388:')
1274  call assert_fails('dsearch BAR', 'E388:')
1275
1276  " Test for [D and ]D
1277  call assert_equal([
1278        \ '  1:    1 #define FOO 1',
1279        \ '  2:    2 #define FOO 2',
1280        \ '  3:    3 #define FOO 3',
1281        \ '  4:    4 #define FOO 4',
1282        \ '  5:    5 #define FOO 5'], split(execute('normal [D'), "\n"))
1283  call assert_equal([
1284        \ '  1:    4 #define FOO 4',
1285        \ '  2:    5 #define FOO 5'], split(execute('normal ]D'), "\n"))
1286
1287  " Test for :dlist
1288  call assert_equal([
1289        \ '  1:    1 #define FOO 1',
1290        \ '  2:    2 #define FOO 2',
1291        \ '  3:    3 #define FOO 3',
1292        \ '  4:    4 #define FOO 4',
1293        \ '  5:    5 #define FOO 5'], split(execute('dlist FOO'), "\n"))
1294  call assert_equal([
1295        \ '  1:    4 #define FOO 4',
1296        \ '  2:    5 #define FOO 5'], split(execute('+1,$dlist /FOO/'), "\n"))
1297  call assert_fails('dlist BAR', 'E388:')
1298
1299  " Test for [ CTRL-D and ] CTRL-D
1300  exe "normal [\<C-D>"
1301  call assert_equal([1, 9], [line('.'), col('.')])
1302  exe "normal 2j4[\<C-D>"
1303  call assert_equal([4, 9], [line('.'), col('.')])
1304  call assert_fails("normal k3[\<C-D>", 'E387:')
1305  call assert_fails("normal 6[\<C-D>", 'E388:')
1306  exe "normal ]\<C-D>"
1307  call assert_equal([4, 9], [line('.'), col('.')])
1308  exe "normal k2]\<C-D>"
1309  call assert_equal([5, 9], [line('.'), col('.')])
1310  call assert_fails("normal 2k3]\<C-D>", 'E388:')
1311
1312  " Test for :djump
1313  call cursor(3, 9)
1314  djump FOO
1315  call assert_equal([1, 9], [line('.'), col('.')])
1316  call cursor(3, 9)
1317  djump 4 /FOO/
1318  call assert_equal([4, 9], [line('.'), col('.')])
1319  call cursor(3, 9)
1320  call assert_fails('djump 3 FOO', 'E387:')
1321  +,$djump 2 FOO
1322  call assert_equal([5, 9], [line('.'), col('.')])
1323  call assert_fails('djump BAR', 'E388:')
1324
1325  " Test for CTRL-W d
1326  call cursor(3, 9)
1327  wincmd d
1328  call assert_equal([1, 9, 3], [line('.'), col('.'), winnr('$')])
1329  close
1330  5wincmd d
1331  call assert_equal([5, 9, 3], [line('.'), col('.'), winnr('$')])
1332  close
1333  call assert_fails('3wincmd d', 'E387:')
1334  call assert_fails('6wincmd d', 'E388:')
1335  new
1336  call assert_fails("normal \<C-W>d", 'E349:')
1337  call assert_fails("normal \<C-W>\<C-D>", 'E349:')
1338  close
1339
1340  " Test for :dsplit
1341  dsplit FOO
1342  call assert_equal([1, 9, 3], [line('.'), col('.'), winnr('$')])
1343  close
1344  dsplit 5 /FOO/
1345  call assert_equal([5, 9, 3], [line('.'), col('.'), winnr('$')])
1346  close
1347  call assert_fails('dsplit 3 FOO', 'E387:')
1348  call assert_fails('dsplit 6 FOO', 'E388:')
1349  call assert_fails('dsplit BAR', 'E388:')
1350
1351  close!
1352endfunc
1353
1354" Test for [*, [/, ]* and ]/
1355func Test_comment_search()
1356  new
1357  call setline(1, ['', '/*', ' *', ' *', ' */'])
1358  normal! 4gg[/
1359  call assert_equal([2, 1], [line('.'), col('.')])
1360  normal! 3gg[*
1361  call assert_equal([2, 1], [line('.'), col('.')])
1362  normal! 3gg]/
1363  call assert_equal([5, 3], [line('.'), col('.')])
1364  normal! 3gg]*
1365  call assert_equal([5, 3], [line('.'), col('.')])
1366  %d
1367  call setline(1, ['', '/*', ' *', ' *'])
1368  call assert_beeps('normal! 3gg]/')
1369  %d
1370  call setline(1, ['', ' *', ' *', ' */'])
1371  call assert_beeps('normal! 4gg[/')
1372  %d
1373  call setline(1, '        /* comment */')
1374  normal! 15|[/
1375  call assert_equal(9, col('.'))
1376  normal! 15|]/
1377  call assert_equal(21, col('.'))
1378  call setline(1, '         comment */')
1379  call assert_beeps('normal! 15|[/')
1380  call setline(1, '        /* comment')
1381  call assert_beeps('normal! 15|]/')
1382  close!
1383endfunc
1384
1385" Test for the 'taglength' option
1386func Test_tag_length()
1387  set tags=Xtags
1388  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
1389        \ "tame\tXfile1\t1;",
1390        \ "tape\tXfile2\t1;"], 'Xtags')
1391  call writefile(['tame'], 'Xfile1')
1392  call writefile(['tape'], 'Xfile2')
1393
1394  " Jumping to the tag 'tape', should instead jump to 'tame'
1395  new
1396  set taglength=2
1397  tag tape
1398  call assert_equal('Xfile1', @%)
1399  " Tag search should jump to the right tag
1400  enew
1401  tag /^tape$
1402  call assert_equal('Xfile2', @%)
1403
1404  call delete('Xtags')
1405  call delete('Xfile1')
1406  call delete('Xfile2')
1407  set tags& taglength&
1408endfunc
1409
1410" Tests for errors in a tags file
1411func Test_tagfile_errors()
1412  set tags=Xtags
1413
1414  " missing search pattern or line number for a tag
1415  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
1416        \ "foo\tXfile\t"], 'Xtags', 'b')
1417  call writefile(['foo'], 'Xfile')
1418
1419  enew
1420  tag foo
1421  call assert_equal('', @%)
1422  let caught_431 = v:false
1423  try
1424    eval taglist('.*')
1425  catch /:E431:/
1426    let caught_431 = v:true
1427  endtry
1428  call assert_equal(v:true, caught_431)
1429
1430  call delete('Xtags')
1431  call delete('Xfile')
1432  set tags&
1433endfunc
1434
1435" When :stag fails to open the file, should close the new window
1436func Test_stag_close_window_on_error()
1437  new | only
1438  set tags=Xtags
1439  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
1440        \ "foo\tXfile\t1"], 'Xtags')
1441  call writefile(['foo'], 'Xfile')
1442  call writefile([], '.Xfile.swp')
1443  " Remove the catch-all that runtest.vim adds
1444  au! SwapExists
1445  augroup StagTest
1446    au!
1447    autocmd SwapExists Xfile let v:swapchoice='q'
1448  augroup END
1449
1450  stag foo
1451  call assert_equal(1, winnr('$'))
1452  call assert_equal('', @%)
1453
1454  augroup StagTest
1455    au!
1456  augroup END
1457  call delete('Xfile')
1458  call delete('.Xfile.swp')
1459  set tags&
1460endfunc
1461
1462" vim: shiftwidth=2 sts=2 expandtab
1463