2011年08月07日(日) [長年日記]
■ [vim][dev] Pyclewnを使ってVimからGDBを操作
GDBは--tuiオプションを使って使用していたのだけれど、PyclewnというPythonスクリプトを使うと、Vim上でGDBを操作できるようになることを知った。Vimにパッチを当てる必要もなく、GVim必須でもなくて素晴らしい。使い方などをメモ。
インストール
現在の最新バージョンは1.6。インストーラがあるのでそれでインストール。ドキュメントの通り、
% vimdir=$HOME/.vim python setup.py install --force --home=$HOME
を実行し、ホームディレクトリへインストールした。これで、pyclewnコマンドやVimのPyclewnプラグインが使えるようになる。
Pyclewnの起動と終了
Pyclewnは、Vimから「:Pyclewn」を実行して起動する方法と、pyclewnコマンドの子プロセスとしてVimを実行する方法の2通りの実行方法がある。後者の方が使いやすく感じた。後者の場合、
% pyclewn -e vim --cargs '-S ~/.pyclewn_mapping.vim' --args デバッグ対象プログラム名
のようにして実行できる。オプションの意味は次の通り。
- -e vim
- 使用するエディタプログラムを指定。gvimではなくvimを使いたいために指定した。
- --cargs '-S ~/.pyclewn_mapping.vim'
- Vimへのオプションを指定。~/.pyclewn_mapping.vimに、Pyclewn使用時だけ有効にしたいVimのキーマッピングを定義している(後述)。
Vimを終了すればPyclewnも終了する。
GDBの操作
GDBのほとんどのコマンドを、Vimのコマンドラインモードで「C」の後に続ければ使用できる。例えば、
:Cbreak main
とすれば、デバッグ対象プログラムの関数mainが表示され、そこにブレイクポイントが設定される。
その後「:Crun」して「:Cnext」して「:Cprint」してという風に、通常のGDBと同じように操作ができる。が、これだけだといつもより2文字多く打つ必要があり不便なので、キーマッピングを定義したい。
キーマッピングの設定例
Pyclewnには「:Cmapkeys」とすることでキーマッピングを定義する機能があり、このマッピング内容を設定ファイルでカスタマイズする機能もある。けれども、このカスタマイズ機能はVimのmapコマンドとは異なる方法でマッピングを定義していて、やりたいマッピングを定義できなかった(具体的には、カーソル位置の単語を取得することができそうになかった)。
なので、この機能は使わず、上に書いたように、~/.pyclewn_mapping.vim にmapコマンドでマッピングを定義して、Pyclewn起動時にこのファイルを読み込ませるようにした。今の ~/.pyclewn_mapping.vim の内容は次の通り。Pyclewn使用中は編集操作はしないと割り切って、いくつかの編集コマンド(編集以外もだけど)は上書きしている。まだ試行錯誤中なので注意。
cnoremap <expr> <SID>lineno line(".") " カーソル行にブレイクポイント設定/取消 nnoremap <script> BB :Cbreak <C-R><C-%>:<SID>lineno<CR> nnoremap <script> BC :Cclear <C-R><C-%>:<SID>lineno<CR> nnoremap R :Crun nnoremap S :Cstep<CR> nnoremap N :Cnext<CR> nnoremap F :Cfinish nnoremap U :Cuntil nnoremap C :Ccontinue nnoremap <C-U> :Cup<CR> nnoremap <C-D> :Cdown<CR> " カーソル位置の変数の値表示 nnoremap PP :Cprint <C-R><C-W> nnoremap PO :Cprint *<C-R><C-W> " カーソル位置の変数をwatch変数バッファに追加 nnoremap P` :Cdbgvar <C-R><C-W> " watch変数バッファのカーソル行の折り畳みを開く/閉じる nnoremap <script> ZZ :Cfoldvar <SID>lineno<CR> " watch変数バッファのカーソル位置の情報を削除 nnoremap ZD :Cdelvar <C-R><C-W>
watch変数バッファ
上のマッピングで使っているが、Pyclewnにはwatched variables bufferというバッファがあって、watchしたい変数をそのバッファに次のコマンドで登録できる。
:Cdbgvar 変数名
変数の型が構造体などの場合は折り畳まれて表示され、折り畳みの展開は次のようにして行う。
:Cfoldvar watch変数バッファの行番号
また、
:Cdelvar watch変数バッファ上での名前
でバッファから変数を削除できる。指定する名前はバッファ上で「var1」などと表示されている名前。
ブレイクポイント設定時の補完
「:Cbreak」コマンドでブレイクポイントを設定するとき、デフォルトでは関数名の補完が効かない。
:Csymcompletion
を実行すると、GDBが保持するシンボル情報を補完に利用できるようになる。