Next: , Previous: , Up: Markers   [Contents][Index]


30.7 The Mark

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

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

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

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

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

マークに加えて、バッファーはそれぞれマークリング(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.texi>
(set-marker m 100)
     ⇒ #<marker at 100 in markers.texi>
(mark-marker)
     ⇒ #<marker at 100 in markers.texi>

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

Function: set-mark position

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

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

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

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を使用すること(The Regionを参照)。

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.texi>
    #<marker at 10832 in markers.texi>
    …)
User Option: mark-ring-max

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