Kirill Bugaev
Kirill Bugaev

Reputation: 390

Vim Ctrl-] tag jump works only for commands

I write a plugin on vimscript and want to jump to function definitions using tags. I have installed ctags, configured vim option set tags=./tags; in .vimrc and made tag file with ctags -R in script directory. In my script I have function:

func s:OnWipeoutEvent()
" ...
endfunc

And command:

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

When I try to jump to my function (OnWipeoutEvent()) definition with Ctrl-] vim says: E257: ctag: tag not found. So it doesn't work for function definition, but works for vim command definitions. I can jump to command with Ctrl-]. Why? How can I solve this problem?

UPD: I think that such behaviour is the result of s: prefix in s:OnWipeoutEvent() function name. Because I can jump to function definition when enter tag s:OnWipeoutEvent in vim command line. May be Ctrl-] use function name without this prefix. Any idea how to solve it?

UPD2: Try to make question more clear. Part of my vim script below:

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>)

tags file:

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

Upvotes: 1

Views: 282

Answers (2)

Ingo Karkat
Ingo Karkat

Reputation: 172590

I have put the following into ~/.vim/after/ftplugin/vim.vim to correct this problem:

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

Upvotes: 1

Kirill Bugaev
Kirill Bugaev

Reputation: 390

I write temporary solution:

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

Upvotes: 1

Related Questions