This is how to achieve “JumpToDefinition” in Vim, for JS and Less files.
I’ve tested a lot of plugins, most famous ones being:
- Result: creates a bar of definitions, ideally
- Advantage: a clear list of definitions to be toggled on and off.
- Disadvantage: in reality, Tagbar rarely works that smoothly. It depends on exuberant-ctags rather than ctags to generate tags, and exuberant-ctags doesn’t work well with modern Javascript, including RequireJS and prototypes. For example, a js file wrapped in Require() yields an empty list.
- Result:
- Advantage: navigates through file, buffer, mru (most recently used), tag… easily
- Disadvantage: can’t directly place cursor upon word and Ctrl-] to definition. You’ll need to open the search panel and type in the keywords. But its fuzzy search is really nice. Besides, sometimes the fire buffer just can’t find the file I need (in both current path and search by file name).
And a workaround for Jumping to CSS definition:
- add this in .vimrc:
function! JumpToCSS() let id_pos = searchpos("id", "nb", line('.'))[1] let class_pos = searchpos("class", "nb", line('.'))[1] if class_pos > 0 || id_pos > 0 if class_pos < id_pos execute ":vim '#".expand('<cword>')."' **/*.less" elseif class_pos > id_pos execute ":vim '.".expand('<cword>')."' **/*.less" endif endif endfunction nnoremap <leader>] :call JumpToCSS()<CR>zz
- Result: place mouse on html class/id and directly jump to definition in less/css
- Advantage: fast in pressing the keys.
- Disadvantage:
- slow in responding if your Less files are large (approximately 0.5s in my case)
- can’t navigate through occurrences by :tn, :tp, :tjump (:ts), :tag…
And there’s also the native Ctag:
which, added support for JavaScript and Less, is actually quite nice to go with CtrlP. Add these to your ctags file (usually placed ~/.ctags on Mac):
--exclude=*.min.js --exclude=vendors --langdef=less --langmap=less:.less --regex-less=/^[ t]*.([A-Za-z0-9_-]+)/1/c,class,classes/ --regex-less=/^[ t]*#([A-Za-z0-9_-]+)/1/i,id,ids/ --regex-less=/^[ t]*(([A-Za-z0-9_-]+[ tn,]+)+){/1/t,tag,tags/ --regex-less=/^[ t]*@medias+([A-Za-z0-9_-]+)/1/m,media,medias/ --langdef=js --langmap=js:.js --regex-js=/([A-Za-z0-9._$]+)[ t]*[:=][ t]*{/1/,object/ --regex-js=/([A-Za-z0-9._$()]+)[ t]*[:=][ t]*function[ t]*(/1/,function/ --regex-js=/function[ t]+([A-Za-z0-9._$]+)[ t]*(([^)]))/1/,function/ --regex-js=/([A-Za-z0-9._$]+)[ t]*[:=][ t]*[/1/,array/ --regex-js=/([^= ]+)[ t]*=[ t]*[^"]'[^']*/1/,string/ --regex-js=/([^= ]+)[ t]*=[ t]*[^']"[^"]*/1/,string/
The first part is files to be excluded, followed by rules for generating tags for less/js files.
Solution 1: Pure Ctags
- update .ctags file
- generate Ctags with
:!ctags -R .
- jump to definition with Ctrl+]
- navigate with :tn (next) :tp (previous) and all sorts or awesomeness detailed in
:help tag
Solution 2: Ctags + CtrlP
References:
- http://stackoverflow.com/questions/635770/jump-to-function-definition-in-vim
- http://stackoverflow.com/questions/1054701/get-ctags-in-vim-to-go-to-definition-not-declaration
- https://github.com/mellort/dotfiles/blob/master/ctags.conf