各バッファには特別なマーカーがあり、これをマークと呼びます。バッファが新規に作成されると、このマーカーは存在しますが、どこにも指していません。つまり、そのバッファにはまだマークが存在しないということです。後続のコマンドでマークを設定できます。
マークは、kill-region や indent-rigidly
など、多くのコマンドにおいてテキスト範囲を限定するための位置を指定します。これらのコマンドは通常、ポイントとマークの間にあるテキスト(リージョンと呼ばれます)に対して作用します。リージョンを操作するコマンドを記述する場合は、マークを直接参照せず、代わりに
r 指定を伴う interactive
を使用してください。これにより、対話的な呼び出し時にはポイントとマークの値がコマンドの引数として渡されますが、他の Lisp
プログラムでは引数を明示的に指定することが可能になります。interactive
のコード文字を参照してください。
一部のコマンドは、副作用としてマークを設定します。コマンドがこれを行うのは、ユーザーにとって有用な可能性がある場合に限り、決して内部的な目的で行ってはなりません。例えば、replace-regexp コマンドは、置換処理を行う前にマークを point
の値に設定します。これにより、置換完了後にユーザーが便利に元の位置に戻れるようになります。
マークがバッファに存在すると、通常は消滅することはありません。ただし、Transient Markモードが有効な場合は、非アクティブ状態になることがあります。バッファローカル変数 mark-active が nil
以外であれば、マークがアクティブであることを意味します。コマンドは、関数 deactivate-mark
を呼び出してマークを直接非アクティブ化するか、あるいはエディタのコマンドループに戻る際に変数 deactivate-mark に nil
以外の値を設定することで、マークの非アクティブ化を要求できます。
一時マークモードが有効な場合、通常はポイント付近のテキストに適用される特定の編集コマンドが、マークが有効な状態では代わりにその領域に適用されます。これが一時マークモードを使用する主な理由です。(もう一つの理由は、マークが有効な状態でその領域をハイライトできるようになることです。Emacs Displayを参照してください。)
マークに加えて、各バッファにはマークリングがあり、これはマークの以前の値を含むマーカーのリストです。編集コマンドによってマークが変更される際、通常はマークの旧値がマークリングに保存されます。変数mark-ring-maxはマークリングの最大エントリ数を指定しており、リストがこの長さに達すると、新しい要素を追加すると最後の要素が削除されます。
別途、グローバルマークリングも存在しますが、これはごく一部の特定のユーザーレベルコマンドでのみ使用されており、Lispプログラミングには関係ありません。したがって、ここでは説明しません。
この関数は、現在のバッファのマーク位置を整数として返します。このバッファで一度もマークが設定されていない場合は、nil を返します。
Transient Markモードが有効で、mark-even-if-inactiveがnilである場合、マークが非アクティブであればmarkがエラーを通知します。ただし、forceがnil以外であれば、markはマークの非アクティブ状態を無視し、いずれにせよマーク位置(またはnil)を返します。
この関数は、現在のバッファのマークを表すマーカーを返します。これはコピーではなく、内部的に使用されるマーカーです。したがって、このマーカーの位置を変更すると、バッファのマークに直接影響します。意図した動作でない限り、このような操作は行わないでください。
(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>
他のマーカーと同様に、このマーカーも任意のバッファを指すように設定できます。もし、自身がマークとなっているバッファ以外のバッファを指させた場合、完全に一貫してはいるものの、かなり奇妙な結果になります。このような操作は行わないことをお勧めします!
この関数はマークを position に設定し、マークを有効にします。マークの旧値はマークリングにプッシュされません。
ご注意:
この関数は、マークが移動したことをユーザーに認識させたい場合、かつ以前のマーク位置を破棄したい場合にのみ使用してください。通常、新しいマークを設定する際は、古いマークは
mark-ring に配置されるべきです。そのため、ほとんどのアプリケーションでは set-mark ではなく、push-mark および
pop-mark を使用する必要があります。
Emacs Lispプログラミングの初心者は、マークを誤った目的で使おうとすることがよくあります。マークはユーザーの利便性のために位置を保存するものです。編集コマンドは、マークの変更がそのコマンドのユーザーレベルの機能の一部である場合を除き、マークを変更すべきではありません。(また、その場合は、この影響についてドキュメントに記載すべきです。)Lispプログラム内部で使用するために位置を記憶しておくには、Lisp変数に格納してください。例えば:
(let ((beg (point))) (forward-line 1) (delete-region beg (point))).
この関数は、現在のバッファのマークを position に設定し、直前のマークのコピーを mark-ring にプッシュします。position が
nil である場合は、point の値が使用されます。
関数 push-mark は通常、マークを有効にしません。有効にするには、引数 activate に t を指定してください。
nomsg が nil でない限り、「Mark set」というメッセージが表示されます。
この関数は mark-ring
の最上部要素をポップし、そのマークをバッファの実際のマークにします。バッファ内のポイントは移動せず、mark-ring が空の場合は何も行われません。また、マークを無効にします。
この変数がnil以外の場合、トランジェントマークモードが有効になります。トランジェントマークモードでは、バッファを変更するすべてのプリミティブがdeactivate-markをセットします。その結果、バッファを変更するほとんどのコマンドは、マークも解除します。
トランジェントマークモードが有効でマークがアクティブな場合、通常はポイント付近のテキストに適用される多くのコマンドが、代わりにリージョンに適用されます。このようなコマンドでは、リージョンに対して操作を行うべきかどうかを判定するために、関数
use-region-p を使用する必要があります。リージョンを参照してください。
Lispプログラムでは、transient-mark-modeにnilおよびt以外の値を設定することで、一時的に一時マークモードを有効にできます。値がlambdaの場合、バッファの変更など、通常であればマークを解除する操作が行われると、一時マークモードは自動的に解除されます。値が(only . oldval)の場合、ポイントを移動させる後続のコマンドのうちシフト変換(shift-translationを参照)されていないもの、あるいは通常であればマークを解除するその他の操作が行われた後、transient-mark-modeに値oldvalが設定されます。(マウスで領域をマークすると、このようにして一時的にtransient-mark-modeが有効になります。)
これが non-nil の場合、Lisp プログラムや Emacs
ユーザーは、マークが非アクティブな状態でもマークを利用できます。このオプションは Transient Mark
モードの動作に影響します。このオプションが non-nil
の場合、マークを非アクティブにするとリージョンのハイライトは解除されますが、マークを使用するコマンドは、あたかもマークが引き続きアクティブであるかのように動作します。
エディタコマンドがこの変数を non-nil
に設定した場合、エディタコマンドループはコマンドの復帰後にマークを無効化します(Transient Mark
モードが有効な場合)。バッファを変更するすべてのプリミティブは、コマンド終了時にマークを無効化するため、deactivate-mark を設定します。この変数を設定すると、バッファローカルになります。
コマンドの末尾でマークの解除を引き起こすことなくバッファを変更するLispコードを記述するには、変更処理を行うコードの前後で deactivate-mark を nil
にバインドします。例えば:
(let (deactivate-mark) (insert " "))
Transient Markモードが有効であるか、またはforceがnilでない場合、この関数はマークを解除し、通常のフックdeactivate-mark-hookを実行します。それ以外の場合は、何も行いません。
この変数が nil
以外の場合、マークは有効になります。この変数は、各バッファにおいて常にバッファローカルです。通常はポイント付近のテキストに対して動作するコマンドを、代わりにリージョンに対して動作させるかどうかの判断に、この変数の値を使用しないでください。その場合は関数 use-region-p
を使用してください(リージョンを参照)。
これらの通常フックは、マークが有効になったとき、および無効になったときにそれぞれ実行されます。また、例えばアクティブなマークを持つバッファに戻るコマンドを使用した後など、リージョンが再有効化されたときにもフック
activate-mark-hook が実行されます。
この関数は、ポイント移動コマンドのシフト選択動作を実装しています。The GNU Emacs
ManualのShift
Selectionを参照してください。interactive 仕様に
‘^’
文字を含むコマンドが呼び出されるたびに、コマンド自体が実行される前に、Emacsのコマンドループによって自動的に呼び出されます(^を参照)。
shift-select-mode が nil
ではなく、かつ現在のコマンドがシフト変換(shift-translation
を参照)によって呼び出された場合、この関数はマークを設定し、リージョンを一時的に有効にします。ただし、すでにこの方法でリージョンが一時的に有効になっている場合はこの限りではありません。それ以外の場合で、リージョンが一時的に有効になっているときは、マークを無効にし、変数
transient-mark-mode を以前の値に戻します。
このバッファローカル変数の値は、現在のバッファにおける保存済みの旧マークのリストであり、直近のものから順に格納されています。
mark-ring
⇒ (#<marker at 11050 in markers.texi>
#<marker at 10832 in markers.texi>
...)
この変数の値は、mark-ringの最大サイズです。mark-ringにこれより多い数のマークがプッシュされた場合、push-markは新しいマークを追加する際に古いマークを破棄します。
「選択範囲の削除」モード(The GNU Emacs ManualのDelete
Selectionを参照)が有効な場合、アクティブなリージョン(いわゆる「選択範囲」)を操作するコマンドの動作がわずかに異なります。これは、pre-command-hookに関数delete-selection-pre-hookを追加することで実現されます(コマンドループの概要を参照)。この関数は、コマンドに応じて選択範囲を削除するためにdelete-selection-helperを呼び出します。コマンドを「選択範囲の削除」モードに適応させたい場合は、その関数のシンボルにdelete-selectionプロパティを付与してください(シンボルプロパティへのアクセスを参照)。シンボルにこのプロパティが設定されていないコマンドは、選択範囲を削除しません。このプロパティには、コマンドが意図する動作に合わせて調整するための複数の値のいずれかを指定できます。詳細はdelete-selection-pre-hookおよびdelete-selection-helperのドキュメント文字列を参照してください。