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