簡體   English   中英

Vim Ctrl-]標記跳轉僅適用於命令

[英]Vim Ctrl-] tag jump works only for commands

我在vimscript上寫了一個插件,想跳到使用標簽的函數定義。 我已經安裝了ctags,配置了vim選項set tags=./tags; 在.vimrc中,並在腳本目錄中使用ctags -R制作了標記文件。 在我的腳本中,我具有以下功能:

func s:OnWipeoutEvent()
" ...
endfunc

和命令:

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

當我嘗試使用Ctrl-] vim跳轉到函數( 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

我寫臨時解決方案:

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

我將以下內容放入~/.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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM