autoinsert.el 14 KB

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