VimのソースコードをVimで解析しよう(Part1-1)
Vimはご存知の通りC言語で書かれています。
ちょっと解析してみましょう。
題材はvim-jpのIssue#94 相対行表示にするとカーソルの表示位置がずれるで。
現象はMacOSXで発生してますが、持ってないので作業はlinux(fedora)でやります。
(追記)本来は先ず現象の発生した環境(OS, Vim ver., etc...)で現象の再現手順を確立すべきです。今回のアプローチはイレギュラーです><。
下準備
.vimrc
" <C-]>でタグジャンプ時にタグが複数あったらリスト表示。カーソルがウィンドウの中心行になるようにジャンプ nnoremap <C-]> g<C-]>zz " タグファイルはカレントファイルのパスを基準に上向き検索 set tags=./tags; " grepは再帰検索、行番号表示あり、バイナリファイルは対象外、マッチ毎にファイル名表示する " .hgフォルダとtagsファイルは対象外 set grepprg=grep\ -rnIH\ --exclude-dir=.hg\ --exclude=tags " (l以外で始まる)QuickFixコマンドの実行が終わったらQuickFixウィンドウを開く autocmd QuickfixCmdPost [^l]* copen
$ cd vimソースをゲットしたディレクトリ/src $ ctags -R -I __ARGS $ vim
※以後の操作はすべてVimからおこないます。
解析の取っ掛かり
「カーソル位置による相対行番号の描画データ設定処理」から「カーソル描画処理」の間にカーソル位置が変更されていると考えられます。もしそうであればその処理間にカーソル位置が変更されないような仕組みを入れれば解決できるかも。
まずは各処理をやっている場所を特定しましょう。
カーソル位置による相対行番号の描画データ設定処理
キーワードは'relativenumber'オプションですからそれを検索してみましょう。
:grep relativenumber .
option.cの2069行がオプションテーブルのデータっぽいんですけど、同7527行、7528行の If 'number' is set, reset 'relativenumber'. がすごく気になります。もろにオプション変数を弄ってそうなので。
" カレントウィンドウを次ウィンドウ(==Quickfixウィンドウ)に移動。 <C-W><C-W> " カーソルを最下行(./option.c|7528|〜)に移動 L " カーソル行のQuickFix情報にジャンプ <CR>
どうやら w_p_nu が 'number'オプションのBOOL値で、w_p_rnu が 'relativenumber'オプションのBOOL値のようです。ということは w_p_rnu でgrepすれば「カーソル位置による相対行番号の描画データ設定処理」に近づけそうです。
" カーソルを2行下の最初の非空白文字に移動 2<CR> " カーソルを右側の最初の _ へ移動 f_ " カーソル下の単語をgrep :grep <C-R><C-W> .
描画処理は screen.c でおこなわれていると思われますのでその辺を見ていきましょう。
" カレントウィンドウを次ウィンドウ(==Quickfixウィンドウ)に移動。 <C-W><C-W> " 「screen.c」を検索 /screen\.c " カーソル行のQuickFix情報にジャンプ <CR>
./screen.c|433| w_redr_typeの値をセットするだけの判定なのでスルー。
" 次のQuickFix情報にジャンプ :cn
./screen.c|950| w_nrwidth絡みの処理っぽいのでスルー。
:cn
./screen.c|3459| おおっ、ここっぽい!一応関数名確認。
" 1桁目が '{' で始まる所へ後方(↑)ジャンプ (== 後方のC関数の定義冒頭部へジャンプ) [[ " ウィンドウを1ページ後方(↑)スクロール <C-B>
fold_line()!?コメントも Display one folded line. って書いてるからfolding機能用だな。残念。スルー。
:cn
./screen.c|3459| うーん。。
" QuickFixウィンドウを閉じる :ccl " ウィンドウを1ページ前方(↓)スクロール <C-F>
!!ここだ!関数名も win_line() だし、関数のコメントもそれっぽい!
(w_p_nu でgrepした方が良かったっぽいけど見つかったからOK)
今回はここまで。
次回は「カーソル描画処理」を探します。よろしくどうぞ。
(Part1-2)へ