*** 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
bf9f5c17 3;; Copyright (C) 1985, 86, 87, 94, 95, 98, 2000, 03 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 \""
f6ec1532
RS
106 (let ((stem (file-name-sans-extension buffer-file-name)))
107 (cond ((file-exists-p (concat stem ".h"))
108 (file-name-nondirectory (concat stem ".h")))
109 ((file-exists-p (concat stem ".hh"))
110 (file-name-nondirectory (concat stem ".hh")))))
111 & ?\" | -10)
112
113 (("[Mm]akefile\\'" . "Makefile") . "makefile.inc")
c11af8a5 114
d60ae75c 115 (html-mode . (lambda () (sgml-tag "html")))
71296446 116
c11af8a5
KH
117 (plain-tex-mode . "tex-insert.tex")
118 (bibtex-mode . "tex-insert.tex")
119 (latex-mode
120 ;; should try to offer completing read for these
121 "options, RET: "
47e58cf5 122 "\\documentclass[" str & ?\] | -1
c11af8a5
KH
123 ?{ (read-string "class: ") "}\n"
124 ("package, %s: "
125 "\\usepackage[" (read-string "options, RET: ") & ?\] | -1 ?{ str "}\n")
126 _ "\n\\begin{document}\n" _
127 "\n\\end{document}")
128
129 (("/bin/.*[^/]\\'" . "Shell-Script mode magic number")
130 lambda ()
131 (if (eq major-mode default-major-mode)
132 (sh-mode)))
71296446 133
c11af8a5
KH
134 (ada-mode . ada-header)
135
bf9f5c17
DL
136 (("\\.[1-9]\\'" . "Man page skeleton")
137 "Short description: "
138 ".\\\" Copyright (C), " (substring (current-time-string) -4) " "
139 (getenv "ORGANIZATION") | "Free Software Foundation, Inc."
140 "
141.\\\" You may distribute this file under the terms of the GNU Free
142.\\\" Documentation Licence.
143.TH " (file-name-sans-extension (file-name-nondirectory (buffer-file-name)))
144 " " (file-name-extension (buffer-file-name))
145 " " (format-time-string "%Y-%m-%d ")
146 "\n.SH NAME\n"
147 (file-name-sans-extension (file-name-nondirectory (buffer-file-name)))
148 " \\- " str
149 "\n.SH SYNOPSIS
150.B " (file-name-sans-extension (file-name-nondirectory (buffer-file-name)))
151 "\n"
152 _
153 "
154.SH DESCRIPTION
155.SH OPTIONS
156.SH FILES
157.SH \"SEE ALSO\"
158.SH BUGS
159.SH AUTHOR
160" (user-full-name)
161 '(if (search-backward "&" (line-beginning-position) t)
162 (replace-match (capitalize (user-login-name)) t t))
163 '(end-of-line 1) " <" (progn user-mail-address) ">\n")
164
c11af8a5
KH
165 (("\\.el\\'" . "Emacs Lisp header")
166 "Short description: "
167 ";;; " (file-name-nondirectory (buffer-file-name)) " --- " str "
168
2103c9fb 169;; Copyright (C) " (substring (current-time-string) -4) " "
c11af8a5
KH
170 (getenv "ORGANIZATION") | "Free Software Foundation, Inc." "
171
172;; Author: " (user-full-name)
a461758e 173'(if (search-backward "&" (line-beginning-position) t)
c11af8a5 174 (replace-match (capitalize (user-login-name)) t t))
c5f7d536 175'(end-of-line 1) " <" (progn user-mail-address) ">
c11af8a5
KH
176;; Keywords: "
177 '(require 'finder)
178 ;;'(setq v1 (apply 'vector (mapcar 'car finder-known-keywords)))
179 '(setq v1 (mapcar (lambda (x) (list (symbol-name (car x))))
180 finder-known-keywords)
181 v2 (mapconcat (lambda (x) (format "%10.0s: %s" (car x) (cdr x)))
182 finder-known-keywords
183 "\n"))
184 ((let ((minibuffer-help-form v2))
185 (completing-read "Keyword, C-h: " v1 nil t))
186 str ", ") & -2 "
187
c5178e8e 188;; This file is free software; you can redistribute it and/or modify
c11af8a5
KH
189;; it under the terms of the GNU General Public License as published by
190;; the Free Software Foundation; either version 2, or (at your option)
191;; any later version.
192
c5178e8e 193;; This file is distributed in the hope that it will be useful,
c11af8a5
KH
194;; but WITHOUT ANY WARRANTY; without even the implied warranty of
195;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
196;; GNU General Public License for more details.
197
198;; You should have received a copy of the GNU General Public License
199;; along with GNU Emacs; see the file COPYING. If not, write to
01bb7524
EN
200;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
201;; Boston, MA 02111-1307, USA.
c11af8a5
KH
202
203;;; Commentary:
204
205;; " _ "
206
207;;; Code:
208
209
210
3c98b2e9
SM
211\(provide '"
212 (file-name-sans-extension (file-name-nondirectory (buffer-file-name)))
213 ")
2103c9fb 214;;; " (file-name-nondirectory (buffer-file-name)) " ends here\n"))
b1d6ae0b 215 "A list specifying text to insert by default into a new file.
c11af8a5
KH
216Elements look like (CONDITION . ACTION) or ((CONDITION . DESCRIPTION) . ACTION).
217CONDITION maybe a regexp that must match the new file's name, or it may be
218a symbol that must match the major mode for this element to apply.
219Only the first matching element is effective.
220Optional DESCRIPTION is a string for filling `auto-insert-prompt'.
221ACTION may be a skeleton to insert (see `skeleton-insert'), an absolute
222file-name or one relative to `auto-insert-directory' or a function to call.
223ACTION may also be a vector containing several successive single actions as
6c5b39e4
SE
224described above, e.g. [\"header.insert\" date-and-author-update]."
225 :type 'sexp
226 :group 'auto-insert)
b1d6ae0b 227
c11af8a5
KH
228
229;; Establish a default value for auto-insert-directory
6c5b39e4 230(defcustom auto-insert-directory "~/insert/"
66e0fd2b 231 "*Directory from which auto-inserted files are taken.
87810ca9
RS
232The value must be an absolute directory name;
233thus, on a GNU or Unix system, it must end in a slash."
6c5b39e4
SE
234 :type 'directory
235 :group 'auto-insert)
b1d6ae0b 236
c11af8a5
KH
237
238;;;###autoload
239(defun auto-insert ()
a461758e 240 "Insert default contents into new files if variable `auto-insert' is non-nil.
b1d6ae0b 241Matches the visited file name against the elements of `auto-insert-alist'."
c11af8a5
KH
242 (interactive)
243 (and (not buffer-read-only)
244 (or (eq this-command 'auto-insert)
245 (and auto-insert
246 (bobp) (eobp)))
247 (let ((alist auto-insert-alist)
248 case-fold-search cond desc action)
249 (goto-char 1)
250 ;; find first matching alist entry
251 (while alist
252 (if (atom (setq cond (car (car alist))))
253 (setq desc cond)
254 (setq desc (cdr cond)
255 cond (car cond)))
256 (if (if (symbolp cond)
257 (eq cond major-mode)
a461758e
DL
258 (and buffer-file-name
259 (string-match cond buffer-file-name)))
c11af8a5
KH
260 (setq action (cdr (car alist))
261 alist nil)
262 (setq alist (cdr alist))))
263
264 ;; Now, if we found something, do it
265 (and action
266 (if (stringp action)
267 (file-readable-p (concat auto-insert-directory action))
268 t)
269 (if auto-insert-query
270 (or (if (eq auto-insert-query 'function)
271 (eq this-command 'auto-insert))
272 (y-or-n-p (format auto-insert-prompt desc)))
273 t)
274 (mapcar
275 (lambda (action)
276 (if (stringp action)
277 (if (file-readable-p
278 (setq action (concat auto-insert-directory action)))
279 (insert-file-contents action))
280 (save-window-excursion
281 ;; make buffer visible before skeleton or function
282 ;; which might ask the user for something
283 (switch-to-buffer (current-buffer))
284 (if (and (consp action)
285 (not (eq (car action) 'lambda)))
286 (skeleton-insert action)
287 (funcall action)))))
288 (if (vectorp action)
289 action
290 (vector action))))
291 (and (buffer-modified-p)
292 (not (eq this-command 'auto-insert))
12394086
DL
293 (set-buffer-modified-p (eq auto-insert t)))))
294 ;; Return nil so that it could be used in
295 ;; `find-file-not-found-hooks', though that's probably inadvisable.
296 nil)
c11af8a5
KH
297
298
299;;;###autoload
4605a50d 300(defun define-auto-insert (condition action &optional after)
c11af8a5
KH
301 "Associate CONDITION with (additional) ACTION in `auto-insert-alist'.
302Optional AFTER means to insert action after all existing actions for CONDITION,
303or if CONDITION had no actions, after all other CONDITIONs."
4605a50d 304 (let ((elt (assoc condition auto-insert-alist)))
c11af8a5
KH
305 (if elt
306 (setcdr elt
307 (if (vectorp (cdr elt))
308 (vconcat (if after (cdr elt))
309 (if (vectorp action) action (vector action))
310 (if after () (cdr elt)))
311 (if after
312 (vector (cdr elt) action)
313 (vector action (cdr elt)))))
314 (if after
4605a50d
DL
315 (nconc auto-insert-alist (list (cons condition action)))
316 (setq auto-insert-alist (cons (cons condition action)
c11af8a5 317 auto-insert-alist))))))
c0274f38 318
6c5b39e4 319;;;###autoload
bff6da3d 320(define-minor-mode auto-insert-mode
12394086
DL
321 "Toggle Auto-insert mode.
322With prefix ARG, turn Auto-insert mode on if and only if ARG is positive.
323Returns the new status of Auto-insert mode (non-nil means on).
6c5b39e4 324
12394086 325When Auto-insert mode is enabled, when new files are created you can
6c5b39e4 326insert a template for the file depending on the mode of the buffer."
44e70da2 327 :global t :group 'auto-insert
bff6da3d
SM
328 (if auto-insert-mode
329 (add-hook 'find-file-hooks 'auto-insert)
330 (remove-hook 'find-file-hooks 'auto-insert)))
6c5b39e4 331
896546cd
RS
332(provide 'autoinsert)
333
ab5796a9 334;;; arch-tag: 5b6630ac-c735-43cf-b097-b78c622af909
c0274f38 335;;; autoinsert.el ends here