Previous: , Up: 適切なウィンドウへのバッファーの表示   [Contents][Index]


29.13.6 バッファー表示の思想

フレームのもっとも単純な形式では常にバッファー表示に使用可能な単一のウィンドウが収容されています。結果としてdisplay-bufferのもっとも最近の呼び出しは、常にそのウィンドウへのバッファーの配置に成功した呼び出しとなります。

そのようなフレームを処理することは実際的ではないので、デフォルトではEmacsはフレームサイズのデフォルト値、split-height-thresholdsplit-width-thresholdのオプションにより制御される、より複雑なレイアウトを許容しています。そのフレームでまだ表示されていないバッファーを表示すると、フレーム上の単一ウィンドウを分割するか、2つのウィンドウのいずれかを(再)利用します。

これらのしきい値のいずれかをカスタマイズしたり手動でフレームのレイアウトを変更するとデフォルトの動作は棄却されます。非nilaction引数でdisplay-bufferを呼び出したろ、前のサブセクションに示したオプションのいずれかをユーザーがカスタマイズした際にもデフォルト動作は棄却されます。display-bufferを習得次第、表示可能なディスプレイアクションとフレイムレイアウト結果の膨大さにフラストレーションを覚えるかもしれません。

しかしバッファー表示関の使用を控えてウィンドウのウィンドウの分割と削除のメタファーに逆行するのは良い考えではありません。Lispプログラムやユーザーにたいしてバッファー表示関数は、異なるニーズを調整するフレームワークを提供します。ウィンドウの分割と削除にたいする同等なフレームワークは存在しません。バッファー表示関数ではフレームからバッファーを削除する際に、少なくともフレームレイアウトを部分的に後からリストアすることが可能です(ウィンドウのquitを参照)。

上述したフラストレーションを埋め合わせるとともに、文字通りフレームのウィンドウ間でバッファーが失われることを避けるためるために、以下にいくつのガイダンスを示します。

Write display actions without stress

ディスプレイアクションの記述はアクション関数とアクションalistを1つの巨大なリストにまとめる必要があるので多きな苦痛をともなうかもしれません(歴史的な理由によってdisplay-bufferの引数として個別にサポートすることができなかった)。以下のリストのような基本形式を覚えておくと便利かもしれません:

'(nil (inhibit-same-window . t))

アクション関数なしのアクションalistエントリーだけを指定する。これの唯一の目的は、どこかで指定されたdisplay-buffer-same-window関数が同一ウィンドウ内でのバッファー表示を抑制すること。前のサブセクションの最後の例も参照のこと。

'(display-buffer-below-selected)

一方こちらは1つのアクション関数と空のアクションalistを指定する。上記2つの指定の効果を1つ組み合わせるためには以下のようなフォームを記述

'(display-buffer-below-selected (inhibit-same-window . t))

別のアクション関数の追加は以下のように記述

'((display-buffer-below-selected display-buffer-at-bottom)
  (inhibit-same-window . t))

別のアクションalistを追加するには以下のように記述

'((display-buffer-below-selected display-buffer-at-bottom)
  (inhibit-same-window . t)
  (window-height . fit-window-to-buffer))

最後のフォームは以下の方法によりdisplay-bufferaction関数に使用できる:

(display-buffer
 (get-buffer-create "*foo*")
 '((display-buffer-below-selected display-buffer-at-bottom)
   (inhibit-same-window . t)
   (window-height . fit-window-to-buffer)))

display-buffer-alistのアスタマイズでは以下のように使用できる:

(customize-set-variable
 'display-buffer-alist
 '(("\\*foo\\*"
    (display-buffer-below-selected display-buffer-at-bottom)
    (inhibit-same-window . t)
    (window-height . fit-window-to-buffer))))

2つ目のバッファーへのカスタマイズを追加するには以下のように記述:

(customize-set-variable
 'display-buffer-alist
 '(("\\*foo\\*"
    (display-buffer-below-selected display-buffer-at-bottom)
    (inhibit-same-window . t)
    (window-height . fit-window-to-buffer))
   ("\\*bar\\*"
    (display-buffer-reuse-window display-buffer-pop-up-frame)
    (reusable-frames . visible))))
互いを尊重して扱う

display-buffer-alistdisplay-buffer-base-actionはユーザーオプションであって、Lispプログラムはそれらのセットやリバインドを行ってはならない。一方でdisplay-buffer-overriding-actionはアプリケーション用に予約されていて滅多に使用されず、使用する場合には細心の注意を払うこと。

display-bufferの旧実装では、pop-up-framespop-up-windowsのようなユーザーオプションのセッティングをめぐってユーザーとアプリケーションの競合が頻生した(バッファー表示の追加オプションを参照)。これがdisplay-bufferを再デザイン(ユーザーおよびアプリケーションにたいして何を行うことが許容されているかを指定する明快なフレームワークを提供する)した主な理由である。

Lispプログラムは表示しようとしているバッファーにたいして予期せず方法ユーザーのカスタマイゼーションが影響を与えることに備えなければならない。display-bufferの後続の振る舞いにおいてaction引数で要求した方法でバッファーが正確に表示されていると仮定しないこと。

ユーザーは任意のバッファーが表示される方法ひついて厳しすぎる制限を過度に多く設けるべきではない。さもないと特定の目的でバッファーを表示する際の特性を失うリスクがある。横並びの2つのウィンドウでバッファーの異なるバージョンを比較するLispプログラムを記述するとしよう。display-buffer-alistのカスタマイズによりそのようなすべてのバッファーは常に選択されたウィンドウの下に表示されるように定められていたら、display-bufferを通じて望ましいウィンドウ構成を構成するのはプログラムにとって困難だろう。

任意のバッファーを表示するための設定を指定するためには、ユーザーはdisplay-buffer-base-actionをカスタマイズする必要がある。複数のフレームで作業を行うことを好むユーザーについての例は前のサブセクションを参照のこと。display-buffer-alistは特定のバッファーを特定の方法で表示するために予約済みである。

すでにバッファーを表示しているウィンドウの再利用の考慮

一般的にユーザーとLispプログラムにとって、ウィンドウがすでに対象となるバッファーを表示していて、それを再利用するのは常に良いアイデアである。前のサブセクションではバッファーを表示しているフレームがすでに存在していても、正しく行うことに失敗するとdisplay-bufferが継続的に新たなフレームをポップアップすることを示した。たとえばバッファーの異なる部分をそのウィンドウで表示する必要がある際のように、少数のケースにおいてはウィンドウの再利用は望ましくないかもしれない。

したがってdisplay-buffer-reuse-windowaction引数とカスタマイゼーションの両方で可能なかぎり使用するべきアクション関数の1つである。action引数のinhibit-same-windowエントリーは、通常はバッファーをを表示中のウィンドウ、つまり対象となるウィンドウが選択されたウィンドウならそのウィンドウの再利用を避けるような、一般的なケースのほとんどを考慮する。

選択したウィンドウにフォーカスを当てる

これは複数フレームで作業を行う人にとっては思考を要しない。バッファーを表示中のフレームは自動的にraiseされてinhibit-switch-frameが禁じていなければフォーカスを取得する。単一フレームのユーザーにとっては、このタスクは顕著に困難になり得る。この点において特にdisplay-buffer-pop-up-windowdisplay-buffer-use-some-windowが厄介になる可能性がある。これらは表面上は任意に見えるウィンドウ(最大のウィンドウか最近もっとも使用されていないウィンドウ)を分割または使用してユーザーの注意を逸らす。

したがってLispプログラムのいくつかは、たとえば新たなウィンドウに関して問いに答える場所として期待されるミニバッファーウィンドウの近傍にバッファーを表示するためにフレーム最下のウィンドウの選択を試みる。選択されたウィンドウは通常はすでにユーーザーの注意を喚起済みなので、入力とは無関係なアクションdisplay-buffer-below-selectedが好ましいかもしれない。

display-bufferに後続する呼び出しの処理

display-bufferは複数のバッファーを順番に表示するのに最適ではないので、結果となるウィンドウ構成でこれらのバッファーのすべてが順に表示されているか確認すること。繰り返しになるが標準のアクション関数display-buffer-pop-up-windowdisplay-buffer-use-some-windowは、より複雑な構成における幾分混沌とした性質のために、この用途に最適とは言えない。

同一の表示サイクル1つで複数バッファーを表示するウィンドウ構成を生成するためには、Lispプログラマーは自身でアクション関数を記述する必要を避けることはできないだろう。この問題において以下にリストしたいくつかのトリックが助けになるかもしれない。

  • 新たなウィンドウのポップアップ時に既存のウィンドウ構成の破壊を回避するためにウィンドウをアトミックにする(アトミックウィンドウを参照)。そうすれば新たなウィンドウは構成の外部にポップアップされる。
  • 別のバッファーを表示中のウィンドウの使用を回避するために、一時的にウィンドウをバッファー専用にする(専用のウィンドウを参照)。そうすれば非専用のウィンドウが使用される。
  • window-preserve-sizeを呼び出すことにより新たなウィンドウのポップアップ時に引数のウィンドウのサイズの維持が試みられる(ウィンドウサイズの保持を参照)。ただし同一構成内の別ウィンドウのサイズが縮小されるかもしれないことに留意する必要がある。
  • 特定のバッファーをフレーム上の同一位置のウィンドウに常に表示するにはサイドウィンドウを使用できる(サイドウィンドウを参照)。これによりフレーム上で同時に表示する際に競合しないバッファーをグループ化して、他のバッファーの表示を妨害せずに同一ウィンドウでグループ化したバッファーを表示することが可能になる。
  • フレームのウィンドウ構成の破壊やdisplay-buffer-pop-up-frameにより課せられる完全なフレームに付加されるオーバーヘッドなしで、選択されたフレームのスクリーン領域内にバッファー表示するために子フレームを使用できる(子フレームを参照)。