これは、新たにファイルを作成するときに、そのファイル名に対応した適切な テンプレートファイルを挿入してくれるものです。また、もっと高度なこともできます。 もともと Emacs に附属しています。 Emacs Lisp で書かれたファイルでおなじみの GPL なんかも自動で挿入してくれるので、 ある程度定型的な文書を多く書く人には大変便利です。
まずは .emacs.elに
(add-hook 'find-file-hooks 'auto-insert) (setq auto-insert-directory "~/lisp/insert/")
などと書いておきます。 2行目は、テンプレートファイルを置く場所を指定します。 そうして、次の節で説明するように、特定のモードやファイル名に対してテンプレートを指定することで、それらを自動挿入することができます。
単なるテンプレート挿入と違うのは、対話的に挿入する文字列を制御することができる点です。 例えばデフォルトの状態であれば、emacs-lisp のファイルを新規に開こうとすると、
Peform Emacs Lisp header auto-insertion? (y or n)
等と聞いてくるので、ここで y と答えると、さっ きの auto-insert-alist という変数に従って、ファイル名に対す るファイルを auto-insert-directory の下から探して、その内容 をバッファに挿入します。
動作をカスタマイズするには、auto-insert-alist を書き換えたり、
define-auto-insert という関数を使ったりします。
これは次の節でもう少し詳しく説明します。
.emacs.el などで、次のように設定します。
(setq auto-insert-alist
(append '(
("\\.txt" . "text-insert.txt")
) auto-insert-alist))
この場合、
("\\\\.txt" . "text-insert.txt")
の部分は
(CONDITION . ACTION) ((CONDITION . DESCRIPTION) . ACTION)
という二種類の書き方があります。各要素の内容は次の通り。
単にテンプレートの内容を挿入するだけではなく、もっと複雑な動作をさせようとする 場合は、真面目に関数を書くのも良いですが、ACTION に skeleton を利用すると良い です。これを使うと、ファイル名や対話的に入力した情報を使ったテンプレート挿入が 可能になります。
skeleton の構造は、(INTERACTOR ELEMENT1 ELEMENT2 ...) という感じに なっています。それぞれの内容は次の通り。
関数は、普通に書くとその値を該当箇所に挿入するのですが、quote すると副 作用のみを実行します。また、制御要素には、次のようなものが用意されています。
| n | 改行して、そのモードに合わせてインデント。 |
| _ | 終了時のカーソル位置? |
| > | メジャーモードに合わせてインデント |
| & | 直前の ELEMENT でポイントが移動すれば、次の ELEMENT を実行 |
| | | 直前の ELEMENT でポイントが移動しなければ、次の ELEMENT を実行 |
| -n | n個の直前の文字を削除 |
| resume: | skipped, continue here if quit is signaled |
| nil | skipped |
関数を書くときなど、複数の ELEMENT で共通に使いたい変数は単純に
let で局所変数にすることはできないので、
次のようにいくつかの変数があらかじめ定められています。
| str | 最初に出てきたものは、INTERACTOR で読み込んだ文字列。次回からは直前に 読み込んだ文字列 |
| help | ユーザーとの対話での help-form ないしは nil |
| input | str を読み込む時の初期文字列 |
| v1,v2 | その他のものを記憶させたい場合に使う変数 |
入れ子になった場合などの動作の仕方はヘルプを読んでも良く分からないんですが
(^^; 興味のある人は、関数 skeleton-insert
のソースを見た方が早いかもしれません。ということで詳しい動作の説明は省略して、
次の節の例を使った説明だけにとどめておきます。
例えば .emacs に
(add-hook 'find-file-hooks 'auto-insert)
(setq auto-insert-directory "~/lisp/insert/")
(setq auto-insert-alist
(append '(
(yatex-mode . "latex-insert.tex")
) auto-insert-alist))
と書いて、~/lisp/insert/latex-insert.tex として、
次のようなファイルを用意しておいたとします。
%#!platex % author: Matsuda Shigeki %%% Local Variables: %%% mode:outline-minor %%% End:
また、拡張子が tex のファイルを読み込んだ時には
yatex-modeが適用されるものとします。すると、
新規に new.tex というファイルを読み込んだ場合、
Perform yatex-mode auto-insertion? (y or n)
と聞いてきますので、y と答えると上のファイル の内容が挿入されます。
(setq auto-insert-alist
(append
'(
(("\\\\.el\\\\'" . "Emacs Lisp header")
"Short description: "
";;; " (file-name-nondirectory (buffer-file-name)) " --- " str "
;; Copyright (C) " (substring (current-time-string) -4) " by Matsu " "
;; Author: Matsuda "
'(end-of-line 1) " <" (user-login-name) ?@ "math.s.chiba.ac.jp>
(defconst "
(substring (file-name-nondirectory (buffer-file-name)) 0 -3)
"-version \\"$Id: "
(file-name-nondirectory (buffer-file-name))
",v 1.1 "
'(require 'time-stamp)
(concat (time-stamp-yyyy/mm/dd) " " (time-stamp-hh:mm:ss))
" matsu Exp matsu $\\")" "
;; Keywords: "
'(require 'finder)
;;'(setq v1 (apply 'vector (mapcar 'car finder-known-keywords)))
'(setq v1 (mapcar (lambda (x) (list (symbol-name (car x))))
finder-known-keywords)
v2 (mapconcat (lambda (x) (format "%10.0s: %s" (car x) (cdr x)))
finder-known-keywords
"\\n"))
((let ((minibuffer-help-form v2))
(completing-read "Keyword, C-h: " v1 nil t))
str ", ") & -2 "
;;
;; This program is free software; you can redistribute it and/or modify
(中略)
;;; Commentary:
;; " _ "
;;; Code:
;;; " (file-name-nondirectory (buffer-file-name)) " ends here"))
auto-insert-alist))
これを使って、yubin.el というファイルを新し
く開いて最初に y と答えると、プロンプトで
Short description と keyword を聞いてきます。これに、
test, tools
と答えて、keyword のプロンプトで単に改行をタイプすると、最終的には次の
ようなテンプレートを挿入して、;;; Code: の二行上の所にカーソル
が来ます。
;;; yubin.el --- test ;; Copyright (C) 1998 by Matsu ;; Author: Matsuda <matsu@math.s.nantoka.ac.jp> (defconst yubin-version "$Id: autoinsert.html,v 1.8 2006/01/15 13:34:42 matsu Exp $") ;; Keywords: tools ;; ;; This program is free software; you can redistribute it and/or modify (中略) ;;; Commentary: ;; ;;; Code: ;;; yubin.el ends hereファイル名や時刻に応じて変化するテンプレートを挿入できるわけです。
例えば Emacs Lisp Mode で autoinsert を利用すると、デフォルトではヘッダの中に E-mail のアドレスが入ります。 もしこれが正しいものなら問題ないですが、自宅の計算機などの普段使っていない address が挿入されてしまう場合はカスタマイズが必要でしょう。 上の例も、元々 Emacs のデフォルトのものを適当に変更したやつです。