在Vim中使用Ctags跳转到Ruby bang方法

xoe*_*bus 6 ruby vim ctags

我在使用Exhuberant Ctags跳转到Ruby bang方法时遇到了问题.我搜索了其他有类似问题的人,但我找不到任何东西.可以使用以下小型Ruby类显示问题的示例:

class Hello
  def start
    method!
  end

  def method
    # Blah
  end

  def method!
    # Blah
  end
end
Run Code Online (Sandbox Code Playgroud)

如果ctags -R .是在这个文件运行生成的tags文件包含以下两行表明这两种方法都在代发现:

method  test.rb /^  def method$/;"  f   class:Hello
method! test.rb /^  def method!$/;" f   class:Hello
Run Code Online (Sandbox Code Playgroud)

但是,如果我将光标放在第method!3行的调用上并按下,^]则光标会跳转到method定义而不是正确的爆炸版本.好像感叹号没有包含在搜索的标识符中.

有没有办法解决这个问题,所以正确的方法是跳到?

iva*_*van 4

我意识到这已经太老了,但我在 Vim 8.0 和 Neovim 中都遇到了同样的事情。如果我:tag mymethod!从 vim 的命令行输入,它会找到相关标签,但如果我尝试<C-]>将光标放在方法名称上,则会出错(请注意它搜索的名称中E426: tag not found: mymethod缺少)。!

您可以通过添加!到 Ruby 语法中被识别为关键字字符的字符列表来解决此问题:

:set iskeyword+=!
Run Code Online (Sandbox Code Playgroud)

您可以将其添加到~/.vim/after/syntax/ruby.vim您打开的任何 Ruby 文件中。我还没有测试过这一点,所以不能说它是否会对其他方面产生不利影响。我知道这会改变跳字行为。w例如,会将 the 视为!“小”词的一部分。

转念一想,肯定会处理不好这样的事情!some_test。如果您用<C-]>光标点击其中的任何位置,它会搜索名为 的方法!some_test,这绝对不是您想要的。更好的解决方案是围绕 Ruby 文件的标记查找编写一个包装函数。我实际上正在为此做一些事情,所以当我有一些像样的东西时我会发布。

更新:我发现了一个非常简单的解决方法:

nnoremap <buffer><silent> <C-]> :tag <C-R><C-W><CR>
Run Code Online (Sandbox Code Playgroud)

由于某种原因,命令行模式下的行为与 的行为<C-R><C-W>不同expand('<cword>'),并且可以说与文档不同。即使!不是一个'iskeyword'字符,并且expand('<cword>')结果为mymethod<C-R><C-W>结果为mymethod!。这同样适用于is_this_your_method?. 您可以通过将以下内容放入其中来应用此解决方法~/.vim/ftplugin/ruby.vim

nnoremap <buffer><silent>  <C-]> :tag     <C-R><C-W><CR>
nnoremap <buffer><silent>     g] :tselect <C-R><C-W><CR>
nnoremap <buffer><silent> g<C-]> :tjump   <C-R><C-W><CR>
Run Code Online (Sandbox Code Playgroud)

更新2

事实证明 的特殊行为<C-R><C-W>是由 vim-ruby 提供的(默认情况下包含在 Vim 的运行时文件中)。该脚本自定义<C-R><C-W>并添加<Plug><cword>映射以正确识别 Ruby 光标标识符。我只是遇到了错误处理,!因为在添加我认为更舒适的键绑定时,我无意中破坏了 vim-ruby 已经提供的映射:

nnoremap <C-.> <C-]>
Run Code Online (Sandbox Code Playgroud)

如果我这样做了nmap,vim-ruby 的映射就可以完成它的工作。或者,您可以通过执行以下操作来利用 vim-ruby 提供的功能(在 ruby​​ ftplugin 文件中):

nnoremap <buffer><silent>  <C-]> :<C-U>exe v:count1."tag <Plug><cword>"<CR>
nnoremap <buffer><silent>     g] :<C-U>tselect <Plug><cword><CR>
nnoremap <buffer><silent> g<C-]> :<C-U>tjump   <Plug><cword><CR>
Run Code Online (Sandbox Code Playgroud)