3 Quick Tips to Making Vim a Jekyll Paradise

Posted by Grego on February 23, 2015

Background

For a while I was using Sublime Text as my main editor for Markdown/Jekyll. I really liked most of the markdown plugins available. However recently I started getting back into vim again and realized how truly powerful it is.

I do most of my blogging these days in jekyll. I really like the performance of a fully static website — yes I know, most of the dynamic blogs offer caching but why deal with the hassle? With jekyll I mainly use markdown. Markdown is awesomely fast for a great many things. I love being able to crack open my favorite editor and just start typing a way at an article or whatever notes I may have to share with the interwebs.

Generally there are 3 things that bother me when working with markdown:

  1. CtrlP in vim being littered with all the generated html junk from the _sites/ directory
  2. Creating links
  3. Inserting images

The last two are actually kind of related, since they both use references and more or less the same syntax, but I’ll approach them in different ways.

Filtering garbage out of CtrlP

In case you don’t use it already, CtrlP is a plugin for vim that allows you to open files ludicrously fast through fuzzy text matching—but what happens when you have a lot of garbage files that you don’t care about and would never want to open, ever?

CtrlP without filters

This is the simplest problem to solve out of all three and to be honest never really bothered me that much, but now that I’ve fixed it I think it’s awesome and needs to be shared.

CtrlP has global option g:ctrlp_custom_ignore which can be used to “hide stuff when using globpath()” so when you hit CtrlP to build your file list, they won’t show up.

Here’s what mine looks like now:

let g:ctrlp_custom_ignore = 'node_modules\|DS_Store\|^.git$\|_site'

I added a bunch of things that kept coming up in my jekyll directory that were bothering me. Probably DS_Store and .git are good ones to have in all settings, but the others could probably be handled in a project or file-type specific manor using autocmd.

Here’s what CtrlP looks like after the change:

CtrlP with filters

Creating links

Markdown provides 3 different ways to create a link:

[One Big Function](http://onebigfunction.com),
[otaku-elite.com][otaku-elite],
[Let's Make Salmon Foil-yaki!][]

This will produce the following output:

One Big Function, otaku-elite.com, Let’s Make Salmon Foil-yaki!

The last two links use the square bracket notation:

[link text][link-reference-name]

Where the link-reference-name is optional, when omitted the link text is used instead.

When using this style, we have to add a footnote at the bottom of the Markdown file to add the references for each link:

[otaku-elite]: http://otaku-elite.com
[Let's Make Salmon Foil-yaki!]: http://otaku-elite.com/japanese/2015/02/22/sake-no-hoiruyaki-tsukurimasho/

Generally, when I’m writing an article I prefer to create links using bracket notation and fill in the link URLs when I’m done.

To help with this, I wrote a very simple python script that scans over stdin and creates footnote links at the bottom, omitting any preexisting footnote links. It’s not flawless, but it works. I then mapped a key CTRL + G to filter the entire file using my script:

nnoremap <C-g> :%!~/bin/mdlinks
I'll post the file on Github later.

(2015-03-15 23:40:06 -0700): Check out mdlinks on GitHub!

Inserting images

The next really irritating thing to deal with in Jekyll is inserting images. This is much like the previous issue of creating links.

I try to be consistent in the way I organize my images and blog posts in the file system. Although really, posts don’t matter all that much since they are managed by jekyll itself.

I usually organize my images like this:

img/
|-- 2014
|   `-- 12
|       |-- 18
|       `-- 27
|           |-- 1-new-file.png
|           `-- 2-new-category.png
`-- 2015
    |-- 01
    |   `-- 15
    |       |-- adding-color-scheme-vim.png
    |       `-- vim-screenshot.png
    `-- 02
        |-- 02
        |   `-- vim-json.gif
        |-- 18
        |   |-- phone-call.png
        |   |-- telnet.png
        |   |-- text.png
        |   `-- title-bar.png
        `-- 21
            |-- custom-color.png
            `-- default-color.png

They are sorted by convention:

  • They are in some folder (img/)
  • and the image path extends to YEAR/MONTH/DAY/filename.png

For a while I’ve been trying to think of a better way to insert images without having to type the path out manually. Today I came up with something that I’m fairly happy with.

Using Ultisnips, we can create a snippet that will automatically expand to the correct YEAR/MONTH/DAY. But how do we get the correct date? I could easily get the current date, but often I tend to write a post and add in images after the original publish date, so current date would be useless in many cases.

Then I realized: everything in jekyll is based on configurations and conventions. The filenames in jekyll are in the format YYYY-mm-dd-article-title.md so I could easily manipulate the filename of the current post to create a snippet that would give me a path name, also based on convention, and then I could just place the filename after.

I used python interpolation for some help processing the filename:

snippet /im "jekyll image path completion"
/${1:images}/`!p
parts = snip.fn.split('-')
rv = ''
if len(parts) >= 3:
	rv = '/'.join(parts[:3])
snip.rv=rv`/${2:file.png}
endsnippet

This is what it looks like if I type /im and hit TAB (my snippet key):

image path completion snippet demo

Of course this doesn’t handle the problem of moving the image files into the designated locations—I’ll leave that for next time :)

[link-reference-name]: