test_tagfunc.vim (12819B)
1 " Test 'tagfunc' 2 3 source vim9.vim 4 source check.vim 5 source screendump.vim 6 7 func TagFunc(pat, flag, info) 8 let g:tagfunc_args = [a:pat, a:flag, a:info] 9 let tags = [] 10 for num in range(1,10) 11 let tags += [{ 12 \ 'cmd': '2', 'name': 'nothing'.num, 'kind': 'm', 13 \ 'filename': 'Xfile1', 'user_data': 'somedata'.num, 14 \}] 15 endfor 16 return tags 17 endfunc 18 19 func Test_tagfunc() 20 set tagfunc=TagFunc 21 new Xfile1 22 call setline(1, ['empty', 'one()', 'empty']) 23 write 24 25 call assert_equal({'cmd': '2', 'static': 0, 26 \ 'name': 'nothing2', 'user_data': 'somedata2', 27 \ 'kind': 'm', 'filename': 'Xfile1'}, taglist('.')[1]) 28 29 call settagstack(win_getid(), {'items': []}) 30 31 tag arbitrary 32 call assert_equal('arbitrary', g:tagfunc_args[0]) 33 call assert_equal('', g:tagfunc_args[1]) 34 call assert_equal('somedata1', gettagstack().items[0].user_data) 35 5tag arbitrary 36 call assert_equal('arbitrary', g:tagfunc_args[0]) 37 call assert_equal('', g:tagfunc_args[1]) 38 call assert_equal('somedata5', gettagstack().items[1].user_data) 39 pop 40 tag 41 call assert_equal('arbitrary', g:tagfunc_args[0]) 42 call assert_equal('', g:tagfunc_args[1]) 43 call assert_equal('somedata5', gettagstack().items[1].user_data) 44 45 let g:tagfunc_args=[] 46 execute "normal! \<c-]>" 47 call assert_equal('one', g:tagfunc_args[0]) 48 call assert_equal('c', g:tagfunc_args[1]) 49 50 let g:tagfunc_args=[] 51 execute "tag /foo$" 52 call assert_equal('foo$', g:tagfunc_args[0]) 53 call assert_equal('r', g:tagfunc_args[1]) 54 55 set cpt=t 56 let g:tagfunc_args=[] 57 execute "normal! i\<c-n>\<c-y>" 58 call assert_equal('\<\k\k', g:tagfunc_args[0]) 59 call assert_equal('cir', g:tagfunc_args[1]) 60 call assert_equal('nothing1', getline('.')[0:7]) 61 62 let g:tagfunc_args=[] 63 execute "normal! ono\<c-n>\<c-n>\<c-y>" 64 call assert_equal('\<no', g:tagfunc_args[0]) 65 call assert_equal('cir', g:tagfunc_args[1]) 66 call assert_equal('nothing2', getline('.')[0:7]) 67 68 func BadTagFunc1(...) 69 return 0 70 endfunc 71 func BadTagFunc2(...) 72 return [1] 73 endfunc 74 func BadTagFunc3(...) 75 return [{'name': 'foo'}] 76 endfunc 77 78 for &tagfunc in ['BadTagFunc1', 'BadTagFunc2', 'BadTagFunc3'] 79 try 80 tag nothing 81 call assert_false(1, 'tag command should have failed') 82 catch 83 call assert_exception('E987:') 84 endtry 85 exe 'delf' &tagfunc 86 endfor 87 88 func NullTagFunc(...) 89 return v:null 90 endfunc 91 set tags= tfu=NullTagFunc 92 call assert_fails('tag nothing', 'E433:') 93 delf NullTagFunc 94 95 bwipe! 96 set tags& tfu& cpt& 97 call delete('Xfile1') 98 endfunc 99 100 " Test for modifying the tag stack from a tag function and jumping to a tag 101 " from a tag function 102 func Test_tagfunc_settagstack() 103 func Mytagfunc1(pat, flags, info) 104 call settagstack(1, {'tagname' : 'mytag', 'from' : [0, 10, 1, 0]}) 105 return [{'name' : 'mytag', 'filename' : 'Xtest', 'cmd' : '1'}] 106 endfunc 107 set tagfunc=Mytagfunc1 108 call writefile([''], 'Xtest') 109 call assert_fails('tag xyz', 'E986:') 110 111 func Mytagfunc2(pat, flags, info) 112 tag test_tag 113 return [{'name' : 'mytag', 'filename' : 'Xtest', 'cmd' : '1'}] 114 endfunc 115 set tagfunc=Mytagfunc2 116 call assert_fails('tag xyz', 'E986:') 117 118 call delete('Xtest') 119 set tagfunc& 120 delfunc Mytagfunc1 121 delfunc Mytagfunc2 122 endfunc 123 124 " Script local tagfunc callback function 125 func s:ScriptLocalTagFunc(pat, flags, info) 126 let g:ScriptLocalFuncArgs = [a:pat, a:flags, a:info] 127 return v:null 128 endfunc 129 130 " Test for different ways of setting the 'tagfunc' option 131 func Test_tagfunc_callback() 132 func TagFunc1(callnr, pat, flags, info) 133 let g:TagFunc1Args = [a:callnr, a:pat, a:flags, a:info] 134 return v:null 135 endfunc 136 func TagFunc2(pat, flags, info) 137 let g:TagFunc2Args = [a:pat, a:flags, a:info] 138 return v:null 139 endfunc 140 141 let lines =<< trim END 142 #" Test for using a function name 143 LET &tagfunc = 'g:TagFunc2' 144 new 145 LET g:TagFunc2Args = [] 146 call assert_fails('tag a10', 'E433:') 147 call assert_equal(['a10', '', {}], g:TagFunc2Args) 148 bw! 149 150 #" Test for using a function() 151 set tagfunc=function('g:TagFunc1',\ [10]) 152 new 153 LET g:TagFunc1Args = [] 154 call assert_fails('tag a11', 'E433:') 155 call assert_equal([10, 'a11', '', {}], g:TagFunc1Args) 156 bw! 157 158 #" Using a funcref variable to set 'tagfunc' 159 VAR Fn = function('g:TagFunc1', [11]) 160 LET &tagfunc = Fn 161 new 162 LET g:TagFunc1Args = [] 163 call assert_fails('tag a12', 'E433:') 164 call assert_equal([11, 'a12', '', {}], g:TagFunc1Args) 165 bw! 166 167 #" Using a string(funcref_variable) to set 'tagfunc' 168 LET Fn = function('g:TagFunc1', [12]) 169 LET &tagfunc = string(Fn) 170 new 171 LET g:TagFunc1Args = [] 172 call assert_fails('tag a12', 'E433:') 173 call assert_equal([12, 'a12', '', {}], g:TagFunc1Args) 174 bw! 175 176 #" Test for using a funcref() 177 set tagfunc=funcref('g:TagFunc1',\ [13]) 178 new 179 LET g:TagFunc1Args = [] 180 call assert_fails('tag a13', 'E433:') 181 call assert_equal([13, 'a13', '', {}], g:TagFunc1Args) 182 bw! 183 184 #" Using a funcref variable to set 'tagfunc' 185 LET Fn = funcref('g:TagFunc1', [14]) 186 LET &tagfunc = Fn 187 new 188 LET g:TagFunc1Args = [] 189 call assert_fails('tag a14', 'E433:') 190 call assert_equal([14, 'a14', '', {}], g:TagFunc1Args) 191 bw! 192 193 #" Using a string(funcref_variable) to set 'tagfunc' 194 LET Fn = funcref('g:TagFunc1', [15]) 195 LET &tagfunc = string(Fn) 196 new 197 LET g:TagFunc1Args = [] 198 call assert_fails('tag a14', 'E433:') 199 call assert_equal([15, 'a14', '', {}], g:TagFunc1Args) 200 bw! 201 202 #" Test for using a lambda function 203 VAR optval = "LSTART a, b, c LMIDDLE TagFunc1(16, a, b, c) LEND" 204 LET optval = substitute(optval, ' ', '\\ ', 'g') 205 exe "set tagfunc=" .. optval 206 new 207 LET g:TagFunc1Args = [] 208 call assert_fails('tag a17', 'E433:') 209 call assert_equal([16, 'a17', '', {}], g:TagFunc1Args) 210 bw! 211 212 #" Set 'tagfunc' to a lambda expression 213 LET &tagfunc = LSTART a, b, c LMIDDLE TagFunc1(17, a, b, c) LEND 214 new 215 LET g:TagFunc1Args = [] 216 call assert_fails('tag a18', 'E433:') 217 call assert_equal([17, 'a18', '', {}], g:TagFunc1Args) 218 bw! 219 220 #" Set 'tagfunc' to a string(lambda expression) 221 LET &tagfunc = 'LSTART a, b, c LMIDDLE TagFunc1(18, a, b, c) LEND' 222 new 223 LET g:TagFunc1Args = [] 224 call assert_fails('tag a18', 'E433:') 225 call assert_equal([18, 'a18', '', {}], g:TagFunc1Args) 226 bw! 227 228 #" Set 'tagfunc' to a variable with a lambda expression 229 VAR Lambda = LSTART a, b, c LMIDDLE TagFunc1(19, a, b, c) LEND 230 LET &tagfunc = Lambda 231 new 232 LET g:TagFunc1Args = [] 233 call assert_fails("tag a19", "E433:") 234 call assert_equal([19, 'a19', '', {}], g:TagFunc1Args) 235 bw! 236 237 #" Set 'tagfunc' to a string(variable with a lambda expression) 238 LET Lambda = LSTART a, b, c LMIDDLE TagFunc1(20, a, b, c) LEND 239 LET &tagfunc = string(Lambda) 240 new 241 LET g:TagFunc1Args = [] 242 call assert_fails("tag a19", "E433:") 243 call assert_equal([20, 'a19', '', {}], g:TagFunc1Args) 244 bw! 245 246 #" Test for using a lambda function with incorrect return value 247 LET Lambda = LSTART a, b, c LMIDDLE strlen(a) LEND 248 LET &tagfunc = string(Lambda) 249 new 250 call assert_fails("tag a20", "E987:") 251 bw! 252 253 #" Test for clearing the 'tagfunc' option 254 set tagfunc='' 255 set tagfunc& 256 call assert_fails("set tagfunc=function('abc')", "E700:") 257 call assert_fails("set tagfunc=funcref('abc')", "E700:") 258 259 #" set 'tagfunc' to a non-existing function 260 LET &tagfunc = function('g:TagFunc2') 261 LET g:TagFunc2Args = [] 262 call assert_fails("set tagfunc=function('NonExistingFunc')", 'E700:') 263 call assert_fails("LET &tagfunc = function('NonExistingFunc')", 'E700:') 264 call assert_fails("tag axb123", 'E433:') 265 call assert_equal(['axb123', '', {}], g:TagFunc2Args) 266 bw! 267 268 #" :setlocal and :setglobal 269 set tagfunc& 270 setlocal tagfunc=function('g:TagFunc1',\ [22]) 271 LET g:TagFunc1Args = [] 272 call assert_fails("tag a22", 'E433:') 273 call assert_equal([22, 'a22', '', {}], g:TagFunc1Args) 274 new 275 LET g:TagFunc1Args = [] 276 call assert_fails("tag a22", 'E433:') 277 call assert_equal([], g:TagFunc1Args) 278 bw! 279 setglobal tagfunc=function('g:TagFunc1',\ [23]) 280 LET g:TagFunc1Args = [] 281 call assert_fails("tag a22", 'E433:') 282 call assert_equal([22, 'a22', '', {}], g:TagFunc1Args) 283 setlocal tagfunc& 284 LET g:TagFunc1Args = [] 285 call assert_fails("tag a23", 'E433:') 286 call assert_equal([], g:TagFunc1Args) 287 new 288 LET g:TagFunc1Args = [] 289 call assert_fails("tag a23", 'E433:') 290 call assert_equal([23, 'a23', '', {}], g:TagFunc1Args) 291 :%bw! 292 END 293 call CheckLegacyAndVim9Success(lines) 294 295 " Test for using a script-local function name 296 func s:TagFunc3(pat, flags, info) 297 let g:TagFunc3Args = [a:pat, a:flags, a:info] 298 return v:null 299 endfunc 300 set tagfunc=s:TagFunc3 301 new 302 let g:TagFunc3Args = [] 303 call assert_fails('tag a21', 'E433:') 304 call assert_equal(['a21', '', {}], g:TagFunc3Args) 305 bw! 306 let &tagfunc = 's:TagFunc3' 307 new 308 let g:TagFunc3Args = [] 309 call assert_fails('tag a22', 'E433:') 310 call assert_equal(['a22', '', {}], g:TagFunc3Args) 311 bw! 312 delfunc s:TagFunc3 313 314 " invalid return value 315 let &tagfunc = "{a -> 'abc'}" 316 call assert_fails("echo taglist('a')", "E987:") 317 318 " Using Vim9 lambda expression in legacy context should fail 319 set tagfunc=(a,\ b,\ c)\ =>\ g:TagFunc1(21,\ a,\ b,\ c) 320 new 321 let g:TagFunc1Args = [] 322 call assert_fails("tag a17", "E117:") 323 call assert_equal([], g:TagFunc1Args) 324 bw! 325 326 " Test for using a script local function 327 set tagfunc=<SID>ScriptLocalTagFunc 328 new 329 let g:ScriptLocalFuncArgs = [] 330 call assert_fails('tag a15', 'E433:') 331 call assert_equal(['a15', '', {}], g:ScriptLocalFuncArgs) 332 bw! 333 334 " Test for using a script local funcref variable 335 let Fn = function("s:ScriptLocalTagFunc") 336 let &tagfunc= Fn 337 new 338 let g:ScriptLocalFuncArgs = [] 339 call assert_fails('tag a16', 'E433:') 340 call assert_equal(['a16', '', {}], g:ScriptLocalFuncArgs) 341 bw! 342 343 " Test for using a string(script local funcref variable) 344 let Fn = function("s:ScriptLocalTagFunc") 345 let &tagfunc= string(Fn) 346 new 347 let g:ScriptLocalFuncArgs = [] 348 call assert_fails('tag a16', 'E433:') 349 call assert_equal(['a16', '', {}], g:ScriptLocalFuncArgs) 350 bw! 351 352 " set 'tagfunc' to a partial with dict. This used to cause a crash. 353 func SetTagFunc() 354 let params = {'tagfn': function('g:DictTagFunc')} 355 let &tagfunc = params.tagfn 356 endfunc 357 func g:DictTagFunc(_) dict 358 endfunc 359 call SetTagFunc() 360 new 361 call SetTagFunc() 362 bw 363 call test_garbagecollect_now() 364 new 365 set tagfunc= 366 wincmd w 367 set tagfunc= 368 :%bw! 369 delfunc g:DictTagFunc 370 delfunc SetTagFunc 371 372 " Vim9 tests 373 let lines =<< trim END 374 vim9script 375 376 def Vim9tagFunc(callnr: number, pat: string, flags: string, info: dict<any>): any 377 g:Vim9tagFuncArgs = [callnr, pat, flags, info] 378 return null 379 enddef 380 381 # Test for using a def function with completefunc 382 set tagfunc=function('Vim9tagFunc',\ [60]) 383 new 384 g:Vim9tagFuncArgs = [] 385 assert_fails('tag a10', 'E433:') 386 assert_equal([60, 'a10', '', {}], g:Vim9tagFuncArgs) 387 388 # Test for using a global function name 389 &tagfunc = g:TagFunc2 390 new 391 g:TagFunc2Args = [] 392 assert_fails('tag a11', 'E433:') 393 assert_equal(['a11', '', {}], g:TagFunc2Args) 394 bw! 395 396 # Test for using a script-local function name 397 def LocalTagFunc(pat: string, flags: string, info: dict<any> ): any 398 g:LocalTagFuncArgs = [pat, flags, info] 399 return null 400 enddef 401 &tagfunc = LocalTagFunc 402 new 403 g:LocalTagFuncArgs = [] 404 assert_fails('tag a12', 'E433:') 405 assert_equal(['a12', '', {}], g:LocalTagFuncArgs) 406 bw! 407 END 408 call CheckScriptSuccess(lines) 409 410 " cleanup 411 delfunc TagFunc1 412 delfunc TagFunc2 413 set tagfunc& 414 %bw! 415 endfunc 416 417 func Test_tagfunc_wipes_buffer() 418 func g:Tag0unc0(t,f,o) 419 bwipe 420 endfunc 421 set tagfunc=g:Tag0unc0 422 new 423 cal assert_fails('tag 0', 'E987:') 424 425 delfunc g:Tag0unc0 426 set tagfunc= 427 endfunc 428 429 func Test_tagfunc_closes_window() 430 split any 431 func MytagfuncClose(pat, flags, info) 432 close 433 return [{'name' : 'mytag', 'filename' : 'Xtest', 'cmd' : '1'}] 434 endfunc 435 set tagfunc=MytagfuncClose 436 call assert_fails('tag xyz', 'E1299:') 437 438 set tagfunc= 439 endfunc 440 441 func Test_tagfunc_deletes_lines() 442 defer delete('Xany') 443 split Xany 444 call writefile([''], 'Xtest', 'D') 445 call setline(1, range(10)) 446 call cursor(10, 1) 447 func MytagfuncDel(pat, flags, info) 448 9,10d 449 return [{'name' : 'mytag', 'filename' : 'Xtest', 'cmd' : '1'}] 450 endfunc 451 set tagfunc=MytagfuncDel 452 call taglist('.') 453 call assert_equal([0, 8, 1, 0], getpos('.')) 454 norm! ofoobar 455 call assert_equal(['0', '1', '2', '3', '4', '5', '6', '7', 'foobar'], getline(1, '$')) 456 457 bw! 458 set tagfunc= 459 endfunc 460 461 " vim: shiftwidth=2 sts=2 expandtab