xref: /vim-8.2.3635/src/testdir/test_tagjump.vim (revision a0122dcd)
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  call delete('Xtags')
610  call delete('Xsomewhere')
611  set tags&
612  let &verbose = old_vbs
613endfunc
614
615" Check that using :tselect does not run into the hit-enter prompt.
616" Requires a terminal to trigger that prompt.
617func Test_tselect()
618  CheckScreendump
619
620  call writefile([
621	\ 'main	Xtest.h	/^void test();$/;"	f',
622	\ 'main	Xtest.c	/^int main()$/;"	f',
623	\ 'main	Xtest.x	/^void test()$/;"	f',
624	\ ], 'Xtags')
625  cal writefile([
626	\ 'int main()',
627	\ 'void test()',
628	\ ], 'Xtest.c')
629
630  let lines =<< trim [SCRIPT]
631    set tags=Xtags
632  [SCRIPT]
633  call writefile(lines, 'XTest_tselect')
634  let buf = RunVimInTerminal('-S XTest_tselect', {'rows': 10, 'cols': 50})
635
636  call TermWait(buf, 50)
637  call term_sendkeys(buf, ":tselect main\<CR>2\<CR>")
638  call VerifyScreenDump(buf, 'Test_tselect_1', {})
639
640  call StopVimInTerminal(buf)
641  call delete('Xtags')
642  call delete('Xtest.c')
643  call delete('XTest_tselect')
644endfunc
645
646func Test_tagline()
647  call writefile([
648	\ 'provision	Xtest.py	/^    def provision(self, **kwargs):$/;"	m	line:1	language:Python class:Foo',
649	\ 'provision	Xtest.py	/^    def provision(self, **kwargs):$/;"	m	line:3	language:Python class:Bar',
650	\], 'Xtags')
651  call writefile([
652	\ '    def provision(self, **kwargs):',
653	\ '        pass',
654	\ '    def provision(self, **kwargs):',
655	\ '        pass',
656	\], 'Xtest.py')
657
658  set tags=Xtags
659
660  1tag provision
661  call assert_equal(line('.'), 1)
662  2tag provision
663  call assert_equal(line('.'), 3)
664
665  call delete('Xtags')
666  call delete('Xtest.py')
667  set tags&
668endfunc
669
670" Test for expanding environment variable in a tag file name
671func Test_tag_envvar()
672  call writefile(["Func1\t$FOO\t/^Func1/"], 'Xtags')
673  set tags=Xtags
674
675  let $FOO='TagTestEnv'
676
677  let caught_exception = v:false
678  try
679    tag Func1
680  catch /E429:/
681    call assert_match('E429:.*"TagTestEnv".*', v:exception)
682    let caught_exception = v:true
683  endtry
684  call assert_true(caught_exception)
685
686  set tags&
687  call delete('Xtags')
688  unlet $FOO
689endfunc
690
691" Test for :ptag
692func Test_tag_preview()
693  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
694        \ "second\tXfile1\t2",
695        \ "third\tXfile1\t3",],
696        \ 'Xtags')
697  set tags=Xtags
698  call writefile(['first', 'second', 'third'], 'Xfile1')
699
700  enew | only
701  ptag third
702  call assert_equal(2, winnr())
703  call assert_equal(2, winnr('$'))
704  call assert_equal(1, getwinvar(1, '&previewwindow'))
705  call assert_equal(0, getwinvar(2, '&previewwindow'))
706  wincmd P
707  call assert_equal(3, line('.'))
708
709  " jump to the tag again
710  wincmd w
711  ptag third
712  wincmd P
713  call assert_equal(3, line('.'))
714
715  " jump to the newer tag
716  wincmd w
717  ptag
718  wincmd P
719  call assert_equal(3, line('.'))
720
721  " close the preview window
722  pclose
723  call assert_equal(1, winnr('$'))
724
725  call delete('Xfile1')
726  call delete('Xtags')
727  set tags&
728endfunc
729
730" Tests for guessing the tag location
731func Test_tag_guess()
732  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
733        \ "func1\tXfoo\t/^int func1(int x)/",
734        \ "func2\tXfoo\t/^int func2(int y)/",
735        \ "func3\tXfoo\t/^func3/",
736        \ "func4\tXfoo\t/^func4/"],
737        \ 'Xtags')
738  set tags=Xtags
739  let code =<< trim [CODE]
740
741    int FUNC1  (int x) { }
742    int
743    func2   (int y) { }
744    int * func3 () { }
745
746  [CODE]
747  call writefile(code, 'Xfoo')
748
749  let v:statusmsg = ''
750  ta func1
751  call assert_match('E435:', v:statusmsg)
752  call assert_equal(2, line('.'))
753  let v:statusmsg = ''
754  ta func2
755  call assert_match('E435:', v:statusmsg)
756  call assert_equal(4, line('.'))
757  let v:statusmsg = ''
758  ta func3
759  call assert_match('E435:', v:statusmsg)
760  call assert_equal(5, line('.'))
761  call assert_fails('ta func4', 'E434:')
762
763  call delete('Xtags')
764  call delete('Xfoo')
765  set tags&
766endfunc
767
768" Test for an unsorted tags file
769func Test_tag_sort()
770  call writefile([
771        \ "first\tXfoo\t1",
772        \ "ten\tXfoo\t3",
773        \ "six\tXfoo\t2"],
774        \ 'Xtags')
775  set tags=Xtags
776  let code =<< trim [CODE]
777    int first() {}
778    int six() {}
779    int ten() {}
780  [CODE]
781  call writefile(code, 'Xfoo')
782
783  call assert_fails('tag first', 'E432:')
784
785  call delete('Xtags')
786  call delete('Xfoo')
787  set tags&
788  %bwipe
789endfunc
790
791" Test for an unsorted tags file
792func Test_tag_fold()
793  call writefile([
794        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
795        \ "!_TAG_FILE_SORTED\t2\t/0=unsorted, 1=sorted, 2=foldcase/",
796        \ "first\tXfoo\t1",
797        \ "second\tXfoo\t2",
798        \ "third\tXfoo\t3"],
799        \ 'Xtags')
800  set tags=Xtags
801  let code =<< trim [CODE]
802    int first() {}
803    int second() {}
804    int third() {}
805  [CODE]
806  call writefile(code, 'Xfoo')
807
808  enew
809  tag second
810  call assert_equal('Xfoo', bufname(''))
811  call assert_equal(2, line('.'))
812
813  call delete('Xtags')
814  call delete('Xfoo')
815  set tags&
816  %bwipe
817endfunc
818
819" Test for the :ltag command
820func Test_ltag()
821  call writefile([
822        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
823        \ "first\tXfoo\t1",
824        \ "second\tXfoo\t/^int second() {}$/",
825        \ "third\tXfoo\t3"],
826        \ 'Xtags')
827  set tags=Xtags
828  let code =<< trim [CODE]
829    int first() {}
830    int second() {}
831    int third() {}
832  [CODE]
833  call writefile(code, 'Xfoo')
834
835  enew
836  call setloclist(0, [], 'f')
837  ltag third
838  call assert_equal('Xfoo', bufname(''))
839  call assert_equal(3, line('.'))
840  call assert_equal([{'lnum': 3, 'bufnr': bufnr('Xfoo'), 'col': 0,
841        \ 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '',
842        \ 'module': '', 'text': 'third'}], getloclist(0))
843
844  ltag second
845  call assert_equal(2, line('.'))
846  call assert_equal([{'lnum': 0, 'bufnr': bufnr('Xfoo'), 'col': 0,
847        \ 'pattern': '^\Vint second() {}\$', 'valid': 1, 'vcol': 0, 'nr': 0,
848        \ 'type': '', 'module': '', 'text': 'second'}], getloclist(0))
849
850  call delete('Xtags')
851  call delete('Xfoo')
852  set tags&
853  %bwipe
854endfunc
855
856" Test for setting the last search pattern to the tag search pattern
857" when cpoptions has 't'
858func Test_tag_last_search_pat()
859  call writefile([
860        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
861        \ "first\tXfoo\t/^int first() {}/",
862        \ "second\tXfoo\t/^int second() {}/",
863        \ "third\tXfoo\t/^int third() {}/"],
864        \ 'Xtags')
865  set tags=Xtags
866  let code =<< trim [CODE]
867    int first() {}
868    int second() {}
869    int third() {}
870  [CODE]
871  call writefile(code, 'Xfoo')
872
873  enew
874  let save_cpo = &cpo
875  set cpo+=t
876  let @/ = ''
877  tag second
878  call assert_equal('^int second() {}', @/)
879  let &cpo = save_cpo
880
881  call delete('Xtags')
882  call delete('Xfoo')
883  set tags&
884  %bwipe
885endfunc
886
887" Tag stack tests
888func Test_tag_stack()
889  let l = []
890  for i in range(10, 31)
891    let l += ["var" .. i .. "\tXfoo\t/^int var" .. i .. ";$/"]
892  endfor
893  call writefile(l, 'Xtags')
894  set tags=Xtags
895
896  let l = []
897  for i in range(10, 31)
898    let l += ["int var" .. i .. ";"]
899  endfor
900  call writefile(l, 'Xfoo')
901
902  " Jump to a tag when the tag stack is full. Oldest entry should be removed.
903  enew
904  for i in range(10, 30)
905    exe "tag var" .. i
906  endfor
907  let l = gettagstack()
908  call assert_equal(20, l.length)
909  call assert_equal('var11', l.items[0].tagname)
910  tag var31
911  let l = gettagstack()
912  call assert_equal('var12', l.items[0].tagname)
913  call assert_equal('var31', l.items[19].tagname)
914
915  " Use tnext with a single match
916  call assert_fails('tnext', 'E427:')
917
918  " Jump to newest entry from the top of the stack
919  call assert_fails('tag', 'E556:')
920
921  " Pop with zero count from the top of the stack
922  call assert_fails('0pop', 'E556:')
923
924  " Pop from an unsaved buffer
925  enew!
926  call append(1, "sample text")
927  call assert_fails('pop', 'E37:')
928  call assert_equal(21, gettagstack().curidx)
929  enew!
930
931  " Pop all the entries in the tag stack
932  call assert_fails('30pop', 'E555:')
933
934  " Pop with a count when already at the bottom of the stack
935  call assert_fails('exe "normal 4\<C-T>"', 'E555:')
936  call assert_equal(1, gettagstack().curidx)
937
938  " Jump to newest entry from the bottom of the stack with zero count
939  call assert_fails('0tag', 'E555:')
940
941  " Pop the tag stack when it is empty
942  call settagstack(1, {'items' : []})
943  call assert_fails('pop', 'E73:')
944
945  call delete('Xtags')
946  call delete('Xfoo')
947  set tags&
948  %bwipe
949endfunc
950
951" Test for browsing multiple matching tags
952func Test_tag_multimatch()
953  call writefile([
954        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
955        \ "first\tXfoo\t1",
956        \ "first\tXfoo\t2",
957        \ "first\tXfoo\t3"],
958        \ 'Xtags')
959  set tags=Xtags
960  let code =<< trim [CODE]
961    int first() {}
962    int first() {}
963    int first() {}
964  [CODE]
965  call writefile(code, 'Xfoo')
966
967  call settagstack(1, {'items' : []})
968  tag first
969  tlast
970  call assert_equal(3, line('.'))
971  call assert_fails('tnext', 'E428:')
972  tfirst
973  call assert_equal(1, line('.'))
974  call assert_fails('tprev', 'E425:')
975
976  tlast
977  call feedkeys("5\<CR>", 't')
978  tselect first
979  call assert_equal(2, gettagstack().curidx)
980
981  set ignorecase
982  tag FIRST
983  tnext
984  call assert_equal(2, line('.'))
985  tlast
986  tprev
987  call assert_equal(2, line('.'))
988  tNext
989  call assert_equal(1, line('.'))
990  set ignorecase&
991
992  call delete('Xtags')
993  call delete('Xfoo')
994  set tags&
995  %bwipe
996endfunc
997
998" Test for previewing multiple matching tags
999func Test_preview_tag_multimatch()
1000  call writefile([
1001        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
1002        \ "first\tXfoo\t1",
1003        \ "first\tXfoo\t2",
1004        \ "first\tXfoo\t3"],
1005        \ 'Xtags')
1006  set tags=Xtags
1007  let code =<< trim [CODE]
1008    int first() {}
1009    int first() {}
1010    int first() {}
1011  [CODE]
1012  call writefile(code, 'Xfoo')
1013
1014  enew | only
1015  ptag first
1016  ptlast
1017  wincmd P
1018  call assert_equal(3, line('.'))
1019  wincmd w
1020  call assert_fails('ptnext', 'E428:')
1021  ptprev
1022  wincmd P
1023  call assert_equal(2, line('.'))
1024  wincmd w
1025  ptfirst
1026  wincmd P
1027  call assert_equal(1, line('.'))
1028  wincmd w
1029  call assert_fails('ptprev', 'E425:')
1030  ptnext
1031  wincmd P
1032  call assert_equal(2, line('.'))
1033  wincmd w
1034  ptlast
1035  call feedkeys("5\<CR>", 't')
1036  ptselect first
1037  wincmd P
1038  call assert_equal(3, line('.'))
1039
1040  pclose
1041
1042  call delete('Xtags')
1043  call delete('Xfoo')
1044  set tags&
1045  %bwipe
1046endfunc
1047
1048" Test for jumping to multiple matching tags across multiple :tags commands
1049func Test_tnext_multimatch()
1050  call writefile([
1051        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
1052        \ "first\tXfoo1\t1",
1053        \ "first\tXfoo2\t1",
1054        \ "first\tXfoo3\t1"],
1055        \ 'Xtags')
1056  set tags=Xtags
1057  let code =<< trim [CODE]
1058    int first() {}
1059  [CODE]
1060  call writefile(code, 'Xfoo1')
1061  call writefile(code, 'Xfoo2')
1062  call writefile(code, 'Xfoo3')
1063
1064  tag first
1065  tag first
1066  pop
1067  tnext
1068  tnext
1069  call assert_fails('tnext', 'E428:')
1070
1071  call delete('Xtags')
1072  call delete('Xfoo1')
1073  call delete('Xfoo2')
1074  call delete('Xfoo3')
1075  set tags&
1076  %bwipe
1077endfunc
1078
1079" Test for jumping to multiple matching tags in non-existing files
1080func Test_multimatch_non_existing_files()
1081  call writefile([
1082        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
1083        \ "first\tXfoo1\t1",
1084        \ "first\tXfoo2\t1",
1085        \ "first\tXfoo3\t1"],
1086        \ 'Xtags')
1087  set tags=Xtags
1088
1089  call settagstack(1, {'items' : []})
1090  call assert_fails('tag first', 'E429:')
1091  call assert_equal(3, gettagstack().items[0].matchnr)
1092
1093  call delete('Xtags')
1094  set tags&
1095  %bwipe
1096endfunc
1097
1098func Test_tselect_listing()
1099  call writefile([
1100        \ "!_TAG_FILE_ENCODING\tutf-8\t//",
1101        \ "first\tXfoo\t1" .. ';"' .. "\tv\ttyperef:typename:int\tfile:",
1102        \ "first\tXfoo\t2" .. ';"' .. "\tkind:v\ttyperef:typename:char\tfile:"],
1103        \ 'Xtags')
1104  set tags=Xtags
1105
1106  let code =<< trim [CODE]
1107    static int first;
1108    static char first;
1109  [CODE]
1110  call writefile(code, 'Xfoo')
1111
1112  call feedkeys("\<CR>", "t")
1113  let l = split(execute("tselect first"), "\n")
1114  let expected =<< [DATA]
1115  # pri kind tag               file
1116  1 FS  v    first             Xfoo
1117               typeref:typename:int
1118               1
1119  2 FS  v    first             Xfoo
1120               typeref:typename:char
1121               2
1122Type number and <Enter> (q or empty cancels):
1123[DATA]
1124  call assert_equal(expected, l)
1125
1126  call delete('Xtags')
1127  call delete('Xfoo')
1128  set tags&
1129  %bwipe
1130endfunc
1131
1132" Test for :isearch, :ilist, :ijump and :isplit commands
1133" Test for [i, ]i, [I, ]I, [ CTRL-I, ] CTRL-I and CTRL-W i commands
1134func Test_inc_search()
1135  new
1136  call setline(1, ['1:foo', '2:foo', 'foo', '3:foo', '4:foo', '==='])
1137  call cursor(3, 1)
1138
1139  " Test for [i and ]i
1140  call assert_equal('1:foo', execute('normal [i'))
1141  call assert_equal('2:foo', execute('normal 2[i'))
1142  call assert_fails('normal 3[i', 'E387:')
1143  call assert_equal('3:foo', execute('normal ]i'))
1144  call assert_equal('4:foo', execute('normal 2]i'))
1145  call assert_fails('normal 3]i', 'E389:')
1146  call assert_fails('normal G]i', 'E349:')
1147  call assert_fails('normal [i', 'E349:')
1148  call cursor(3, 1)
1149
1150  " Test for :isearch
1151  call assert_equal('1:foo', execute('isearch foo'))
1152  call assert_equal('3:foo', execute('isearch 4 /foo/'))
1153  call assert_fails('isearch 3 foo', 'E387:')
1154  call assert_equal('3:foo', execute('+1,$isearch foo'))
1155  call assert_fails('1,.-1isearch 3 foo', 'E389:')
1156  call assert_fails('isearch bar', 'E389:')
1157  call assert_fails('isearch /foo/3', 'E488:')
1158
1159  " Test for [I and ]I
1160  call assert_equal([
1161        \ '  1:    1 1:foo',
1162        \ '  2:    2 2:foo',
1163        \ '  3:    3 foo',
1164        \ '  4:    4 3:foo',
1165        \ '  5:    5 4:foo'], split(execute('normal [I'), "\n"))
1166  call assert_equal([
1167        \ '  1:    4 3:foo',
1168        \ '  2:    5 4:foo'], split(execute('normal ]I'), "\n"))
1169  call assert_fails('normal G]I', 'E349:')
1170  call assert_fails('normal [I', 'E349:')
1171  call cursor(3, 1)
1172
1173  " Test for :ilist
1174  call assert_equal([
1175        \ '  1:    1 1:foo',
1176        \ '  2:    2 2:foo',
1177        \ '  3:    3 foo',
1178        \ '  4:    4 3:foo',
1179        \ '  5:    5 4:foo'], split(execute('ilist foo'), "\n"))
1180  call assert_equal([
1181        \ '  1:    4 3:foo',
1182        \ '  2:    5 4:foo'], split(execute('+1,$ilist /foo/'), "\n"))
1183  call assert_fails('ilist bar', 'E389:')
1184
1185  " Test for [ CTRL-I and ] CTRL-I
1186  exe "normal [\t"
1187  call assert_equal([1, 3], [line('.'), col('.')])
1188  exe "normal 2j4[\t"
1189  call assert_equal([4, 3], [line('.'), col('.')])
1190  call assert_fails("normal k3[\t", 'E387:')
1191  call assert_fails("normal 6[\t", 'E389:')
1192  exe "normal ]\t"
1193  call assert_equal([4, 3], [line('.'), col('.')])
1194  exe "normal k2]\t"
1195  call assert_equal([5, 3], [line('.'), col('.')])
1196  call assert_fails("normal 2k3]\t", 'E389:')
1197  call assert_fails("normal G[\t", 'E349:')
1198  call assert_fails("normal ]\t", 'E349:')
1199  call cursor(3, 1)
1200
1201  " Test for :ijump
1202  call cursor(3, 1)
1203  ijump foo
1204  call assert_equal([1, 3], [line('.'), col('.')])
1205  call cursor(3, 1)
1206  ijump 4 /foo/
1207  call assert_equal([4, 3], [line('.'), col('.')])
1208  call cursor(3, 1)
1209  call assert_fails('ijump 3 foo', 'E387:')
1210  +,$ijump 2 foo
1211  call assert_equal([5, 3], [line('.'), col('.')])
1212  call assert_fails('ijump bar', 'E389:')
1213
1214  " Test for CTRL-W i
1215  call cursor(3, 1)
1216  wincmd i
1217  call assert_equal([1, 3, 3], [line('.'), col('.'), winnr('$')])
1218  close
1219  5wincmd i
1220  call assert_equal([5, 3, 3], [line('.'), col('.'), winnr('$')])
1221  close
1222  call assert_fails('3wincmd i', 'E387:')
1223  call assert_fails('6wincmd i', 'E389:')
1224  call assert_fails("normal G\<C-W>i", 'E349:')
1225  call cursor(3, 1)
1226
1227  " Test for :isplit
1228  isplit foo
1229  call assert_equal([1, 3, 3], [line('.'), col('.'), winnr('$')])
1230  close
1231  isplit 5 /foo/
1232  call assert_equal([5, 3, 3], [line('.'), col('.'), winnr('$')])
1233  close
1234  call assert_fails('isplit 3 foo', 'E387:')
1235  call assert_fails('isplit 6 foo', 'E389:')
1236  call assert_fails('isplit bar', 'E389:')
1237
1238  close!
1239endfunc
1240
1241" Test for :dsearch, :dlist, :djump and :dsplit commands
1242" Test for [d, ]d, [D, ]D, [ CTRL-D, ] CTRL-D and CTRL-W d commands
1243func Test_macro_search()
1244  new
1245  call setline(1, ['#define FOO 1', '#define FOO 2', '#define FOO 3',
1246        \ '#define FOO 4', '#define FOO 5'])
1247  call cursor(3, 9)
1248
1249  " Test for [d and ]d
1250  call assert_equal('#define FOO 1', execute('normal [d'))
1251  call assert_equal('#define FOO 2', execute('normal 2[d'))
1252  call assert_fails('normal 3[d', 'E387:')
1253  call assert_equal('#define FOO 4', execute('normal ]d'))
1254  call assert_equal('#define FOO 5', execute('normal 2]d'))
1255  call assert_fails('normal 3]d', 'E388:')
1256
1257  " Test for :dsearch
1258  call assert_equal('#define FOO 1', execute('dsearch FOO'))
1259  call assert_equal('#define FOO 5', execute('dsearch 5 /FOO/'))
1260  call assert_fails('dsearch 3 FOO', 'E387:')
1261  call assert_equal('#define FOO 4', execute('+1,$dsearch FOO'))
1262  call assert_fails('1,.-1dsearch 3 FOO', 'E388:')
1263  call assert_fails('dsearch BAR', 'E388:')
1264
1265  " Test for [D and ]D
1266  call assert_equal([
1267        \ '  1:    1 #define FOO 1',
1268        \ '  2:    2 #define FOO 2',
1269        \ '  3:    3 #define FOO 3',
1270        \ '  4:    4 #define FOO 4',
1271        \ '  5:    5 #define FOO 5'], split(execute('normal [D'), "\n"))
1272  call assert_equal([
1273        \ '  1:    4 #define FOO 4',
1274        \ '  2:    5 #define FOO 5'], split(execute('normal ]D'), "\n"))
1275
1276  " Test for :dlist
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('dlist FOO'), "\n"))
1283  call assert_equal([
1284        \ '  1:    4 #define FOO 4',
1285        \ '  2:    5 #define FOO 5'], split(execute('+1,$dlist /FOO/'), "\n"))
1286  call assert_fails('dlist BAR', 'E388:')
1287
1288  " Test for [ CTRL-D and ] CTRL-D
1289  exe "normal [\<C-D>"
1290  call assert_equal([1, 9], [line('.'), col('.')])
1291  exe "normal 2j4[\<C-D>"
1292  call assert_equal([4, 9], [line('.'), col('.')])
1293  call assert_fails("normal k3[\<C-D>", 'E387:')
1294  call assert_fails("normal 6[\<C-D>", 'E388:')
1295  exe "normal ]\<C-D>"
1296  call assert_equal([4, 9], [line('.'), col('.')])
1297  exe "normal k2]\<C-D>"
1298  call assert_equal([5, 9], [line('.'), col('.')])
1299  call assert_fails("normal 2k3]\<C-D>", 'E388:')
1300
1301  " Test for :djump
1302  call cursor(3, 9)
1303  djump FOO
1304  call assert_equal([1, 9], [line('.'), col('.')])
1305  call cursor(3, 9)
1306  djump 4 /FOO/
1307  call assert_equal([4, 9], [line('.'), col('.')])
1308  call cursor(3, 9)
1309  call assert_fails('djump 3 FOO', 'E387:')
1310  +,$djump 2 FOO
1311  call assert_equal([5, 9], [line('.'), col('.')])
1312  call assert_fails('djump BAR', 'E388:')
1313
1314  " Test for CTRL-W d
1315  call cursor(3, 9)
1316  wincmd d
1317  call assert_equal([1, 9, 3], [line('.'), col('.'), winnr('$')])
1318  close
1319  5wincmd d
1320  call assert_equal([5, 9, 3], [line('.'), col('.'), winnr('$')])
1321  close
1322  call assert_fails('3wincmd d', 'E387:')
1323  call assert_fails('6wincmd d', 'E388:')
1324  new
1325  call assert_fails("normal \<C-W>d", 'E349:')
1326  call assert_fails("normal \<C-W>\<C-D>", 'E349:')
1327  close
1328
1329  " Test for :dsplit
1330  dsplit FOO
1331  call assert_equal([1, 9, 3], [line('.'), col('.'), winnr('$')])
1332  close
1333  dsplit 5 /FOO/
1334  call assert_equal([5, 9, 3], [line('.'), col('.'), winnr('$')])
1335  close
1336  call assert_fails('dsplit 3 FOO', 'E387:')
1337  call assert_fails('dsplit 6 FOO', 'E388:')
1338  call assert_fails('dsplit BAR', 'E388:')
1339
1340  close!
1341endfunc
1342
1343" Test for [*, [/, ]* and ]/
1344func Test_comment_search()
1345  new
1346  call setline(1, ['', '/*', ' *', ' *', ' */'])
1347  normal! 4gg[/
1348  call assert_equal([2, 1], [line('.'), col('.')])
1349  normal! 3gg[*
1350  call assert_equal([2, 1], [line('.'), col('.')])
1351  normal! 3gg]/
1352  call assert_equal([5, 3], [line('.'), col('.')])
1353  normal! 3gg]*
1354  call assert_equal([5, 3], [line('.'), col('.')])
1355  %d
1356  call setline(1, ['', '/*', ' *', ' *'])
1357  call assert_beeps('normal! 3gg]/')
1358  %d
1359  call setline(1, ['', ' *', ' *', ' */'])
1360  call assert_beeps('normal! 4gg[/')
1361  %d
1362  call setline(1, '        /* comment */')
1363  normal! 15|[/
1364  call assert_equal(9, col('.'))
1365  normal! 15|]/
1366  call assert_equal(21, col('.'))
1367  call setline(1, '         comment */')
1368  call assert_beeps('normal! 15|[/')
1369  call setline(1, '        /* comment')
1370  call assert_beeps('normal! 15|]/')
1371  close!
1372endfunc
1373
1374" Test for the 'taglength' option
1375func Test_tag_length()
1376  set tags=Xtags
1377  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
1378        \ "tame\tXfile1\t1;",
1379        \ "tape\tXfile2\t1;"], 'Xtags')
1380  call writefile(['tame'], 'Xfile1')
1381  call writefile(['tape'], 'Xfile2')
1382
1383  " Jumping to the tag 'tape', should instead jump to 'tame'
1384  new
1385  set taglength=2
1386  tag tape
1387  call assert_equal('Xfile1', @%)
1388  " Tag search should jump to the right tag
1389  enew
1390  tag /^tape$
1391  call assert_equal('Xfile2', @%)
1392
1393  call delete('Xtags')
1394  call delete('Xfile1')
1395  call delete('Xfile2')
1396  set tags& taglength&
1397endfunc
1398
1399" Tests for errors in a tags file
1400func Test_tagfile_errors()
1401  set tags=Xtags
1402
1403  " missing search pattern or line number for a tag
1404  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
1405        \ "foo\tXfile\t"], 'Xtags', 'b')
1406  call writefile(['foo'], 'Xfile')
1407
1408  enew
1409  tag foo
1410  call assert_equal('', @%)
1411  let caught_431 = v:false
1412  try
1413    eval taglist('.*')
1414  catch /:E431:/
1415    let caught_431 = v:true
1416  endtry
1417  call assert_equal(v:true, caught_431)
1418
1419  call delete('Xtags')
1420  call delete('Xfile')
1421  set tags&
1422endfunc
1423
1424" When :stag fails to open the file, should close the new window
1425func Test_stag_close_window_on_error()
1426  new | only
1427  set tags=Xtags
1428  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
1429        \ "foo\tXfile\t1"], 'Xtags')
1430  call writefile(['foo'], 'Xfile')
1431  call writefile([], '.Xfile.swp')
1432  " Remove the catch-all that runtest.vim adds
1433  au! SwapExists
1434  augroup StagTest
1435    au!
1436    autocmd SwapExists Xfile let v:swapchoice='q'
1437  augroup END
1438
1439  stag foo
1440  call assert_equal(1, winnr('$'))
1441  call assert_equal('', @%)
1442
1443  augroup StagTest
1444    au!
1445  augroup END
1446  call delete('Xfile')
1447  call delete('.Xfile.swp')
1448  set tags&
1449endfunc
1450
1451" vim: shiftwidth=2 sts=2 expandtab
1452