Physicist, Emacser, Digitales Spielkind

Auto-inserting .gitignore (and license) templates in Emacs
Published on Nov 23, 2020.

When you are using Emacs with the Doom-Emacs configuration, you might have noticed that you are being offered a couple of templates to select from whenever you are visiting certain types of file for the first time: your brand new file will be pre-populated from the template you pick. That is really quite convenient, and I especially enjoy that for files such as the special .gitignore file that tells git what files should not be considered relevant for the repository. As I typically work with repositories holding different types of code (and sometimes mixes thereof), this is really practical!

However, the templates that Doom ships with are quite limited. The LaTeX one only covers a handful of patterns while the LaTeX compiler typically litters the working directory with countless generated files. But manually copying over files for each project is boring, so let’s extend the mechanism!

DOOM uses yasnippet to populate those blank files whose name matches a certain pattern. The templates are hard-coded though and I would rather build upon excellent template collections such as github’s gitignores. So time to create our own little function:

1: (defun hanno/template-insert-gitignore()
2:   (interactive)
3:   (let* ((dir (concat doom-private-dir "/templates/gitignore/"))
4:          (files (directory-files dir nil ".*\\.gitignore"))
5:          (pick (yas-choose-value (mapcar #'file-name-sans-extension files))))
6:     (insert-file-contents (concat dir (concat pick ".gitignore")))))

This function lists all files in [doom-private-dir]/templates/gitignore (located under ~/.doom.d for me) and offers an interactive selection prompt via yas-choose-value. There, I can place all the templates I want:

1: cd ~/.doom.d
2: mkdir templates
3: cd templates
4: git clone https://github.com/github/gitignore

Just make sure they have the file extension “.gitignore” as we filter on that in the above elisp code. Now we can register the template through Doom’s set-file-template! macro:

1: (set-file-template! "\\.gitignore$" :trigger 'hanno/template-insert-gitignore :mode 'gitignore-mode)

And here is the code in action when visiting a new file: 2020-11-23-215728_774x726_scrot.png

This can be easily extended to other template types, for example the various (FOSS) licences hosted at choosealicense.com:

1: (defun hanno/template-insert-license()
2:   (interactive)
3:   (let* ((dir (concat doom-private-dir "/templates/choosealicense.com/_licenses/"))
4:          (files (directory-files dir nil ".*\\.txt"))
5:          (pick (yas-choose-value (mapcar #'file-name-sans-extension files))))
6:     (insert-file-contents (concat dir (concat pick ".txt")))))
8: (set-file-template! "license\\($\\|\\.txt\\|\\.md\\)" :trigger 'hanno/template-insert-license)

The regular expression of the template matches for example license, LICENSE, license.txt and license.md.

Tags: emacs, lisp, git