*** empty log message ***
[bpt/emacs.git] / lisp / autoinsert.el
CommitLineData
c0274f38 1;;; autoinsert.el --- automatic mode-dependent insertion of text into new files
b578f267 2
a461758e 3;; Copyright (C) 1985, 86, 87, 94, 95, 98, 2000 Free Software Foundation, Inc.
9750e079 4
e5167999 5;; Author: Charlie Martin <crm@cs.duke.edu>
3e910376 6;; Adapted-By: Daniel Pfeiffer <occitan@esperanto.org>
f5f727f8 7;; Keywords: convenience
4228277d 8;; Maintainer: FSF
b1d6ae0b
JB
9
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
e5167999 14;; the Free Software Foundation; either version 2, or (at your option)
b1d6ae0b
JB
15;; any later version.
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
b578f267
EN
23;; along with GNU Emacs; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25;; Boston, MA 02111-1307, USA.
b1d6ae0b 26
e5167999 27;;; Commentary:
b1d6ae0b 28
c11af8a5
KH
29;; The following defines an association list for text to be
30;; automatically inserted when a new file is created, and a function
31;; which automatically inserts these files; the idea is to insert
32;; default text much as the mode is automatically set using
33;; auto-mode-alist.
34;;
12394086 35;; To use:
c11af8a5
KH
36;; (add-hook 'find-file-hooks 'auto-insert)
37;; setq auto-insert-directory to an appropriate slash-terminated value
38;;
6c5b39e4
SE
39;; You can also customize the variable `auto-insert-mode' to load the
40;; package. Alternatively, add the following to your .emacs file:
41;; (auto-insert-mode 1)
42;;
c11af8a5
KH
43;; Author: Charlie Martin
44;; Department of Computer Science and
45;; National Biomedical Simulation Resource
46;; Box 3709
47;; Duke University Medical Center
48;; Durham, NC 27710
12394086 49;; (crm@cs.duke.edu,mcnc!duke!crm)
b1d6ae0b 50
e5167999
ER
51;;; Code:
52
6c5b39e4
SE
53(defgroup auto-insert nil
54 "Automatic mode-dependent insertion of text into new files."
55 :prefix "auto-insert-"
f5f727f8
DN
56 :group 'files
57 :group 'convenience)
6c5b39e4
SE
58
59
6c5b39e4 60(defcustom auto-insert 'not-modified
12394086
DL
61 "*Controls automatic insertion into newly found empty files.
62Possible values:
c11af8a5
KH
63 nil do nothing
64 t insert if possible
65 other insert if possible, but mark as unmodified.
66Insertion is possible when something appropriate is found in
67`auto-insert-alist'. When the insertion is marked as unmodified, you can
68save it with \\[write-file] RET.
a461758e 69This variable is used when the function `auto-insert' is called, e.g.
c11af8a5 70when you do (add-hook 'find-file-hooks 'auto-insert).
12394086 71With \\[auto-insert], this is always treated as if it were t."
4605a50d
DL
72 :type '(choice (const :tag "Insert if possible" t)
73 (const :tag "Do nothing" nil)
12394086 74 (other :tag "insert if possible, mark as unmodified."
4605a50d 75 not-modified))
6c5b39e4 76 :group 'auto-insert)
c11af8a5 77
6c5b39e4 78(defcustom auto-insert-query 'function
12394086 79 "*Non-nil means ask user before auto-inserting.
6c5b39e4 80When this is `function', only ask when called non-interactively."
5c213454
AS
81 :type '(choice (const :tag "Don't ask" nil)
82 (const :tag "Ask if called non-interactively" function)
83 (other :tag "Ask" t))
6c5b39e4 84 :group 'auto-insert)
c11af8a5 85
6c5b39e4 86(defcustom auto-insert-prompt "Perform %s auto-insertion? "
c11af8a5 87 "*Prompt to use when querying whether to auto-insert.
6c5b39e4
SE
88If this contains a %s, that will be replaced by the matching rule."
89 :type 'string
90 :group 'auto-insert)
c11af8a5
KH
91
92
6c5b39e4 93(defcustom auto-insert-alist
c11af8a5
KH
94 '((("\\.\\([Hh]\\|hh\\|hpp\\)\\'" . "C / C++ header")
95 (upcase (concat (file-name-nondirectory
96 (substring buffer-file-name 0 (match-beginning 0)))
97 "_"
98 (substring buffer-file-name (1+ (match-beginning 0)))))
99 "#ifndef " str \n
100 "#define " str "\n\n"
101 _ "\n\n#endif")
102
103 (("\\.\\([Cc]\\|cc\\|cpp\\)\\'" . "C / C++ program")
104 nil
105 "#include \""
106 ;; nop without latest cc-mode
107 (and (fboundp 'c-companion-file)
108 ;(file-readable-p (c-companion-file 'name))
109 (file-name-nondirectory (c-companion-file 'name))) & ?\"
110 | -10)
111
112 ("[Mm]akefile\\'" . "makefile.inc")
113
d60ae75c 114 (html-mode . (lambda () (sgml-tag "html")))
c11af8a5
KH
115
116 (plain-tex-mode . "tex-insert.tex")
117 (bibtex-mode . "tex-insert.tex")
118 (latex-mode
119 ;; should try to offer completing read for these
120 "options, RET: "
47e58cf5 121 "\\documentclass[" str & ?\] | -1
c11af8a5
KH
122 ?{ (read-string "class: ") "}\n"
123 ("package, %s: "
124 "\\usepackage[" (read-string "options, RET: ") & ?\] | -1 ?{ str "}\n")
125 _ "\n\\begin{document}\n" _
126 "\n\\end{document}")
127
128 (("/bin/.*[^/]\\'" . "Shell-Script mode magic number")
129 lambda ()
130 (if (eq major-mode default-major-mode)
131 (sh-mode)))
132
133 (ada-mode . ada-header)
134
135 (("\\.el\\'" . "Emacs Lisp header")
136 "Short description: "
137 ";;; " (file-name-nondirectory (buffer-file-name)) " --- " str "
138
a461758e 139;; Copyright (C) " (substring (current-time-string) -4) " "
c11af8a5
KH
140 (getenv "ORGANIZATION") | "Free Software Foundation, Inc." "
141
142;; Author: " (user-full-name)
a461758e 143'(if (search-backward "&" (line-beginning-position) t)
c11af8a5 144 (replace-match (capitalize (user-login-name)) t t))
c5f7d536 145'(end-of-line 1) " <" (progn user-mail-address) ">
c11af8a5
KH
146;; Keywords: "
147 '(require 'finder)
148 ;;'(setq v1 (apply 'vector (mapcar 'car finder-known-keywords)))
149 '(setq v1 (mapcar (lambda (x) (list (symbol-name (car x))))
150 finder-known-keywords)
151 v2 (mapconcat (lambda (x) (format "%10.0s: %s" (car x) (cdr x)))
152 finder-known-keywords
153 "\n"))
154 ((let ((minibuffer-help-form v2))
155 (completing-read "Keyword, C-h: " v1 nil t))
156 str ", ") & -2 "
157
c5178e8e 158;; This file is free software; you can redistribute it and/or modify
c11af8a5
KH
159;; it under the terms of the GNU General Public License as published by
160;; the Free Software Foundation; either version 2, or (at your option)
161;; any later version.
162
c5178e8e 163;; This file is distributed in the hope that it will be useful,
c11af8a5
KH
164;; but WITHOUT ANY WARRANTY; without even the implied warranty of
165;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
166;; GNU General Public License for more details.
167
168;; You should have received a copy of the GNU General Public License
169;; along with GNU Emacs; see the file COPYING. If not, write to
01bb7524
EN
170;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
171;; Boston, MA 02111-1307, USA.
c11af8a5
KH
172
173;;; Commentary:
174
175;; " _ "
176
177;;; Code:
178
179
180
181;;; " (file-name-nondirectory (buffer-file-name)) " ends here"))
b1d6ae0b 182 "A list specifying text to insert by default into a new file.
c11af8a5
KH
183Elements look like (CONDITION . ACTION) or ((CONDITION . DESCRIPTION) . ACTION).
184CONDITION maybe a regexp that must match the new file's name, or it may be
185a symbol that must match the major mode for this element to apply.
186Only the first matching element is effective.
187Optional DESCRIPTION is a string for filling `auto-insert-prompt'.
188ACTION may be a skeleton to insert (see `skeleton-insert'), an absolute
189file-name or one relative to `auto-insert-directory' or a function to call.
190ACTION may also be a vector containing several successive single actions as
6c5b39e4
SE
191described above, e.g. [\"header.insert\" date-and-author-update]."
192 :type 'sexp
193 :group 'auto-insert)
b1d6ae0b 194
c11af8a5
KH
195
196;; Establish a default value for auto-insert-directory
6c5b39e4
SE
197(defcustom auto-insert-directory "~/insert/"
198 "*Directory from which auto-inserted files are taken."
199 :type 'directory
200 :group 'auto-insert)
b1d6ae0b 201
c11af8a5
KH
202
203;;;###autoload
204(defun auto-insert ()
a461758e 205 "Insert default contents into new files if variable `auto-insert' is non-nil.
b1d6ae0b 206Matches the visited file name against the elements of `auto-insert-alist'."
c11af8a5
KH
207 (interactive)
208 (and (not buffer-read-only)
209 (or (eq this-command 'auto-insert)
210 (and auto-insert
211 (bobp) (eobp)))
212 (let ((alist auto-insert-alist)
213 case-fold-search cond desc action)
214 (goto-char 1)
215 ;; find first matching alist entry
216 (while alist
217 (if (atom (setq cond (car (car alist))))
218 (setq desc cond)
219 (setq desc (cdr cond)
220 cond (car cond)))
221 (if (if (symbolp cond)
222 (eq cond major-mode)
a461758e
DL
223 (and buffer-file-name
224 (string-match cond buffer-file-name)))
c11af8a5
KH
225 (setq action (cdr (car alist))
226 alist nil)
227 (setq alist (cdr alist))))
228
229 ;; Now, if we found something, do it
230 (and action
231 (if (stringp action)
232 (file-readable-p (concat auto-insert-directory action))
233 t)
234 (if auto-insert-query
235 (or (if (eq auto-insert-query 'function)
236 (eq this-command 'auto-insert))
237 (y-or-n-p (format auto-insert-prompt desc)))
238 t)
239 (mapcar
240 (lambda (action)
241 (if (stringp action)
242 (if (file-readable-p
243 (setq action (concat auto-insert-directory action)))
244 (insert-file-contents action))
245 (save-window-excursion
246 ;; make buffer visible before skeleton or function
247 ;; which might ask the user for something
248 (switch-to-buffer (current-buffer))
249 (if (and (consp action)
250 (not (eq (car action) 'lambda)))
251 (skeleton-insert action)
252 (funcall action)))))
253 (if (vectorp action)
254 action
255 (vector action))))
256 (and (buffer-modified-p)
257 (not (eq this-command 'auto-insert))
12394086
DL
258 (set-buffer-modified-p (eq auto-insert t)))))
259 ;; Return nil so that it could be used in
260 ;; `find-file-not-found-hooks', though that's probably inadvisable.
261 nil)
c11af8a5
KH
262
263
264;;;###autoload
4605a50d 265(defun define-auto-insert (condition action &optional after)
c11af8a5
KH
266 "Associate CONDITION with (additional) ACTION in `auto-insert-alist'.
267Optional AFTER means to insert action after all existing actions for CONDITION,
268or if CONDITION had no actions, after all other CONDITIONs."
4605a50d 269 (let ((elt (assoc condition auto-insert-alist)))
c11af8a5
KH
270 (if elt
271 (setcdr elt
272 (if (vectorp (cdr elt))
273 (vconcat (if after (cdr elt))
274 (if (vectorp action) action (vector action))
275 (if after () (cdr elt)))
276 (if after
277 (vector (cdr elt) action)
278 (vector action (cdr elt)))))
279 (if after
4605a50d
DL
280 (nconc auto-insert-alist (list (cons condition action)))
281 (setq auto-insert-alist (cons (cons condition action)
c11af8a5 282 auto-insert-alist))))))
c0274f38 283
6c5b39e4 284;;;###autoload
bff6da3d 285(define-minor-mode auto-insert-mode
12394086
DL
286 "Toggle Auto-insert mode.
287With prefix ARG, turn Auto-insert mode on if and only if ARG is positive.
288Returns the new status of Auto-insert mode (non-nil means on).
6c5b39e4 289
12394086 290When Auto-insert mode is enabled, when new files are created you can
6c5b39e4 291insert a template for the file depending on the mode of the buffer."
44e70da2 292 :global t :group 'auto-insert
bff6da3d
SM
293 (if auto-insert-mode
294 (add-hook 'find-file-hooks 'auto-insert)
295 (remove-hook 'find-file-hooks 'auto-insert)))
6c5b39e4 296
896546cd
RS
297(provide 'autoinsert)
298
c0274f38 299;;; autoinsert.el ends here