Next: , Previous: , Up: マーカー   [Contents][Index]


32.7 マーク

バッファーはそれぞれマーク(mark)というバッファー専用の特別なマーカーをもちます。バッファーが新たに作成される際には、このマーカーはすでに存在していますがどこも指していません。これはそのバッファーにはまだマークが存在しないことを意味します。それ以降のコマンドがマークをセットできます。

マークはkill-regionindent-rigidlyのような多くのコマンドにたいしてテキスト範囲をバインドするための位置を指定します。これらのコマンドは、通常はポイントとマークの間のリージョン(region)と呼ばれるテキストに作用します。リージョンを操作するコマンドを記述する場合にはマークを直接調べず、かわりに‘r’指定とともにinteractiveを使用してください。このようにすればインタラクティブな呼び出しではコマンドの引数としてポイントとマークの値が提供され、かつ他のLispプログラムは引数を明示的に指定できます。interactiveにたいするコード文字を参照してください。

いくつかのコマンドは副作用(side-effect)としてマークをセットします。コマンドはユーザーがそれを使用する可能性がある場合のみマークをセットするべきであって、決してコマンドの内部的な目的にたいして使用してはなりません。たとえばreplace-regexpコマンドは何らかの置換を行う前にマークにポイントの値をセットしますが、その理由はこれによりユーザーが置換を終えた後に簡単にその位置に戻ることが可能になるからです。

一度バッファー内にマークが存在すれば、その存在は通常は決して消えることはありません。しかしTransient Markモードが有効だとマークが非アクティブ(inactive)になることはあります。バッファーローカル変数mark-activeが非nilなら、それはマークがアクティブであることを意味します。コマンドはマークを直接非アクティブにするために関数deactivate-markを呼び出すことができ、変数deactivate-markを非nil値にセットすることにより、エディターコマンドループ(editor command loop)にリターン時にマークの非アクティブ化を要求できます。

Transient Markモードが有効だと、通常ならポイント近傍に適用される特定の編集コマンドはマークがアクティブなときはかわりにリージョンに適用されます。これがTransient Markモードを使用する主な動機です(他にもマークアクティブ時にはリージョンのハイライトが有効になるという理由もある。Emacsのディスプレー表示を参照)。

マークに加えてバッファーはそれぞれマークリング(mark ring)をもっています。これは以前のマーク値を含むマーカーのリストです。編集コマンドがマークを変更する際には、それらのコマンドは通常はマークの旧値をマークリングに保存するべきです。変数mark-ring-maxはマークリング内のエントリー最大数を指定します。リストがこの長さに達すると最後の要素を削除して新たな要素が追加されます。

これとは別にグローバルマークリング(global mark ring)がありますが、それは少数の特定のユーザーレベルコマンドでのみ使用されて、Lispプログラムとは関連しないのでここでは説明しません。

Function: mark &optional force

この関数はカレントバッファーのマーク位置を整数でリターンする。そのバッファー内でそれまでマークがセットされていなければnilをリターンする。

Transient Markモードが有効、かつmark-even-if-inactivenilの場合、マークが非アクティブならmarkはエラーをシグナルする。しかし、forceが非nilなら、markはマークの非アクティブ性を無視して、何にせよマーク位置(かnil)をリターンする。

Function: mark-marker

この関数はカレントバッファーのマークを表すマーカーをリターンする。これはコピーではなく内部的に使用されるマーカー。したがってこのマーカー位置にたいする変更は、そのバッファーのマークに直接影響する。それが望む効果でなければこれを行ってはならない。

(setq m (mark-marker))
     ⇒ #<marker at 3420 in markers-ja.texi>
(set-marker m 100)
     ⇒ #<marker at 100 in markers-ja.texi>
(mark-marker)
     ⇒ #<marker at 100 in markers-ja.texi>

他のマーカー同じように、このマーカーを任意のバッファー位置にセットできる。このマーカーにたいして、これがマークする以外のバッファーを指すようにすると、完全に整合性があるものの、いささか奇妙な結果を得ることになるだろう。わたしたちはこれを行わないことを推奨する!

Function: set-mark position

この関数はマークをpositionにセットして、そのマークをアクティブにする。マークの旧値はマークリングにpushされない

注意: マークが移動したことをユーザーに確認させて、かつ前のマーク位置が失われることを望む場合のみこの関数を使用すること。通常はマークセット時に古いマークをmark-ringにpushすること。この理由により、ほとんどのアプリケーションはset-markではなく、push-markpop-markを使用するべきである。

Emacs Lisp初心者のプログラマーは誤った用途にマークの使用を試みがちである。ユーザーの利便のために位置を保存するのがマークである。編集コマンドはマーク変更がコマンドのユーザーレベル機能の一部でない限りマークを変更しないこと(そのような場合にはその効果をドキュメントするべきである)。Lispプログラムの内部的な使用のために位置を記憶するためには、マークをLisp変数に格納すること。たとえば:

(let ((beg (point)))
  (forward-line 1)
  (delete-region beg (point)))
Function: push-mark &optional position nomsg activate

この関数はカレントバッファーのマークをpositionにセットして、前のマークをmark-ringにpushする。positionnilならポイントの値を使用する。

関数push-markは通常はマークをアクティブにしない。アクティブにする場合には引数activatetを指定する。

nomsgnilならメッセージ‘Mark set’が表示される。

Function: pop-mark

この関数はmark-ringのトップ要素をpopして、そのマークをバッファーの実際のマークにする。これはバッファー内のポイントを移動せず、mark-ringが空なら何も行わない。これはマークを非アクティブ化する。

User Option: transient-mark-mode

この変数が非nilならTransient Markモードを有効にする。Transient Markモードでは、すべてのバッファー変更プリミティブがdeactivate-markをセットする。結果としてバッファーを変更するほとんどのコマンドもマークを非アクティブにする。

Transient Markモードが有効かつマークがアクティブなら、通常はポイント近傍に適用されるコマンドの多くは、かわりにリージョンに適用される。そのようなコマンド、リージョンを処理すべきかどうかをテストするために、関数use-region-pを使用すること。リージョンを参照のこと。

Lispプログラムは一時的にTransient Markモードを有効にするために、transient-mark-modenilでもtでもない値にセットできる。値がlambdaなら、通常ならマークを非アクティブ化するバッファー変更ような操作の後に、Transient Markモードを自動的にオフに切り替える。値が(only . oldval)なら後続のコマンドがポイントを移動かつシフト変換(shift-translationを参照)されていない場合、あるいは通常はマークを非アクティブにするその他の操作の場合に、transient-mark-modeに値oldvalをセットする(マウスでリージョンをマークした際には、、この方法によって一時的にtransient-mark-modeがオンになる)。

User Option: mark-even-if-inactive

これが非nilなLispプログラムおよびEmacsユーザーは、たとえ非アクティブでもマークを使用できる。このオプションはTransient Markモードの動作に影響を及ぼす。このオプションが非nilならマークの非アクティブ化によりリージョンのハイライトはオフに切り替えられるが、マークを使用するコマンドは、あたかもマークがアクティブであるかのように振る舞う。

Variable: deactivate-mark

エディターコマンドがこの変数を非nilにセットすると、エディターコマンドループはコマンドのリターン後に、(Transient Markモードが有効なら)マークを非アクティブにする。バッファーを変更するすべてのプリミティブは、コマンド終了時にマークを非アクティブにするためにdeactivate-markをセットする。この変数はセットすらことによりバッファーローカルになる。

コマンド終了時にマークを非アクティブにすることなくバッファーを変更するLispコードを記述するためには、変更を行うコードの周辺でdeactivate-marknilにバインドすること。たとえば:

(let (deactivate-mark)
  (insert " "))
Function: deactivate-mark &optional force

Transient Markモードが有効、またはforceが非nilなら、この関数はマークを非アクティブにしてノーマルフックdeactivate-mark-hookを実行して、それ以外は何も行わない。

Variable: mark-active

この変数が非nilならマークはアクティブ。この変数はそれぞれのバッファーにたいして常にローカル。通常はポイント近傍を操作するコマンドが、かわりにリージョンを操作すべきかどうかを判断するためにこの変数の値を使用してはならない。その目的にたいしては関数use-region-pを使用すること(リージョンを参照)。

Variable: activate-mark-hook
Variable: deactivate-mark-hook

これらのノーマルフックはマークがアクティブや非アクティブになった際に順次実行される。たとえばアクティブなマークがあるバッファーに切り替えて戻るコマンドの使用後のようにリージョンが再アクティブ化された際には、フックactivate-mark-hookも実行される。

Function: handle-shift-selection

この関数はポイント移動コマンドのシフト選択(shift-selection)の動作を実装する。Shift Selection in The GNU Emacs Manualを参照のこと。これはinteractive指定に文字‘^’を含むコマンドの呼び出し時は常に、そのコマンド自身を実行する前にEmacsコマンドループにより自動的に呼び出される(^を参照)。

shift-select-modeが非nil、かつカレントコマンドがシフト変換(shift-translationを参照)を通じて呼び出された場合には、この関数はマークをセットして一時的にリージョンをアクティブにする(すでにこの方法によりリージョンが一時的にアクティブにされている場合を除く)。それ以外ではリージョンが一時的にアクティブにされていればマークを非アクティブにして、変数transient-mark-modeに前の値をリストアする。

Variable: mark-ring

このバッファーローカル変数の値は、もっとも最近のものが先頭となるような、以前に保存されたカレントバッファーのマークのリスト。

mark-ring
⇒ (#<marker at 11050 in markers-ja.texi>
    #<marker at 10832 in markers-ja.texi>
    …)
User Option: mark-ring-max

この変数の値はmark-ringの最大サイズ。これより多くのマークがmark-ringにpushされると、push-mark新たなマーク追加時には古いマークを破棄する。

Delete Selectionモード(Delete Selection in The GNU Emacs Manualを参照)が有効な際には、アクティブリージョン(いわゆる“選択”)を操作するコマンドは若干異なる振る舞いをします。これはpre-command-hookに関数delete-selection-pre-hookを追加することにより機能します(コマンドループの概要を参照)。この関数はそのコマンドにたいして適切なように選択を削除するためにdelete-selection-helperを呼び出します。コマンドをDelete Selectionモードに適応させたければ、その関数シンボルのdelete-selectionプロパティにputしてください(シンボルのプロパティへのアクセスを参照)。シンボルにこのプロパティをもたないコマンドは選択を削除しません。そのコマンドに期待される挙動を調整するために、このプロパティはいくつかの値のいずれかをもつことができます。詳細はdelete-selection-pre-hookdelete-selection-helperのドキュメント文字列を参照してください。


Next: リージョン, Previous: マーカー位置の移動, Up: マーカー   [Contents][Index]