Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

VimでC++のコードリーディング

$
0
0

この記事は 初心者C++er Advent Calendar 2017、20日目の記事です。

VimでC++のコードリーディング

私はC++の開発にVimを使用しています。
IDEにはさすがに負けるかもしれませんが、Vimでも結構快適にコードを読むことができます。

以下にVimを使用してC++のコードリーディングを行う際のTipsについて記載していきたいと思いますー。

環境

Windows 7

VIM - Vi IMproved 8.0 (2016 Sep 12, compiled May 2 2017 12:56:41)
MS-Windows 64 ビット GUI 版
適用済パッチ: 1-596

デフォルトで使用できるキーマップ

多用するのは以下です。

map説明
[#カーソルが#if-#endif内ならば#if or #elseにジャンプ
]#カーソルが#if-#endif内ならば#else of #endifにジャンプ
gd変数の定義位置にジャンプ(大抵うまくジャンプできるらしい)
gD変数(global)の定義位置にジャンプ(大抵うまくジャンプできるらしい)
[[一桁目が{の行(大抵関数の開始位置(?))にジャンプ
]]一桁目が}の行(大抵関数の終了位置(?))にジャンプ
[* or [/C コメントの始まり(/*)に移動します。
]* or ]/C コメントの終わり(*/)に移動します。
gfカーソル下のファイルを開く(環境によってpathの設定が必要です)
<C-^> or <C-6>直前に開いたファイルを開く(厳密には違います。詳細は:h CTRL-6)

このあたりのマップは実はC++用ではなくC言語用のマップかもしれません。
ただ、C++でも問題なく使用できます。

定義位置ジャンプ、参照元ジャンプ

ctagscscopeを使用します
Windowsの場合にctagsはここから、cscopeはここからバイナリをダウンロードできます。
ダウンロード後はパスが通っている場所に配置すればよいだけ。
あとは以下のような設定をvimrc内に記載して、少し便利にします。
(一部vim-submodeというプラグインを使用して、<C-t>と逆方向への移動を楽にしてます。)

" cscope show/killをマッピングnnoremap<Leader>zs :<C-u>cscope show<CR>nnoremap<Leader>zk :<C-u>cscope kill -1<CR>" :cscope find c <関数名> " 指定した関数を呼び出している関数を検索" :cscope find f <ファイル名> " ファイルを検索" :cscope find s <Cのシンボル> " シンボルを検索" 最後に指定する文字を大文字にするとクリップボード内の文字列を使用して:cscope findを実行します。" NOTE: @+ についてはclipboardの設定により、適宜変更してくださいnnoremap<Leader>zfc :<C-u>cscope find c<C-r>=expand('<cword>')<CR><CR>nnoremap<Leader>zfC :<C-u>cscope find c<C-r>=@+<CR><CR>nnoremap<Leader>zfs :<C-u>cscope find s <C-r>=expand('<cword>')<CR><CR>nnoremap<Leader>zfS :<C-u>cscope find s <C-r>=@+<CR><CR>nnoremap<Leader>zff :<C-u>cscope find f<C-r>=expand('<cfile>')<CR><CR>nnoremap<Leader>zfF :<C-u>cscope find f<C-r>=@+<CR><CR>" 定義位置へのジャンプ時に複数候補表示" クリップボード内の文字列使って:tjumpnnoremap<C-]>g<C-]>nnoremapg<C-]> :<C-u>tjump<C-r>=@+<CR><CR>" <C-t>と逆方向への移動をg<C-t>tttt..とできるよう設定" NOTE: <C-t>は定義への移動前にいた場所にジャンプ。" NOTE: vimデフォルトだと<C-t>の逆方向への移動用マップはない(<C-o>で逆移動っぽい動作はするが、少し違う)ので、定義call submode#enter_with('tag','n','','g<C-t>',':<C-u>tag<CR>')call submode#map('tag','n','','t',':<C-u>tag<CR>')

私の場合にはSVNの各ブランチのルートディレクトリ(.svn or .gitディレクトリがある場所)でctags, cscopeを実行したかったので、
以下のような設定も追加しています。

" 特定のファイルを開いた場合にはカレントディレクトリをルートディレクトリに変更function! s:root_dir() abortlet search_dir_names = ['.svn','.git']for dir_name in search_dir_nameslet ret_dir = finddir(dir_name, expand('%:p:h') . ';')if ret_dir !=''return substitute(fnamemodify(ret_dir,':p:h'), dir_name . '$','','g')endifendforreturn''endfunction
augroup cd_project_root
  autocmd!
  autocmd BufEnter *.cpp,*.h,*.c,silent execute 'lcd' s:root_dir()
augroup END" do ctagsfunction! s:do_ctags() abortif isdirectory('.svn')|| isdirectory('.git')if input('now: ' . getcwd() . "\nrun ctags? (y)es or (n)o : ")=~'^y$\|^yes$'silent!start ctags -Rendifelse
    echohl ErrorMsg | echo 'check current dir!'| echohl noneendifendfunction" cscope build/addfunction! s:cscope_build() abortif isdirectory('.svn')|| isdirectory('.git')if input('now: ' . getcwd() . "\nrun cscope -Rb? (y)es or (n)o : ")=~'^y$\|^yes$'silent!startcscope-Rbendifelse
    echohl ErrorMsg | echo 'check current dir!'| echohl noneendifendfunctionfunction! s:cscope_add() abortif(isdirectory('.svn')|| isdirectory('.git'))&& filereadable('cscope.out')cscope add cscope.out
    echo "cscope add cscope.out!"else
    echohl ErrorMsg | echo 'check current dir!'| echohl noneendifendfunction" ctags, cscope build/add用のマップ
nmap <Leader>ct :<C-u>call<SID>do_ctags()<CR>
nmap <Leader>zb :<C-u>call<SID>cscope_build()<CR>
nmap <Leader>za :<C-u>call<SID>cscope_add()<CR>

cscopeについて

記事を書いていく中で知ったのですが、cscopeはC言語用のパーサとして作られているようですね。。
c++でも大抵動くらしいですが、以下のような記載もあり油断は禁物らしいです。

The fuzzy parser supports C, but is flexible enough to be useful for C++ and Java, and for use as a generalized 'grep database'

現状はrtagsというのが流行っているそうですね。
どなたかWindowsでrtagsを使う方法をまとめてください(切実)

まとめ

いかがだったでしょうか?
Vimをつかえば設定しなくとも快適にコードを読めますし、設定すれば更に快適にコードを読むことができます!
他のIDEの使い方がわからないだけとは言えない

また、ここでは紹介しませんが、Vimのプラグインであるunite.vimのmru, bookmark, file機能をつかえば
ファイルを開くまでの時間を短縮できますし、unite-outlineを使用すれば
ファイル内の定義の一覧を常に表示でき、VimをIDEっぽくすることもできます。

皆様もいろいろ試してみて、Vimで快適なコードリーディングを行ってみましょー!
Happy C++ Life!


Viewing all articles
Browse latest Browse all 5608

Trending Articles