これは、新たにファイルを作成するときに、そのファイル名に対応した適切なテンプレートファイルを挿入してくれるものです。 もともと Emacs に附属しています。 Emacs Lisp で書かれたファイルでおなじみの GPL なんかも自動で挿入してくれるので、大変便利です。
以下 Emacs 19.34 のもので解説しますが、どうも 19.28 の頃から機能アップしているみたいで、neumann の人はちょっとアレかもしれません。 もっとも、自分でテンプレートを書こうとかいう人もあまりいないでしょうから、普通に使う分には関係ないでしょう。
.emacsに
(add-hook 'find-file-hooks 'auto-insert) (setq auto-insert-directory "~/lisp/insert/")
などと書いておくだけです。新たにファイルを読み込むと auto-insert-alist という変数で指定されているファイル名やモードに該当する場合は、例えば
Peform Emacs Lisp header auto-insertion? (y or n)
等と聞いてくるので、ここで y と答えると、さっきの auto-insert-alist という変数に従って、ファイル名に対するファイルを auto-insert-directory の下から探して、その内容をバッファに挿入します。
デフォルトでもかなり沢山のテプレートファイル名が対応しています。 これは実際に、C-h v auto-insert-alist などとやれば分かります。 動作をカスタマイズするには、一旦 autoinsert.el(c) を load しておいてから auto-insert-alist を書き換えればいいでしょう。
(load "autoinsert")
(setq auto-insert-alist
(append '(
("\\.txt" . "text-insert.txt")
) auto-insert-alist))
この場合、
("\\.txt" . "text-insert.txt")
の部分には
(CONDITION . ACTION) ((CONDITION . DESCRIPTION) . ACTION)
という二種類の書き方があります。各要素の内容は次の通り。
例えば .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 と答えると上のファイルの内容が挿入されます。
単にテンプレートの内容を挿入するだけではなく、もっと複雑な動作をさせようとする場合は、真面目に関数を書くのも良いですが、 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 のソースを見た方が早いかもしれません。
ということで詳しい動作の説明は省略して次の節の例を使った説明だけにとどめておきます。
(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.chiba.ac.jp> (defconst yubin-version "$Id: autoinsert.html,v 1.5 2006/01/15 13:34:41 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 のデフォルトのものを適当に変更したやつです。