autoinsert.el 14 KB

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