[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

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

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=eintro&node=Narrowing%20&%20Widening"
"intro/ナロイングとワイドニング"へのコメント(無し)

ナロイングとは、バッファの特定部分に集中して残りの部分を 不用意に変更しないようにするEmacsの機能である。 初心者に混乱を与えないように、ナロイングは、通常、無効にしてある。

The Advantages of Narrowing

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=eintro&node=narrowing%20advantages"
"intro/TheAdvantagesofNarrowing"へのコメント(無し)

ナロイングすると、バッファの残りの部分は存在しないかのように見えなくなる。 たとえば、バッファのある部分のみで単語を置き換えるような場合には、 利点となる。 望みの範囲にナロイングすれば、その部分だけで置き換えを行える。 文字列検索もその範囲内のみで行えるので、 たとえば、文書のある部分を編集する場合、編集範囲にナロイングしておけば それ以外の範囲の文字列を拾うことがない。

しかし、ナロイングするとバッファの残りの部分が見えなくなるため、 偶然にナロイングしてしまうとファイルのその部分を削除してしまったと思うような 読者を怯えさせる。 さらに、(通常C-x uにバインドされる)コマンドundoでも、 ナロイングを無効にしない(また、そうすべきでもない)ので、 コマンドwidenによりバッファの残りの部分が見えるようになることを 知らない人は絶望することになる (Emacsの第18版では、widenC-x wに、 第19版では、C-x n wにバインドしてある)。

ナロイングは人間にとってと同様にLispインタープリタにとっても有用である。 Emacs Lisp関数は、しばしば、バッファの一部分に働くように設計されている。 逆に、ナロイングしてあるバッファの全体に働く必要があるEmacs Lisp関数もある。 たとえば、関数what-lineは、ナロイングが有効な場合にはそれを無効にし、 処理を終了するともとのようにナロイングする。 一方で、what-lineからも呼ばれる関数count-linesでは、 ナロイングを用いてバッファの操作範囲を限定し、終了するときにもとに戻す。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

6.1 スペシャルフォームsave-restriction

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=eintro&node=save-restriction"
"intro/スペシャルフォーム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の本体は、1つ以上の式であり、 Lispインタープリタが順番に評価する。

save-excursionsave-restrictionを続けて使う場合には、 save-excursionは外側で使うべきである。 逆順に使うと、save-excursionを呼んでEmacsが切り替えたバッファの ナロイングを記録し損なうことがある。 つまり、save-excursionsave-restrictionとを一緒に使う場合には、 つぎのように書く。

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



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

6.2 what-line

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=eintro&node=what-line"
"intro/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)))))))

関数には、予想どおり、説明文とinteractive式がある。 続く2つの行では関数save-restrictionwidenを使っている。

スペシャルフォームsave-restrictionは、 カレントバッファに設定されているナロイングを記録し、 save-restrictionの本体のコードを評価したあと、 記録したナロイングを復元する。

スペシャルフォームsave-restrictionに続いて、widenがある。 この関数は、what-lineが呼ばれたときにカレントバッファに設定されている ナロイングを無効にする (このナロイングはsave-restrictionが記録している)。 このワイドニングにより、バッファの先頭から行数を数えられるようになる。 さもないと、参照可能なリージョン内に制限されてしまう。 設定されていたもとのナロイングは、 スペシャルフォームsave-restrictionを終了する直前に復元される。

widenの呼び出しに続いて、save-excursionがあり、 カーソル(つまり、ポイント)とマークの位置を記録し、 save-excursionの本体のコードでポイントを移動する 関数beginning-of-lineを呼んだあとにそれらを復元する。

(式(widen)は、save-restrictionsave-excursionのあいだに ある。 2つのsave- ...式を続けて順に書く場合には、 save-excursionを外側にすること。)

関数what-lineの最後の2行で、バッファの行数を数えて、 エコー領域にその数を表示する。

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

関数messageはEmacsの画面の最下行に1行のメッセージを表示する。 第1引数は二重引用符のあいだにあり、文字列として表示される。 ただし、この文字列には、これに続く引数を表示するための `%d'や`%s'や`%c'が含まれてもよい。 `%d'は、引数を10進数で表示するので、 メッセージは`Line 243'のようになる。

`%d'のかわりに表示される数は、関数のつぎの行で計算される。

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

このコードは、1で示されるバッファの先頭から(point)までの 行数を数え、それに1を加える (関数1+は、引数に1を加える)。 1を加えるのは、たとえば、2番目の行のまえには1行しかないからであり、 count-linesは現在行の直前までの行数を数える。

count-linesが処理を終了するとエコー領域にメッセージが表示され、 save-excursionがポイントとマークの位置をもとに戻す。 さらに、save-restrictionはもとのナロイングの設定を復元する。



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

6.3 ナロイングの演習問題

URL="https://bookshelf.jp/cgi-bin/goto.cgi?file=eintro&node=narrow%20Exercise"
"intro/ナロイングの演習問題"へのコメント(無し)

バッファの後半にナロイングしていて最初の行を参照できないような場合であっても、 カレントバッファの最初の60文字を表示する関数を書いてみよ。 これには、save-restrictionwidengoto-charpoint-minbuffer-substringmessageを始め、 さまざまな関数をポプリのように混ぜ合わせて使う必要がある。


[ << ] [ >> ]           [表紙] [目次] [索引] [検索] [上端 / 下端] [?]