Previous: , Up: インデント   [Contents][Index]


25.5 コードのアライメント

アライメント(Alignment: 整列)とはリージョン内の一連の行において、すべての行の特定の部分が同じ列で始まるように、空白文字を調整するプロセスのことです。これはテキストやコードの可読性を向上させるために、あなたが通常行っていることです。以下はCのようなプログラミング言語における一連の割り当てを整列する古典的な例を示しましょう:

int a = 1;
short foo = 2;
double blah = 4;

これは典型的には以下のように整列されます:

int    a    = 1;
short  foo  = 2;
double blah = 4;

コマンドM-x alignを使えば、カレントリージョン内の行を整列できます。このコマンドは多くのマークアップやプログラミング言語に通じる一般的なアライメントパターンを承知しています。異なるコンテキストにおける異なる種類のテキストをどのように整列するかを指定するためのアライメントルール(alignment rules)のセットとして、これらのパターンを符号化するのです。

ユーザーオプションalign-rules-listは、どのアライメントルールをM-x alignが参照すべきかを指示します。このオプションの値は、アライメントルールが記述された要素のリストです。要素はそれぞれ(title . attributes)という形式のコンスセルです。ここでtitleはそのアライメントルールの名前(シンボル)、attributesはそのルールをいつ適用するか、どのように行を区切って整列するかを定義するルール属性のリストです。ルール属性はそれぞれ(attribute . value)という形式のコンスセルでありattributeは属性の名前、valueがその属性の値になります。唯一必須の属性であるregexp値は、それぞれの行においてM-x alignが空白を展開、あるいは縮小すべき部分にマッチする部分式(sub-expressions)を表す正規表現です。利用可能なアライメントルールの属性についての完全な説明については、align-rules-listのドキュメント文字列(C-h v align-rules-list RET)を参照してください。このオプションのデフォルトには、Emacsがサポートする多くの言語用にアライメントルールの長いリストがセットされています。デフォルトのルールでは、M-x alignを適用するメジャーモードを指定するルール属性であるmodesが使用されます。メジャーモードのほうもバッファーローカル変数align-mode-rules-listに非nilのアライメントルールのリストをセットして、align-rules-listをオーバーライドできます。align-mode-rules-listが非nilなら、M-x alignalign-rules-listではなくそちらを参照します。

アライメントルール以外にも、M-x align除外ルール(exclusion rules)と呼ばれる別の類のルールを使用します。M-x alignにたいしてリージョン内のどの部分を整列せずに手つかずのまま残すよう指示するのが除外ルールです。この除外ルールはユーザーオプションalign-exclude-rules-listによって指定されます。align-rules-listと同じように、align-exclude-rules-listの値も除外ルールを記述するコンスセルのリストです。デフォルトでalign-exclude-rules-listに含まれているのはクォートされた文字列、およびLispやCなどの言語のコメントを整列から除外するためのルールです。align-mode-exclude-rules-listに非nilのルールのリストをセットすることによって、メジャーモードはデフォルトの除外ルールから更にモード用に誂えた除外ルールを定義することができます。align-mode-rules-listalign-rules-listをオーバーライドするのと同じように、このルールはalign-exclude-rules-listをオーバーライドします。

M-x alignはリージョンを一連のセクション(sections)に分割します。セクションとは通常は連続する非空行のことです。マッチするすべてのアライメントルールに応じて空白部分を展開あるいは縮小することによる、それぞれのセクションを整列します。M-x alignは1つのセクション内部のすべての行にたいして一貫性をもった整列を行いますが、リージョンに含まれている別のセクションにたいしては異なる整列を行うかもしれません。M-x alignがリージョンをどのようにセクションに分割するかは、ユーザーオプションalign-region-separateで指定します。このオプションにはシンボルentiregroup、あるいは正規表現を指定できます。align-region-separateentireならEmacsはリージョン全体を単一のセクションとして整列、groupならリージョン内で連続する非空行のグループそれぞれを個別のセクションとして整列します。align-region-separateが正規表現の場合には、M-x alignはリージョンからその正規表現にたいするマッチをスキャンして、それらのマッチを個別のセクションとして扱います。デフォルトではalign-region-separateは空行、空白のみからなる行、単独の中カッコ(curly brace; ‘{’や‘}’)にマッチする正規表現がセットされています。正規表現では不十分であるような特殊ケースについては、セクション整列のためにリージョンをどのように分割するかを指示する関数をalign-region-separateにセットすることもできます。詳細についてはalign-region-separateのドキュメント文字列を参照してください。特定のアライメントルールはルール属性separateを指定してセクション区切りを独自に定義することによって、align-region-separateの値をオーバーライドすることができます。

プレフィックス引数(C-u)とともにM-x alignを呼び出せば、より多くのアライメントルールを有効にできます。これは役に立つことが多いものの、場合によっては煩わし過ぎるかもしれません。たとえばLispバッファーで以下のようなフォームがあるとすると:

(set-face-attribute 'mode-line-inactive nil
                    :box nil
                    :background nil
                    :underline "black")

C-u M-x alignとタイプして以下が得られるでしょう:

(set-face-attribute 'mode-line-inactive nil
                    :box                nil
                    :background         nil
                    :underline          "black")

ほとんどの場合においてはまずプレフィックス引数なしのM-x alignを試してみて、正しい結果が生み出されなければC-/でアンドゥしてから再度C-u M-x alignを試みるべきでしょう。

カレントリージョンにたいして特定のアライメントルールや除外ルールの視覚的効果を確認するためにコマンドM-x align-highlight-ruleを使うことができます。このコマンドはルールのタイトルの入力を求めて、そのルールが効果を及ぼすリージョン部分をハイライトします。アライメントルールにたいしてこのコマンドはM-x alignが展開あるいは縮小するであろう空白をハイライト、除外ルールにたいしてはM-x alignが整列から除外するであろう部分をハイライトします。このコマンドが作成したハイライトを削除するには、M-x align-unhighlight-ruleとタイプしてください。

コマンドM-x align-currentM-x alignと似ていますが、カレントリージョンとは無関係にポイントを含むアライメント対象セクションだけを処理する点が異なります。align-region-separateで定義されたセクション区切りに応じて、このコマンドはカレントセクションの境界を判断します。もう一つのM-x alignの変種であるM-x align-entirealign-region-separateを無視して、リージョン全体を単一のアライメント対象セクションとして一貫した整列を行います。align-region-separateentireをセットしている場合には、M-x alignはデフォルトではM-x align-entireと同じように振る舞います。リージョン全体を単一のアライメント対象セクションとして整列する効果を説明するために、以下のコードで考えてみましょう:

one = 1;
foobarbaz = 2;

spam = 3;
emacs = 4;

リージョンがこれらの行すべてを含む場合には、M-x alignをタイプすることによって以下が得られるでしょう:

one       = 1;
foobarbaz = 2;

spam  = 3;
emacs = 4;

一方M-x align-entireはすべての行を単一のセクションとして整列するので、‘=’はすべての行で同じ列に表示されることになります:

one       = 1;
foobarbaz = 2;

spam      = 3;
emacs     = 4;

コマンドM-x align-regexpalign-rules-listに事前定義されているルールを用いるのではなく、その場で定義したアライメントルールによってカレントリージョンを整列する手段を与えます。M-x align-regexpは正規表現の入力を求めて、その式をそのとき限りのアライメントルール用のregexp属性として使用します。このコマンドはデフォルトでは指定された正規表現の最初の部分式にマッチした空白を調整します。プレフィックス引数とともにM-x align-regexpを呼び出すと、このコマンドは使用する部分式、パディングとして用いる空白の量、更にそれぞれの行において正規表現のすべてのマッチにルールを繰り返し適用するかどうかの入力を求めます。正規表現と正規表現の部分式に関する詳細については正規表現でのバックスラッシュを参照してください。

ユーザーオプションalign-indent-before-aligningが非nilの場合には、M-x alignで整列する前にEmacsがそのリージョンをインデントします。インデントを参照してください。align-indent-before-aligningはデフォルトではnilにセットされています。

ユーザーオプションalign-to-tab-stopは整列される部分をタブストップ(タブストップを参照)から開始する必要があるかどうかを指定します。コンスオプションがnilなら、M-x alignはタブストップを無視して整列に必要となる空白だけを使用します。非nilのシンボルの場合には、M-x alignがそのシンボルの値をチェックして非nilならM-x alignはタブストップに整列します。このオプションはデフォルトではindent-tabs-modeにセットされているので、インデントにタブを用いているバッファーではタブストップを考慮した整列を行います。タブ vs. スペースを参照してください。

ユーザーオプションalign-default-spacingは、M-x alignとその関連コマンドが行を整列する際にそれぞれの行の異なる部分の間のパディングに用いる空白のデフォルト量を指定します。align-to-tab-stopnilならalign-default-spacingの値はパディングに用いるスペースの数、非nilならalign-default-spacingの値はタブストップの数です。各アライメントルールはspacing属性ルールによってalign-default-spacingで指定されたデフォルトをオーバーライドできます。