*develop.txt* For Vim バージョン 8.1. Last change: 2019 Aug 05 VIMリファレンスマニュアル by Bram Moolenaar
この文書は、Vim の更なる開發に參加しようといふ人にとつて重要なものです。
1. 設計上の目標 | |design-goals| |
2. コーディングスタイル | |coding-style| |
3. 決定事項 | |design-decisions| |
4. 想定してゐること | |design-assumptions| |
ソースコードの槪要については "src" ディレクトリの README.txt を見てください。
Vim はオープンソースソフトウェアです。誰でも Vim の開發に協力できます。パッチを送る時はなるべく "unified diff" 形式 ("diff -u" で作る) でお願ひします。GitHub 上でプルリクエストを作ることも可能ですが、必須ではありません。
http://vim.wikia.com/wiki/How_to_make_and_submit_a_patch
も見てください。
重要度の順に從つて書かれてゐます(大雜把ですが)。
Note:
かなりの項目が矛盾してゐることに注意してください。これは故意でさうしてゐます。それらの閒で、バランスを取つていかなければなりません。
何よりもまづ、Vim は Vi の氣輕な置き換へとして使ふことができるべきであります。ユーザーが望むなら、オリジナルの Vi との區別がほとんど付かない互換モードで Vim を使ふことができます。
例外:
Vim の改良點は、それをよりよい Vi にすべきであつて、まつたく違つたエディタにしてしまつてはなりません。擴張は "Vi の精神" に從つて行はれます。
(1) | ユーザーが求めてゐることか |
(2) | 實裝にはどれほどの勞力が必要か |
(3) | 誰かが實際に實裝してゐるか |
といつたことに基づいて選擇されます。
Vim は可能な限り、多くのプラットフォーム上の多くのユーザーの助けでありたい。
Vim を使ふことでシステムリソースに大打擊を與へてはなりません。Vim を小さく、速く保ちませう。
Vim は、そのユーザーに特定の作業パターンを强ひるよりは、ユーザーの好むスタイルでの作業を支援すべきです。これは大きな影響をもつ項目 (例へば、’compatible’ オプション) や、その他の詳細によつて實現されます。デフォルトは、多くのユーザーがそのままの Vim を樂しんで使へるやうに愼重に選ばれてゐます。コマンドとオプションは、Vim をユーザーの希望と環境に調整するために使はれます。
諷刺を込めて曰く: "Vim は Emacs のやうに流し臺以外ならなんでもかんでも取り込んでしまふやうなことはしないが、Vim で流し臺を洗ふことはできるぞ。 ;-)"
Vim と gdb を連携させる方法については次を參照:
Vim のソースコードに變更を加へる際に守るべきルールがあります。ソースを讀めるもの、保守できるものとして保つため、これらのルールに從つてください。
このリストは完全ではありません。より多くの例はソースコードを見てください。
コードに變更を加へる基本的なステップは:
git diff
" でパッチを作成します。GitHub でプルリクエストを作成しても良いのですが、重要なのはその diff です。
サポートされてゐる最小の C コンパイラのバージョンは C89 (ANSI C とも呼ばれてゐる) です。C99 のやうな後繼の標準規格はあまりサポートされてゐません。もしくは少なくとも 100% サポートされてゐるわけではありません。したがつて C99 のいくつかの機能だけを使用し、その他の使用は (少なくとも現時點では) 禁止します。
現存するパッチに對してマージの問題を引き起こすため、C99 の機能を使ふ變更を至る所に入れてはいけません。新しくコードを書く場合、もしくは既存のコードを書き直す場合に限り使用しませう。
慣習的に Vim では /* コメント */ を使用します。特にファイルと函數のヘッダに關してはこれを維持するつもりです。新しいコードもしくは變更される行については、// コメント を使用してもよいでせう。特にコードの後ろに續くコメントなど:
int some_var; // ここで一行コメントは有用
列擧型の末尾の要素にコンマ (trailing comma) が付いてゐてもよいでせう。C89 では認められてゐませんでした。
"long long" は使用してもよく、64 bit を想定してゐます。printf では %lld を使用してください。同じやうに "long long unsigned" では %llu を使用してください。
これらの C99 の機能は、コンパイラのサポートが不十分なため使用してはいけません:
よく使はれる函數のうち、特別な Vim バージョンを持つものがあります。これらは理由があつて導入されたものなので、常に Vim バージョンを使ふやうに意識しませう。
標準的な名前 | Vim での名前 | Vim 版での違ひ |
---|---|---|
free() | vim_free() | NULL の解放をチェックする |
malloc() | alloc() | アウトオブメモリの狀況をチェックする |
malloc() | lalloc() | alloc() に似てゐるが、long 型の引數を持つ |
strcpy() | STRCPY() | char_u *引數を、(char *) へキャストする |
strchr() | vim_strchr() | スペシャルキャラクタを受け入れる |
strrchr() | vim_strrchr() | スペシャルキャラクタを受け入れる |
isspace() | vim_isspace() | 128 以上のキャラクタを扱ふことができる |
iswhite() | vim_iswhite() | Tab とスペースに對してのみ TRUE |
memcpy() | mch_memmove() | オーバーラップしたコピーを扱ふ |
bcopy() | mch_memmove() | オーバーラップしたコピーを扱ふ |
memset() | vim_memset() | 全てのシステムで一定である |
函數の名前に 31 文字より長い名前は使へません (VMSのために)。
"delete" や "this" といふ名前の變數を使はないでください。C++ で問題となります。
Vim をできる限り多くのシステム上で實行できるやうにするといふ必要上、システムによつてすでに定義されてゐる名前を使ふことは避けなければなりません。以下は問題となることが知られてゐる名前のリストです。名前は regexp パターンとして與へられてゐます。
is.*() | POSIX, ctype.h |
to.*() | POSIX, ctype.h |
d_.* | POSIX, dirent.h |
l_.* | POSIX, fcntl.h |
gr_.* | POSIX, grp.h |
pw_.* | POSIX, pwd.h |
sa_.* | POSIX, signal.h |
mem.* | POSIX, string.h |
str.* | POSIX, string.h |
wcs.* | POSIX, string.h |
st_.* | POSIX, stat.h |
tms_.* | POSIX, times.h |
tm_.* | POSIX, time.h |
c_.* | POSIX, termios.h |
MAX.* | POSIX, limits.h |
__.* | POSIX, system |
_[A-Z].* | POSIX, system |
E[A-Z0-9]* | POSIX, errno.h |
.*_t | POSIX, for typedefs, *_T を使ふこと |
wait | types.h とコンフリクトするため、函數の引數として使はない |
index | グローバル宣言を覆ひ隱す |
time | グローバル宣言を覆ひ隱す |
new | C++ の豫約語 |
clear | Mac curses.h |
echo | Mac curses.h |
instr | Mac curses.h |
meta | Mac curses.h |
newwin | Mac curses.h |
nl | Mac curses.h |
overwrite | Mac curses.h |
refresh | Mac curses.h |
scroll | Mac curses.h |
typeahead | Mac curses.h |
basename() | GNU 文字列函數 (GNU string function) |
dirname() | GNU 文字列函數 (GNU string function) |
get_env_value() | Linux システム函數 |
型の定義に使ふ名前は最後を "_T" にします:
typedef int some_T;
マクロ定義はすべて大文字にします:
#define SOME_THING
機能に關する定義は "FEAT_" で始めます:
#define FEAT_FOO
’\"’ は使はないでください。これを扱へないコンパイラがあります。’"’ はうまく機能します。
次は使つてはいけません:
#if HAVE_SOME
あるコンパイラはこれを扱へず、"HAVE_SOME" が定義されてゐないと訴へます。
次を使ひます:
#ifdef HAVE_SOME
または
#if defined(HAVE_SOME)
一般的なルール: 1 行に 1 つのステートメント。
閒違ひ: if (cond) a = 1; OK: if (cond) a = 1;
閒違ひ: while (cond); OK: while (cond) ;
閒違ひ: do a = 1; while (cond); OK: do a = 1; while (cond);
閒違ひ: if (cond) { cmd; cmd; } else { cmd; cmd; } OK: if (cond) { cmd; cmd; } else { cmd; cmd; }
ブロックが 1 行の場合は、波括弧を省くことができます。if/else の 1 つのブロックに波括弧がある場合、他のブロックにも波括弧があると通常は見榮えが良くなります:
OK: if (cond) cmd; else cmd; OK: if (cond) { cmd; } else { cmd; cmd; }
函數宣言には ANSI スタイルを使ひ、戾り値の型は獨立した行にインデントをつけて書いてください。
閒違ひ: int function_name(int arg1, int arg2) OK: /* * Explanation of what this function is used for. * この函數が何に使はれるかの說明。 * * Return value explanation. * 戾り値の說明。 */ int function_name( int arg1, // short comment about arg1 int arg2) // short comment about arg2 { int local; // comment about local local = arg1 * arg2;
函數名とブラケットの閒にスペースを入れないでください:
閒違ひ: func (arg); OK: func(arg);
if, while, switch などの後にはスペースを入れてください。
閒違ひ: if(arg) for(;;) OK: if (arg) for (;;)
コンマ、セミコロンの後にはスペースを入れてください:
閒違ひ: func(arg1,arg2); for (i = 0;i < 2;++i) OK: func(arg1, arg2); for (i = 0; i < 2; ++i)
’=’, ’+’, ’/’ などの前と後には、スペースを入れてください。
閒違ひ: var=a*5; OK: var = a * 5;
一般的なこと: コードの行をグループ分けするために空行を使ひます。行グループのすぐ上にコメントを入れます。かうすることによつて、何が行はれるのかをより簡單に知ることができます。
OK: /* Prepare for building the table. */ /* テーブルの作成の準備 */ get_first_item(); table_idx = 0; /* Build the table */ /* テーブルの作成 */ while (has_item()) table[table_idx++] = next_item(); /* Finish up. */ /* 仕上げ */ cleanup_items(); generate_hash(table);
同じバッファにいくつもの折疊狀態を設定可能にします。例へば、あるウィンドウに函數を折疊んだ狀態で表示し、他のウィンドウで函數の中身を表示するなど。
折疊はテキストを表示する方法です。テキストを變更すべきではありません。したがつてバッファ內のテキストをウィンドウに表示する際のフィルタとして實行されます。
"ウィンドウ" といふ單語は一般にいくつかの意味で使はれてゐます。スクリーン上のウィンドウ、xterm のウィンドウ、Vim のバッファを表示するウィンドウなど。
混亂を避けるため、時にウィンドウと呼ばれる他の物には別の名前が付けられてゐます。ここに關聯する物の槪觀を示します。
ディスプレイ全體。GUI では例へば 1024x768 ピクセルの畫面。Vim シェルはスクリーン全體を使ふことも一部を使ふこともできます。
Vim アプリケーション。スクリーン全體 (例へばコンソールで實行した時)、あるいはその一部 (xterm や GUI)。
バッファの表示畫面。Vim は複數のウィンドウを持つことができます。ウィンドウはコマンドラインやメニューバー、ツールバーなどといつしよに表示されます。これらはシェルに納まります。
Vim にスペルチェックを追加することになつたとき、利用可能なスペルチェックのライブラリやプログラムについての調査が行はれました。その結果は殘念なことに、Vim 內でスペルチェックエンジンとして使へるものはないとわかりました。これには樣々な理由があります:
オンザフライな變換は常に可能とは限りません (iconv に對應してゐる必要があります)。
候補の作成には 2 つの基本的なメカニズムがあります:
最初のメカニズムはタイプミスを見つけるのには良いです。ハッシュテーブルの實驗と、他のスペルチェッカのソリューションを見ると、これには trie (ツリー構造の一種) が最適であるとの結論になりました。メモリ使用量の削減と、賢い變更を試みるといふことの兩方の面でです。例へば、文字を插入するときは正しい單語につながる文字だけを試せば良いです。他の (ハッシュテーブルを使つた) メカニズムは、單語のすべての位置でありうるすべての文字を試さねばなりません。また、ハッシュテーブルを使ふには、單語の境界が個別に認識されなければならないのに對し、trie はそれを要求しません。そのためメカニズムがより單純になります。
ある單語の撥音は知つてゐるけれどもスペルは知らないといふ場合に soundfolding は有用です。例へば、"dictionary" といふ單語を "daktonerie" と書いてしまふかもしれません。これを最初の方法で訂正しようとすると變更回數が非常に多くなつてしまひ、正しいスペルを見つけるのは困難になります。それに對し、これらの單語に soundfolding を行ふと "tktnr" と "tkxnry" になり、2 文字しか違ひません。
soundfold の同値 (音が似てゐる單語) により單語を見つけるには、全ての soundfolded words のリストが必要です。どれが最良の方法かを探すための實驗が行はれました。案:
我々が採用したのは、2 番目のメカニズムを使ひ、別ファイルを使ふ方法です。かうすることによつて、十分なメモリを持つてゐるユーザーはとてもよい候補を得ることができるし、メモリが不足してゐるユーザーやスペルチェックだけで候補は出さなくてよいといふユーザーはそれほどメモリを使はなくて濟みます。
候補をソートするにはどの單語が共通であるかを知ると役に立ちます。理論的には單語の頻度は單語とともに辭書の中に保持することができます。しかしさうすると、單語につき回數を保持しなければなりません。これは單語ツリー壓縮を大いに劣化させます。また、全ての言語に對して單語の頻度を保守するのは大變な作業です。また、テキストに既に出てきてゐる單語を優先するとよいでせう。このやうにして特定のテキスト內に表れる單語は候補の中で優先度が高くなります。
實裝されたのは、表示中に單語を數へることです。ハッシュテーブルを使つてその單語の回數を高速に檢索します。回數は接辭ファイルで COMMON アイテムにリストされてゐる單語から初期化されます。そのため新規ファイルの編輯を始めたときも機能します。
これは理想的ではありません。Vim が長時閒稼動してゐるほど回數は大きくなるためです。しかし實用的には單語の回數を使はない場合と比べて注目に値するほどの改善です。
變數のサイズ:
char | 8 bit signed |
char_u | 8 bit unsigned |
int | 32 or 64 bit signed (限定された機能については 16 ビットもありうる) |
unsigned | 32 or 64 bit unsigned (16 ビットについては int と同樣) |
long | 32 or 64 bit signed, can hold a pointer |
Note:
いくつかのコンパイラは長すぎる行は文字列をうまく扱へないことに注意していください。C89 の標準規格では 509 文字までに制限されてゐます。