【问题标题】:Vim Ctrl-] tag jump works only for commandsVim Ctrl-] 标签跳转只对命令有效
【发布时间】:2019-02-20 16:58:05
【问题描述】:

我在 vimscript 上编写了一个插件,并想使用标签跳转到函数定义。 我已经安装了 ctags,在 .vimrc 中配置了 vim 选项 set tags=./tags; 并在脚本目录中使用 ctags -R 制作了标签文件。 在我的脚本中,我有函数:

func s:OnWipeoutEvent()
" ...
endfunc

和命令:

command! -bar -nargs=* -complete=file -bang TermdebugEasymaps
            \ call s:StartDebug(<bang>0, <f-args>)

当我尝试使用 Ctrl- 跳转到我的函数 (OnWipeoutEvent()) 定义时,vim 说:E257: ctag: tag not found. 所以它不适用于函数定义,但适用于 vim 命令定义。我可以使用 Ctrl-] 跳转到命令。为什么?我该如何解决这个问题?

UPD:我认为这种行为是s:OnWipeoutEvent() 函数名中的s: 前缀的结果。因为在vim命令行输入tag s:OnWipeoutEvent可以跳转到函数定义。可能是 Ctrl-] 使用没有这个前缀的函数名。知道如何解决吗?

UPD2:尽量让问题更清楚。下面是我的 vim 脚本的一部分:

func s:OnWipeoutEvent()
"...
endfunc

augroup termdebug-easymaps
    autocmd BufWipeout * call s:OnWipeoutEvent()
augroup END

command! -bar -nargs=* -complete=file -bang TermdebugEasymaps
            \ call s:StartDebug(<bang>0, <f-args>)

标签文件:

TermdebugEasymaps   termdebug-easymaps.vim  /^command! -bar -nargs=* -complete=file -bang TermdebugEasymaps$/;" c
TermdebugEasymapsCommand    termdebug-easymaps.vim  /^command! -bar -nargs=* -complete=file -bang TermdebugEasymapsCommand$/;"  c
TermdebugEasymapsStop   termdebug-easymaps.vim  /^command! -bar TermdebugEasymapsStop call s:Stop_termdebug()$/;"   c
s:CloseBuffers  termdebug-easymaps.vim  /^func s:CloseBuffers()$/;" f
s:CommOutput    termdebug-easymaps.vim  /^func s:CommOutput(out, msg)$/;"   f
s:CreateCommWin termdebug-easymaps.vim  /^func s:CreateCommWin()$/;"    f
s:DecodeMessage termdebug-easymaps.vim  /^func s:DecodeMessage(quotedText)$/;"  f
s:GetCurrentSourceFullname  termdebug-easymaps.vim  /^func s:GetCurrentSourceFullname()$/;" f
s:GetFullname   termdebug-easymaps.vim  /^func s:GetFullname(msg)$/;"   f
s:GetOpenedList termdebug-easymaps.vim  /^func s:GetOpenedList()$/;"    f
s:GoToDebugWindow   termdebug-easymaps.vim  /^func s:GoToDebugWindow()$/;"  f
s:MapsCurrentBuffer termdebug-easymaps.vim  /^func s:MapsCurrentBuffer()$/;"    f
s:OnWipeoutEvent    termdebug-easymaps.vim  /^func s:OnWipeoutEvent()$/;"   f
s:ProgramRunState   termdebug-easymaps.vim  /^func s:ProgramRunState()$/;"  f
s:RestoreBuffersState   termdebug-easymaps.vim  /^func s:RestoreBuffersState()$/;"  f
s:SaveCurrentBufferState    termdebug-easymaps.vim  /^func s:SaveCurrentBufferState()$/;"   f
s:SetRunMapForCurrent   termdebug-easymaps.vim  /^func s:SetRunMapForCurrent()$/;"  f
s:SetRunMapsForOpened   termdebug-easymaps.vim  /^func s:SetRunMapsForOpened()$/;"  f
s:SetRunMapsForTreated  termdebug-easymaps.vim  /^func s:SetRunMapsForTreated()$/;" f
s:StartDebug    termdebug-easymaps.vim  /^func s:StartDebug(bang, ...)  $/;"    f
s:StartDebugCommand termdebug-easymaps.vim  /^func s:StartDebugCommand(bang, ...)$/;"   f
s:StartDebug_internal   termdebug-easymaps.vim  /^func s:StartDebug_internal(command_mode, args, bang)$/;"  f
s:StopTermdebug termdebug-easymaps.vim  /^func s:StopTermdebug()$/;"    f
s:TerminateProgram  termdebug-easymaps.vim  /^func s:TerminateProgram()$/;" f
s:TreatOpened   termdebug-easymaps.vim  /^func s:TreatOpened()$/;"  f
s:comm_timeout  termdebug-easymaps.vim  /^let s:comm_timeout = 5000$/;" v
s:commflags termdebug-easymaps.vim  /^let s:commflags = { 'current_source': 0, 'all_sources': 0, 'program_run': 0 }$/;" v
s:sleeptime termdebug-easymaps.vim  /^let s:sleeptime = 10$/;"  v
termdebug   termdebug-easymaps.vim  /^augroup termdebug-easymaps$/;"    a

【问题讨论】:

  • 你从哪里跳?我只看到你问题中的定义。另外,也请包含标签文件的内容。您可以通过 :echo taglist('.*') 检查 Vim 是否知道这两个定义
  • 感谢重播。 Vim 通过:echo taglist('.*') 显示这两个定义。

标签: vim


【解决方案1】:

我已将以下内容放入~/.vim/after/ftplugin/vim.vim 以纠正此问题:

if v:version >= 703
    " The runtime update of Vim 7.3.488 (changeset 2cfb68fa26cd) adds ":" to
    " 'iskeyword'; ostensibly "To make syntax highlighting of 'vimVar's work
    " correctly". But this breaks tag jumping, because ctags puts functions
    " without scope prefix into the tags database. (And this is better, because
    " prefixes are sometimes optional, and <SID> and s: are equivalent.)
    setlocal iskeyword-=:
endif

【讨论】:

  • setlocal iskeyword+=: 适合我,因为 ctags 使用 : 制作标签
【解决方案2】:

我写临时解决方案:

let s:mapped_buffers = []

autocmd BufReadPost,BufWritePost,BufEnter *.vim call s:MapBuffer()

func s:MapBuffer()
    let nomap = 0
    for buf_i in s:mapped_buffers
        if bufnr('%') == buf_i
            let nomap = 1
        endif
    endfor
    if !nomap
        nnoremap <buffer> <silent> <C-]> :call <SID>JumpToTag()<CR>
        nnoremap <buffer> <silent> <C-W>] :call <SID>JumpToTagInNewWindow()<CR>
        nnoremap <buffer> <silent> g] :call <SID>SelectTag()<CR>
        nnoremap <buffer> <silent> <C-W>g] :call <SID>SelectTagInNewWindow()<CR>
        call add(s:mapped_buffers, bufnr('%'))
    endif
endfunc

func s:JumpToTag()
    exe 'tag ' . s:GetTagName()
endfunc

func s:JumpToTagInNewWindow()
    exe 'stag ' . s:GetTagName()
endfunc

func s:SelectTag()
    exe 'tjump ' . s:GetTagName()
endfunc

func s:SelectTagInNewWindow()
    exe 'stjump ' . s:GetTagName()
endfunc

func s:GetTagName()
    let short_word = expand("<cword>")
    let long_word = expand("<cWORD>")
    let mi = match(long_word, short_word)
    if mi >= 2 && long_word[mi - 1] == ':'
        " Add prefix
        let tag_name = long_word[mi - 2: mi - 1] . short_word
    else
        let tag_name = short_word
    endif
    return tag_name
endfunc

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    相关资源
    最近更新 更多