[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

30. マーカ

マーカ(marker)とは, バッファ内位置をそれを取り巻くテキストを 基準に指定するために使われるLispオブジェクトです. テキストが挿入されたり削除されると, バッファの先頭からマーカまでの距離は自動的に変更され, マーカは同じ前後の文字のあいだに留まります.


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

30.1 マーカの概要

マーカは, バッファとそのバッファ内での位置を指定します. マーカは, 位置を必要とする関数に対して位置を表すものとして使えます. バッファ内の位置について詳しくはSee section バッファ内の位置.

マーカには2つの属性, つまり, マーカ位置とマーカバッファがあります. マーカ位置は, 当該バッファ内の位置としてのマーカに (その時点で)等価な整数です. しかし, マーカの生存期間中, マーカ位置の値はしばしば変化します. バッファにテキストを挿入したり削除すると, マーカは再配置されます. これは, バッファの任意の箇所で挿入したり削除したとしても, 2つの文字のあいだに置かれたマーカが 同じ文字のあいだに留まるようにするためです. 再配置によって, マーカに等価な整数は変わります.

マーカ位置の周りのテキストを削除すると, 削除されたテキストの前後の文字のあいだにマーカは留まります. マーカの位置にテキストを挿入すると, insert-before-markers(see section テキストの挿入)で挿入しない限り, マーカの挿入型(insertion type)(see section マーカの挿入型)に 依存して, マーカは挿入されたテキストのまえかうしろに留まります.

バッファに対する挿入や削除では, すべてのマーカを検査し, 必要ならばマーカを再配置する必要があります. マーカを多数抱えるバッファでは, このために処理が遅くなります. そのため, マーカが不要であると確信したときには, マーカがどこも指さないようにしておくのがよいです. 参照されていないマーカは最終的には(ガベッジコレクションで)回収されますが, それまでは, マーカがどこかを指していると処理時間を浪費します.

マーカ位置にはよく算術演算を施すので, (+-を含む)ほとんどの算術演算は 引数としてマーカを受け付けます. そのような場合, マーカはその現在位置を表します.

マーカを作って位置を設定し, ポイントをマーカへ移動する例を示します.

 
;; どこも指していない新しいマーカを作る
(setq m1 (make-marker))
     ⇒ #<marker in no buffer>
;; マーカm1の位置をカレントバッファの
;; 99番目と100番目の文字のあいだにする
(set-marker m1 100)
     ⇒ #<marker at 100 in markers.texi>
;; バッファの先頭に1文字挿入する
(goto-char (point-min))
     ⇒ 1
(insert "Q")
     ⇒ nil
;; それにしたがってm1が更新される
m1
     ⇒ #<marker at 101 in markers.texi>
;; 同じ位置を指す2つのマーカはeqではないが
;; equalである
(setq m2 (copy-marker m1))
     ⇒ #<marker at 101 in markers.texi>
(eq m1 m2)
     ⇒ nil
(equal m1 m2)
     ⇒ t
;; マーカを使い終ったら, どこも指していないようにする
(set-marker m1 nil)
     ⇒ #<marker in no buffer>

[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

30.2 マーカ向けの述語

オブジェクトがマーカであるかどうかや, オブジェクトが整数かマーカであるかどうかを検査できます. マーカと整数の両者を扱う算術関数に関連して, 後者の検査は有用です.

Function: markerp object

この関数は, objectがマーカであればtを返し, さもなければnilを返す. 多くの関数がマーカや整数を受け付けるが, 整数はマーカではないことに注意すること.

Function: integer-or-marker-p object

この関数は, objectが整数かマーカであるとtを返し, さもなければnilを返す.

Function: number-or-marker-p object

この関数は, objectが数(整数か浮動小数点数)かマーカであると tを返し, さもなければnilを返す.


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

30.3 マーカ作成関数

新たにマーカを作成するときには, そのマーカが, どこも指していない, 現在のポイント位置を指している, バッファの参照可能部分の先頭や末尾を指している, 別のマーカと同じ箇所を指しているのいずれかにできます.

Function: make-marker

この関数は, どこも指していない新たに作成したマーカを返す.

 
(make-marker)
     ⇒ #<marker in no buffer>
Function: point-marker

この関数は, カレントバッファの現在のポイント位置を 指す新たに作成したマーカを返す. see section ポイント. 例については, 下記のcopy-markerを参照.

Function: point-min-marker

この関数は, バッファの参照可能部分の先頭を指す新たに作成したマーカを返す. ナロイングしていなければ, これはバッファの先頭である. see section ナロイング.

Function: point-max-marker

この関数は, バッファの参照可能部分の末尾を指す新たに作成したマーカを返す. ナロイングしていなければ, これはバッファの末尾である. see section ナロイング.

本章のソースファイル(の原文)を入れたバッファでの この関数とpoint-min-markerの例を示す.

 
(point-min-marker)
     ⇒ #<marker at 1 in markers.texi>
(point-max-marker)
     ⇒ #<marker at 15573 in markers.texi>
(narrow-to-region 100 200)
     ⇒ nil
(point-min-marker)
     ⇒ #<marker at 100 in markers.texi>
(point-max-marker)
     ⇒ #<marker at 200 in markers.texi>
Function: copy-marker marker-or-integer &optional insertion-type

引数としてマーカを渡されると, copy-markerは, marker-or-integerが指すのと同じ バッファとバッファ内位置を指す新たなマーカを返す. 引数として整数を渡されると, copy-markerは, カレントバッファで位置marker-or-integerを指す新たなマーカを返す.

新たなマーカの挿入型は引数insertion-typeで指定する. see section マーカの挿入型.

渡された整数引数が1未満であると, copy-markerは, カレントバッファでバッファの先頭を指す新たなマーカを返す. 渡された整数引数がバッファの長さより大きいと, copy-markerは, バッファの末尾を指す新たなマーカを返す.

 
(copy-marker 0)
     ⇒ #<marker at 1 in markers.texi>
(copy-marker 20000)
     ⇒ #<marker at 7572 in markers.texi>

marker-or-integerがマーカでも整数でもないと, エラーを通知する.

2つの異なるマーカが, 同じバッファの同じバッファ内位置であるか, どちらもどこも指していないときには, 両者を(eqではないが)equalとみなします.

 
(setq p (point-marker))
     ⇒ #<marker at 2139 in markers.texi>
(setq q (copy-marker p))
     ⇒ #<marker at 2139 in markers.texi>
(eq p q)
     ⇒ nil
(equal p q)
     ⇒ t

[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

30.4 マーカの情報

本節では, マーカオブジェクトの構成要素を参照する関数について述べます.

Function: marker-position marker

この関数は, markerが指す位置を返す. あるいは, markerがどこも指していなければnilを返す.

Function: marker-buffer marker

この関数は, markerが指すバッファを返す. あるいは, markerがどこも指していなければnilを返す.

 
(setq m (make-marker))
     ⇒ #<marker in no buffer>
(marker-position m)
     ⇒ nil
(marker-buffer m)
     ⇒ nil
(set-marker m 3770 (current-buffer))
     ⇒ #<marker at 3770 in markers.texi>
(marker-buffer m)
     ⇒ #<buffer markers.texi>
(marker-position m)
     ⇒ 3770

[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

30.5 マーカの挿入型

マーカが指す箇所に直接テキストを挿入すると, マーカの再配置方法には2つの可能性, つまり, 挿入したテキストのまえに留まるか, あとにくるかのどちらかです. マーカの挿入型(insertion type)を設定することで, あるマーカではどちらを選ぶか指定できます. insert-before-markersを使うとマーカの挿入型は無視され, マーカは挿入したテキストのうしろにつねに再配置されることに注意してください.

Function: set-marker-insertion-type marker type

この関数は, マーカmarkerの挿入型をtypeとする. typetであると, テキストが挿入されるとmarkerはその位置へ進む. typenilであると, テキストが挿入されてもmarkerはその位置へ進まない.

Function: marker-insertion-type marker

この関数は, markerの現在の挿入型を報告する.


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

30.6 マーカ位置の移動

本節では, 既存のマーカの位置を変更する方法について述べます. これを行うときには, 読者のプログラムの外側で 当該マーカが使われているかどうか, 使われているときには移動による効果はなにかを確実に理解してください. さもないと, Emacsの別の部分で混乱を生じるかもしれません.

Function: set-marker marker position &optional buffer

この関数は, bufferにおいてmarkerpositionへ移動する. bufferを与えないと, デフォルトはカレントバッファである.

positionが1未満であると, set-markermarkerをバッファの先頭へ移動する. positionがバッファのサイズよりも大きいと, set-markermarkerをバッファの末尾へ移動する. positionnilであったりどこも指していないマーカであると, markerはどこも指さないようにする.

戻り値はmarkerである.

 
(setq m (point-marker))
     ⇒ #<marker at 4714 in markers.texi>
(set-marker m 55)
     ⇒ #<marker at 55 in markers.texi>
(setq b (get-buffer "foo"))
     ⇒ #<buffer foo>
(set-marker m 0 b)
     ⇒ #<marker at 1 in foo>
Function: move-marker marker position &optional buffer

これはset-markerの別名である.


[ < ] [ > ]   [ << ] [] [ >> ]         [冒頭] [目次] [見出し] [ ? ]

30.7 マーク

各バッファの1つの特別なマーカをマーク(mark)として区別します. これは, kill-regionindent-rigidlyなどのコマンド向けに ユーザーのために位置を記録するものです. Lispプログラムでは, ユーザーが使う可能性のある値だけをマークに設定し, プログラムの内部向けにはけっしてマークを使いません. たとえば, コマンドreplace-regexpは, 置換を行うまえのポイント値をマークに設定します. 置換を完了したあとに, ユーザーが手軽にまえの位置に戻れるようにするためです.

多くのコマンドは, 対話的に呼ばれるとポイントとマークのあいだの テキストに作用するように設計されています. 読者がそのようなコマンドを書くときには, マークを直接検査しないでください. そのかわりに, ‘r’を指定したinteractiveを使います. こうすると, 対話的に呼ばれるとポイントとマークの値がコマンドの引数に与えられますが, 別のLispプログラムからは引数を明示できます. See section interactiveのコード文字.

各バッファには, 他のバッファのマークの値とは独立な 独自のマークの値があります. バッファが作成されると, マークは存在しますがどこも指さない状態です. これを『バッファのマークは欠如している』状態とみなします.

バッファでいったんマークが『存在』するようになれば, マークが存在しなくなることは普通はありません. しかし, 暫定マーク(transient-mark)モードをオンにすると, マークが不活性になることはあります. すべてのバッファでつねにバッファローカルな変数mark-activeが マークが活性かどうかを表します. その値がnil以外であるとマークは活性です. コマンドでdeactivate-marknil以外の値を設定すると, エディタコマンドループに戻ったときにマークを不活性にするようにできます (ただし, 暫定マーク(transient-mark)モードがオンの場合に限る).

暫定マーク(transient-mark)モードを使う主な目的は, マークが活性であるとこのモードはリージョンを強調表示するからです. See section Emacsの画面表示.

マークに加えて, 各バッファにはマークリング(mark ring), つまり, マークの以前の値を保持したリストがあります. 編集コマンドがマークを変更すると, 通常, 編集コマンドはマークの古い値をマークリングに保存します. 変数mark-ring-maxで, マークリングに収める要素の最大個数を指定します. リストがこの長さに達すると, 新たな要素を加えるたびに古い要素を削除します.

Function: mark &optional force

この関数は, カレントバッファのマーク位置を整数で返す.

マークが不活性であると, 通常, markはエラーを通知する. しかし, forcenil以外であるとmarkはマーク位置を返すが, 当該バッファでマークが設定されたことがなければnilを返す.

Function: mark-marker

この関数は, カレントバッファのマークを返す. これは, Emacs内部のマーク位置を記録したマーカそのものであり, コピーではない. したがって, このマーカの位置を変更すると, マークの位置に直接影響する. この効果を望まない限り, そのようにしないこと.

 
(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にマークを設定し, マークを活性にする. マークの古い値はマークリングに保存しない.

注意: ユーザーにマークが移動したことを示し, かつ, まえのマーク位置を破棄したい場合にのみこの関数を使うこと. 通常, 新たにマークを設定したときには, 古いマークをmark-ringに入れるべきである. この理由から, ほとんどのアプリケーションでは, 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へ入れる. positionnilであると, ポイントの値を使う. push-marknilを返す.

関数push-markは, 通常, マークを活性にしない. 活性にするには引数activatetを指定する.

nomsgnilであると, メッセージ‘Mark set’を表示する.

Function: pop-mark

この関数は, mark-ringから先頭要素を取り出し, そのマークをカレントバッファの実際のマークとする. バッファのポイントは移動しない. また, mark-ringが空であるとなにもしない. マークを不活性にする.

戻り値に意味はない.

User Option: transient-mark-mode

この変数がnil以外であると 暫定マーク(transient-mark)モードがオンであるが, バッファを変更する各基本関数はdeactivate-markに設定する. つまり, バッファを変更するコマンドは, 通常, マークを不活性にする.

User Option: mark-even-if-inactive

これがnil以外であると, LispプログラムやEmacsユーザーは, マークが不活性であってもマークを使える. このオプションは, 暫定マーク(transient-mark)モードのふるまいに影響する. このオプションがnil以外であると, マークが不活性になるとリージョンの強調表示を止めるが, マークを使うコマンドはマークが活性であるものとして動作する.

Variable: deactivate-mark

編集コマンドがこの変数にnil以外を設定すると, エディタコマンドループは(暫定マーク(transient-mark)モードがオンであると) コマンドから戻るとマークを不活性にする. コマンドが終了したらマークを不活性にするために, バッファを変更するすべての基本関数はdeactivate-markに設定する.

Function: deactivate-mark

この関数は, 暫定マーク(transient-mark)モードが オンであるとマークを不活性にする. さもなければなにもしない.

Variable: mark-active

この変数がnil以外であると, マークは活性である. この変数は各バッファにおいてつねにバッファローカルである.

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

これらのノーマルフックは, それぞれ, マークが活性になったとき, 不活性になったときに実行される. マークが活性でありリージョンが変更されたときには, フックactivate-mark-hookはコマンドの終りでも実行される.

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-markは新しいものを追加するときに古いものを削除する.


関数region-beginningregion-endを使う必要がある プログラムはほとんどないはずです. リージョンに作用するように設計されたコマンドは, 普通, ‘r’を指定したinteractiveを使って リージョンの先頭と末尾をみつけます. これにより, Lispプログラムからは引数として境界を明示的に指定できます. (See section interactiveのコード文字. )


[ << ] [ >> ]           [冒頭] [目次] [見出し] [ ? ]

この文書は新堂 安孝によって2009年9月22日texi2html 1.82を用いて生成されました。