Go to the first, previous, next, last section, table of contents.


マークとリージョン

Emacsの数多くのコマンドは、カレントバッファの任意の連続領域を操作します。 このようなコマンドに操作対象となるテキストを指定するには、 その一方の端にマーク(mark)を置き、 もう一方の端にポイントを移動します。 ポイントとマークに挟まれたテキストをリージョン(region)と呼びます。 暫定マーク(transient-mark)モードをオンにすると、 リージョンが存在すれば Emacsはつねにそのリージョンを強調表示します (see section 暫定マークモード(transient-markモード))。

リージョンの境界を調整するには、ポイントやマークを移動します。 時間的にどちらを先に設定したとか、 テキスト内でどちらが先にあるかとかは関係ありません。 いったんマークを設定すると、他の箇所に再設定するまで、 その位置情報はそのまま変わりません。 各Emacsバッファには個別にマークがありますから、 以前に選択したバッファへ戻ったときには、 以前と同じままのマークが残っています。

C-yyank)やM-x insert-bufferなどのテキストを 挿入するコマンドの多くは、挿入したテキストの両端にポイントとマークを置いて、 挿入したテキストがリージョンに含まれるようにします。

リージョンの境界を定めること以外に、 あとで戻る可能性のある箇所を覚えておくためにもマークを使えます。 この機能をより使いやすくするために、 各バッファでは、それまでに設定した16個のマーク位置を マークリング(mark ring)に記録しています。

マークを設定する

マークを設定するコマンドはつぎのとおりです。

C-SPC
ポイント位置にマークを置く(set-mark-command)。
C-@
上と同様。
C-x C-x
マークとポイントを入れ換える(exchange-point-and-mark)。
Drag-Mouse-1
ドラッグしたテキストの周囲にポイントとマークを設定する。
Mouse-3
ポイント位置にマークを設定し、クリックした箇所にポイントを移動する (mouse-save-then-kill)。

たとえば、コマンドC-x C-uupcase-region)を使って、 バッファのある部分をすべて大文字に変換したいとしましょう。 このコマンドは、リージョン中のテキストに作用します。 まず、大文字に変換したいテキストの先頭に移動し、 C-SPCと打ってマークを設定します。 続いてテキストの終端に移動してC-x C-uと打ちます。 あるいは、先にテキストの終端にマークを設定して、 テキストの始点に移動してからC-x C-uと打ちます。

マークを設定するもっとも一般的な方法は、 C-SPCコマンド(set-mark-command)を使うことです。 このコマンドは、ポイント位置にマークを設定します。 そうすれば、マークを置いたままで、ポイントを移動できます。

マウスを使ったマークの設定方法は2つあります。 テキストのある範囲でマウスボタン1をドラッグします。 マウスボタンを離した位置にポイントが置かれ、 ドラッグを開始した箇所にマークが設定されます。 あるいは、マウスボタン3をクリックします。 これは(C-SPCと同様に)ポイント位置にマークを設定してから、 ポイントを(Mouse-1のように)移動します。 両者は、マークを設定するだけでなく、リージョンをキルリングにコピーします。 これは、他のウィンドウアプリケーションの動作と一貫性を持たせるためです。 キルリングを変更したくなければ、 キーボードコマンドを使ってマークを設定する必要があります。 See section 編集用マウスコマンド

普通の端末にはカーソルは1つしかありませんから、 Emacsにはマークを置いた位置を表示する術はありません。 ユーザーがその位置を覚えておく必要があります。 この問題に対する通常の解決方法は、マークを設定したら、 忘れてしまうまえにただちにそれを利用することです。 あるいは、C-x C-xexchange-point-and-mark)コマンドを使って、 マーク位置を確認します。 このコマンドは、ポイント位置にマークを置き、 マークのあった位置にポイントを置きます。 リージョンの範囲は変わらずに、 カーソルとポイントは以前マークのあった箇所に移動します。 暫定マーク(transient-mark)モードでは、 このコマンドはマークを再度活性にします。

ポイント位置を変えずに、 リージョンのもう一方の端(マークの位置)を移動させたい場合にも、 C-x C-xは便利な方法です。 まず、C-x C-xでポイントをリージョンの一方の端に移して、 その端を移動します。 必要ならば、もう1度C-x C-xを使って新しい位置にマークを置き、 ポイントをもとの位置に戻します。

ASCIIには、C-SPCという文字は存在しません。 CTRLを押し下げながらSPCを打つと、 ほとんどの普通の端末では文字C-@になります。 このキーは、実際にset-mark-commandにバインドしてあります。 ただし、幸運にもC-SPCC-@を送出する端末を 使っているのであれば、 C-@C-SPCとみなしてかまいません。 Xウィンドウシステムでは、C-SPCは実際には 別の文字として認識されますが、 そのバインドはやはりset-mark-commandです。

暫定マークモード(transient-markモード)

Xウィンドウシステムを使っているのであれば、 Emacsはカレントリージョンを強調表示できます。 ただし、通常はリージョンを強調表示しません。 なぜでしょうか?

実は、もともとのEmacsではリージョンの強調表示をうまくできないのです。 いったんマークを設定してしまうと、 そのバッファ内にはつねにリージョンが存在することになるからです。 リージョンを強調表示し続けても迷惑なだけでしょう。

暫定マーク(transient-mark)モードをオンにすると、 リージョンの強調表示機能をオンにできます。 暫定マーク(transient-mark)モードは、 リージョンが一時的にしか『存続』しない、 通常よりきびしい操作モードです。 ユーザーは、リージョンを使うコマンドごとにリージョンを設定する必要があります。 暫定マーク(transient-mark)モードでは、 ほとんどの期間、リージョンは存在しません。 それゆえ、リージョンが存在するときにリージョンを強調表示しても 邪魔になりません。

暫定マーク(transient-mark)モードをオンにするには、 M-x transient-mark-modeと打ちます。 このコマンドはモードのオン/オフを切り替えますから、 モードをオフにしたいときにはコマンドをもう1度繰り返します。

暫定マーク(transient-mark)モードの詳細を以下に示します。

リージョンの強調表示には、regionフェイスを使います。 このフェイスを変更すれば、リージョンの強調表示方法をカスタマイズできます。

複数のウィンドウで同じバッファを表示しているときには、 それぞれのウィンドウで別の部分を表示できます。 というのは、(マーク位置は共有されるが) 各ウィンドウごとに別々にポイントの値があるからです。 通常、選択されたウィンドウでのみ、 リージョンを強調表示します(see section 複数のウィンドウ)。 しかし、変数highlight-nonselected-windowsnil以外を設定すると、 (暫定マーク(transient-mark)モードがオンであり、かつ、 ウィンドウのバッファのマークが活性である場合に限り) 各ウィンドウでそれぞれのリージョンを強調表示します。

暫定マーク(transient-mark)モードがオフであると、 マークを設定するすべてのコマンドはマークを活性にし、 マークを不活性にするものは何もありません。

暫定マーク(transient-mark)モードにおいて、 変数mark-even-if-inactivenil以外であると、 マークが不活性であってもコマンドはマークやリージョンを利用できます。 通常の暫定マーク(transient-mark)モードと同様に、 リージョンが強調表示されたりされなかったりしますが、 強調表示されていなくてもマークが本当になくなることはありません。

暫定マーク(transient-mark)モードは『zmacsモード』としても知られています。 というのも、MITのLispマシン上で動作していたZmacsエディタが 同じようにマークを扱っていたからです。

リージョンに対する操作

いったんリージョンを設定しマークを活性にすれば、 以下のようにリージョンを操作できます。

リージョン内のテキストを操作するコマンドの多くは、 その名前にregionという単語を含みます。

テキストオブジェクトをマークするコマンド

単語、リスト、段落、ページといったテキストのまとまりに ポイントやマークを置くコマンドがあります。

M-@
つぎの語の末尾にマークを設定する(mark-word)。 このコマンドとつぎのコマンドはポイントを移動しない。
C-M-@
つぎのLisp式の末尾にマークを設定する(mark-sexp)。
M-h
現在の段落を囲むリージョンを設定する(mark-paragraph)。
C-M-h
現在のLisp関数定義(defun)を囲むリージョンを設定する(mark-defun)。
C-x h
バッファ全体をリージョンとする(mark-whole-buffer)。
C-x C-p
現在のページを囲むリージョンを設定する(mark-page)。

M-@mark-word)がつぎの語の末尾にマークを設定するのに対し、 C-M-@mark-sexp)はつぎのLisp式の末尾にマークを設定します。 これらのコマンドは、M-fC-M-fと同様に引数を扱います。

その他のコマンドは、ポイントとマークの両方を設定して、 バッファ内で対象物を区切ります。 たとえば、M-hmark-paragraph)は、 ポイントを囲むあるいはポイントに続く段落の先頭にポイントを移動し、 その段落の末尾にマークを置きます(see section 段落)。 このようにリージョンを設定するので、 段落全体を字下げしたり、大文字小文字を変換したり、キルしたりできます。

C-M-hmark-defun)も同様に、 現在の関数定義や後続の関数定義の先頭にポイントを置き、 その末尾にマークを置きます(see section 関数定義(defun))。 C-x C-pmark-page)は、 現在のページの先頭にポイントを置き、 その末尾にマークを置きます(mark-page)。 マークはページ区切りの直後に設定され(リージョンに含まれる)、 一方、ポイントはページ区切りの直後に置かれます(リージョンに含まれない)。 数引数で、現在のページのかわりに(正ならば)後続のページや、 (負ならば)先行するページを指定できます。

最後に紹介するC-x hmark-whole-buffer)は、 バッファ全体にリージョンを設定します。 つまり、ポイントをバッファの先頭に置き、 マークをバッファの末尾に置きます。

暫定マーク(transient-mark)モードでは、 これらのコマンドはすべて、マークを活性にします。

マークリング

マークには、リージョンを区切る以外にも、 あとで戻る可能性のある箇所を記録するという便利な使い方があります。 この機能をより便利にするために、 各バッファでは以前の16箇所のマーク位置を マークリング(mark ring)に記録しています。 マークを設定するコマンドは、古いマークをこのマークリングに入れます。 マークを設定していた箇所に戻るには、 C-u C-SPC(またはC-u C-@)を使います。 これは、set-mark-commandコマンドに数引数を指定したものです。 このコマンドは、マークがあった箇所にポイントを移動し、 それ以前のマークを収めたマークリングからマークを復元します。 したがって、このコマンドを繰り返すと、 マークリング上にある過去のマークのすべてを1つ1つ遡って移動できます。 このように辿ったマーク位置は、マークリングのうしろに付け加えられるので、 なくなってしまうことはありません。

各バッファには独自のマークリングがあります。 すべての編集コマンドは、カレントバッファのマークリングを使います。 特に、C-u C-SPCは、つねに同じバッファに留まります。

M-<beginning-of-buffer)のような長距離を 移動するコマンドの多くは、まずマークを設定して、 古いマークをマークリングに保存してから動作を開始します。 このようにして、あとで簡単に戻れるようにしておきます。 探索コマンドは、ポイントを移動するときにはマークを設定します。 コマンドがマークを設定したかどうかは、 エコー領域に`Mark Set'と表示されるのでわかります。

何度も同じ場所に戻りたい場合には、マークリングでは不十分でしょう。 このような場合には、あとで使うために位置情報をレジスタに記録できます (see section レジスタに位置を保存する)。

変数mark-ring-maxは、マークリングに保存する最大項目数を指定します。 すでに多くの項目が存在していて、さらにもう1つ押し込むときには、 リスト内の最古の項目を捨てます。 C-u C-SPCを繰り返し実行すると、 いまマークリングに入っている位置を巡回することになります。

変数mark-ringは、最新のマーカオブジェクトを先頭にして、 マーカオブジェクトのリストとしてマークリングを保持します。 この変数は各バッファにローカルです。

グローバルマークリング

個々のバッファごとの普通のマークリングに加えて、 Emacsにはグローバルマークリング(global mark ring)が1つあります。 グローバルマークリングは、最近マークを設定したバッファの系列を記録しますから、 それらのバッファに戻ることができます。

マークを設定すると、つねにカレントバッファのマークリングに項目を作ります。 マークを設定した以降にバッファを切り替えていると、 新しくマークを設定するとグローバルマークリングにも項目を作成します。 その結果、グローバルマークリングには訪れていたバッファの系列が記録され、 各バッファではマークを設定した箇所が記録されます。

コマンドC-x C-SPCpop-global-mark)は、 グローバルマークリングの最新の項目が示すバッファの位置に移動します。 グローバルマークリングも巡回されるので、 C-x C-SPCを繰り返し使用すると、 1つずつまえのバッファに移動できます。


Go to the first, previous, next, last section, table of contents.