一部の表示仕様では、そのプロパティを持つテキストの代わりに表示する内容を指定します。これらは置換表示仕様と呼ばれます。Emacsでは、このように置換されたバッファテキストの途中に、ユーザーが対話的にポイントを移動させることはできません。
表示仕様のリストに複数の置換用表示仕様が含まれている場合、最初の仕様がそれ以外の仕様に優先します。置換用表示仕様は、他のほとんどの表示仕様を無効にします。なぜなら、それらの仕様は置換対象には適用されないためです。さらに、置換されるテキストの
invisible および composition
プロパティは無視されます。これは、置換されるテキストがスキップされ、そのプロパティが処理されないためです。
表示仕様の置換において、プロパティを持つテキストとは、displayプロパティとして同一のLispオブジェクトを持つ連続するすべての文字を指し、これらの文字は一つの単位として置換されます。2つの文字のdisplayプロパティとして異なるLispオブジェクト(すなわち、eqではないオブジェクト)が指定されている場合は、それぞれ個別に処理されます。
この点を説明する例を以下に示します。文字列は置換表示指定として機能し、指定された文字列で当該プロパティを持つテキストを置換します(その他の表示指定を参照)。次の関数を考えてみましょう。
(defun foo ()
(dotimes (i 5)
(let ((string (concat "A"))
(start (+ i i (point-min))))
(put-text-property start (1+ start) 'display string)
(put-text-property start (+ 2 start) 'display string))))
この関数は、バッファ内の最初の10文字それぞれに、文字列 "A" である
display
プロパティを付与しますが、すべての文字に同じ文字列オブジェクトが割り当てられるわけではありません。最初の2文字には同じ文字列オブジェクトが割り当てられるため、1つの
‘A’ に置き換えられます。display プロパティが put-text-property
への2回の個別の呼び出しで割り当てられたという事実は関係ありません。同様に、次の2文字には2つ目の文字列(concat は新しい文字列オブジェクトを作成します)が割り当てられるため、1つの ‘A’ に置き換えられます。以下同様です。したがって、10文字は5つの A として表示されます。
注意:同一の :box スタイルを持つ通常テキストに隣接する置換用の display 文字列に :box フェイス属性(フェイス属性
を参照)を使用すると、このフェイス属性を持つテキスト上でカーソルを移動させた際に表示上の不具合が生じることがあります。これらは、display 文字列自体に(あるいはそれに加えて)ではなく、置換対象のテキストに直接 :box 属性を適用することで回避できます。以下に例を示します:
;; Causes display artifacts when moving the cursor across text (progn (put-text-property 1 2 'display (propertize " [" 'face '(:box t))) (put-text-property 2 3 'face '(:box t)) (put-text-property 3 4 'display (propertize "] " 'face '(:box t))))
;; No display artifacts due to `:box' (progn (add-text-properties 1 2 '(face (:box t) display " [")) (put-text-property 2 3 'face '(:box t)) (add-text-properties 3 4 '(face (:box t) display "] ")))