この章では、基本編では述べなかったEmacsの高度概念と、
それを利用した機能の解説を行う。これが理解できれば、
Emacsの内部動作が大分理解し易くなる筈だ。
●数値引数(Numeric Argument)
Emacsで、キー操作を行うと、そのキーに割り当てたコマンドが動作する
ということは、第1章で述べた。コマンドは、引数を受け取ることができる。
引数の種類の詳細については、第5章で述べる。
ここでは、そのうちの「数値引数」について説明する。
数値引数とは、Emacsのコマンドに与える数値のことである。
コマンドは、与えられた数値引数に応じて動作を変える
(勿論、数値引数を受け取らないコマンドもある)。
コマンドの数値引数の利用法は、殆ど次の2通りのうちのいづれかである。
1. ある動作をする/しないのスイッチとして使う
2. コマンド実行の繰り返し回数を指定する
1. の場合。
数値引数を渡すのであれば、
C-u コマンドのキー操作
と、操作する。渡さないなら当然、単純に、
コマンドのキー操作
である。
例えば、
M-q fill-paragraph 段落をfill(整形)する
というコマンドは、
通常は、単純にfill動作を行なう
数値引数があれば、justify動作を同時に行なう
と動作する。
2. の場合。
数値引数を渡すのであれば、
C-u 10進数値 コマンドのキー操作
と、操作する。
カーソル移動関係のコマンドは、殆どが数値引数を受け取るようになっている。
C-h k で、C-n の解説を読んでみると、
next-line:
Move cursor vertically down ARG lines.
......
とある。ここでいう、ARGが、「数値引数(Numeric Argument)」のことである。
よって、数値引数を渡さなければ1行下にカーソルを移動する。
数値引数を、次のように渡せば、
C-u 30 C-n
カーソルを30行下に移動する。
M-x で始まるコマンドを実行する時にも、勿論数値引数は渡せる。
C-u 10 M-x goto-line [CR]
こう操作すれば、カーソルはファイル先頭から10行目に移動する。
この2.のケースの数値引数の場合、C-uの代わりに、M-数字 を使うこともできる。
M-- 9 C-v
数値引数で、-9を渡したので、画面は9行分逆スクロールする。
また、同じ文字を繰り返し入力するためにも、数値引数は使える。
コメント等で、'-'記号を60個並べることによって、ブロックの区切りを示したい時、
M-6 0 -
とすれば、
'------------------------------------------------------------'
のように、60個の'-'が並ぶことになる。口の中で「1, 2, 3, 4, ……」と、
数字を唱えながらキーを叩く必要はない。
C-u a
と操作してみよう。'a'が4つ入力されると思う。C-uの次に何も数字を
指定しなければ、4を指定したのと同じになる。C-uは、ネストもできる。
C-u C-u a
と操作すると、'a'は、4×4で16個挿入される。
しかし、
C-u C-u 2 a
とすると、今度は2個の'a'しか入らない。数字を最後に指定したものが有効で、
ネストしたい場合は、C-uだけを連続してタイプする必要がある。
C-uが4である一方、
C-u -
も、
M- -
も、-1である。
ここで、問題。数字の9を、16個入れるのに、数値引数は使えるか?
答: C-u C-u C-q 9
これで、OK。
1., 2.以外の例で、引数の数値自体が意味を持つ例を一つ挙げよう。
C-u 3 M-r
このように操作すると、ウィンドウの上から(0から数えて)3行目に
カーソルが移動する。
これは、
M-r move-to-window-line そのウィンドウの指定行にカーソル移動
というコマンドである。数値引数を与えないと、ウィンドウの中央行にカーソルは
移動する。負数-nを与えると、ウィンドウの下から(1から数えて)n行目にカーソルは
移動する。
数値引数にはこういう使い方もある。
●キーボード・マクロ
数値引数は、一つのコマンドの繰り返し回数を指定するものだった。
では、一連のキー操作を繰り返したい場合には、どうしたらいいのだろう?
例えば、Cでプログラムを書いている場合、行末に余計なタブ/スペースが
残ってしまうことがある。これを全ての行に渡って、削除したいと考えたとする。
次のような場合である。
int a = 10; /* counter */
~~~~~~~~~~~ この部分を削除したい
普通にこういう行を処理しようと考えると、
1. この行にカーソルを移動し
2. 行末にカーソルを移動し
3. M-\ (delete-horizontal-space) を実行する
としてやればいいことが分かる。連続する3行を処理したいなら、
1. 最初の行にカーソルを移動し
2. その行末にカーソルを移動し
3. M-\ (delete-horizontal-space) を実行する。
4. 次の行にカーソルを移動し
5. その行末にカーソルを移動し
6. M-\ (delete-horizontal-space) を実行する。
7. 次の行にカーソルを移動し
8. その行末にカーソルを移動し
9. M-\ (delete-horizontal-space) を実行する。
と、してやればいいことはすぐに分かる。
この手順の2.〜9.のキー操作だけを書けば、
C-e M-\ C-n C-e M-\ C-n C-e M-\
となる。従って、1行につき1回、
C-e M-\ C-n
を実行してやれば、連続する行の行末の余分なタブ/スペースを削除できる。
この一連の手順を登録し、1単位の操作にしてしまうのが、
キーボード・マクロである。登録には、次のコマンドを使用する。
C-x ( start-kbd-macro キーボード・マクロ登録開始
C-x ) end-kbd-macro キーボード・マクロ登録終了
C-x ( を実行すると、モード・ラインのモードのところに、
キーボード・マクロ定義中であることを表す Def という記号が現れる。
図0401
同時に、ミニバッファには、
Defining kbd macro...
というメッセージが出る。
C-x ) を実行することで、モード・ラインの Def 表示は消え、
ミニバッファには、
Keyboard macro definend
というメッセージが現れ、登録は完了する。
登録中に操作を誤る等してエラーを発生させると、キーボード・マクロの
登録は中断されてしまう。この場合、C-x ( からやり直せば良い。
先の例を、キーボード・マクロとして登録してみよう。
C-x ( C-e M-\ C-n C-x )
これで、登録完了だ。
登録したキーボード・マクロの実行は、
C-x e call-last-kbd-macro (最後に)登録した
キーボード・マクロの実行
である。試しに、C-x e を実行してみると、カーソルのある行の
行末のタブ/スペースは削除され、カーソルは次の行に移動する。
C-x e を実行する度に、1行ずつ処理され、カーソルは次の行へと進む。
C-x u で、アンドゥを実行してみると、キーボード・マクロ1回分、
元の状態に戻る。定義したキーボード・マクロを何回か実行してみて
不都合を感じたなら、アンドゥによって、バッファを元の状態に戻した後
また新たにキーボード・マクロを定義してみればいい。
何度か試せば、正しい動作をするマクロが作れるだろう。
キーボード・マクロの定義を誤った場合、新たに定義し直すと述べたが、
既に定義されたキーボード・マクロのキー操作の終わりに、幾つかキー操作を
追加するという形の修正ならば可能になっている。
例えば、
C-e M-\ C-n
とすべきところを、C-nするのを忘れて、
C-e M-\
と定義してしまった場合である。このような時は、
C-u C-x (
として、追加分のキー操作を入力してやればよい。
C-u C-x ( C-n C-x )
とするのである。これで、
C-x ( C-e M-\ C-n C-x )
と、キーボード・マクロを再定義するのと同じ結果が得られる。
キーボード・マクロ実行時に、何か値を入力させたいことがあると思う。
例えば、キーボード・マクロの中の検索/置換で、実行の度に違う文字列を
使用したいとき等。方法はある。但し、実行時に「リカーシブ・エディット
(recursive edit)」を使わないといけない等複雑だし、
そうそう使用することもないと思うが、簡単に触れておく。
このような場合は、
C-x q kbd-macro-query
というコマンドを使用すれば良い。キーボード・マクロ定義中、
実行時にユーザの入力が欲しい箇所で、C-x qとタイプしておくのである。
この場合、定義中には何も起こらない。キーボード・マクロ実行時に、
この箇所に来ると停止する。ここで入力可能なのは、
[SPACE] キーボード・マクロ実行継続
[DEL] 今回のキーボード・マクロの繰り返しの、
残り部分をスキップし、
キーボード・マクロの次の回の繰り返しに入る
C-d 今回のキーボード・マクロの繰り返しの、
残りの部分をスキップし、
キーボード・マクロの繰り返しも中止する
C-l 画面を書き直す
C-r リカーシブ・エディットに入る
リカーシブ・エディットを抜けるには、C-M-cとタイプする
である。これ以外のどんなキーも、キーボード・マクロの実行を中止すると同時に
そのキーのコマンドを実行する。
C-u C-x qというように、数値引数付きでキーボード・マクロ定義時に使用した場合、
少々動作が変わる。この場合は、単純にリカーシブ・エディットを起動する。
定義途中のキーボード・マクロを破壊せずに、バッファのテキストそのものを
エディットしたいという時に利用すると便利。筆者は殆ど使ったことはないが。
cf. Info: Emacs → Keyboard Macros → Kbd Macro Query
注:
リカーシブ・エディット(recursive edit)については、ここでは触れない。
このような場合以外、殆んど使用されることはないと思う。それ故省略する。
一言で言えば、エディットのネスティングだろう。あるエディット作業の
中から、サブルーチン・コールのようにして、もう一度Emacsの通常エディット
状態に入ることを言う。勿論、リカーシブ・エディットを抜けると、
リカーシブ・エディットに入る直前の状態に戻る。つまり、実行途中だった
元の作業の続きの実行に移る。これが、今回の場合のように便利なこともある
というだけのこと。
リカーシブ・エディット状態は、モード行の表示によって判断できる。
図0417
複数レベルのリカーシブ・エディットに入ってしまった場合、
top-level
というコマンドを実行すれば、一気に全て抜けることができる。
さて、キーボード・マクロを実行するC-x e には、
繰り返し回数を指定する数値引数が渡せる。まずは9行程やってみる。
M-9 C-x e
うまくいく筈である。では、ファイルの残りの行全てを処理させるにはどうしたら
良いだろうか? カーソル行以降の行数を数える必要はあるだろうか?
実はそんな必要はない。無造作に大きな値を数値引数として与えれば十分である。
そこで、
M-9 9 9 C-x e
としてやる。カーソルの行以降、999行を処理する筈である。
カーソル以降に999行存在しないにも関わらず、やってみると、
(場合によっては結構時間がかかるかも知れないが)終了後
カーソルは何もない画面に置かれているように見えるかも知れない。
実は、バッファ最終行で実行するC-n は、空白行を1行挿入してしまうのだ。
仕方がないので、
C-x C-o delete-blank-lines カーソル行周囲の空白行を削除
を実行することで、本来の目的を得る。
キーボード・マクロを定義する時に、C-n の代わりに forward-line と
いうコマンドを使ってみよう。これは、C-n と殆ど同じだが、
バッファ最終行で実行した場合、空白行を挿入しない。
C-x ( C-e M-\ M-x forward-line [CR] C-x )
このキーボード・マクロを先と同じように繰り返してみる。
M-9 9 9 C-x e
今度は、随分待たされた後に目的の結果を得られたと思う。
最後の行で、このキーボード・マクロを実行してみよう。
M-> で、バッファ最終行に移動してから、C-x eとやってみる。
数回繰り返せば分かるが、何も変化はない。この状態で、
M-9 9 9 C-x e
を実行すれば、何も変化しないまま、延々とキーボード・マクロが実行される。
その状態で、
C-g
をタイプしてみよう。おそらく、キーボード・マクロ実行が中断される。
もし中断した時が、ミニバッファへのM-x forward-lineの入力途中だったりしたら、
もう1度C-gとすればよい。
このように、キーボード・マクロは、C-gによって中断できるので、
数値引数で繰り返し実行させている途中、様子がおかしいから
中断したいと思ったら、C-gをタイプすればいい。
C-x C-qによって、そのバッファをRead Onlyに変更してから、
同じキーボード・マクロを実行してみよう。ビープ音が鳴り
図0402のようなメッセージがエコー領域に表示されて、キーボード・マクロの実行は
中断される。
キーボード・マクロ実行中に、エラー発生すると、キーボード・マクロの
実行は中断されるのである。
続いて、C のarrayという名前の2次元配列の行要素と列要素を入れ換えてみよう。
array[x][y]
というのがあったら、
array[y][x]
にするのである。
色々方法はあると思うが、
C-s array ESC C-@ C-s ] ESC C-w C-s ] ESC C-y
という操作をキーボード・マクロ化すれば、目的を達成できる。
この手順を登録して実行すれば、実際にうまくいくことが確認できると思う。
キーボード・マクロを利用すれば、このように試行錯誤的に定型処理を
簡単化できる。キーボード・マクロが自在に操れるようになると、
Unixで使い捨てのつまらないツール(awkやsed等のスクリプト)を
作る必要が殆どなくなる筈である。是非、活用して貰いたい。
因みに、このやり方でキーボード・マクロの定義/実行を行うと、
同時には1つのキーボード・マクロしか利用できない。新しいものを
登録すると、以前のものは消えてしまう。
○キーボード・マクロをコマンドにする
キーボード・マクロは、先の方法では、同時には1つしか定義できない。
実は、1度作ったキーボード・マクロは、名前を与えて
再利用/保存をすることが可能になっている。
name-last-kbd-macro 定義したキーボード・マクロに、名前を付ける
このコマンドを実行すると、先に定義したキーボード・マクロに名前を付け、
以後コマンドして使用できるようになる。このコマンド名は、既存のものと
ダブらないようにしないといけない。もっとも、Emacsが元から持っているコマンドと
同じ名前を付けようとすれば、エラー・メッセージが出て定義できないのだが。
図0403
但し、既存の名前付きキーボード・マクロと同じ名前を入力すると、
古いものを新しいもので置き換えることになるので要注意。
このように名前をつけると、以後はコマンドとして使用できる。
つまり、
M-x コマンド名 [CR]
として利用することができるようになる。
新たに、別のキーボード・マクロを定義しても、このキーボード・マクロは
このコマンド名で使用できるのである。このようにして、自分の好みの
コマンドをEmacsに追加することが可能である。
但し、このコマンドは現在のEmacsのセッション中でしか有効ではない。
つまり、現在立ち上げているEmacsを終了すれば、このコマンドは
消去されてしまう。
次回Emacsを起動した時にもこのコマンドを使用したいならば、
このキーボード・マクロを保存しておかなければならない。
insert-kbd-macro 名前付きキーボード・マクロの定義内容を
カーソル直前に挿入する。マークは設定されない。
このコマンドによって、キーボード・マクロの定義内容がカーソル直前に
挿入される。これを、Emacsの起動時初期化ファイルに入れておけば良い。
その方法の具体例については5章に述べる。
●正規表現(REGEXP; Regular Expression)
Unixに十分慣れた人ならば、この前の項で述べた
「行末の不要なタブ/スペースを除く」
という程度のことならば、ed(vi)やsedの正規表現を使って置換した方が
早いと思うだろう。そういう人も安心して良い。勿論Emacsにも
これらに類似する正規表現は存在するのだ。
正規表現というのは、特殊文字(special character)というものを
使って、文字列を一般的に表現する方法である。--- 個人的には、
「正規表現」という訳は分かりにくく、むしろ「正則表現」或いは「通常表現」
と言った方が適切ではないかと思っている。
因みに一般的には、ここでいう特殊文字は、
「メタキャラクタ(metacharacter)」と呼ぶようである。
Unixでは、コマンドによって使える正規表現に若干の差がある。
edとgrepとegrepに、大体種類分けできるのだろうか。コマンド自体の
文法も正規表現の記述に影響を与えるので、更に混乱し易くなっている。
これが「正規表現」が理解しにくい原因の一つになっていると思う。
(C-Shell等のコマンド・インタープリタが解釈してしまう\や$と、
正規表現の特殊文字がぶつかっていること等も、更に混乱させるだろう)
この辺の事情は、文献0703の第25章を参照して頂きたい。
Emacsに於いても、正規表現の使用が可能になっている。
Emacs内部では、正規表現の扱いは一意である(統一されている、uniqの意)。
正規表現についての詳しい説明は、Infoシステム(第3章参考)の
Info: Emacs → Regexps
に記述されている。Emacsでは、正規表現をREGEXPと記述することが多い。
以下、「正規表現」と言えば、Emacsでの正規表現を表すものとする。
Emacsの正規表現は、edとegrepのものを合わせ、一部修正し、
更にEmacs独自の拡張を加えたものになっている。
正規表現では、各特殊文字は次のような意味を持つ。
これ以外の文字は、「文字通り」の意味を持つ。つまり、自分自身とのみ一致する。
'.' 改行以外の1文字と一致する特殊文字。
'*' 他の文字に続いたときに意味がある。
直前の最小の正規表現を0回以上繰り返す。
可能な限り長い文字列と一致する。
'+' '*'と同じだが、1回以上の繰り返しを表す。
'?' '*'と似ている。0回か1回の繰り返しを表す。
'[……]'
'['と']'との間に入る文字列を、文字集合として扱う。
この文字集合の中の任意の1文字と一致する。
通常の特殊文字は、この'[ ]'内では特別な意味を失う。
代わりに、この中でのみ特別な意味を持つ文字がある。
'-'は、'[文字1-文字2]'と書いて、文字1〜文字2迄の
文字範囲の文字全てを表す。
例えば、'[a-z]'は、英小文字全てを表す。
'^'は、'['の直後にあった場合に限り、「補・文字集合」を
表す。つまり、「それ以外」を表すのに使用される。
例えば、'[^a-z0-9]'は、「数字と英小文字、以外」を
表す。
'^'を、'[ ]'内に含めるには、'['直後を避けて書けば良い。
'-'を、'[ ]'内に含めるには、'---'と表現する。
']'を、'[ ]'内に含めるには、'['直後に書けば良い。
'^' 行頭を表す、仮想的文字。
'$' 行末を表す、仮想的文字。
'\' 2つの機能を持つ。
1. 今迄述べた特殊文字をクォートする。
2. 特別な構成要素を導入する。
1.は、特殊文字の特殊な意味を打ち消し、その文字自身を
表すようにするために使う。つまり、単に'$'と書けば
行末を表す特殊文字として解釈されてしまうが、
'\$'と書けば、'$'という文字自身に一致するようになる。
2.は、この文字に「単独で使えば特殊でない文字」を
続けることで、特別な意味を表すようにする。
以下のようなものがある。
'\|' 代替を表す。この記号の両側の正規表現を併せて、
どちらか一方と一致するという新たな1つの正規表現を作り出す。
両側の最大の正規表現を1つに結合する。
次に示す'\(……\)'によるグループ化によってのみ、
この結合力の影響範囲を制限できる。
例えば、正規表現a, b, c, dについて、
'ab\|cd'
とすれば、「正規表現ab或いはcdに一致する」正規表現を表すが、
'a\(b\|cd\)'
とすれば、「正規表現ab或いはacdに一致する」正規表現を
表すようになる。
'\(……\)'
グループ化のために使用する。次の3つの働きを持つ。
1. '\|'による代替構成要素集合の結合力を制限する。
例えば、'\(z\|a\|b\)cd'のようにして、
正規表現bとcdとの間を区切っている。
2. 複雑な正規表現をグループ化して1つの正規表現として扱う。
例えば、'\(abcd\)*'とすれば、'abcd'の0回以上の繰り返しを
表す。
3. 後に参照する目的で、正規表現に一致した文字列を記憶する。
これは、次の'\数字'によって参照する。
'\数字' 数字は、1〜9迄の9個。
正規表現の'\(……\)'内の構成要素と一致した「文字列」を
参照する。
数字は、先の正規表現中で何番目に使用された'\(……\)'内の
正規表現であったかを表す。
例えば、
'\(n\)\(a\|b\|c\|d\)\2\1'
の場合、'\2'は2番目の'\(……\)'グループである
「正規表現\(a\|b\|c\|d\)」に一致した「文字列」を表す。
従って、上の正規表現でn, a, c, dがそれぞれ通常文字で、
bが正規表現[xy]、x, yは通常文字だったとすれば、
先の正規表現は、
naan
nxxn
nyyn
nccn
nddn
のいづれかの文字列と一致する。
'\2'は「正規表現\(a\|b\|c\|d\)」自身ではなく、
「正規表現\(a\|b\|c\|d\)」に一致した文字列を表すので、
こうなる。
従って、先の正規表現が、
nxyn
に一致することはない。
'\`' バッファ先頭を表す仮想的な文字。
'\'' バッファ末尾を表す仮想的な文字。
'\b' 語の先頭或いは語尾を表す仮想的文字。
'\B' 語中を表す仮想的文字。
'\<' 語の先頭を表す仮想的文字。
'\>' 語尾を表す仮想的文字。
'\w' 任意の語構成可能文字に一致。
'\W' 任意の非・語構成可能文字に一致。
'\sクラス'
任意の構文クラス'クラス'の文字と一致。
'\Sクラス'
任意の非・「構文クラス'クラス'の文字」と一致。
最後の幾つかは、「構文規則(Syntax)」と密接な関係を持つ。
GNU Emacsでは、例えば「語」というものがどのような文字から構成されるか?
ということを、任意に定義できる。構文規則については、本章で後述する。
以上をまとめてみると、図0407のようになる。特に、字間を表す正規表現に
注意するといいだろう。これらは、文字ではなく、文字と文字との間が、
どのような性質を持つかを指定するものである。
また、正規表現の繰り返しについては、最長のものと一致するという約束がある。
○NEmacs, Muleにおける、正規表現の拡張
NEmacsにおいては日本語文字が、Muleにおいては多国語文字が、
それぞれ扱えるように先の正規表現が拡張されている。
Info: Nemacs → NemacsUsers → Search → RegExp
Info: Mule → Features for Text → Regular Expression
→ Extended Pattern
次の説明中に出てくる「カテゴリ」とは、「文字カテゴリ(char category)」
のことで、本章で「構文規則」を説明する時に解説する。簡単にいえば、
「構文規則」を多国語向けに拡張した概念である。
「文字」は、1バイト文字/多バイト文字双方に対応できるように拡張されている。
「語」は、NEmacs, Muleの語である「拡張word」のことを指すように
拡張されている。
これらに見合うように、
'.', '[……]', '\b', '\B', '\<', '\>', '\w', '\W'
も拡張されている(図0418)。
それ以外に、正規表現の特殊文字自体も次のように拡張されている。
拡張部:
'\cカテゴリ'
任意の文字カテゴリ'カテゴリ'の文字と一致。
'\Cカテゴリ'
任意の非・「文字カテゴリ'カテゴリ'の文字」と一致。
次の2つは、NEmacs固有でMuleには無い。カテゴリを代わりに使えばいいからである。
'\h'
改行を除く1バイト文字(半角文字)1つと一致。
'\z' 全ての2バイト文字(全角文字)1つと一致。
Muleのカテゴリについては、
Info: Mule → Features → Features for Text →
Syntax → char-category
を参照のこと。
注意:
'\sw'('\Sw')は、Emacsでは'\w'('\W')と等価だが、
NEmacs, Muleでは等価ではない。
NEmacs, Muleでは、
'\w'('\W')は、「語(拡張word)」構成可能文字(非・構成可能文字)と一致する。
'\sw'('\Sw')は、構文クラス'w'の文字(それ以外の文字)とのみ一致する。
構文クラス'w'は、多国語文字を含まない。「語(拡張word)」構成可能文字は、
勿論多国語文字を含む。
'\cw'('\Cw')と、'\sw'('\Sw')とも等価ではない。
○検索コマンドと正規表現
正規表現を使用できるコマンドの例として、置換と検索を取り上げる。
検索:
M-C-s isearch-forward-regexp 正規表現の段階的前方検索
isearch-backward-regexp 正規表現の段階的後方検索
いづれも、
C-s isearch-forward 文字列の段階的前方検索
C-r isearch-backward 文字列の段階的後方検索
の正規表現版である。正規表現の後方検索は、デフォルトではキーに
割り当てられていない。そこで、第5章に述べる方法で、
M-C-rに割り当てておくと便利だろう(M-C-rは、元々何のコマンドも
割り当てられていない)。デフォルトのまま使用するには、
M-xで起動するか、M-C-s C-rと操作するしかない。
注: Emacs Ver.19では、M-C-rが標準でバインドされるようである。
正規表現を使って、行末に不要なタブ/スペースのついた行を
探してみよう。
「タブまたはスペースの1回以上の連続の直後に行末が来る」という
正規表現は、
[ ]+$
なので([ ]内には、タブとスペースが1つずつある)、これをそのまま使って、
M-C-s [ ]+$
と、操作すればいいことが分かる。検索開始後の操作は、C-sの時と同じである。
第1章では、極簡単にしか説明しなかったので、ここで整理する。
C-sによる段階的検索中では、検索文字列の文字以外に、次のキーを使用できる。
[DEL] ミニバッファのカーソルの直前の文字を消去する。
C-q 普通通りに、制御文字入力の前置きとして使用する。
C-w 現バッファのカーソル直後の単語を、検索文字列に追加する。
C-y 現バッファのカーソル直後の行の残りを、検索文字列に追加する。
C-s バッファ前方に検索を繰り返す。
C-r バッファ後方に検索を繰り返す。
[ESC] 段階的検索の終了(カーソルは、最後に見つけた文字列に位置する)。
C-g 検索コマンドの中断(検索開始前の位置に、カーソルは戻る)。
C-k NEmacs, Muleにおいてのみ有効。一時的に、
文字列一括入力モードになる。
ここで、多国語文字の入力が行える。こうしないと、
漢字等の非ASCII文字を入力した途端に、
段階的検索コマンド自体が終了してしまう。
例. 文字列'abc漢字def'を、段階的前方検索する。
C-s abc C-k 漢字 [CR] def
これらキーは、次の変数で設定可能である。但し、変更しない方が良いと思う。
変数の設定の仕方は、第5章を参照のこと。左がオリジナルのキーで、
右がそれを変更するための変数名である。
[DEL] search-delete-char
[ESC] search-exit-char
C-q search-quote-char
C-s search-repeat-char
C-r search-reverse-char
C-y search-yank-line-char
C-w search-yank-word-char
これ以外の表示可能文字を段階的検索中に入力すると、
カーソルをその場においた状態で検索を終了し、
続いてそのキーのコマンドを実行する。
検索を行う別のコマンドを紹介する。これらは、段階的検索の代わりに
一括型の検索を行う。
C-s [ESC] search-forward 前方検索
C-r [ESC] search-backward 後方検索
ミニバッファから検索文字列を入力すると、その文字列を見つけた位置に
カーソル・ジャンプする。
これらコマンドの正規表現版もある。
M-C-s [ESC] re-search-forward 正規表現前方検索
re-search-backward 正規表現後方検索
re-search-backwardは、M-C-s C-r [ESC] によっても起動できる。
isearch-backward-regexpがM-C-rに割り当ててあれば、M-C-r [ESC]によっても
起動可能だろう。
この他に、単語単位での検索もできる。
C-s [ESC] C-w word-search-forward 単語列の前方検索
C-r [ESC] C-w word-search-backward 単語列の後方検索
単語単位の検索は、文章(単語列)の検索に便利である。
通常の検索では、単語1と単語2の間を空白で区切った単語列'単語1 単語2'の
検索をすると、「単語1の直後で改行し、単語2が次の行にある」という
単語列は見つけることができない。然し、上の単語列の検索コマンドを
使用すれば、1つずつ空白を空けた単語の列を検索文字列として入力した場合に、
「単語間に、複数の空白、改行文字、句読点」があるような文字列も
見つけることができる。
このコマンドは、コマンド内部で正規表現を生成して、その正規表現で
検索を行うことで、こういう機能を実現している。
○置換コマンドと正規表現
次に置換を例に取る。
置換:
query-replace-regexp 正規表現の確認付き置換
勿論これは、
M-% query-replace 文字列の確認付き置換
の正規表現版である。
これを使って、「行末の不要なタブ/スペース」を削除してみよう。
正規表現は先に使用した
[ ]+$
で、これをヌル・ストリングに置換するのだから、
M-x query-replace-regexp [CR] [ ]+$ [CR] [CR]
と操作すればいいことが分かる。
置換開始後の操作方法は、M-% の時と同じである。第1章では簡単に説明した
だけなので、ここでもう一度詳細に解説する。
[SPACE] この文字列を置換して、次に進む。
[DEL] この文字列は置換しないで、次に進む。
, この文字列を置換し、カーソルはそのまま。
ここで、もう1度だけ、キー入力が行える。
つまり、ここで解説しているキー([SPACE], [DEL]等々)を
入力できる。
[ESC] 置換コマンドをここで終了する。
. この文字列を置換した後、置換コマンドを終了する。
! この文字列以降残り全てを、確認なしで置換する。
^ 1つだけ前の位置に戻る。間違って置換した時に使用。
これは、1回しか戻れない。実際に間違いを正すには、
C-rでリカーシブ・エディットに入って直すしかない。
C-r リカーシブ・エディットに入る。M-C-cで、置換に戻る。
C-w バッファのこの文字列を削除した後、
リカーシブ・エディットに入る。
C-l 画面の再表示。再び、ここで解説しているキーが入力できる。
C-h ここで解説しているキーの説明をした後、
再び、これらのキーが入力できる。
置換コマンドに与える文字列について:
置換コマンドに与える文字列は、2つある。1番目の文字列が検索文字列で、
2番目のの文字列がそれを置換する文字列である。
1番目の文字列を全て小文字で入力した場合、
置換後の文字列は大文字/小文字を保存している。
つまり、第1引数に'foo'を、第2引数に'bar'を指定すると、
foo → bar
FOO → BAR
Foo → Bar
という形で置換を行う。
2番目の文字列に大文字を使った場合、その大文字は保存される。
1番目の文字列に大文字を使った場合、2番目の引数はそのまま使用される。
他の場合のような大文字/小文字の変換は行わない。
変数case-replaceがnilになっていれば、矢張大文字/小文字の変換をせずに
2番目の引数をそのまま使うようになる。
変数case-fold-searchがtならば、第1引数の文字列を検索するときに
大文字/小文字の区別を行わない。nilならば、区別する。nilならば、
置換時の大文字/小文字の保存も行わない。
Info: Emacs → Replace
筆者は、case-fold-searchをnilにするのをデフォルトとしている。
正規表現置換の場合、第2引数には通常の文字列の他に、
次のような特殊文字列も使用できる。
'\&' 第1引数で指定した正規表現に一致した文字列全体を表す
'\数字' 第1引数で指定した正規表現中の括弧でくくったグループに
一致した文字列を表す。数字は、第1引数の何番目の
括弧のグループかを表す。
eg.
文字列'Emacs'を'NEmacs'で置き換える。
M-x query-replace-regexp [CR]
Emacs [CR]
N\& [CR]
文字列'NEmacs'を'Emacs'に戻す。
M-x query-replace-regexp [CR]
N\(Emacs\) [CR]
\1 [CR]
余談だが、query-replace, query-replace-regexpいづれも数値引数をつけて
起動すると、置換対象を「語(word)」に限定するようになる。
●Emacsでの文字列(文字表現)
Emacsでは、
C-q quoted-insert 特殊文字を入力する前置き
によって、制御コード(control code)を入力できるため、
どのような文字列でも作成可能になっている。
しかし、制御コードを表現するために'\'エスケープを使うこともできる。
Emacs-Lispによるプログラムを行う場合等に使用する。
書式は、C言語のそれに酷似している。
\b BS; C-h
\t TAB; C-i
\n NL; C-j
\v VT; C-k
\f FF; C-l
\r CR; C-m
\e ESC; C-[
\\ '\'自身
\" '"'自身
\8進3桁 そのコードのASCIIコード文字
\C-文字 その文字のコントロール・コード
\M-文字 その文字のメタキャラクタ・コード
これら表記法は、インタラクティブに実行する場合 --- つまり、
キーボードからキー操作でコマンド実行し、プロンプトに対して文字列を入力する場合
--- は、あまり覚える気にならないだろう。
C-q 制御コード
で、特殊文字を入力すればいいのだから(第1章参照)。
しかし、第5章に述べる方法によって、カスタマイズするためには
知っておいた方がよいことだろう。
文字列の場合は、
"\b"
のような表記になるし、文字の場合は、
?\b
のようになる。
●構文規則(Syntax)
Emacsでは、「語」の認識や括弧の対応、プログラミング言語の制御構造等を
理解する。また、それに基づいたコマンドが使用できるようになっている。
つまり、一種の構文解析をしながら動作している。そのためには、
何が「語」であるのかとか、何が開き括弧/閉じ括弧であるのか等を
知らなければならない。そういった規則を定めるのが、この構文規則(Syntax)である。
NEmacs, Muleでは、この構文規則を多バイト文字に見合うように修正し、
更に多バイト文字を扱えるように拡張した概念である「文字カテゴリ」というものを
定義している。
これらを順に解説する。
○Emacsの構文規則
Emacsでは、この構文規則を構文規則表(Syntax Table; 構文テーブル)に
まとめている。1バイト(8ビット)の256文字がそれぞれどのような
文法的意味を持つかをまとめて定義したテーブルである。
このテーブルは、メジャー・モード毎に存在する。実態は変数である。
従って、通常はモード毎(場合によっては、バッファ毎)に構文規則が異なる。
構文テーブルでは、各文字に「構文クラス(Syntax Class)」というものを
対応させている。1つの文字は、1つの構文クラスに属する。
構文テーブルは、次のコマンドで表示できる。
C-h s describe-syntax 現在のモードの構文テーブルを表示
図0404は、構文テーブルの表示例である。左側が文字(範囲)で、
その右に出ているのが構文クラスである。
構文クラスには、以下のようなものがある。
Info: Emacs → Syntax → Syntax Entry
以下は、Info及び文献0503の抄訳である。
' ' 空白文字のクラス(' 'の代わりに'-'も使える)
(whitespace character)
'w' 単語構成可能文字のクラス
(word constituent)
'_' シンボル構成可能文字のクラス
シンボル名の一部ではあるが、単語ではない文字のクラス。
C言語の'_'文字等がこのクラス。
(symbol constituent)
'.' これ以外のクラス属するのが適当でない、句読点文字のクラス。
(punctuation character)
'(' 開き括弧文字のクラス。
(open parenthesis character)
')' 閉じ括弧文字のクラス。
(close parenthesis character)
''' 式前置子クラス。これら文字は、シンボル中にあれば
シンボルの一部であり、式の直前にあればその式の一部である。
但し、空白中にあれば、空白として扱われる。
(expression prefix)
'"' 文字列クォート文字のクラス。互いに対応する
ペアで使用され、その中に入った引用文字列は、構文的意味を失う。
但し、構文クラス'\'と'/'の文字によって、構文クラス'"'自身の
文字を引用文字列中に含めることができる。
(string quote)
'$' 自己対応デリミタのクラス。TeXの数式モードに入る/から出るための
'$'を意図している。対応(match)の目的時には、隣合うペアの'$'文字は、
1つとして扱われる。
(paired delimiter)
'/' 文字クォート文字のクラス。これに続く1文字は、構文的な意味を失い、
常に只の文字(alphabetic)として扱われる。
(character quote)
'\' エスケープ文字のクラス。事実上は、構文クラス'/'の文字と
同様に扱われる。というのは、例えばCのエスケープの通常外の場合
(数字が続くような場合)でも、それを含む式がどこで終わるかという
ことに対しては何の影響も与えないので。
(escape)
'<' コメント開始文字のクラス。1文字でコメント開始になる場合
(Lispの';'等)に限って、この表現を使う。
(comment starter)
'>' コメント終了文字のクラス。(Lispでは改行が、このクラスに入る)。
(comment ender)
上記説明中、各クラスを表す'/'や'\'という文字を見出しに使用した。
この構文クラスを代表する文字を、「構文ニモニック(Syntax Mnemonic)」という。
ある文字が属する構文クラスを変更するには、次のコマンドを使用する。
modify-syntax-entry 指定文字の構文クラスを変更する
このコマンドの第1引数は、構文クラスを変更したい文字である。
第2引数は、その文字に指定する構文記述子(syntax descriptor)である。
構文記述子の内容は文字列で、文字単位で次の順で指定する。
1. 構文クラスを表す文字(構文ニモニック)
2. 構文クラス'(', ')'を指定した場合の対応文字。
対応するものがなければ、SPACEを使用する。
3. 構文フラグ
構文記述子に指定する文字列は、途中迄で打ち切ることができる。
構文フラグ(Syntax Flags)は、C言語等2文字のコメント開始/終了文字列に
対応するために用意された。構文テーブルの各文字は、次の4つのフラグを持てる。
各フラグは、数字(文字)である。
'1' 2文字のコメント開始文字列の第1文字
'2' 2文字のコメント開始文字列の第2文字
'3' 2文字のコメント終了文字列の第1文字
'4' 2文字のコメント終了文字列の第2文字
このコマンドは、インタラクティブに使用するよりも、
Emacsの初期化ファイルで関数として使用して、カスタマイズをかけるのに
使う方がいいだろう。具体例については、第6章を参照のこと。
○NEmacsの文字構文と文字カテゴリ
NEmacsでは、Emacsの構文規則を若干拡張している。然し、構文規則の方で
定義するのは矢張1バイト文字についての構文クラスだけである。NEmacsでは
この拡張した構文規則を、「文字構文(char-syntax)」と呼んでいる。
2バイト文字については、文字構文では詳しいことは何も決めていない。
つまり、漢字は「日本語文字を表す構文クラスのバイトが2つ並んでいる」と
いう認識しかできない。日本語文字(2バイト単位)の詳細は、
「文字カテゴリ(char-category)」の方で定義している。
文字構文、文字カテゴリを順に説明する。
NEmacsの構文クラスには、Emacsのそれに、次のものが追加されている。
'j' 日本語文字(2バイトのうちの1バイト)
プログラム中で使用するときはどうかしらないが、インタラクティブに
使用する場合、変数kanji-flagをnilにしないと、"\sj"の検索には失敗する。
"\sj"が、「あくまでバイト単位」で検索しようとするためだろう。
C-x C-k t toggle-kanji-flag
によって、kanji-flagをnilにすれば、動作確認できる。
Info: Nemacs → Functions → Jtextfunc
→ Syntax :: char-syntax
NEmacsの文字カテゴリは、文字構文と同じようなものだが、
文字構文とは違う、別の概念/定義である。文字カテゴリには、
全ての「文字(1バイト文字/2バイト文字双方を含む)」について定義される。
文字カテゴリ種には、次のようなものがある。
以下は、
Info: Nemacs → Functions → Jtextfunc
→ Syntax :: char-category
より。
1バイト文字の場合:
' ' 空白文字
'w' 単語構成可能文字
'_' シンボル名の一部ではあるが、単語ではない文字
'.' 句読点文字
'(' 開き括弧
')' 閉じ括弧
''' 文字クォート
'"' 文字列クォート
'$' 数式
'/' 文字エスケープ
'\' エスケープ
'<' コメント開始文字
'>' コメント終了文字
2バイト文字の場合:
`s' 記号.漢字コードの区点が1、2、8区のもの.
`a' 英数字.漢字コードの区点が3区のもの.
`h' ひらがな.漢字コードの区点が4区のもの.特殊ひらがなを除く.
`H' 特殊ひらがな."ヽ", "ヾ", "ゝ", "ゞ"
`k' かたかな.漢字コードの区点が5区のもの.特殊かたかなを除く.
`K' 特殊かたかな."ー"
`g' ギリシャ文字.漢字コードの区点が6区のもの.
`r' ロシア文字.漢字コードの区点が7区のもの.
`u' 未定義.漢字コードの区点が9〜15区のもの.
`c' 漢字.漢字コードの区点が16区以上のもの.特殊漢字を除く.
`C' 特殊漢字. "仝", "々", "〆", "〇"
これら構文クラスや文字カテゴリは、前述のように正規表現中から利用できる。
NEmacsにおいては、ある文字の文字カテゴリを変更することはできない。
$NEMACS/src/syntax.cにおいて、固定的に定義されている
(ハード・コーディング)。
Muleでは、変更可能になる。
○Muleの文字構文と文字カテゴリ
NEmacsで文字構文をバイト単位で定義していたのに対して、Muleでは
「文字」単位で文字構文を定義している。バッファ内部表現では
複数バイトで1文字を表すのだが、この1文字毎に文字構文が定義される。
これとは独立して、文字カテゴリも定義できる。
NEmacsでの文字構文と文字カテゴリは、
文字構文 ・文字単位ではなく、バイト単位で適用する
・構文クラスは既存のものだけ
・ある文字の構文クラスを変更することは可能
文字カテゴリ ・バイト単位ではなく、文字単位で適用
・文字カテゴリ種は既存のものだけ
・ある文字の文字カテゴリは始めから決まっていて、変更不可
・1つの文字は1つの文字カテゴリに属する
という違いがあった。Muleにおいてはこれが、
文字構文 ・バイト単位ではなく、文字単位で適用
・構文クラスは既存のものだけ
・ある文字の構文クラスを変更することは可能
文字カテゴリ ・バイト単位ではなく、文字単位で適用
・文字カテゴリ種は、ユーザが定義して増やすことも可能
・ある文字の文字カテゴリを変更することは可能
・1つの文字が複数の文字カテゴリに属することが可能
というように、拡張された。
詳細は、
Info: Mule → Features → Features for Text → Syntax
を参照のこと。
●Emacsのテキスト単位
Emacsでのテキスト操作の単位には、
文字 char
語 word ; Syntax
行 line ; '\n'
文 sentence ; Var: sentence-end
段落 paragraph ; Var: paragraph-{separate,start}
領域 region ; Point & Mark
ページ page ; Var: page-delimiter
矩形領域 rectangle ; Point & Mark
S式 sexp ; Syntax
(Lispの)リスト list ; Syntax
関数定義 defun ; Syntax: top levelでのlist
を単位とするものがある。この本では今迄、これらの定義を曖昧にしたまま
扱ってきたが、ここで厳密に定義したいと思う。
上の表の左側が日本語での意味で、真中がEmacsのコマンド名等に
埋め込まれている名前である。右は、私のメモでそれぞれが何によって
定義されるかを意味する私専用のニモニック(Mnemonic)である。
このうち、S式、リスト、関数定義については、プログラミング言語の
モード以外では殆ど意味をなさないと思う。そこで、これら3つの概念については、
6章に譲る。
それ以外のものについて、ここできちんと定義してみよう。
○文字(char)
Emacsにおいては、charというものは1バイト文字のことを表すと
考えていいだろう。文字コード(ASCII)0x00〜0xFF迄の256文字である。
バッファ中にある時には、この文字コードがそのまま格納される。
表示の際には、
0x20〜0x7E迄の文字は表示可能文字なので、画面上1桁を占めて、
そのコードに相当する文字として表示される
0x00〜0x1Fと0x7Fの文字は、制御文字なので、
'^文字'、というお馴染みの表記で2桁使用して表示される
0x80〜0xFF迄の文字は、
'\8進3桁'、という形で4桁使用して表示される
と、いうふうになる。
Emacsの文字を単位とする操作では、バッファ中の1バイトを基準として
動作する。
NEmacs, Muleの場合には、この文字の概念が日本語に見合うように拡張される。
多国語文字は、0x80〜0xFFの部分に配置されて扱われる。バッファ内部コードは
NEmacsならばEUCコードが、MuleではMule独自の内部コードが使用される。
NEmacsの場合、0x00〜0x7F迄の文字は1バイト1文字として
扱われ、0x80〜0xFF迄の文字は2バイトで1文字として扱われる。
連続する0x80〜0xFFの各バイト・コードから0x80を引いた値が、
JISX0208の文字コードに相当することになる。当然これらの文字は、
画面上では2桁を占有する漢字として表示される。文字コードに対応する漢字が
存在しない場合には、'\8進3桁'、という形で表示される。
Muleの場合、0x00〜0x7F迄の文字は1バイト1文字として
扱われ、0x80〜0xFF迄の文字は多バイトで1文字として扱われる。
ある文字のバッファ内部表現がどのようになるかは、文字種によって異なる。
(cf. 附録 「NEmacs 3.3.2/Muleにおける、日本語文字コードの扱い」)
当然これらの文字は、画面上では多桁を占有する文字として表示される。
文字コードに対応する適当な文字が存在しない場合には、
'\8進3桁'、という形で表示される。
NEmacs, Muleいづれも、C-fやC-b等の文字単位でのエディット・コマンドも、
この文字に対応している。
NEmacsでは、バッファ毎にあるkanji-flagという変数を、
Muleではmc-flagを、それぞれnilに設定することで、
Emacsと全く同じように文字を扱うようにすることもできる。
cf. 2章モード・ライン
これは、C-h Tにもあったと思うが、C-x C-k tという操作でも行える。
文字を単位とするコマンドは、次の通り。
ARGとあるのは、数値引数のことである。デフォルトは1である。
C-b backward-char ARG文字戻る
C-f forward-char ARG文字進む
[DEL] delete-backward-char カーソル直前の文字をARG文字削除
C-d delete-char カーソル直後の文字をARG文字削除
C-t transpose-chars カーソル前後の文字を交換し、1文字進む
ARG回繰り返す
C-@ set-mark-command カーソル位置をマークする
他に、次のコマンドがある。
goto-char バッファ内ポイント位置にジャンプ
C-x = what-cursor-position カーソル位置の表示
NEmacsではARG文字といっても、日本語文字の関係で(ARG-1)バイトになるかも
知れない。つまり、日本語文字上では、M-5 C-fでカーソルは2文字分しか動かない。
数値引数指定すると、途端にバイト単位の勘定に戻ってしまうのだ。
Muleでは、厳密に文字になり、M-5 C-fで、5「文字」分動く。
○語(word)
Emacsにおける語の定義は、「構文クラス'w'の文字の連続」である。
従って、「語」の定義は、基本的にそのバッファで使用する構文テーブルの内容に
左右される。
NEmacsでは、「語」を拡張wordというもので定義している。
先にNEmacsでは、Emacsの(バイト単位の)構文規則と別に、
文字カテゴリ(1バイト文字/2バイト文字に関わらず、文字単位)と
いうものを設けていることを述べた。NEmacsでは、この文字カテゴリによって、
全ての文字(1バイト文字/2バイト文字の双方)を分類する。
これを利用して、語、つまり拡張word(疑似文節)というものは、
NEmacsでは図0405(疑似文節のノードそのまま引用)のように定義される。
kanji-flagをoffにしても、NEmacsではEmacsと同じ語の扱いとならない。
つまり、拡張wordのままである。
Muleでは、語の定義を正規表現によって自在に任意のものに変更できる。
また、NEmacs同様mc-flagをoffにしても語が拡張wordのままである。
語を単位とする操作コマンドは、次の通り。
M-b backward-word ARG語戻る
M-f forward-word ARG語進む
M-[DEL] backward-kill-word カーソル直前のARG語を削除
M-d kill-word カーソル直後のARG語を削除
M-t transpose-words カーソル前後の語を交換し、1語進む
これをARG回繰り返す。
M-@ mark-word 次の語尾をマークする
「ARG語」といった場合、「語境界までをARG回」という意味である。
他にも、次のようなものがある。
M-c capitalize-word カーソル直後のARG語について、英文字なら
頭文字だけ大文字にし、残りを小文字にする。
カーソルは、進む。
M-l downcase-word カーソル直後のARG語について、英文字なら
全て英小文字に変換する。
カーソルは、進む。
M-u upcase-word カーソル直後のARG語について、英文字なら
全て英大文字に変換する。
カーソルは、進む。
M-$ spell-word カーソル位置の英単語のスペル・チェック
NEmacs, Muleでは、
これはM-#に割り当てられている。
○行(line)
Emacsにおいて、行は、
改行コード('\n')で区切られたバッファ内の文字列
として、定義される。この改行コード自体は行の最後に属し、行の一部と考える。
行を単位とする操作コマンドは、次の通り。
C-p previous-line ARG行上に行く
C-n next-line ARG行下に行く
C-a beginning-of-line 行頭に行く
C-e end-of-line 行末に行く
C-k kill-line カーソル直後の文字列を行末迄削除。
ARGがあれば、ARG行削除。
C-x C-t transpose-lines カーソル行と直前の行を交換し、1行進む
これをARG回繰り返す。
その他。
goto-line 指定行にジャンプ
what-line 現在のカーソルの行位置を表示
○文(sentence)
Emacsにおいて、文は、変数sentence-endの値によって決定する。
変数sentence-endに設定された正規表現に一致する文字が、文末であると
判断される。段落境界も矢張、文末と看做される。
この正規表現に一致した文字列自体は、文末に含まれる。
デフォルトでは、この変数は、
"[.?!][]\"')}]*\\($\\|\t\\| \\)[ \t\n]*"
という値になっている。変数一般に関する操作等は、5章を参照して頂きたい。
また、第8章ではNEmacs使用時にこの値を日本語向けに設定する方法を述べる。
文を操作単位とするコマンドは、次の通り。
M-a backward-sentence ARG回1文戻る
M-e forward-sentence ARG回1文進む
C-x [DEL] backward-kill-sentence カーソル直前の文をARG回削除
M-k kill-sentence カーソル直後の文をARG回削除
transpose-sentence カーソル前後の文を交換し、1文進む
ARG回繰り返す
mark-end-of-sentence 文末をマークする
○段落(paragraph)
Emacsでは段落を、次の2つの変数に設定された正規表現によって認識する。
paragraph-start 段落開始或いは、段落区切りを表す行に一致
paragraph-separate 段落区切りを表す行に一致
段落の一部であると同時に段落開始を表すような行は、2つの変数の正規表現
双方に一致する必要がある。
通常、ページ境界が段落区切りでもあるようになっていることが望ましい。
変数のデフォルト値は、次の通り。
paragraph-start "^[ \t\n\f]"
paragraph-separate "^[ \t\f]*$"
段落を操作単位とするコマンドは、次の通り。
M-[ backward-paragraph 1段落戻る。ARG回繰り返す。
M-] forward-paragraph 1段落進む。ARG回繰り返す。
backward-kill-paragraph カーソル直前の段落を削除。ARG回繰り返す。
kill-paragraph カーソル直後の段落を削除。ARG回繰り返す。
transpose-paragraphs カーソル前後の段落を交換。ARG回繰り返す。
M-h mark-paragraph 現段落をリージョンにする
(現段落末にマークを設定し、
現段落頭にカーソルを移動する)
○リージョン(region; 領域)
リージョンは、マークとカーソルで囲まれたテキストである。
リージョンを操作単位にするコマンドは、種々雑多なものがある。
他のところで説明しなかったようなものを幾つか述べる。
M-= count-lines-region リージョンの行数を求める
capitalize-region リージョンに対する、M-c
C-x C-l downcase-region リージョンに対する、M-l
C-x C-u upcase-region リージョンに対する、M-u
spell-region リージョン内英単語のスペル・チェック
○ページ(page)
Emacsにおいて、ページは変数page-delimiterに設定された正規表現によって
認識する。この正規表現に一致する行からページ開始をする。
変数のデフォルト値は次の通り。
"^^L"
ページを操作単位とするコマンドは、次の通り。
C-x [ backward-page ページ境界に戻る。ARG回繰り返す。
C-x ] forward-page ページ境界に進む。ARG回繰り返す。
C-x C-p mark-page ページをリージョンにする
(ページ末にマークを設定し、
ページ頭にカーソルを移動する)
what-page ページ番号とそのページ内行位置表示
C-x l count-lines-page 現ページの行数と、カーソル前後の行数を表示
○矩形領域(rectangle)
Emacsでは、マークとカーソルで囲んだ領域内の文字列をリージョンと呼んだ。
この時、画面上にマークとカーソルを対角とする長方形がイメージできる。
この長方形の領域を rectangle といい、Emacsでのテキスト操作の単位にできる。
他のスクリーン・エディタで「矩形ブロック」等と呼んでいる概念である。
ここでは、矩形領域と呼んでおくことにする。
図0406 リージョンと矩形領域
Emacsでの矩形操作には、
clear-rectangle 矩形領域内をスペースで埋める
delete-rectangle 矩形領域内を消去
kill-rectangle 矩形領域内を削除し、
killバッファにコピー
open-rectangle その位置に、空の矩形領域を出す
元その場にあったテキストは、
右に移動する
yank-rectangle killバッファから、矩形領域を
取り出す
がある。いづれもキー・バインドはされていない。
この他にも、レジスタというものを使った矩形操作がある。
これについては、次の項で述べる。
図0408 各種rectコマンド実行例
矩形操作がもっとも得意なのは、picture-modeである。
picture-modeについても、後に述べる。
●レジスタ(register)の概念
Emacsには、レジスタと呼ばれるものがある。電卓の独立メモリのように、
テキスト等の記憶/呼びだしができる。具体的には、次のものを
記憶させておくことができる。
・リージョンのテキスト
・矩形領域のテキスト
・バッファ/カーソル位置
レジスタとして使用可能なのは、A〜Z, a〜z の52個である。
この52個のレジスタ1つ1つに、上に挙げた3つの種類のものを
記憶させることができ、任意の時点で呼び出すことができる。
レジスタ記憶自体の寿命は、現在立ち上げているEmacsの終了時までである。
記憶方法と呼びだし方法を、順に解説する。
・リージョンのテキスト
リージョンのテキストをレジスタに記憶させるには、
C-x x copy-to-register リージョンのテキストをレジスタにコピー
を使用する。操作は、
リージョン設定 C-x x レジスタ名入力 [CR]
となる。
リージョンのテキストをレジスタに追加することもできる。
prepend-to-register リージョンのテキストを
レジスタのテキストの前に追加
append-to-register リージョンのテキストを
レジスタのテキストの後ろに追加
・矩形領域のテキスト
矩形領域をレジスタに記憶させるには、
C-x r copy-rectangle-to-register
矩形領域のテキストを、レジスタにコピー
を使用する。操作は、
リージョン設定 C-x r レジスタ名入力 [CR]
となる。
・テキストの取り出し
リージョンのテキストも矩形領域テキストも、いづれも同じ操作で取り出せる。
C-x g insert-register 指定レジスタのテキストを取り出す
・バッファ/カーソル位置
あるバッファ内のカーソル位置を記憶させることもできる。
C-x / point-to-register カーソル位置をレジスタに記憶
操作は、
記憶させたい位置にカーソル移動 C-x / レジスタ名 [CR]
となる。
任意の時点で、この記憶させた位置にカーソルを戻すことができる。
C-x j register-to-point レジスタに記憶したカーソル位置へ
カーソルをジャンプ
操作は、任意のバッファで、
C-x j レジスタ名 [CR]
とすると、先のバッファが選ばれ、記憶させた位置にカーソルがジャンプする。
この呼び出しは、対象のバッファが消去されるまで有効である。
・レジスタ内容の確認
現在レジスタにどのような値が設定されているかは、次のコマンドによって
知ることができる。
view-register 指定レジスタの内容を見る
操作は、
M-x view-register [CR] レジスタ名 [CR]