[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

6. ナローイングとワイドニング

ナローイングはバッファの特定部分にのみ注目し、その他の部分を間違って変更 したりすることなく作業するための Emacs の機能である。ナローイングは普通 は使えないようになっている。これは初心者を混乱させないためである。

ナローイングの利点  
6.1 特殊形式 save-restriction  
6.2 what-line  ポイントは今何行目にあるか
6.3 ナローイングの練習問題  

ナローイングの利点

ナローイングを使うと、バッファのその他の部分はあたかも存在しないかのよう に見えなくなる。これは、例えばバッファのある部分でのみ単語を置き換えたい 場合なんかに有効である。つまり特定の部分にナローイングしてそこで置換を実 行すると、その部分のみ置換が実行されて残りの部分は無視される。検索につい ても同様で、ナローイングされた部分でのみ検索を行い、外の部分は探さない。 というわけで、文書のある部分のみ修正したい場合など、そのリージョンにナロー イングをかけることで、間違って修正不要な箇所まで見てしまうのを防ぐことが 出来るのである。

しかしながら、ナローイングするとバッファの残りの部分が見えなくなるので、 意図せずナローイングしてしまった場合、ファイルのその部分を削除してしまっ たのではないかと不安に思う人も出てくるかもしれない。更に、undo コ マンド (これは大抵 C-x u にバインドされている) でもナローイングは 解除されない(それに、そうすべきではない)。従って、もし widen コマ ンドでまた見えるように出来るということを知らなかった場合、パニックに陥い るかもしれない。(Emacs version 18 では、widen のキーバインディン グは C-x w だった。version 19 では C-x n w になっている。)

ナローイングは、人間だけではなく Lisp インタプリタにとっても便利なように なっている。 Emacs Lisp の関数はしばしば、バッファのある限定された部分に 対してのみ働くように設計されている。逆に言うと、Emacs Lisp 関数はナロー イングされたバッファ全体に対して働くようになっているとも言える。例えば what-line 関数は、もしバッファにナローイングがかかっていればそれ を解除し、仕事が終わるとまたナローイングを元に戻す。一方、 what-line 関数の中から呼び出される count-lines 関数は、ま ずナローイングを用いてバッファの目的とする部分に限定して仕事を行い、その 後ナローイングを解除して元の状態に戻す。


6.1 特殊形式 save-restriction

Emacs Lisp では、save-restriction という特殊形式を使うことで、 ナローイングのかかった状態を保持することが出来るようになっている。Lisp インタプリタが save-restriction 式に出逢った場合、まず save-restriction 式の本体部分を評価し、次にそのコードを実行するこ とでナローイングの状況が変わった場合にそれを元に戻す。例えば、バッファが ナローイングされていて、save-restriction の本体で、ナローイングが 解除された場合、実行後にsave-restriction はバッファにナローイング されたリージョンを返してくれる。what-line コマンドでは、バッファ にどんなナローイングが設定されていても save-restriction に続く widen コマンドで解除してしまう。元のナローイングはこの関数が終了 する直前に元に戻されるわけである。

save-restriction 式のテンプレートは単純である。

 
(save-restriction
  本体... )

save-restriction の本体は一つないしは複数のS式であり、それらは Lisp インタプリタによって順に評価される。

最後に注意しておくことがある。それは save-excursionsave-restriction の両方を、片方のすぐ後にもう片方を続けて使う場合、 save-excursion の方を外側にすることだ。これを逆にすると、 save-excursion を呼び出してからナローイングが設定されたバッファに 移動した場合にそのナローイングの状況を記録しそこねることがあるのだ。とい うことで、もし save-excursionsave-restriction を両方一 緒に使うなら、次のように使うことになる。

 
(save-excursion
  (save-restriction
    本体...))


6.2 what-line

what-line コマンドは現在カーソルがある場所までの行数を教えてくれ るものである。この関数を見ることで、save-restrictionsave-excursion の使い方を知ることが出来る。以下がこの関数の完全な コードである。

 
(defun what-line ()
  "Print the current line number (in the buffer) of point."
  (interactive)
  (save-restriction
    (widen)
    (save-excursion
      (beginning-of-line)
      (message "Line %d"
               (1+ (count-lines 1 (point)))))))

この関数は一行の説明文字列を持ち、あなたが予想した通 り、インタラクティブな関数である。次の二つの行では save-restrictionwiden を使っている。

特殊形式 save-restriction は、カレントバッファにどのようなナロー イングがかかっていようと、それを記録して本体のコードが評価し終わった後に その状態に戻してくれる。

特殊形式 save-restriction の後には widen が続いている。 この関数は、what-line が呼ばれた時にカレントバッファのナローイン グを解除する。(ここでのナローイングは、save-restriction が憶えて いるナローイングである。) これによって行数を数えるコマンドは、バッファの 最初からの行数を数えることが出来るのである。そうしない場合は、現在アクセ ス可能なリージョンの範囲内でしか行数をカウントしない。元のナローイングは 特殊形式 save-restriction によってこの関数が終了する直前に元の状 態に戻される。

widen の呼び出しに続いて save-excursion が使われている。こ れはカーソルの位置、(即ち、point の位置) とマークの位置を保存し、本体部 分のコードの中の beginning-of-line 関数によって動かされたポイント の位置を元に戻す、という働きをしている。

((widen) 式が save-restrictionsave-excursion の 間にあることに注意しよう。これら二つの save- ... 式を続けて使 う場合は save-excursion を外側に書かないといけないのであった。)

what-line 関数の最後の二つの行は、バッファ内の行数を数え、それを エコー領域に表示するものである。

 
(message "Line %d"
         (1+ (count-lines 1 (point)))))))

message 関数は Emacs の画面の最下行に一行メッセージを表示する関数 である。最初の引数は二重引用符に挟まれていて、これは文字文字列を表示する ものである。ただし、`%d', `%s', `%c' も入れることが出来て、 これらはこの文字列の後に続く引数を表示する。`%d' は引数を10進数とし て表示するので、メッセージは例えば `Line 243' と言った感じになる。

`%d' の場所に表示される数字は、この関数の最後の行で計算される。

 
(1+ (count-lines 1 (point)))

これがやっていることは1で示された位置、つまりバッファの最初の位置から (point) までの行数を数え、それに1を加えることである。(1+ という関数は引数に 1 を加える関数である。)1を加えるのは、例えば二行目は その前に一行しかないからである。count-lines はカレント行の 前の行までしか数えないので、こうしないと一行ずれてしまうのだ。

count-lines が仕事を終えてメッセージがエコー領域に表示された後は save-excursion によってポイントとマークの位置が元の状態に戻される。 そして、save-restriction がナローイングの状態を元に戻す。


6.3 ナローイングの練習問題

カレントバッファの最初の60文字を表示するような関数を書きなさい。その際、 例えばナローイングにより後半部分しかアクセス不能であり、最初の行が見えな い状態であってもきちんと表示するようなものにしなさい。また、ポイント、マー ク、及びナローイングを復元するようにすること。この練習問題のためには、 save-restrictionwidengoto-charpoint-minbuffer-substringmessage 及び他の関数を うまく組み合わせて使う必要がある。


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Matsuda Shigeki on April, 10 2002 using texi2html