neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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