藻ログ

都会でOLをしています

vimでソースをもりもり読む

普段はOLなのであまり凝った設定はしていません.

ソースをもりもり読むときに使う機能

  • ファイル絞りこみ検索(ctrlp)
  • 関数アウトライン(unite-outline)
  • ヘッダジャンプ(vim
  • カレントディレクトリ以下の全文検索 & ジャンプ(unite-grep
  • 定義元・参照ジャンプ(unite-gtag)
  • 複数単語のハイライト表示(vim-quickhl)

プラグイン

プラグイン管理はneobundle.vimからdein.vim へ移行しました.
dein.vimにお引越し - 藻ログ

[[plugins]]
repo = 'kien/ctrlp.vim'
hook_add = '''
let g:ctrlp_show_hidden = 1
let g:ctrlp_custom_ignore = {
  \ 'dir':  '\v[\/]\.(git|hg|svn)$',
  \ 'file': '\v\.(exe|so|dll|png)$',
  \ 'link': '',
  \ }
'''
[[plugins]]
repo = 'Shougo/unite.vim'
hook_add = 'source ~/.vim/userautoload/plugins/plugins-unite.vim'

[[plugins]]
repo = 'Shougo/unite-outline'
depends = 'unite.vim'
hook_add = 'source ~/.vim/userautoload/plugins/plugins-unite-outline.vim'

[[plugins]]
repo = 'hewes/unite-gtags'
hook_add = 'source ~/.vim/userautoload/plugins/plugins-unite-gtags.vim'
depends = 'unite.vim'

[[plugins]]
repo = "t9md/vim-quickhl"
hook_add = '''
nmap ,h <Plug>(quickhl-manual-this)
xmap ,h <Plug>(quickhl-manual-this)
nmap ,H <Plug>(quickhl-manual-reset)
xmap ,H <Plug>(quickhl-manual-reset)
'''

ファイル絞りこみ検索

ctrlp.vim

カレントディレクトリ以下のファイルを絞りこみながら検索します.
GitHub - kien/ctrlp.vim: Fuzzy file, buffer, mru, tag, etc finder.
dotファイルをひっかけて,バイナリや.gitを避けたいときはこんな感じに.

let g:ctrlp_show_hidden = 1
let g:ctrlp_custom_ignore = {
  \ 'dir':  '\v[\/]\.(git|hg|svn)$',
  \ 'file': '\v\.(exe|so|dll|png)$',
  \ 'link': '',
  \ }

後述のuniteで:Unite fileしても同様に絞りこみ検索できますが,ctrlpの方がシンプルです.
より詳しくは,:h ctrlpで.

全文検索

unite.vim

GitHub - Shougo/unite.vim: Unite and create user interfaces
検索結果など様々な出力の絞りこみやaction(tabopenとか)の指定ができます(こんな説明をするとすごく怒られそう).

基本的な設定

あまり設定してなくて,C-vで:vsplit openするぐらいです.tabopenはデフォルトでtに割り当てられてます.
iでインサートモードに入り,入力すると絞りこみができます.
その他のマッピング:h unite_default_key_mappingsで.

" insert modeで開始しない
let g:unite_enable_start_insert = 0

" 大文字小文字を区別しない
let g:unite_enable_ignore_case = 1
let g:unite_enable_smart_case = 1

augroup UniteSettingGroup
  autocmd!
  au FileType unite nnoremap <silent> <buffer> <expr> <C-v> unite#do_action('vsplit')
  au FileType unite inoremap <silent> <buffer> <expr> <C-v> unite#do_action('vsplit')
augroup END
unite-grep

:Unite grep でカレントディレクトリ以下のファイル群を全文検索にかけて,絞りこみ&該当箇所にジャンプします.
spaceキーをmakeやgit系プラグインにあててるので良いキーマップがない...

" grep検索
nnoremap <silent> ,g  :<C-u>Unite grep:. -buffer-name=search-buffer<CR>
" カーソル位置の単語をgrep検索
nnoremap <silent> ,cg :<C-u>Unite grep:. -buffer-name=search-buffer<CR><C-R><C-W><CR>
" grep検索結果の再呼出
nnoremap <silent> ,r  :<C-u>UniteResume search-buffer<CR>

また,defaultのgrepを高速なhighwayに置き換えて使っています.*1
highway という高速検索ツールを作りました · けんごのお屋敷

$ brew install highway
" unite grep に hw(highway) を使う
if executable('hw')
  let g:unite_source_grep_command = 'hw'
  let g:unite_source_grep_default_opts = '--no-group --no-color'
  let g:unite_source_grep_recursive_opt = ''
endif

関数アウトライン表示

unite-outline

GitHub - Shougo/unite-outline: outline source for unite.vim
今開いているファイルの関数リストを出力して,ジャンプできるようにします.
texlabelも拾えるので,寧ろ原稿を書くときに便利です.
f:id:nisimur:20161023215506p:plain
なんでtrに割り当てたのかイマイチ思い出せない...*2

nnoremap <silent> tr :<C-u>Unite -no-quit -vertical -winwidth=40 outline<CR>

" unite-outline の自動更新
let g:unite_source_outline_filetype_options = {
      \ '*': {
      \   'auto_update': 1,
      \   'auto_update_event': 'write',
      \ },
      \ 'cpp': {
      \   'ignore_types': ['enum', 'typedef', 'macro'],
      \ },
      \ 'javascript': {
      \   'ignore_types': ['comment'],
      \ },
      \ 'markdown': {
      \   'auto_update_event': 'hold',
      \ },
      \}

裏でctagsを使っているので,ctagsを入れないといかんかったはず

$ brew install ctags

インクルードヘッダジャンプ

普通に基本機能のgfでできます.パスにカーソルを合わせてgfすれば飛びます.
デフォルトのpathにないとダメなので,適宜追加してください.

augroup GfPathGroup
  autocmd!
  autocmd FileType cpp setlocal path+=/usr/local/include,/path/to/lib
augroup END

定義元・参照ジャンプ(タグジャンプ)

ctagsでも良いですが,gtagsの方が便利だと教えてもらったのでgtagsを使うようにしました.

GNU GLOBAL

GNU GLOBAL source code tagging system

$ brew install global

タグファイルを作成したいプロジェクトのrootで

$ gtags -v

するとGPATH, GRTAGS, GTAGSができます.
詳しい使い方は$ man global.
globalコマンドは,カレントディレクトリ下以外に環境変数$GTAGSLIBPATHにあるライブラリも見に行ってくれますが,たとえば

$ export GTAGSLIBPATH=/path/to/lib1:/path/to/lib2

という場合,カレントディレクトリ -> lib1 -> lib2 の順番にみにいきます.
ここでlib1でmatchがあると,lib2は見に行ってくれません.なので,例えばSTLとboost両方見に行きたい場合は/usr/local/include でタグを作るとかになります.また,

$ export GTAGSFORCECPP=1

しないと.h はcppファイルとして処理してもらえません.これも$ man globalで.

unite-gtags

gtags入れると/usr/local/share/gtags/gtags.vimもついてくるのでそっちを使ってもいいです*3が,絞りこみを使いたいのでunite-gtagsにします.
GitHub - hewes/unite-gtags: Unite source for GNU GLOBAL
よく使うものだけマッピングしておきます.

" カーソル下の呼び出し元一覧を出力
nnoremap <silent> ,tr  :<C-u>Unite gtags/ref:<CR>
" カーソル下の定義元を出力
nnoremap <silent> ,td  :<C-u>Unite gtags/def:<CR>
" タグファイル内grep
nnoremap <silent> ,tg  :<C-u>Unite gtags/grep:<CR>

環境変数$GTAGSLIBPATHg:unite_source_gtags_project_configからも制御でき,カレントディレクトリのパス毎に変更可能です

let g:unite_source_gtags_project_config = {
\   '_': {
\     'gtags_libpath':
\       [ '/usr/local/include' ]
\   },
\   '/path/to/opencv_proj/': {
\     'gtags_libpath':
\       [ '/usr/local/include', '/path/to/opencv' ]
\   },
\ }

単語ハイライト

vim-quickhl

カーソル下の単語を色付けたり元に戻したりして,複数単語のハイライトができます.
GitHub - t9md/vim-quickhl: quickly highlight <cword> or visually selected word
ハイライト&解除のキーマップだけ設定.

nmap ,h <Plug>(quickhl-manual-this)
xmap ,h <Plug>(quickhl-manual-this)
nmap ,H <Plug>(quickhl-manual-reset)
xmap ,H <Plug>(quickhl-manual-reset)

まとめ

今後はunite.vimからdenite.nvimに移行するということで,いまの環境を整理してみました.


整理したらそんないろいろ設定してるわけではなかった.
移行したらctrlpもやめて,deniteに一本化するかもしれない.

*1:ちょっと前まではag=silver searcherでした

*2:もともとNERDtree系に割り当てていて,NERDtreeを使わなくなったので空きがでたのかも...

*3::Gtags コマンドがいろいろ定義されている