Software projects are commonly composed of similar files in a specific location and new files typically require some minimal boilerplate. Tim Pope’s projectionist.vim offers a handy way to templatize the creation of new files directly in Vim.

The Vim Tricks codebase, which is based on Jekyll, is a perfect candidate for such a file template since creating new Vim Tricks requires adding a file to the _posts directory. and that file follows a standard format with metadata.

After installing Projectionist, we can create a .projections.json file in the project root that defines the file type we want. In this case, post. The most basic usage of Projectionist simply defines the file type along with a path glob:

{
  "_posts/*.md": {
    "type": "post"
  }
}

After reopening Vim, we can now use :Epost along with tab completion to open any existing post. If we pass the name of a file that does not exist, Projectionist opens a new empty buffer for us at that path. For example:

:Epost 2017-10-31-carving-a-pumpkin

will open a buffer called _posts/2017-10-31-carving-a-pumpkin.md.

From here, we can extend our projection to include a template for new posts:

{
  "_posts/*.md": {
    "type": "post",
    "template": [
      "---",
      "layout: post",
      "title: {blank}",
      "date:",
      "categories:",
      "author:",
      "  name:",
      "  email:",
      "  url:",
      "  github:",
      "---",
    ]
  }
}

The template attribute of the projection accepts an array of lines to prepopulate the buffer. There are even a host of filters such as capitalize, camelcase, or blank which we’ve used here to convert the - characters to spaces.

Now, when we navigate to a new post with :Epost whatever-we-want, the file will open with the exact template we need to create a new post!

---
layout: post
title: Whatever we want
date:
categories:
author:
  name:
  email:
  url:
  github:
---

This same technique is used in the rails.vim plugin to prepopulate models, controllers, helpers, and more. You can really extend this to just about any file type and it requires running no generation script from a command line.