Next: , Previous: , Up: Modes   [Contents][Index]


22.7 Automatic Indentation of code

プログラミング言語のメジャーモードにとって、自動的なインデントの提供は、重要な機能です。これには2つのパートがあります。1つ目は正しい行のインデントが何か、そして2つ目はいつ行を再インデントするかの判断です。デフォルトでは、electric-indent-charsに含まれる文字(デフォルトでは改行のみ)をタイプしたとき、Emacsは常に行を再インデントします。メジャーモードは、その言語の構文に合わせて、electric-indent-charsに文字を追加できます。

正しいインデントの決定は、indent-line-functionによりEmacs内で制御されます(Mode-Specific Indentを参照)。いくつかのモードでは、へのインデントは信頼性がないことが知られています。これは通常、複数のインデントが有効だが、それぞれが異なる意味をもつので、インデント自体が重要だからです。そのような場合、そのモードは行が常にユーザーの望み通り再インデントされないことを念押しするために、electric-indent-inhibitをセットするべきです。

よいインデント関数の記述は難しく、その広範な領域において、未だ黒魔術の域を脱していません。メジャーモード作者の多くは、単純なケース(たとえば前のテキスト行のインデントとの比較)にたいして機能する、単純な関数の記述からスタートすることでしょう。実際には行ベースではないほとんどのプログラミング言語にたいして、これは貧弱なスケールになりがちです。そのような関数にたいして、より多様な状況を処理するような改良を行うと、関数はより一層複雑になり、最終的な結果は誰にも触れようとする気を起こさせない、巨大で複雑な保守不可能のインデント関数になる傾向があります。

よいインデント関数は通常、その言語の構文に応じて、実際にテキストをパースする必要があるでしょう。幸運なことに、このテキストパースはコンパイラーが要するほど詳細である必要はないでしょうが、その一方でインデントコードに埋め込まれたパーサーは、構文的に不正なコードにたいして、コンパイラーより幾分寛容な振る舞いを求められるでしょう。

保守可能なよいインデント関数は、通常2つのカテゴリーに落ち着きます。どちらも何らかの“安全”な開始ポイントから、関心のある位置まで前方にパースを行うか、あるいは後方へパースを行います。この2つの方法は、どちらも一方が他方に明快に優る選択ではありません。後方へのパースは、プログラミング言語が前方にパースされるようデザインされているため、前方へのパースに比べて難しいことが多々ありますが、インデントという目的においては“安全”な開始ポイントを推測する必要がないという利点があり、一般的にある行のインデントの判断のために分析を要するのは最小限のテキストだけという特性に恵まれているので、前の無関係なコード片内にある、何らかの構文エラーの影響をインデントが受けにくくなる傾向があります。一方で前方へのパースは、通常はより簡単であり、一度のパースで、リージョン全体を効果的に再インデントすることが可能になるという利点があります。

インデント関数をスクラッチから記述するよりも、既存のインデント関数の試用と再利用、または一般的なインデントエンジンに委ねるほうが優る場合が、しばしばあります。しかし、そのようなエンジンは悲しむべきほど少数しかありません。CCモードのインデントコード(C、C++、Java、Awk、およびその類のモードが使用)は年月を経てより一般化されてきているので、あなたの言語にこれらの言語と何らかの相似点があるなら、このエンジンの使用を試みるかもしれません。もう一方のSMIEはLispのsexp精神によるアプローチを採用して、それを非Lisp言語に適応します。