src/README.txt の翻訳

README for the Vim source code

ここにはソースコードを探索するためのいくつかのヒントが書かれている。
これを読むことによってそれが簡単になりはしないが、とっかかりにはなるだろう。

":help development" も読むと良いだろう。


飛び回る

まず最初に ":make tags" としてタグファイルを生成しよう。そうすれば
":tag" コマンドでソースコード中を飛び回れるようになる。

関数や変数定義にジャンプするには、その名前の上にカーソルを乗せて
CTRL-] コマンドを使う。戻るには CTRL-T または CTRL-O を使う。

ファイルへジャンプするには、その名前の上にカーソルを乗せて "gf"
コマンドを使う。

ほとんどのコードは明らかな名前のファイル中で見つかる(以下は不完全なリスト):
buffer.c バッファ操作(読み込み済みのファイル)
diff.c diff モード (vimdiff)
eval.c 式評価
fileio.c ファイル読み書き
fold.c 折り畳み
getchar.c 文字取得とキーマッピング
mark.c マーク
mbyte.c マルチバイト文字処理
memfile.c バッファの行をスワップファイルに保存する
memline.c バッファの行をメモリに保存する
menu.c メニュー
message.c (エラー)メッセージ
ops.c オペレータ処理 ("d", "y", "p")
option.c オプション
quickfix.c quickfix コマンド (":make", ":cn")
regexp.c パターンマッチング
screen.c ウィンドウ更新
search.c パターン検索
spell.c スペルチェック
syntax.c シンタックスその他のハイライティング
tag.c タグ
term.c ターミナル処理、termcapコード
undo.c アンドゥとリドゥ
window.c 分割ウィンドウ処理


重要な変数

現在のモードは "State" に保持される。とりうる値は NORMAL,
INSERT, CMDLINE, その他2,3。

現在のウィンドウは "curwin"。現在のバッファは "curbuf"。これらは
ウィンドウ中のカーソル位置、オプション値、ファイル名などの構造体を指す。
それらは structs.h 中で定義されている。

全てのグローバル変数は globals.h 中で宣言されている。


メインループ

便利なことにこれには main_loop() という名前がついている。この関数は
2,3 のものを更新し、その後 normal_cmd()を呼んでコマンドを処理する。
この関数はコマンドが終了したら戻ってくる。

基本的な考え方としては、Vim はユーザが文字をタイプするのを待ち、
別の文字が必要になるまでそれを処理する。それゆえ、文字がタイプ
されるのを待つ箇所はいくつかある。関数 vgetc() がそれを行う。
またこの関数はマッピングも処理する。

スクリーンの更新は、コマンドやコマンド列が完了するまで先延ばしにされる。
この作業は update_screen() によって行われる。この関数は 各ウィンドウ毎に
win_update()を呼び、win_update() は各行ごとに win_line() を呼ぶ。
さらなる説明は screen.c の最初を参照のこと。


コマンドラインモード
":" をタイプすると normal_cmd() は getcmdline() を呼び、Ex コマンドの行
を取得する。getcmdline() はタイプされた文字を処理するループを持つ。
などコマンドラインモードを抜ける文字が打たれたとき、
この関数は終了する。


Ex コマンド

Ex コマンドは関数 do_cmdline() によって処理される。この関数は
":" コマンドラインを総称的にパースし、分割された各コマンドに
対して do_one_cmd() を呼ぶ。またこの関数はループ全体も
考慮に入れる。

do_one_cmd() は範囲と総称的な引数をパースし、それらを
exarg_t に入れ、コマンドを処理する関数に渡す。

":" コマンドのリストが ex_cmds.h にある。各アイテムの
3番目の要素はそのコマンドを処理する関数の名前である。
最後の要素はコマンドのフラグである。


ノーマルモードコマンド
ノーマルモードコマンドは関数 normal_cmd() で処理される。
この関数はまたオプショナルの回数指定や、いくつかのコマンド
に対する追加の文字も処理する。これらは cmdarg_t に入れて
それをコマンドを処理する関数に渡される。

normal.c に nv_cmds というテーブルがあり、各コマンド
の最初の文字をリストしている。各アイテムの2番目の要素は
そのコマンドを処理する関数の名前である。


インサートモードコマンド

"i" や "a" コマンドが入力されると、normal_cmd() は 関数 edit() を呼ぶ。
この関数は次の文字を待ち、それを処理する。インサートモードを抜けたとき、
この関数を抜ける。


オプション

option.c に options[] という全オプション名のリストがある。


GUI

GUI コードのほとんどは、賢いターミナルであるかのように実装されている。
文字を打つ、スクロールバーを動かす、マウスをクリックする等は全て
入力バッファ中で書かれたイベントに翻訳される。それらは
ターミナルから読まれたの同じようにメインコードに解釈される。
そのコードは gui.c 中にちらばっている。例えば、マウスクリックを
処理するgui_send_mouse_event()、メニューアクションを処理する
gui_menu_cb()。キー押打はシステム固有の GUI コードによって処理される。
その GUI コードは add_to_input_buf() を呼んでキーコードを送らせる。

GUI ウィンドウの更新は、ターミナルに出力するのと同じように出力バッファ
にコードを書き込むことによって行われる。バッファが一杯になったとき、
またはフラッシュされたとき gui_write() がコードをパースし、適切な
アイテムを描画する。最終的にシステム固有の GUI コードがその仕事を
するために呼ばれる。


GUIデバッグ

gvim が fork して、デバッガに vim が終了したと思われるのを避ける
ために、引数に"-f"を加えるのを忘れないこと。

ディスプレイ更新コードの中に入ると、デバッガとVimを行き来するとき
フォーカスイベントがトリガーされてしまう。これを避けるには、
gui_focus_change() を無効化して同じコードをコンパイルしなおすこと。