I have a commonly used c++ boilerplate for competitive coding (looks something like this), I'm looking for some way to insert this boilerplate code which is in a file named competitiveCoding/cpp_template.cpp
automatically when ever I create a new .cpp
file in a specific directory named ~/competitiveCoding
or in any of it's sub directories, right now I just get a header file #include<file_name.h>
as boiler plate when I create a new file, I would like to replace this with the contents in the template file. Is there any way to do this in emacs?
1 Answer
A beginning use of auto-insert
could look something like this.
;; the following is by no means perfect...
(use-package autoinsert
:config
(setq auto-insert-query nil) ; disable the default auto-inserts
(auto-insert-mode 1) ; enable auto-insert-mode globally
(add-hook 'find-file-hook 'auto-insert) ; insert templates when we C-x C-f new files
(setq auto-insert-alist nil) ; remove this line to restore defaults
;; add our "competitive coding" templates
;; a basic example
(add-to-list 'auto-insert-alist
'("competitiveCoding/.+\\.hpp\\'" . "/home/Adeeb_HS/competitiveCoding/hpp_template.hpp"))
;; if we want to use ~ expansion we need to do it like this
(add-to-list 'auto-insert-alist
(cons "competitiveCoding/.+\\.cpp\\'"
(expand-file-name "~/competitiveCoding/cpp_template.cpp")))
;; get more restrictive w/ what files get templates inserted
(add-to-list 'auto-insert-alist
'("^/home/Adeeb_MS/competitiveCoding/.+\\.cc\\'" . "/home/Adeeb_HS/competitiveCoding/cc_template.cc"))
;; the same w/ ~ expansion
(add-to-list 'auto-insert-alist
(cons (concat "^" (expand-file-name "~/competitiveCoding/") ".+\\.hh\\'")
(expand-file-name "~/competitiveCoding/hh_template.hh"))))
Generally speaking, the elements of auto-insert-alist
are a pair that is a regular expression of the file to act on, and action to take (ie your template). That regular expression can contain subdirectory or path element.
In the first two examples, any cpp/hpp file in any subdirectory named "competitiveCoding" (~/competitiveCoding/
or /tmp/competitiveCoding/
, etc) will have their templates inserted.
The second two examples anchor the regex and use tilde expansion. In the interest of clarity, I'd avoid examples 2, 3 and 4. (Meh, maybe 3 is ok.)
-
Thanks, it does the job. Btw could you suggest a resource to learn elisp regexp, I'm quite confused on why there are 2 forward slash before and after the file expansion shouldn't it be just one?– Adeeb HSCommented Feb 7, 2022 at 9:47
-
A "\" in a lisp string has special meaning, therefore to get backslash-as-an-escape-character you need two. The paragraph on "\" in the Elisp manual explains it.– negaCommented Feb 8, 2022 at 4:39
-
1Unfortunately I don't have any recommendations for Elisp regex resources. I learned from the Elisp manual a long time ago. Jeffery Friedl's Mastering Regular Expressions had chapter on Emacs/Elisp regexes in the first edition that I found useful. I can't speak to the newer editions. If you're going to do any serious work with regexes that you use an abstraction such as the (included)
rx
notation– negaCommented Feb 8, 2022 at 4:52
auto-insert-mode
, but it does not satisfy the requirement that the boilerplate insertion only be done in a specific directory or its subdirectories. I suspect that you will have to implement your own function(s) for that, but maybe you can build on top ofauto-insert-mode
.file-header
or forheader2
. See also Emacs Wiki page Automatic File Headers.