Zen-Coding for C系言語
Zen-Coding は独特の短い記法で構文を指定し、コマンドによりテキストを入力する方式です。
Zen-Coding for C系言語 を使うと、for文、if文、while文、do-while文、return文、構造体・クラス定義、typedef文、namespace文 などを少ないストロークで、非常に簡単かつ高速に入力できます。
展開ルールはユーザがテキストファイルで指定することができます。詳しくは こちら を参照してください。
ZenCoding for C系言語 をマスターして、3倍速いコーディングを身につけてください。
使い方はいたって簡単。i a != b の様に構文指定子、パラメータ直後で Ctrl + ,(カンマ)を入力するだけです。
i a != b(カーソル) ↓ Ctrl + ,(カンマ)を押下 if (a != b) { (カーソル) }
f または for に続けて、ループ変数、初期値、比較演算子、最終値、増減などを指定可能です。
以下の例で、型名が「int」になっていますが、JavaScript タイプの場合は「var」が生成されます。
for文に限っては、php, JavaScript, python, Ruby に対応しています。
展開前 | 展開後 | 説明 |
---|---|---|
f | for (int i = 0; i < N; ++i) { (カーソル) } | int i を 0 から N-1 までループ |
f j | for (int j = 0; j < N; ++j) { (カーソル) } | f の直後にループ変数を指定 |
f i 100 | for (int i = 0; i < 100; ++i) { (カーソル) } | ループ回数指定 |
f i 10 100 | for (int i = 10; i < 100; ++i) { (カーソル) } | ループ初期値、最終値指定 |
f i 100 10 | for (int i = 100; --i > 10; ) { (カーソル) } | 初期値>最終値 の場合 |
f i N | for (int i = 0; i < N; ++i) { (カーソル) } | 変数指定時 |
f i first != last | for (int i = first; i != last; ++i) { (カーソル) } | ループ初期値、比較演算子、最終値指定 |
f i v.size() | for (int i = 0; i < v.size(); ++i) { (カーソル) } | 最終値を式で指定 |
f i first last | for (int i = first; i < last; ++i) { (カーソル) } | 初期値、最終値を式で指定 |
f i first last - | for (int i = first; --i > last; ) { (カーソル) } | - でデクリメント指定 |
f; | for (;;) { (カーソル) } | 無限ループ |
展開前 | 展開後 | 説明 |
---|---|---|
f | for ($i = 0; $i < N; ++$i) { (カーソル) } | $i を 0 から N-1 までループ |
f j | for ($j = 0; $j < N; ++$j) { (カーソル) } | f の直後にループ変数($は省略可能)を指定 |
f $k | for ($k = 0; $k < N; ++$k) { (カーソル) } | f の直後にループ変数を指定 |
展開前 | 展開後 | 説明 |
---|---|---|
f | for (var i = 0; i < N; ++i) { (カーソル) } | i を 0 から N-1 までループ |
f j | for (var j = 0; j < N; ++j) { (カーソル) } | f の直後にループ変数(は省略可能)を指定 |
f k | for (var k = 0; k < N; ++k) { (カーソル) } | f の直後にループ変数を指定 |
展開前 | 展開後 | 説明 |
---|---|---|
f | for i in range(N): (カーソル) | i を 0 から N-1 までループ |
f k | for k in range(N): (カーソル) | ループ変数指定 |
f 100 | for i in range(N): (カーソル) | ループ回数指定 |
展開前 | 展開後 | 説明 |
---|---|---|
f | for i in 1..N do (カーソル) end | i を 0 から N-1 までループ |
f k | for k in 1..N do (カーソル) end | 変数指定 |
f 100 | for k in 1..100 do (カーソル) end | 繰り返し回数指定 |
f 10..20 | for k in 10..20 do (カーソル) end | 繰り返し範囲指定 |
i(または if)条件式 を if (条件式) { } に、
ie 条件式 を if (条件式) { } else { } に展開します。
条件式は省略可能で、省略すると true が挿入されます。
展開前 | 展開後 | 説明 |
---|---|---|
i | if (true) { (カーソル) } | if 文のひな形生成 |
i a != b | if (a != b) { (カーソル) } | 条件式指定で if 文を生成 |
ie | if (true) { (カーソル) } else { } | if-else 文のひな形生成 |
ie a != b | if (a != b) { (カーソル) } else { } | 条件式指定で if-else 文を生成 |
e | else { (カーソル) } | else 節生成 |
ei | else if (true) { (カーソル) } | else if 文のひな形生成 |
ei a != b | else if (a != b) { (カーソル) } | 条件式指定で else if 文を生成 |
w 条件式 を if (条件式) { } に展開します。
条件式は省略可能で、省略すると true が挿入されます。
展開前 | 展開後 | 説明 |
---|---|---|
w | while (true) { (カーソル) } | while 文のひな形生成 |
w first != last | while (first != last) { (カーソル) } | 条件式指定で while 文を生成 |
d 条件式 をdo { } while (条件式); に展開します。
条件式は省略可能で、省略すると true が挿入されます。
展開前 | 展開後 | 説明 |
---|---|---|
d | do { (カーソル) } while( true ); | while 文のひな形生成 |
d first != last | do { (カーソル) } while( first != last ); | 条件式指定で while 文を生成 |
展開前 | 展開後 | 説明 |
---|---|---|
r | return;(カーソル) | return 文を生成します。 |
r true | return true;(カーソル) | 返り値付き return 文を生成します。 |
b | break;(カーソル) | break 文を生成します。 |
展開前 | 展開後 | 説明 |
---|---|---|
s | struct Name { (カーソル) }; | 構造体定義のひな形生成 |
s MyStruct | struct MyStruct { (カーソル) }; | 構造体定義のひな形生成 |
c | class Name { (カーソル) }; | クラス定義のひな形生成 |
c MyClass | struct MyClass { (カーソル) }; | クラス定義のひな形生成 |
展開前 | 展開後 | 説明 |
---|---|---|
ts | typedef struct { (カーソル) } Name; | 構造体定義のひな形生成 |
ts MyStruct | typedef struct { (カーソル) } MyStruct; | 構造体定義のひな形生成 |
展開前 | 展開後 | 説明 |
---|---|---|
tuc | typedef unsigned char uchar;(カーソル) | 符号なし8ビット型定義を生成 |
tus | typedef unsigned short ushort;(カーソル) | 符号なし16ビット型定義を生成 |
tui | typedef unsigned int uint;(カーソル) | 符号なし32ビット型定義を生成 |
展開前 | 展開後 | 説明 |
---|---|---|
tcc | typedef const char cchar;(カーソル) | const char 型定義を生成 |
展開前 | 展開後 | 説明 |
---|---|---|
# | #include "(カーソル) | #include 文を生成 |
#i | #include "(カーソル) | #include 文を生成 |
#< | #include <(カーソル) | #include 文を生成 |
#d | #define (カーソル) | #define 文を生成 |
#0 | #if 0(カーソル) | #if 文を生成 |
#e | #endif(カーソル) | #endif 文を生成 |
#el | #else(カーソル) | #else 文を生成 |
#ei | #elif(カーソル) | #elif 文を生成 |
展開前 | 展開後 | 説明 |
---|---|---|
im | int main() { (カーソル) return 0; } | main関数のひな形生成 |
ima | int main(int argc, char *argv[]) { (カーソル) return 0; } | 引数付きmain関数のひな形生成 |
展開前 | 展開後 | 説明 |
---|---|---|
// | //---(70個)---(カーソル) | // に続く70個の - 生成 |
展開前 | 展開後 | 説明 |
---|---|---|
sop | System.out.println("(カーソル)"); | print文生成 |
設定ファイルを用意しておき、下記の書式で展開パターンを指定可能とします。
構文指定子(タブ)展開後テキスト
「\c」は展開後のカーソル位置を表します。「\c」が無い場合はカーソルは末尾に設定されます。
改行は「\n」で指定します。「\t」でタブを指定することも可能です。「\」そのものを入力したい場合は「\\」と記述します。
パラメータを展開する部分は「\{」と「\}」でマークします。その中にパラメータが省略された場合のテキストを記述します。
s や c など既に定義済みのものを指定した場合、ファイルによる指定の方が優先されます。
例:
sop(タブ)System.out.println("\c");
w(タブ)while (\{true\}) {\n\t\c\n}
より詳しい例は、アーカイブに同梱されている ZenCoding.txt を参照してください。
展開パターンを指定するテキストファイルを作成したら、文字エンコーディングUTF-8で適当なディレクトリに保存します。 次に、設定>全体設定 メニューを実行し、全体設定ダイアログを開き、Zen-Coding ファイル:の部分に作成したファイルフルパスを入力します。 直ぐ横の【参照…】ボタンを押すと、ファイルツリーからフィルを選択することも出来ます。
Zen-Coding は定型的なテキストを短いストロークで高速に入力するためのものです。
同様の目的を持つ機能・手法としては、(1) テキストファイル挿入、(2) 短文入力、(3) vi の abbreviations、(4) snipets,
(5) マクロ関数 などがあります。以下比較します。
エディタによっては、テキストファイルをカーソル位置に挿入する機能があります。
この機能を使えば、定形テキストをカーソル位置に読み込むことが可能です。
しかし、「ファイル挿入」コマンド実行 → ファイル選択 という操作は Zen-Coding に比べるとステップが多く、
パラメータ指定による柔軟なテキスト生成が不可能です。
エディタによっては、登録テキストをカーソル位置に挿入する機能があります。
この方法はテキストファイル挿入よりはステップが少ない場合が多いですが、
やはり、パラメータ指定による柔軟なテキスト生成が不可能です。
vi には abbreviations(短縮入力)という機能があり、「.virc」ファイルに展開元、展開後テキストを記述しておくことで、
キーワードなどを短いテキストで入力することが可能です。
しかし、テキスト展開がスペース(半角空白)キーのために i、a などといったよく使う1文字を展開元として指定すると、
i という文字そのものを入力出来ないという不都合が起こります。
また、直後が空白でないといけないため、「return;」を「ret」で入力するということも出来ません
(厳密には不可能ではないが、末尾に余分な空白が付加されてします)。
また、ファイル挿入・短文入力同様にパラメータ指定による柔軟なテキスト生成が不可能です。
Zen-Coding と snipets は非常によく似ています。本稿と実質的に同じ機能を snipets と呼んでいる例もあるかもしれませんが、 筆者は、定型文を指定する時にパラメータを指定する方式が Zen-Coding であり、 展開前にはパラメータを指定せず展開後にパラメータ変更機能をサポートするものが snipets だと考えています。
例えば、本方式で「f」を展開すると「for (int i = 0; i < N; ++i) { }」となります。
変数名を「i」ではなく「k」にしたい場合は「f k」とします。
それに対して snipets では 「for (int i = 0; i < N; ++i) { }」を生成した後、「i」の部分一箇所を「k」に変更すると、
全ての「i」が「k」に変わる機能を提供しているものが主流です。
つまり、パラメータ的な部分を展開前に指定するか、展開後に指定するかという違いです。
この違いは一長一短です。
一般論を言えば、展開後を想像しパラメータを指定する必要があるので、Zen-Coding の方が若干敷居が高いかもしれません。
しかし、修正箇所への移動操作を考えると、Zen-Coding の方式の方が速くテキストを入力可能です。
それに間違った場合は undo で元に戻してパラメータを修正し再度展開することも可能なので、
事前にパラメータを指定することはそれほど高い敷居ではないと考えます。
また、テキストバッファに特殊な属性を付加する必要が無いので、実装的には Zen-Coding の方がはるかに簡単です。
スクリプト・マクロを使えばどのようなエディタにも簡単に Zen-Coding を実装可能だと考えます。
筆者の知り合いに競技プログラミングを行っている人がいて、彼は速くコーディングするために以下のようなマクロを定義しています。
#define rep(i,a,b) for(int i = (a); i != (b); ++i)
この方式に比べると、Zen-Coding の打鍵回数は約2分の1です。
場合によってはいくつかのパラメータを省略出来る場合がありますし、デクリメントする場合にも対応しています。
また、この方式では他人がソースを読むにはマクロ定義を知っていないといけないという問題があります。
Zen-Coding であれば、展開後のソースは通常の文法に従ったものなので、誰でも直ぐにソースを理解することが可能です。
Zen-Coding は定型的なテキストを短いストロークで高速に入力するため非常に優れた方式です。 しかも、自分で展開ルールを追加することも簡単だ。使わないと損だぜ。