EmacsはArabicやFarsi、Hebrewのような、テキストを水平方向の右から左に記述するスクリプトで書かれたテキストの編集をサポートします。しかし数字やそれらのスクリプトに埋め込まれたLatinテキストは、左から右に表示されます。Latin文書の中に少量のArabicやHebrewのテキスト部分が含まれている場合も、稀ではありません(例: プログラムソース内のコメントや文字列)。これらの理由により、これらのスクリプトを使うテキストは、実際には双方向(bidirectional)、つまりそれらはleft-to-right(左から右)の文字とright-to-left(右から左)文字の混交されたものになります。
このセクションでは、双方向テキストを編集するためにEmacsが提供する機能とオプションを説明します。
Emacsはright-to-leftおよび双方向テキストを、いわゆるlogical順(またはreading順)で格納します。バッファーまたは文字列の最初の文字の位置は、次に読む文字の前になります。双方向テキストをvisual順に再配置するには表示時間が発生します。結果として文字の位置は、それらが表示される位置にたいして単調に増加しなくなります。Emacsは表示のための双方向テキストの再配置を、Unicode Standard Annex #9で説明されているUBA(Unicode Bidirectional Algorithm)で実装しています。right-to-leftパラグラフ中に長い英文テキストが出現するような、基本となるパラグラフと継続行が逆方向のときに表示する方法だけが、UBAと異なります。
バッファーローカルな変数bidi-display-reordering
は、表示用にバッファーのテキストを再配置するかどうかを制御します。この変数の値が非nil
の場合、Emacsは右から左の方向に表示される文字を再配置します。デフォルト値はt
です。
双方向テキストの各パラグラフは、それ自身のbase
direction(基本方向)をもっており、それはright-to-leftまたはleft-to-rightです。left-to-rightのパラグラフはスクリーンの左端から開始し、右端に到達すると切り詰め、または継続されます。対照的にright-to-leftのパラグラフのテキストは右端から開始し、左端で継続、または切り詰められて表示されます。デフォルトでは、パラグラフの境界は空行(たとえば行全体が空白文字からなる行)です。これを変更するために、2つの変数bidi-paragraph-start-re
とbidi-paragraph-separate-re
をカスタマイズできます。これらの値には正規表現(文字列)を指定します。たとえば単一の改行を新たなパラグラフの開始とする場合は、両方の変数に\"^\"
をセットします。これら2つの変数はバッファーローカルです(ローカル変数を参照)。
Emacsは、パラグラフを開始するテキストにもとづいて、各パラグラフの基本方向を動的に決定します。しかし、バッファーのパラグラフにたいして特定の基本方向を強制する必要もあるでしょう。変数bidi-paragraph-direction
が非nil
の場合、これは基本方向の動的な決定を無効にして、バッファーのすべてのパラグラフの方向を、このバッファーローカルな値で指定された方向に強制します。値にはright-to-left
とleft-to-right
が指定できます。これ以外の値はnil
と解釈されます。
かわりにパラグラフの先頭に特別な文字を挿入することにより、パラグラフの基本方向を制御できます。特別な文字RIGHT-TO-LEFT
MARK
またはRLMは、以降に続くパラグラフをright-to-left方向に強制します。その効果はLEFT-TO-RIGHT
MARK
またはLRMによりleft-to-right方向に再強制されるまで続きます(C-x 8
RETを使ってこれらの文字を挿入できます)。GUIセッションではLRM文字およびRLM文字は、極端に細いスペースで表示されます。テキスト端末では、それらはスペースで表示されます。
文字は表示用に再配置されるので、logical順で処理を行うEmacsコマンドやバッファーの拡大は、普通とは異なる効果を生みます。たとえばコマンドC-fおよびC-bはポイントをlogical順で移動するので、再配置された双方向テキストではポイントがジャンプすることがあります。同様に隣接する文字位置の範囲をカバーするハイライトされたリージョンは、リージョンが再配置されたテキストにかかる場合には不連続に見える場合があります。これは双方向テキストをサポートする他のプログラムの振る舞いとしては普通であり、似通っています。
LEFTやC-RIGHTのように、矢印キーにバインドされたカーソル移動コマンドは、カレントパラグラフの基本方向にしたがいます。left-to-rightパラグラフでは、修飾キーの有無に関わらず、RIGHTにバインドされるコマンドは、バッファーテキスト内を前方(forward)に移動しますが、right-to-leftパラグラフではかわりに後方(backward)に移動することになります。これは、right-to-leftパラグラフのバッファー位置は、ディスプレイ上を左に移動することにより大部分は増加するという事実を反映しています。
パラグラフ外に移動した際、先行または後続するパラグラフの基本方向が、移動する前のパラグラフの方向と異なる場合は、矢印キーのもつ意味は変化するでしょう。これが発生したときは、新たな基本方向に合わせて矢印キーを押下する必要があります。
デフォルトでは、LEFTおよびRIGHTはlogical方向に移動しますが、visual-order-cursor-movement
が非nil
の場合、これらのコマンドはそれぞれスクリーン位置を左または右に、必要ならスクリーン行の次行または前行へと移動します。これは周辺の双方向コンテキストに依存して、多くのバッファー位置が移動される可能性を秘めることに注意してください。
双方向テキストは表示にたいするテキストの再並べ替えのために、特殊なフォーマット文字を使うことがあります。上述したLRMおよびRLMという2つの文字もそのような文字の一部ですが、他にもそのような文字は存在します。このような文字はデフォルトではGUIフレームなら細いスペースのグリフ(thin
space
glyph)、テキストモードのフレームなら単純にスペースとして表示されます。このような特殊な制御文字がもたらす表示効果に驚かされないように識別可能にしたければ、glyphless-display-mode
をオンに切り替えることができます(テキストが表示される方法を参照)。これはこれらのフォーマット用文字を、内部に制御文字の頭文字をもつ小さなボックスとして表示することで容易に理解できるようにするためのマイナーモードです。