Convert consecutive FSF copyright years to ranges.
[bpt/emacs.git] / lisp / autoinsert.el
CommitLineData
c0274f38 1;;; autoinsert.el --- automatic mode-dependent insertion of text into new files
b578f267 2
73b0cd50 3;; Copyright (C) 1985-1987, 1994-1995, 1998, 2000-2011 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
eb3fa2cf 12;; GNU Emacs is free software: you can redistribute it and/or modify
b1d6ae0b 13;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
b1d6ae0b
JB
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
eb3fa2cf 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
b1d6ae0b 24
e5167999 25;;; Commentary:
b1d6ae0b 26
c11af8a5
KH
27;; The following defines an association list for text to be
28;; automatically inserted when a new file is created, and a function
29;; which automatically inserts these files; the idea is to insert
30;; default text much as the mode is automatically set using
31;; auto-mode-alist.
32;;
12394086 33;; To use:
a702ffbb 34;; (add-hook 'find-file-hook 'auto-insert)
c11af8a5
KH
35;; setq auto-insert-directory to an appropriate slash-terminated value
36;;
6c5b39e4
SE
37;; You can also customize the variable `auto-insert-mode' to load the
38;; package. Alternatively, add the following to your .emacs file:
39;; (auto-insert-mode 1)
40;;
c11af8a5
KH
41;; Author: Charlie Martin
42;; Department of Computer Science and
43;; National Biomedical Simulation Resource
44;; Box 3709
45;; Duke University Medical Center
46;; Durham, NC 27710
12394086 47;; (crm@cs.duke.edu,mcnc!duke!crm)
b1d6ae0b 48
e5167999
ER
49;;; Code:
50
6c5b39e4
SE
51(defgroup auto-insert nil
52 "Automatic mode-dependent insertion of text into new files."
53 :prefix "auto-insert-"
f5f727f8 54 :group 'files
b1d4664a
JB
55 :group 'convenience
56 :link '(custom-manual "(autotype) Autoinserting"))
6c5b39e4
SE
57
58
6c5b39e4 59(defcustom auto-insert 'not-modified
9201cc28 60 "Controls automatic insertion into newly found empty files.
12394086 61Possible values:
c11af8a5
KH
62 nil do nothing
63 t insert if possible
64 other insert if possible, but mark as unmodified.
65Insertion is possible when something appropriate is found in
66`auto-insert-alist'. When the insertion is marked as unmodified, you can
67save it with \\[write-file] RET.
a461758e 68This variable is used when the function `auto-insert' is called, e.g.
a702ffbb 69when you do (add-hook 'find-file-hook 'auto-insert).
12394086 70With \\[auto-insert], this is always treated as if it were t."
4605a50d
DL
71 :type '(choice (const :tag "Insert if possible" t)
72 (const :tag "Do nothing" nil)
12394086 73 (other :tag "insert if possible, mark as unmodified."
4605a50d 74 not-modified))
6c5b39e4 75 :group 'auto-insert)
c11af8a5 76
6c5b39e4 77(defcustom auto-insert-query 'function
9201cc28 78 "Non-nil means ask user before auto-inserting.
6c5b39e4 79When this is `function', only ask when called non-interactively."
5c213454
AS
80 :type '(choice (const :tag "Don't ask" nil)
81 (const :tag "Ask if called non-interactively" function)
82 (other :tag "Ask" t))
6c5b39e4 83 :group 'auto-insert)
c11af8a5 84
6c5b39e4 85(defcustom auto-insert-prompt "Perform %s auto-insertion? "
9201cc28 86 "Prompt to use when querying whether to auto-insert.
6c5b39e4
SE
87If this contains a %s, that will be replaced by the matching rule."
88 :type 'string
89 :group 'auto-insert)
c11af8a5
KH
90
91
6c5b39e4 92(defcustom auto-insert-alist
c11af8a5
KH
93 '((("\\.\\([Hh]\\|hh\\|hpp\\)\\'" . "C / C++ header")
94 (upcase (concat (file-name-nondirectory
a3610f0c 95 (file-name-sans-extension buffer-file-name))
c11af8a5 96 "_"
a3610f0c 97 (file-name-extension buffer-file-name)))
c11af8a5
KH
98 "#ifndef " str \n
99 "#define " str "\n\n"
100 _ "\n\n#endif")
101
102 (("\\.\\([Cc]\\|cc\\|cpp\\)\\'" . "C / C++ program")
103 nil
104 "#include \""
f6ec1532
RS
105 (let ((stem (file-name-sans-extension buffer-file-name)))
106 (cond ((file-exists-p (concat stem ".h"))
107 (file-name-nondirectory (concat stem ".h")))
108 ((file-exists-p (concat stem ".hh"))
109 (file-name-nondirectory (concat stem ".hh")))))
110 & ?\" | -10)
111
112 (("[Mm]akefile\\'" . "Makefile") . "makefile.inc")
c11af8a5 113
d60ae75c 114 (html-mode . (lambda () (sgml-tag "html")))
71296446 115
c11af8a5
KH
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
a6ed0e28
JL
128 (("/bin/.*[^/]\\'" . "Shell-Script mode magic number") .
129 (lambda ()
14acf2f5 130 (if (eq major-mode (default-value 'major-mode))
a6ed0e28 131 (sh-mode))))
71296446 132
c11af8a5
KH
133 (ada-mode . ada-header)
134
bf9f5c17
DL
135 (("\\.[1-9]\\'" . "Man page skeleton")
136 "Short description: "
137 ".\\\" Copyright (C), " (substring (current-time-string) -4) " "
12148b0e 138 (getenv "ORGANIZATION") | (progn user-full-name)
bf9f5c17
DL
139 "
140.\\\" You may distribute this file under the terms of the GNU Free
2201b59a 141.\\\" Documentation License.
bf9f5c17
DL
142.TH " (file-name-sans-extension (file-name-nondirectory (buffer-file-name)))
143 " " (file-name-extension (buffer-file-name))
144 " " (format-time-string "%Y-%m-%d ")
145 "\n.SH NAME\n"
146 (file-name-sans-extension (file-name-nondirectory (buffer-file-name)))
147 " \\- " str
148 "\n.SH SYNOPSIS
149.B " (file-name-sans-extension (file-name-nondirectory (buffer-file-name)))
150 "\n"
151 _
152 "
153.SH DESCRIPTION
154.SH OPTIONS
155.SH FILES
156.SH \"SEE ALSO\"
157.SH BUGS
158.SH AUTHOR
159" (user-full-name)
160 '(if (search-backward "&" (line-beginning-position) t)
161 (replace-match (capitalize (user-login-name)) t t))
162 '(end-of-line 1) " <" (progn user-mail-address) ">\n")
163
c11af8a5
KH
164 (("\\.el\\'" . "Emacs Lisp header")
165 "Short description: "
166 ";;; " (file-name-nondirectory (buffer-file-name)) " --- " str "
167
2103c9fb 168;; Copyright (C) " (substring (current-time-string) -4) " "
fbee29e6 169 (getenv "ORGANIZATION") | (progn user-full-name) "
c11af8a5
KH
170
171;; Author: " (user-full-name)
a461758e 172'(if (search-backward "&" (line-beginning-position) t)
c11af8a5 173 (replace-match (capitalize (user-login-name)) t t))
c5f7d536 174'(end-of-line 1) " <" (progn user-mail-address) ">
c11af8a5
KH
175;; Keywords: "
176 '(require 'finder)
177 ;;'(setq v1 (apply 'vector (mapcar 'car finder-known-keywords)))
178 '(setq v1 (mapcar (lambda (x) (list (symbol-name (car x))))
179 finder-known-keywords)
8ed6049f 180 v2 (mapconcat (lambda (x) (format "%12s: %s" (car x) (cdr x)))
c11af8a5
KH
181 finder-known-keywords
182 "\n"))
183 ((let ((minibuffer-help-form v2))
184 (completing-read "Keyword, C-h: " v1 nil t))
185 str ", ") & -2 "
186
88ddede6 187\;; This program is free software; you can redistribute it and/or modify
31b6b8cd 188\;; it under the terms of the GNU General Public License as published by
88ddede6
GM
189\;; the Free Software Foundation, either version 3 of the License, or
190\;; (at your option) any later version.
c11af8a5 191
88ddede6 192\;; This program is distributed in the hope that it will be useful,
31b6b8cd
SM
193\;; but WITHOUT ANY WARRANTY; without even the implied warranty of
194\;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
195\;; GNU General Public License for more details.
c11af8a5 196
31b6b8cd 197\;; You should have received a copy of the GNU General Public License
88ddede6 198\;; along with this program. If not, see <http://www.gnu.org/licenses/>.
c11af8a5 199
31b6b8cd 200\;;; Commentary:
c11af8a5 201
31b6b8cd 202\;; " _ "
c11af8a5 203
31b6b8cd 204\;;; Code:
c11af8a5
KH
205
206
207
3c98b2e9
SM
208\(provide '"
209 (file-name-sans-extension (file-name-nondirectory (buffer-file-name)))
210 ")
1caf5f96
GM
211\;;; " (file-name-nondirectory (buffer-file-name)) " ends here\n")
212 (("\\.texi\\(nfo\\)?\\'" . "Texinfo file skeleton")
213 "Title: "
214 "\\input texinfo @c -*-texinfo-*-
215@c %**start of header
216@setfilename "
217 (file-name-sans-extension
218 (file-name-nondirectory (buffer-file-name))) ".info\n"
219 "@settitle " str "
220@c %**end of header
221@copying\n"
222 (setq short-description (read-string "Short description: "))
223 ".\n\n"
224 "Copyright @copyright{} " (substring (current-time-string) -4) " "
225 (getenv "ORGANIZATION") | (progn user-full-name) "
226
227@quotation
228Permission is granted to copy, distribute and/or modify this document
d5259d01 229under the terms of the GNU Free Documentation License, Version 1.3
af8b50d1 230or any later version published by the Free Software Foundation;
d5259d01
GM
231with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
232A copy of the license is included in the section entitled ``GNU
af8b50d1 233Free Documentation License''.
1caf5f96
GM
234
235A copy of the license is also available from the Free Software
236Foundation Web site at @url{http://www.gnu.org/licenses/fdl.html}.
237
238@end quotation
239
240The document was typeset with
241@uref{http://www.texinfo.org/, GNU Texinfo}.
242
243@end copying
244
245@titlepage
246@title " str "
247@subtitle " short-description "
248@author " (getenv "ORGANIZATION") | (progn user-full-name)
249 " <" (progn user-mail-address) ">
250@page
251@vskip 0pt plus 1filll
252@insertcopying
253@end titlepage
254
255@c Output the table of the contents at the beginning.
256@contents
257
258@ifnottex
259@node Top
260@top " str "
261
262@insertcopying
263@end ifnottex
264
265@c Generate the nodes for this menu with `C-c C-u C-m'.
266@menu
267@end menu
268
269@c Update all node entries with `C-c C-u C-n'.
270@c Insert new nodes with `C-c C-c n'.
271@node Chapter One
272@chapter Chapter One
273
274" _ "
275
276@node Copying This Manual
277@appendix Copying This Manual
278
279@menu
280* GNU Free Documentation License:: License for copying this manual.
281@end menu
282
283@c Get fdl.texi from http://www.gnu.org/licenses/fdl.html
284@include fdl.texi
285
286@node Index
287@unnumbered Index
288
289@printindex cp
290
291@bye
292
293@c " (file-name-nondirectory (buffer-file-name)) " ends here\n"))
b1d6ae0b 294 "A list specifying text to insert by default into a new file.
c11af8a5 295Elements look like (CONDITION . ACTION) or ((CONDITION . DESCRIPTION) . ACTION).
2a575769 296CONDITION may be a regexp that must match the new file's name, or it may be
c11af8a5
KH
297a symbol that must match the major mode for this element to apply.
298Only the first matching element is effective.
299Optional DESCRIPTION is a string for filling `auto-insert-prompt'.
300ACTION may be a skeleton to insert (see `skeleton-insert'), an absolute
301file-name or one relative to `auto-insert-directory' or a function to call.
302ACTION may also be a vector containing several successive single actions as
6c5b39e4
SE
303described above, e.g. [\"header.insert\" date-and-author-update]."
304 :type 'sexp
305 :group 'auto-insert)
b1d6ae0b 306
c11af8a5
KH
307
308;; Establish a default value for auto-insert-directory
6c5b39e4 309(defcustom auto-insert-directory "~/insert/"
9201cc28 310 "Directory from which auto-inserted files are taken.
87810ca9
RS
311The value must be an absolute directory name;
312thus, on a GNU or Unix system, it must end in a slash."
6c5b39e4
SE
313 :type 'directory
314 :group 'auto-insert)
b1d6ae0b 315
c11af8a5
KH
316
317;;;###autoload
318(defun auto-insert ()
a461758e 319 "Insert default contents into new files if variable `auto-insert' is non-nil.
b1d6ae0b 320Matches the visited file name against the elements of `auto-insert-alist'."
c11af8a5
KH
321 (interactive)
322 (and (not buffer-read-only)
323 (or (eq this-command 'auto-insert)
324 (and auto-insert
325 (bobp) (eobp)))
326 (let ((alist auto-insert-alist)
327 case-fold-search cond desc action)
328 (goto-char 1)
329 ;; find first matching alist entry
330 (while alist
331 (if (atom (setq cond (car (car alist))))
332 (setq desc cond)
333 (setq desc (cdr cond)
334 cond (car cond)))
335 (if (if (symbolp cond)
336 (eq cond major-mode)
a461758e
DL
337 (and buffer-file-name
338 (string-match cond buffer-file-name)))
c11af8a5
KH
339 (setq action (cdr (car alist))
340 alist nil)
341 (setq alist (cdr alist))))
342
343 ;; Now, if we found something, do it
344 (and action
bdaf166c
SM
345 (or (not (stringp action))
346 (file-readable-p (expand-file-name
347 action auto-insert-directory)))
348 (or (not auto-insert-query)
349 (if (eq auto-insert-query 'function)
350 (eq this-command 'auto-insert))
351 (y-or-n-p (format auto-insert-prompt desc)))
6fd09e19 352 (mapc
c11af8a5
KH
353 (lambda (action)
354 (if (stringp action)
355 (if (file-readable-p
bdaf166c
SM
356 (setq action (expand-file-name
357 action auto-insert-directory)))
c11af8a5
KH
358 (insert-file-contents action))
359 (save-window-excursion
360 ;; make buffer visible before skeleton or function
361 ;; which might ask the user for something
362 (switch-to-buffer (current-buffer))
363 (if (and (consp action)
364 (not (eq (car action) 'lambda)))
365 (skeleton-insert action)
366 (funcall action)))))
367 (if (vectorp action)
368 action
369 (vector action))))
370 (and (buffer-modified-p)
371 (not (eq this-command 'auto-insert))
12394086
DL
372 (set-buffer-modified-p (eq auto-insert t)))))
373 ;; Return nil so that it could be used in
374 ;; `find-file-not-found-hooks', though that's probably inadvisable.
375 nil)
c11af8a5
KH
376
377
378;;;###autoload
4605a50d 379(defun define-auto-insert (condition action &optional after)
c11af8a5
KH
380 "Associate CONDITION with (additional) ACTION in `auto-insert-alist'.
381Optional AFTER means to insert action after all existing actions for CONDITION,
382or if CONDITION had no actions, after all other CONDITIONs."
4605a50d 383 (let ((elt (assoc condition auto-insert-alist)))
c11af8a5
KH
384 (if elt
385 (setcdr elt
386 (if (vectorp (cdr elt))
387 (vconcat (if after (cdr elt))
388 (if (vectorp action) action (vector action))
389 (if after () (cdr elt)))
390 (if after
391 (vector (cdr elt) action)
392 (vector action (cdr elt)))))
393 (if after
4605a50d 394 (nconc auto-insert-alist (list (cons condition action)))
bdaf166c 395 (push (cons condition action) auto-insert-alist)))))
c0274f38 396
6c5b39e4 397;;;###autoload
bff6da3d 398(define-minor-mode auto-insert-mode
12394086
DL
399 "Toggle Auto-insert mode.
400With prefix ARG, turn Auto-insert mode on if and only if ARG is positive.
401Returns the new status of Auto-insert mode (non-nil means on).
6c5b39e4 402
12394086 403When Auto-insert mode is enabled, when new files are created you can
6c5b39e4 404insert a template for the file depending on the mode of the buffer."
44e70da2 405 :global t :group 'auto-insert
bff6da3d 406 (if auto-insert-mode
a702ffbb
SM
407 (add-hook 'find-file-hook 'auto-insert)
408 (remove-hook 'find-file-hook 'auto-insert)))
6c5b39e4 409
896546cd
RS
410(provide 'autoinsert)
411
c0274f38 412;;; autoinsert.el ends here