[英]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.