xref: /vim-8.2.3635/src/testdir/test_tagjump.vim (revision 12ee7ff0)
1" Tests for tagjump (tags and special searches)
2
3" SEGV occurs in older versions.  (At least 7.4.1748 or older)
4func Test_ptag_with_notagstack()
5  set notagstack
6  call assert_fails('ptag does_not_exist_tag_name', 'E426')
7  set tagstack&vim
8endfunc
9
10func Test_cancel_ptjump()
11  set tags=Xtags
12  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
13        \ "word\tfile1\tcmd1",
14        \ "word\tfile2\tcmd2"],
15        \ 'Xtags')
16
17  only!
18  call feedkeys(":ptjump word\<CR>\<CR>", "xt")
19  help
20  call assert_equal(2, winnr('$'))
21
22  call delete('Xtags')
23  quit
24endfunc
25
26func Test_static_tagjump()
27  set tags=Xtags
28  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
29        \ "one\tXfile1\t/^one/;\"\tf\tfile:\tsignature:(void)",
30        \ "word\tXfile2\tcmd2"],
31        \ 'Xtags')
32  new Xfile1
33  call setline(1, ['empty', 'one()', 'empty'])
34  write
35  tag one
36  call assert_equal(2, line('.'))
37
38  bwipe!
39  set tags&
40  call delete('Xtags')
41  call delete('Xfile1')
42endfunc
43
44func Test_duplicate_tagjump()
45  set tags=Xtags
46  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
47        \ "thesame\tXfile1\t1;\"\td\tfile:",
48        \ "thesame\tXfile1\t2;\"\td\tfile:",
49        \ "thesame\tXfile1\t3;\"\td\tfile:",
50        \ ],
51        \ 'Xtags')
52  new Xfile1
53  call setline(1, ['thesame one', 'thesame two', 'thesame three'])
54  write
55  tag thesame
56  call assert_equal(1, line('.'))
57  tnext
58  call assert_equal(2, line('.'))
59  tnext
60  call assert_equal(3, line('.'))
61
62  bwipe!
63  set tags&
64  call delete('Xtags')
65  call delete('Xfile1')
66endfunc
67
68func Test_tagjump_switchbuf()
69  set tags=Xtags
70  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
71        \ "second\tXfile1\t2",
72        \ "third\tXfile1\t3",],
73        \ 'Xtags')
74  call writefile(['first', 'second', 'third'], 'Xfile1')
75
76  enew | only
77  set switchbuf=
78  stag second
79  call assert_equal(2, winnr('$'))
80  call assert_equal(2, line('.'))
81  stag third
82  call assert_equal(3, winnr('$'))
83  call assert_equal(3, line('.'))
84
85  enew | only
86  set switchbuf=useopen
87  stag second
88  call assert_equal(2, winnr('$'))
89  call assert_equal(2, line('.'))
90  stag third
91  call assert_equal(2, winnr('$'))
92  call assert_equal(3, line('.'))
93
94  enew | only
95  set switchbuf=usetab
96  tab stag second
97  call assert_equal(2, tabpagenr('$'))
98  call assert_equal(2, line('.'))
99  1tabnext | stag third
100  call assert_equal(2, tabpagenr('$'))
101  call assert_equal(3, line('.'))
102
103  tabclose!
104  enew | only
105  call delete('Xfile1')
106  call delete('Xtags')
107  set switchbuf&vim
108endfunc
109
110" Tests for [ CTRL-I and CTRL-W CTRL-I commands
111function Test_keyword_jump()
112  call writefile(["#include Xinclude", "",
113	      \ "",
114	      \ "/* test text test tex start here",
115	      \ "		some text",
116	      \ "		test text",
117	      \ "		start OK if found this line",
118	      \ "	start found wrong line",
119	      \ "test text"], 'Xtestfile')
120  call writefile(["/* test text test tex start here",
121	      \ "		some text",
122	      \ "		test text",
123	      \ "		start OK if found this line",
124	      \ "	start found wrong line",
125	      \ "test text"], 'Xinclude')
126  new Xtestfile
127  call cursor(1,1)
128  call search("start")
129  exe "normal! 5[\<C-I>"
130  call assert_equal("		start OK if found this line", getline('.'))
131  call cursor(1,1)
132  call search("start")
133  exe "normal! 5\<C-W>\<C-I>"
134  call assert_equal("		start OK if found this line", getline('.'))
135  enew! | only
136  call delete('Xtestfile')
137  call delete('Xinclude')
138endfunction
139
140" Test for jumping to a tag with 'hidden' set, with symbolic link in path of
141" tag.  This only works for Unix, because of the symbolic link.
142func Test_tag_symbolic()
143  if !has('unix')
144    return
145  endif
146  set hidden
147  call delete("Xtest.dir", "rf")
148  call system("ln -s . Xtest.dir")
149  " Create a tags file with the current directory name inserted.
150  call writefile([
151        \ "SECTION_OFF	" . getcwd() . "/Xtest.dir/Xtest.c	/^#define  SECTION_OFF  3$/",
152        \ '',
153        \ ], 'Xtags')
154  call writefile(['#define  SECTION_OFF  3',
155        \ '#define  NUM_SECTIONS 3'], 'Xtest.c')
156
157  " Try jumping to a tag, but with a path that contains a symbolic link.  When
158  " wrong, this will give the ATTENTION message.  The next space will then be
159  " eaten by hit-return, instead of moving the cursor to 'd'.
160  set tags=Xtags
161  enew!
162  call append(0, 'SECTION_OFF')
163  call cursor(1,1)
164  exe "normal \<C-]> "
165  call assert_equal('Xtest.c', expand('%:t'))
166  call assert_equal(2, col('.'))
167
168  set hidden&
169  set tags&
170  enew!
171  call delete('Xtags')
172  call delete('Xtest.c')
173  call delete("Xtest.dir", "rf")
174  %bwipe!
175endfunc
176
177" Tests for tag search with !_TAG_FILE_ENCODING.
178" Depends on the test83-tags2 and test83-tags3 files.
179func Test_tag_file_encoding()
180  if has('vms')
181    return
182  endif
183
184  if !has('iconv') || iconv("\x82\x60", "cp932", "utf-8") != "\uff21"
185    return
186  endif
187
188  let save_enc = &encoding
189  set encoding=utf8
190
191  let content = ['text for tags1', 'abcdefghijklmnopqrs']
192  call writefile(content, 'Xtags1.txt')
193  let content = ['text for tags2', 'ABC']
194  call writefile(content, 'Xtags2.txt')
195  let content = ['text for tags3', 'ABC']
196  call writefile(content, 'Xtags3.txt')
197  let content = ['!_TAG_FILE_ENCODING	utf-8	//', 'abcdefghijklmnopqrs	Xtags1.txt	/abcdefghijklmnopqrs']
198  call writefile(content, 'Xtags1')
199
200  " case1:
201  new
202  set tags=Xtags1
203  tag abcdefghijklmnopqrs
204  call assert_equal('Xtags1.txt', expand('%:t'))
205  call assert_equal('abcdefghijklmnopqrs', getline('.'))
206  close
207
208  " case2:
209  new
210  set tags=test83-tags2
211  tag /.BC
212  call assert_equal('Xtags2.txt', expand('%:t'))
213  call assert_equal('ABC', getline('.'))
214  close
215
216  " case3:
217  new
218  set tags=test83-tags3
219  tag abc50
220  call assert_equal('Xtags3.txt', expand('%:t'))
221  call assert_equal('ABC', getline('.'))
222  close
223
224  set tags&
225  let &encoding = save_enc
226  call delete('Xtags1.txt')
227  call delete('Xtags2.txt')
228  call delete('Xtags3.txt')
229  call delete('Xtags1')
230endfunc
231
232func Test_tagjump_etags()
233  if !has('emacs_tags')
234    return
235  endif
236  call writefile([
237        \ "void foo() {}",
238        \ "int main(int argc, char **argv)",
239        \ "{",
240        \ "\tfoo();",
241        \ "\treturn 0;",
242        \ "}",
243        \ ], 'Xmain.c')
244
245  call writefile([
246	\ "\x0c",
247        \ "Xmain.c,64",
248        \ "void foo() {}\x7ffoo\x011,0",
249        \ "int main(int argc, char **argv)\x7fmain\x012,14",
250	\ ], 'Xtags')
251  set tags=Xtags
252  ta foo
253  call assert_equal('void foo() {}', getline('.'))
254
255  call delete('Xtags')
256  call delete('Xmain.c')
257  bwipe!
258endfunc
259
260" Test for getting and modifying the tag stack
261func Test_getsettagstack()
262  call writefile(['line1', 'line2', 'line3'], 'Xfile1')
263  call writefile(['line1', 'line2', 'line3'], 'Xfile2')
264  call writefile(['line1', 'line2', 'line3'], 'Xfile3')
265
266  enew | only
267  call settagstack(1, {'items' : []})
268  call assert_equal(0, gettagstack(1).length)
269  call assert_equal([], gettagstack(1).items)
270  " Error cases
271  call assert_equal({}, gettagstack(100))
272  call assert_equal(-1, settagstack(100, {'items' : []}))
273  call assert_fails('call settagstack(1, [1, 10])', 'E715')
274  call assert_fails("call settagstack(1, {'items' : 10})", 'E714')
275  call assert_fails("call settagstack(1, {'items' : []}, 10)", 'E928')
276  call assert_fails("call settagstack(1, {'items' : []}, 'b')", 'E962')
277
278  set tags=Xtags
279  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
280        \ "one\tXfile1\t1",
281        \ "three\tXfile3\t3",
282        \ "two\tXfile2\t2"],
283        \ 'Xtags')
284
285  let stk = []
286  call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'one',
287	\ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1})
288  tag one
289  call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'two',
290	\ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1})
291  tag two
292  call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'three',
293	\ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1})
294  tag three
295  call assert_equal(3, gettagstack(1).length)
296  call assert_equal(stk, gettagstack(1).items)
297  " Check for default - current window
298  call assert_equal(3, gettagstack().length)
299  call assert_equal(stk, gettagstack().items)
300
301  " Try to set current index to invalid values
302  call settagstack(1, {'curidx' : -1})
303  call assert_equal(1, gettagstack().curidx)
304  call settagstack(1, {'curidx' : 50})
305  call assert_equal(4, gettagstack().curidx)
306
307  " Try pushing invalid items onto the stack
308  call settagstack(1, {'items' : []})
309  call settagstack(1, {'items' : ["plate"]}, 'a')
310  call assert_equal(0, gettagstack().length)
311  call assert_equal([], gettagstack().items)
312  call settagstack(1, {'items' : [{"tagname" : "abc"}]}, 'a')
313  call assert_equal(0, gettagstack().length)
314  call assert_equal([], gettagstack().items)
315  call settagstack(1, {'items' : [{"from" : 100}]}, 'a')
316  call assert_equal(0, gettagstack().length)
317  call assert_equal([], gettagstack().items)
318  call settagstack(1, {'items' : [{"from" : [2, 1, 0, 0]}]}, 'a')
319  call assert_equal(0, gettagstack().length)
320  call assert_equal([], gettagstack().items)
321
322  " Push one item at a time to the stack
323  call settagstack(1, {'items' : []})
324  call settagstack(1, {'items' : [stk[0]]}, 'a')
325  call settagstack(1, {'items' : [stk[1]]}, 'a')
326  call settagstack(1, {'items' : [stk[2]]}, 'a')
327  call settagstack(1, {'curidx' : 4})
328  call assert_equal({'length' : 3, 'curidx' : 4, 'items' : stk},
329        \ gettagstack(1))
330
331  " Try pushing items onto a full stack
332  for i in range(7)
333    call settagstack(1, {'items' : stk}, 'a')
334  endfor
335  call assert_equal(20, gettagstack().length)
336  call settagstack(1,
337        \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 'a')
338  call assert_equal('abc', gettagstack().items[19].tagname)
339
340  " Tag with multiple matches
341  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
342        \ "two\tXfile1\t1",
343        \ "two\tXfile2\t3",
344        \ "two\tXfile3\t2"],
345        \ 'Xtags')
346  call settagstack(1, {'items' : []})
347  tag two
348  tnext
349  tnext
350  call assert_equal(1, gettagstack().length)
351  call assert_equal(3, gettagstack().items[0].matchnr)
352
353  " Memory allocation failures
354  call test_alloc_fail(GetAllocId('tagstack_items'), 0, 0)
355  call assert_fails('call gettagstack()', 'E342:')
356  call test_alloc_fail(GetAllocId('tagstack_from'), 0, 0)
357  call assert_fails('call gettagstack()', 'E342:')
358  call test_alloc_fail(GetAllocId('tagstack_details'), 0, 0)
359  call assert_fails('call gettagstack()', 'E342:')
360
361  call settagstack(1, {'items' : []})
362  call delete('Xfile1')
363  call delete('Xfile2')
364  call delete('Xfile3')
365  call delete('Xtags')
366  set tags&
367endfunc
368
369func Test_tag_with_count()
370  call writefile([
371	\ 'test	Xtest.h	/^void test();$/;"	p	typeref:typename:void	signature:()',
372	\ ], 'Xtags')
373  call writefile([
374	\ 'main	Xtest.c	/^int main()$/;"	f	typeref:typename:int	signature:()',
375	\ 'test	Xtest.c	/^void test()$/;"	f	typeref:typename:void	signature:()',
376	\ ], 'Ytags')
377  cal writefile([
378	\ 'int main()',
379	\ 'void test()',
380	\ ], 'Xtest.c')
381  cal writefile([
382	\ 'void test();',
383	\ ], 'Xtest.h')
384  set tags=Xtags,Ytags
385
386  new Xtest.c
387  let tl = taglist('test', 'Xtest.c')
388  call assert_equal(tl[0].filename, 'Xtest.c')
389  call assert_equal(tl[1].filename, 'Xtest.h')
390
391  tag test
392  call assert_equal(bufname('%'), 'Xtest.c')
393  1tag test
394  call assert_equal(bufname('%'), 'Xtest.c')
395  2tag test
396  call assert_equal(bufname('%'), 'Xtest.h')
397
398  set tags&
399  call delete('Xtags')
400  call delete('Ytags')
401  bwipe Xtest.h
402  bwipe Xtest.c
403  call delete('Xtest.h')
404  call delete('Xtest.c')
405endfunc
406
407func Test_tagnr_recall()
408  call writefile([
409	\ 'test	Xtest.h	/^void test();$/;"	p',
410	\ 'main	Xtest.c	/^int main()$/;"	f',
411	\ 'test	Xtest.c	/^void test()$/;"	f',
412	\ ], 'Xtags')
413  cal writefile([
414	\ 'int main()',
415	\ 'void test()',
416	\ ], 'Xtest.c')
417  cal writefile([
418	\ 'void test();',
419	\ ], 'Xtest.h')
420  set tags=Xtags
421
422  new Xtest.c
423  let tl = taglist('test', 'Xtest.c')
424  call assert_equal(tl[0].filename, 'Xtest.c')
425  call assert_equal(tl[1].filename, 'Xtest.h')
426
427  2tag test
428  call assert_equal(bufname('%'), 'Xtest.h')
429  pop
430  call assert_equal(bufname('%'), 'Xtest.c')
431  tag
432  call assert_equal(bufname('%'), 'Xtest.h')
433
434  set tag&
435  call delete('Xtags')
436  bwipe Xtest.h
437  bwipe Xtest.c
438  call delete('Xtest.h')
439  call delete('Xtest.c')
440endfunc
441
442func Test_tag_line_toolong()
443  call writefile([
444	\ '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678	django/contrib/admin/templates/admin/edit_inline/stacked.html	16;"	j	line:16	language:HTML'
445	\ ], 'Xtags')
446  set tags=Xtags
447  let old_vbs = &verbose
448  set verbose=5
449  " ":tjump" should give "tag not found" not "Format error in tags file"
450  call assert_fails('tj /foo', 'E426')
451  try
452    tj /foo
453  catch /^Vim\%((\a\+)\)\=:E431/
454    call assert_report(v:exception)
455  catch /.*/
456  endtry
457  call assert_equal('Ignoring long line in tags file', split(execute('messages'), '\n')[-1])
458  call writefile([
459	\ '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567	django/contrib/admin/templates/admin/edit_inline/stacked.html	16;"	j	line:16	language:HTML'
460	\ ], 'Xtags')
461  call assert_fails('tj /foo', 'E426')
462  try
463    tj /foo
464  catch /^Vim\%((\a\+)\)\=:E431/
465    call assert_report(v:exception)
466  catch /.*/
467  endtry
468  call assert_equal('Ignoring long line in tags file', split(execute('messages'), '\n')[-1])
469  call delete('Xtags')
470  let &verbose = old_vbs
471endfunc
472
473" vim: shiftwidth=2 sts=2 expandtab
474