VimのソースコードをVimで解析しよう(Part1-2)
(Part1-1)からの続きです。
(お知らせ) コマンドラインモードのエンターキー押下の表記を省略せずに [Enter] で表すようにします。
カーソル描画処理を探す
NO PLANっす。とりあえず cursor でgrepしてみましょう。
" 「cursor」をgrep :grep cursor .[Enter] " (grepが終わってから) " カレントウィンドウを次ウィンドウ(==Quickfixウィンドウ)に移動。 <C-W><C-W> " Quickfixウィンドウの高さを可能な限り最大化 <C-W>_ " ウィンドウを1ページ前方(↓)スクロール <C-F> " 〜しばしgrep結果と戯れる(時おり <C-F> 押しながら)〜
戯れて感じたこと
- CUIのカーソル処理の話なのでおそらく gui*.c とか関係ないはず。
- カーソル下の文字によってカーソル幅とか変わるからマルチバイト(mbyte.c)は関係するよなぁ。
- ml_get_cursor()はカーソル位置の文字取得する関数かぁ。
- curwin->w_cursor.lnum とか wp->w_cursor.lnum がカーソル行番号か?
(curwinは多分カレントウィンドウの情報だろう) - setcursor()ってもろそれっぽい関数がある!
まずは curwin と w_cursor の定義を見てみましょう。
" QuickFixウィンドウを閉じる :ccl[Enter] " 「curwin」でタグジャンプ。(タグが複数あった時だけリスト表示) :tj curwin[Enter]
タグが複数あったのでリスト表示になりました。
1つ目はkindがv(外部変数)だしファイル名がそれっぽい!
2つ目はkindがm(構造体等のメンバ変数)ですし、ファイル名がTclインターフェイス関連っぽいのでどう考えても1つ目が正解です。
ちなみにkindの文字の意味はタグファイルからの情報なので、ctagsで確認できます。
" リスト表示をキャンセル [Enter] " 外部プログラムを実行(ctagsでC言語のタグ種別を一覧表示) :!ctags --list-kinds=c[Enter]
以下のように表示されます。(exuberant ctags 5.8 / 5.8J2の場合)
c classes d macro definitions e enumerators (values inside an enumeration) f function definitions g enumeration names l local variables [off] m class, struct, and union members n namespaces p function prototypes [off] s structure names t typedefs u union names v variable definitions x external and forward variable declarations [off] 続けるにはENTERを押すかコマンドを入力してください
本題に戻ってリスト表示で 1 を選択しましょう。
" 2つ前のコマンドライン履歴(:tj curwin)を呼び出して実行。 :<C-P><C-P>[Enter] " リスト表示で1つ目を選択 1[Enter]
" 前方(→)にword移動 w " カーソル下のキーワード(win_T)でタグジャンプ。(Part1-1の下準備参照) <C-]> " 前方(→)に2word移動 ww " カーソル下のキーワード(window_S)でタグジャンプ。 <C-]> " ウィンドウを1ページ前方(↓)スクロール <C-F> " カーソルを2パラグラフ前方(↓)移動 }} " カーソルを1行下の最初の非空白文字に移動 <CR> " カーソル下のキーワード(pos_T)でタグジャンプ。 <C-]>
ん?コメントに position in file or buffer 。。ファイルかバッファ内の位置??
(カレントウィンドウにアサインされている)バッファ内の位置ということは、バッファ内のどこに注目しているかという情報であって画面上の「カーソル」を描画する位置ではないですね。
でも画面描画する時はこの情報を使うはず!深追いは止めて次いきましょう。
次は setcursor() をチェック!
" 「setcursor」でタグジャンプ。(Tabキーを押して補完) :tj setcu<Tab>[Enter] " カーソルを4行下へ移動 jjjj " カーソル下(右側)のキーワード(validate_cursor)でタグジャンプ。 <C-]> " カーソルを2行下の最初の非空白文字に移動 <CR><CR> " カーソル下(右側)のキーワード(check_cursor_moved)でタグジャンプ。 <C-]>
引数はcurwinが渡されていますから wp は curwin です。ということはさきほどの curwin->w_cursor を参照してますね。
比較相手の w_valid_cursor の定義を見にいくと cached values とコメントに書いてます。w_cursor が キャッシュ値(w_valid_cursor) と異なる場合は、w_valid の各種フラグを落として、キャッシュ値(w_valid_cursor)を更新しています。
" タグジャンプを1つ遡る。(validate_cursorの関数定義部分へ) <C-T>
w_valid の VALID_WCOL か VALID_WROW のフラグが落ちている場合は curs_columns() でもろもろ更新しています。
" タグジャンプを1つ遡る。(setcursorの関数定義部分へ) <C-T> " ウィンドウのバッファを下へ6行スクロールする。 6<C-E>
windgoto()は定義部分のコメントを見る限り、画面上の「カーソル」を描画する関数です。それも踏まえて考えると curwin->w_wrow と curwin->w_wcol は、カレントウィンドウ上のカーソル位置(行、列)でしょう。
あと気になるのはカーソル描画処理の実行/非実行を redrawing() で制御しているというところでしょうか。
調査結果まとめ
カーソル位置による相対行番号の描画データ設定処理は win_line() [screen.c : 3482]
カーソル描画処理は setcursor() [screen.c : 8644]
今回はここまで。
次回はデバッガで追いかけてみましょう。よろしくどうぞ。
(Part1-3)へ