xyzzyのページの概念

コメントで教えてもらったのがチョット面白かったので、適当に調べてみた。話

■問題のpage

C-x ]               forward-page
C-x [               backward-page

これの中身を見ると、両方とも本当は同じもので、唯進む向きが違う風になっていて、そのコードはこんな感じ。

(defun forward-page (&optional (arg 1))
  (interactive "p")
  (if (plusp arg)
      (dotimes (x arg)
	(unless (scan-buffer page-delimiter :regexp t :no-dup t)
	  (goto-char (point-max))
	  (return)))
    (dotimes (x (- arg))
      (unless (scan-buffer page-delimiter :regexp t :no-dup t :reverse t)
	(goto-char (point-min))
	(return))))
  t)

結局中身を見ると

page-delimiter

をスキャンしてるだけなんだけど。

■page-delimiterとは何か
page-delimiterの中身を調べてみると

page-delimiter
=>^L

C-Lが入っている。これがxyzzyでのページ区切りらしい。

■^Lの入力の仕方
 xyzzyでは標準のキー設定ならC-qで色々入力できるのはお馴染みの方法*1なのでソレを使って

C-q C-L

これで

^L

が入力できる。ちょっと色が違う文字で表示されたら上手くできてる。

■^Lの違う表記
後はEmacsのマニュアルによると

変数page-delimiterの値は,ページを分ける行の先頭を表す正規表現です.これはページの始まりを定義します.通常この変数の値は "^\fで,行の先頭の改ページ文字を表します.

xyzzyだと^\fなんて入ってなくてそのまま^Lが入っているような気がするんだけどコレは何か影響があるんだろうかとか思ってたけど色々試してみたら、Emacsと同じだった。具体的には

(format nil "\f")
=>"^L"

"\f"で"^L"を表記できる。

(or (boundp 'page-delimiter)
    (setq page-delimiter "^\f"))

■ページの機能
 ページを区切りに出来ると何が嬉しいかとか。

  • ページ単位での移動

まず、先に書いた"C-x ["とかで、ページを移動できるというのがあるんだけど、後は印刷とかする時にも嬉しい感じ。

  • ページのマーク
C-x C-p     現在の(または別のページの)まわりにポイントとマークを置きます (mark-page).
  • ページ数のカウント
C-x l    現在のページの行数を数えます(count-lines-page).
  • ページの印刷

 "^L"を入力した状態で印刷すると^Lの所でまだ設定した用紙のサイズ的に余白があって印刷できるとしても、次の紙にしてくれる様子*2

■参考
GNU Emacs Manual - Pages
http://flex.ee.uec.ac.jp/texi/emacs-jp/emacs-jp_118.html
GNU text utilities: 文字の処理
http://www.bookshelf.jp/texi/textutils/textutils-ja_9.html#SEC39

■ちょっと気になるのは
コードに"^L"が入ってしまっても問題ないのかとか。で、ちょっと検索したらPythonだとこんな風になってるらしい。

    Pythonは、改行文字からControl-L(すなわち^L)を、ホワイトスペースとし
    て扱う。Emacs(および、いくつかの印刷機器)はこれを改ページとして扱
    うので、ファイル内部で関連する部分ごとにページを分けるために、これら
    の文字を使うことができる。

PEP 8 -- Style Guide for Python Code
http://www.oldriver.org/python/pep-0008j.html

JavaScriptでも置換とかには普通に文字列の所に
正規表現RegExp
http://www.tohoho-web.com/js/regexp.htm

Cの場合
GNUコーディング・スタンダード: Cの一番良い使い方
http://www.bookshelf.jp/texi/standards/standards-ja_5.html

■肝心のlispの場合
何となくlispもCと同じく"^L"のみなら出来そうな気がしてきたので適当に^Lを入れてみたりして試してる所。後で結果を追記する予定。

■追記
今見てたら佐野さんの所でも言及してもらってて、lispでも案の定"^L"で使えるらしい。多分Cと殆ど同じような感じで良さそうな雰囲気。その他役に立ちそうだと思ったメモ

* 改ページの使用例で覚えているもの
o プログラムのソースに書かれているのは、ごくまれに見たことがあるなぁ。
o xyzzy ML の過去ログを読んでいれば遭遇するけど、なかださんがパッチと本文の区切りとして使っていたりする。(xyzzy:08621とか)

http://raido.sakura.ne.jp/southly/rn/index.rb?1208017073.txt

http://www.geocities.co.jp/SiliconValley-Bay/9285/EMACS-JA/emacs_444.html
ローカル変数リストを書くという慣習がemacs(のもちろん一部)にはあって、
リストの探索範囲を制限するためにはページデリミタを入れないとねー
という話があるらし。
長いソースの場合はローカル変数リストがいらなくてもページデリミタで終わっときましょ…と

*1:c-modeとか結構メジャーなモードでTab入力が直接は出来なくなっているのでTabを"C-q Tab"で入力したりする事は偶に在ると思う。

*2:実際には試してないけど、プレビューを見る限りそういう風になってるのでそうだろうと