GUR.vim - Grand Unified Reference
こんなもん作ってみた。いかがでしょう。
とりあえず自分では使うつもりだけど、反響があれば vim.org にアップしてメンテナンスするつもり。
概要
統一されたインターフェイスで各種言語のリファレンスを閲覧できます。
対応言語
言語 | 実行コマンド |
---|---|
C/C++ | man -a |
perl | perldoc -f |
php | w3m "http://www.php.net/ja/" |
python | pydoc |
ruby | refe |
vim | :help |
その他 | man -a |
JavaScript とか対応したいけど、いいリファレンスが見つからず…
インストール
~/.vim/plugin におくだけ。
使い方
キーワード(関数名)などの上にカーソルを置いて K を押します。
Ruby の場合、カーソル位置に応じて下記のキーワードを refe で検索します。
カーソル位置 | 検索するキーワード |
---|---|
メソッド名の上 | そのメソッド |
「String#split」の「split」の上 | String#strip |
「"hoge".split」の「split」の上 | String#strip |
「1234.nonzero?」の「nonzero?」の上 | Integer#nonzero? |
「[1,2,3].length」の「length」の上 | Array#length |
「1234」の上 | Integer |
「"hoge"」の上 | String |
Python もほぼ同様。
他の言語では普通の K と同様に 'iskeyword' に従いカーソル下のキーワードを抽出します。
結果ウィンドウでは
カスタマイズ
g:GUR_dict をいじることで対応言語を増やしたり、実行コマンドをカスタマイズできます。
ソース
GUR.vim
" Grand Unified Reference if &cp || exists("g:loaded_GUR") finish endif if v:version < 700 echoerr "GUR: this plugin requires Vim >= 7.0" finish endif let g:loaded_GUR = 1 let g:GUR_dict = { \ "c" : ["r!man -a %s | col -b", 1], \ "cpp" : ["r!man -a %s | col -b", 1], \ "perl" : ["r!perldoc -T -t -f %s", 1], \ "php" : ["r!w3m -dump http://www.php.net/ja/%s", 1], \ "python" : ["r!pydoc %s", 1], \ "ruby" : ["r!refe %s", 1], \ "default" : ["r!man -a %s | col -b", 1], \ "default_count": ["r!man %d %s | col -b", 1] \ } "nnoremap <silent> <unique> <Plug>GURGUReference :<C-u>call <SID>GUReference(&ft, "")<CR> nnoremap K :<C-u>call <SID>GUReference(&ft, "")<CR> xnoremap K <Esc>:<C-u>call <SID>GUReference(&ft, <SID>GetVisualRegionString())<CR> command! -nargs=? GUR call <SID>GUReference(&ft, "<args>") let s:separator = "===============================================" function! s:GUReference(language, word) try let bufnr_save = bufnr("%") if exists("b:GUR_language") let language = b:GUR_language else let language = a:language endif let isk_save = &l:isk let pos_save = getpos(".") let re_number = '[0-9]\+$' " Extract the word. if a:word != "" let word = a:word else if language ==? "vim" normal! K return else let line = strpart(getline('.'), 0, col('.')) let re = '\(\S\+\)\.\k*$' let match = matchstr(line, re) let receiver = substitute(match, re, '\1', '') let syntax = synIDattr(synID(line("."),col("."),1),"name") if 0 " dummy elseif language ==? "c" || language ==? "cpp" let word = expand("<cword>") elseif language ==? "html" let word = expand("<cword>") elseif language ==? "javascript" let word = expand("<cword>") elseif language ==? "perl" let word = expand("<cword>") elseif language ==? "php" let word = expand("<cword>") elseif language ==? "python" if syntax =~ 'String' let word = "__builtin__.str" elseif expand("<cword>") =~? re_number let word = "__builtin__.int" else if receiver =~ "[\"']$" let word = "__builtin__.str." . expand("<cword>") elseif receiver =~? re_number let word = "__builtin__.int." . expand("<cword>") elseif receiver =~ '\]$' let word = "__builtin__.list." . expand("<cword>") else let word = expand("<cword>") endif endif elseif language ==? "ruby" setlocal isk+=#,!,? if syntax =~ 'String' let word = "String" elseif expand("<cword>") =~? re_number let word = "Integer" else let sp = search('^==== \k\+ ====$', 'bWn', line(".") - 200 >= 0 ? line(".") - 200 : 0) if sp " in _GUR_ruby buffer let module_name = matchstr(getline(sp), '\k\+') let word = module_name . "#" . expand("<cword>") else if receiver =~ "[\"']$" let word = "String#" . expand("<cword>") elseif receiver =~? re_number let word = "Integer#" . expand("<cword>") elseif receiver =~ '\]$' let word = "Array#" . expand("<cword>") else let word = expand("<cword>") endif endif endif else let word = expand("<cword>") endif endif endif " Setup the result buffer. if !(has_key(g:GUR_dict, language) && g:GUR_dict[language][1] == 0) call s:SingletonBuffer("_GUR_" . language, 1) let b:GUR_language = language setlocal bt=nofile nnoremap <buffer> q :close<CR> nnoremap <silent> <C-p> :call <SID>GUR_Back()<CR> nnoremap <silent> <C-n> :call <SID>GUR_Forward()<CR> normal! G call append(line("$"), s:separator) normal! G endif let escaped_word = shellescape(word, '%#') let dont_move = 0 " Do look-up command. if has_key(g:GUR_dict, language) let cmd = "sil " . printf(g:GUR_dict[language][0], escaped_word) else if v:count == 0 let cmd = "sil " . printf(g:GUR_dict["default"][0], escaped_word) else let cmd = "sil " . printf(g:GUR_dict["default_count"][0], v:count, escaped_word) endif endif echomsg cmd exe cmd finally let &l:isk = isk_save endtry if !dont_move exe "normal! `[kz\<CR>" endif endfunction function! s:GUR_Back() call search('^'.s:separator, 'bW') exe "normal! z\<CR>" endfunction function! s:GUR_Forward() call search('^'.s:separator, 'W') exe "normal! z\<CR>" endfunction " If a buffer named 'name' exists, move the cursor on it. " Else create one. function! s:SingletonBuffer(name, split) let name = a:name if bufexists(name) let bufnr = s:GetBufferNumberByName(name, 0) let winlist = filter(range(1, winnr("$")), 'winbufnr(v:val)==' . bufnr) if empty(winlist) if a:split split endif exe "b " . bufnr else exe winlist[0] . "wincmd w" endif else if a:split exe "sil new " . escape(name, ' |') else exe "sil e " . escape(name, ' |') endif endif endfunction function! s:GetVisualRegionString() " save the register let old_reg=getreg('a') let old_regmode=getregtype('a') silent normal! gv"ay let selected=@a " restore it call setreg('a', old_reg, old_regmode) return selected endfunction function! s:GetBufferNumberByName(name, ignorecase) let buflist = filter(range(1, bufnr("$")), 'bufexists(v:val)') for bufnr in buflist if (a:ignorecase && bufname(bufnr) ==? a:name) || bufname(bufnr) ==# a:name return bufnr end endfor return -1 endfunction