Jumping to a Ruby bang method using Ctags in Vim
ctags, ruby, vim
Solution
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>
Problem
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?