これは、新たにファイルを作成するときに、そのファイル名に対応した適切な テンプレートファイルを挿入してくれるものです。もともと 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.nantoka.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 のデフォルト のものを適当に変更したやつです。