teaching machines

Vim Autotemplates

May 20, 2016 by . Filed under public, vim.

When I create a brand new file in Vim, I automatically insert template text into it. For Java, the template looks like this:

public class CLASS {
  CURSOR
}

The C template looks like this:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  CURSOR
  return 0;
}

The HTML template looks like this:

<!DOCTYPE html>
<html>
<head>
  <title>...</title>
</head>
<body>
  CURSOR
</body>
</html>

A student has asked how I do this. I’m sure I picked up the knowledge from somewhere else, but the provenance data has been lost. So, I’ll share my configuration here and pretend like I was its sole author.

First, I put all my template files in some known location. I have a universal configuration repository that I clone on all the machines I use regularly. My templates sit in a directory within this clone named vim/templates. The template files are named according to the extension I use for that file type. For example, the Java template file is named java, the C++ template file is named cpp, and so on.

Second, I added the following autocommand to my .vimrc file, which I explain in more detail below:

autocmd BufNewFile *
\ let templatefile = expand("/PATH/TO/UNIVERSAL/CONFIGURATION/configs/vim/templates/") . expand("%:e")|
\ if filereadable(templatefile)|
\   execute "silent! 0r " . templatefile|
\   execute "normal Gdd/CURSOR\<CR>dw"|
\ endif|
\ startinsert!

Let’s break this down a bit:

  1. The autocommand will run on new file events (BufNewFile) for all files (*).
  2. The %:e grabs the extension of the new file.
  3. Command filereadable checks to see if a template file with this extension exists in the known location.
  4. If the file is readable, I use the r command to read in the template’s contents. The 0r ensures that the contents are placed after line 0—in other words, at the start of the file.
  5. Gdd removes the extra blank that appears at the bottom of the file.
  6. To indicate where I want the cursor to be, I include a CURSOR placeholder in each template. /CURSOR\<CR>dw jumps to the CURSOR placeholder and deletes it. The cursor stays there.
  7. The startinsert command puts us in insert mode. The ! makes this command behave like A, so we start appending text to the line that once held the placeholder.

Adding new templates requires only that I put a new template file in the templates directory.