what-line ¶what-line コマンドは、カーソルが位置する行番号を表示します。この関数では、save-restriction および save-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)))))))
(GNU Emacsの最新バージョンでは、what-line
関数が拡張され、幅を狭めたバッファでの行番号だけでなく、幅を広げたバッファでの行番号も表示されるようになっています。最新バージョンは、ここで示しているバージョンよりも複雑です。挑戦してみたい方は、このバージョンの仕組みを理解した上で、確認してみるとよいでしょう。おそらく
C-h f (describe-function)
を使う必要があるでしょう。新しいバージョンでは、条件式を用いてバッファが狭められているかどうかを判定しています。)
また、what-line の現代版では line-number-at-pos が用いられており、(goto-char (point-min)) などの他の単純な表現と同様に、beginning-of-line ではなく (forward-line
0) でポイントを現在の行の先頭に移動させます。)
ここに示すwhat-line関数には、予想通りドキュメント行があり、インタラクティブです。続く2行では、save-restriction関数とwiden関数を使用しています。
save-restriction
特殊形式は、現在のバッファで適用されているナローイング(もしあれば)を記録し、save-restriction の本体内のコードが評価された後、そのナローイングを復元します。
特殊形式 save-restriction の後には widen が続きます。この関数は、what-line
が呼び出された際に現在のバッファに生じていた可能性のある狭めを解除します。(その狭めとは、save-restriction
が記憶している狭めのことです。)この広げ処理により、行数カウントコマンドがバッファの先頭からカウントできるようになります。そうでなければ、アクセス可能な範囲内でのカウントに限定されていたでしょう。元の狭めは、関数の終了直前に特殊形式
save-restriction によって復元されます。
widen への呼び出しに続いて save-excursion が呼び出され、これによりカーソル(すなわちポイント)の位置が保存され、save-excursion の本体内のコードが beginning-of-line 関数を用いてポイントを移動させた後にその位置が復元されます。
(なお、(widen) 式は save-restriction と save-excursion の特殊形式の間に配置されます。2つの save- … 式を連続して記述する場合は、save-excursion を最外層に記述してください。)
what-line
関数の最後の2行は、バッファ内の行数をカウントし、その数値をエコーエリアに出力するための関数です。
(message "Line %d"
(1+ (count-lines 1 (point)))))))
message 関数は、Emacs
画面の下部に1行のメッセージを出力します。第1引数は引用符で囲まれ、文字列として出力されます。ただし、後続の引数を出力するための
‘%d’ 式を含めることができます。‘%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 は(もしあれば)元の幅制限を復元します。