テキストに行番号をつける。
といっても、Emacsの表示上行番号がつくのではなく、テキ スト内に行番号を埋め込むものです。
これは実はずっと欲しかった機能で、探せばあったのかも知れないけ れど探すゆとりも気力もなく今日に至り、どうしても必要になったので 急いで書きました。
M-x linum <RET>
と実行すると、
Format string?:
Start number?:
Step?:
と聞いてきます。
format
関数の書式文字列を与えます。たとえば、
%3d:
"
%04d
"
%-3d|
"
C-u M-x linum <RET>
とすると、バッファ全体に行番号を挿入します。
例によってエラーや例外の処理は甘ちゃんです。
行頭に文字列を挿入するのは、
beginning-of-line
)
でできます。行番号は変化するので整数として保持し、その都度
format
関数で文字列化して挿入します。
format
の第一引数は書式文字列ですが、先にキーボード
から入力した文字列をそのまま使います。
プログラムとしては、
というものになります。ここで、当初はリージョンの終わり数行に行番 号がつかないという問題がありました。どうやら行番号文字列を挿入し た分、リージョン末尾の値が実際とずれていることによるようでした。 これを解消するため、挿入した文字列の長さを終了位置に加算していま す。これはスマートな、あるいは根源的な解決法とは思えません。もっ と適切な方法があると思うのですが、いかんせん今手許にEmacs Lispの マニュアルがないので第一版はこれでよしとします。
ひととおり出来上がってから悪戯っ気が出てきて、前置引数がある場 合(かつそれが1でない場合)、バッファ全体に行番号を挿入するよう にしました。これ自体は、開始位置と終了位置に、リージョンの先頭と 末尾でなくバッファの先頭と末尾を与えるようにすればいいだけです。 ただ、前置引数の取扱いに関してはまだまだ知見が足りず、ヘンなこと をしているかも知れません。
1: (defun linum (whole) 2: "insert line number at each line in region from START NUMVER by STEP." 3: (interactive "p") 4: ; (1以外の)前置引数があったら、wholeをtに 5: (if (not (numberp whole)) (setq whole 0)) 6: (if (= whole 1) (setq whole nil) 7: (setq whole t)) 8: 9: (let ((fmtstr) 10: (number) 11: (step) 12: (insstr) 13: (rb (region-beginning)) 14: (re (region-end)) 15: ) 16: (setq fmtstr (read-input "Format string?: ")) 17: (setq number (string-to-number (read-input "Start number?: "))) 18: (setq step (string-to-number (read-input "Step?: "))) 19: (if (< step 1) (setq step 1)) 20: 21: ; wholeがtなら、バッファ全体を対象とする 22: ; そうでなければリージョンを対象とする 23: (if (eq whole t) 24: (let () 25: (setq rb (point-min)) 26: (setq re (point-max))) 27: (let () 28: (setq rb (region-beginning)) 29: (setq re (region-end)))) 30: 31: (save-excursion 32: (let () 33: (goto-char rb) 34: (while (< (point) re) 35: (beginning-of-line) 36: (setq insstr (format fmtstr number)) 37: (insert insstr) 38: (setq re (+ re (string-width insstr))) 39: (setq number (+ number step)) 40: (forward-line 1) 41: ) 42: ) 43: )) 44: )
テキストファイルを相手に行番号を振るのならAwkの一行野郎で片が つきますが、ファイルの一部分に振りたい場合――プログラムのコード 片など――には向きません。エディタの中でできた方が気持がいいと思 います。長年の懸案が解消されたのでうれしいです。
最初は、もとテキストを変更するのがイヤなこともあるだろうから行 番号がついたテキストを別バッファに置くことを考えていました。でも、 どうせリージョンが対象になるのなら、リージョンを別のバッファにコ ピー&ペーストして行番号を振ればいいわけです。それは手作業でもで きるでしょうし、このコマンドをラップするようなコマンドを書いても いいでしょう。ということで、別バッファは諦め、代わりに(?)バッ ファ全体に行番号をつける機能を加えてひとまず終了としました。
(2003.03.28)
(C) ©Copyright Noboru HIWAMATA (nulpleno). All rights reserved.