Next: , Up: displayプロパティ   [Contents][Index]


41.16.1 テキストを置換するディスプレイ仕様

ある種のディスプレイ仕様は、そのプロパティをもつテキストのかわりに表示する何かを指定します。これらは置換(replacing)ディスプレイ仕様と呼ばれます。Emacsはユーザーにたいして、この方法で置換されたバッファーテキストの中間への対話的なポイント移動を許可しません。

ディスプレイ仕様のリストに1つ以上の置換ディスプレイ仕様が含まれる場合には、最初の置換ディスプレイ仕様が残りをオーバーライドします。置換ディスプレイ仕様は他のほとんどのディスプレイ仕様は置換を許容しないので、それらとは無関係です。

置換ディスプレイ仕様では、そのプロパティをもつテキストとは、displayプロパティとして同一のLispオブジェクトをもつ連続したすべての文字を意味します。これらの文字は単一の単位として置換されます。displayプロパティに異なるLispオブジェクト(eqではないオブジェクト)をもつ2つの文字は個別に処理されます。

以下はこの要点を示すための例です。文字列が置換ディスプレイ仕様としての役割をもち、指定された文字列のプロパティをもつテキストを置換します(その他のディスプレイ仕様を参照)。以下の関数を考えてみてください:

(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’に置換されます。2つの別々のput-text-property呼び出しでそのディスプレイプロパティが割り当てられたという事実は無関係です。同様に次の2文字は2つ目の文字列(concatにより新たに作成された文字列オブジェクト)を取得するので1つの‘A’で置換されて、...となります。したがって10文字は5つのAで表示されます。

注意: :boxスタイルをもつ通常のテキストに隣接して、置換するdisplay文字列に同じフェイス属性:boxを使用すると(フェイスの属性を参照)、カーソルがそのフェイス属性をもったテキスト上を横切って移動した際に表示ノイズがショウジル可能性があることに注意してください。これはdisplay文字列自体に:box属性を適用(または追加)するかわりに、置換されるテキストに直接:box属性を適用して回避できます。たとえば:

;; テキストを横切ってカーソルを移動すると表示ノイズが発生する
(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))))

;; `: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 "]  ")))