I'm having a problem with jumping to a Ruby bang method using Exhuberant Ctags. I have searched for others having a similar problem and am unable to find anything. An example of the problem can be shown using the following small Ruby class:
class Hello
def start
method!
end
def method
# Blah
end
def method!
# Blah
end
end
When ctags -R .
is run on this file the resulting tags
file contains the following 2 lines demonstrating that both methods are discovered at generation:
method test.rb /^ def method$/;" f class:Hello
method! test.rb /^ def method!$/;" f class:Hello
However, if I place my cursor on the call to method!
on line 3 and press ^]
then the cursor jumps to the method
definition rather than to the correct bang version. It seems as if the exclamation mark is not being included in the identifier that is searched for.
Is there a way to fix this so the correct method is jumped to?
I realize this is super-old, but I ran into the same thing in both Vim 8.0 and Neovim. If I enter :tag mymethod!
from vim's command-line, it finds the relevant tag, but if I try <C-]>
with my cursor on the method name, it errors E426: tag not found: mymethod
(note the lack of !
in the name it searched for).
You can fix this by adding !
to the list of characters recognized as keyword characters in Ruby syntax:
:set iskeyword+=!
You could add this to ~/.vim/after/syntax/ruby.vim
to apply it in any Ruby file you open. I haven't tested this though, so can't say whether it will adversely affect anything else. I know it will change word jumping behavior. w
will, for instance, treat the !
as part of the "small" word.
On second thought, it will definitely mishandle things like !some_test
. If you were to hit <C-]>
with the cursor anywhere in there, it would search for a method named !some_test
, which is definitely not what you want. A better solution would be to write a wrapper function around the tag lookup for Ruby files. I'm actually working on something for that, so I'll post when I have something that presentable.
Update: I found a surprisingly simple workaround:
nnoremap <buffer><silent> <C-]> :tag <C-R><C-W><CR>
For some reason, the behavior of <C-R><C-W>
in command-line mode differs from that of expand('<cword>')
, and arguably from the documentation. Even though !
is not an 'iskeyword'
character, and expand('<cword>')
results in mymethod
, <C-R><C-W>
results in mymethod!
. The same applies to is_this_your_method?
. You could apply this workaround by putting the following in ~/.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>
Update 2
It turns out the special behavior of <C-R><C-W>
was provided by vim-ruby (and included in Vim's runtime files by default). That script customizes <C-R><C-W>
and also adds a <Plug><cword>
mapping to correctly identify the Ruby cursor identifier. I only ran into the mishandling of !
because I had inadvertently clobbered the mappings already provided by vim-ruby when adding what I find to be more a comfortable keybinding:
nnoremap <C-.> <C-]>
If I'd done nmap
instead, vim-ruby's mapping could have done its job. Alternatively, you could leverage what vim-ruby provides by doing (in a ruby ftplugin file):
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>
You can always use :tag
:
:tag method!
Or visual mode - if you highlight any text (with v + movement) before you hit ^], it will use the highlighted text as the tag instead of trying to find an 'identifier' under the cursor. So if your cursor is on the m
in method!
, then
vE^]
should do the trick. If your cursor is elsewhere in the word, then hit b
first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With