Implement jump to ruby method (bang-aware)

It always annoyed me that vim jump-to-tag (ctrl-] or ,f in yadr)
totally flopped when it came to ruby bang methods. This function
handles methods! and method.invocations! to find bang versions
of methods.
This commit is contained in:
Yan Pritzker
2012-10-08 18:39:08 -07:00
parent e1fe13d022
commit a5b5dd63e0
3 changed files with 47 additions and 7 deletions

View File

@@ -241,6 +241,7 @@ If you omit the key combo, you'll get a list of all the maps. You can do the sam
#### Search/Code Navigation #### Search/Code Navigation
* `,f` - instantly Find definition of class (must have exuberant ctags installed) * `,f` - instantly Find definition of class (must have exuberant ctags installed)
* `ctrl-m` - jump to Method. Same as vim's built in jump to tag, but much more aware of ruby bang_methods! and method.invocations!
* `,F` - same as ,f but in a vertical split * `,F` - same as ,f but in a vertical split
* `,gf` or `Ctrl-f` - same as vim normal gf (go to file), but in a vertical split (works with file.rb:123 line numbers also) * `,gf` or `Ctrl-f` - same as vim normal gf (go to file), but in a vertical split (works with file.rb:123 line numbers also)
* `gF` - standard vim mapping, here for completeness (go to file at line number) * `gF` - standard vim mapping, here for completeness (go to file at line number)

View File

@@ -0,0 +1,46 @@
function! JumpToRubyMethod()
" Grab the current WORD. Which could be something like
" object.some_method!
let l:stuff_under_cursor = expand("<cWORD>")
" Figure out if this is a method call (obj.some_method)
" by looking for the period
let l:method_invocation = split(matchstr(l:stuff_under_cursor, '\..*'), '\.')
" If there was no method invocation in the current word then
" we want to avoid the <cWORD> which might be something
" like foo_bar(baz). We just want the method name, which
" is already stored for us as <cword> by vim
if empty(l:method_invocation)
" See if this is a regular method ending in !
let l:bang_method = matchstr(l:stuff_under_cursor, '.*!')
if(empty(l:bang_method))
let l:method_name = expand("<cword>")
else
let l:method_name = l:bang_method
end
else
" If there is a method invocation, then figure out
" the method name, which is the first element in the match
let l:method_name = l:method_invocation[0]
endif
try
execute ':tag ' . l:method_name
catch
endtry
endfunction
" hit ,f to find the definition of the current class
" this uses ctags. the standard way to get this is Ctrl-]
" Using viW so we select the entire word, including any
" exclamation point in a ruby method. FIXME this is not
" good for methods like this(foo) which has parens
" nnoremap <silent> ,f viW<C-]>
nnoremap <silent> ,f <C-]>
nnoremap <silent><C-m> :call JumpToRubyMethod()<CR>
" use ,F to jump to tag in a vertical split
nnoremap <silent> ,F :let word=expand("<cword>")<CR>:vsp<CR>:wincmd w<cr>:exec("tag ". word)<cr>

View File

@@ -126,13 +126,6 @@ nnoremap ,gcp :GitGrepCurrentPartial<CR>
"GitGrep Current File "GitGrep Current File
nnoremap ,gcf :call GitGrep(expand("%:t:r"))<CR> nnoremap ,gcf :call GitGrep(expand("%:t:r"))<CR>
" hit ,f to find the definition of the current class
" this uses ctags. the standard way to get this is Ctrl-]
nnoremap <silent> ,f <C-]>
" use ,F to jump to tag in a vertical split
nnoremap <silent> ,F :let word=expand("<cword>")<CR>:vsp<CR>:wincmd w<cr>:exec("tag ". word)<cr>
"Move back and forth through previous and next buffers "Move back and forth through previous and next buffers
"with ,z and ,x "with ,z and ,x