Blogging with Vim
Just thought I'd give a disclaimer here that I no longer blog in vim or use jekyll to power this site so a few examples like footnotes aren't operational as they once were, but the vast majority of this article should still be relevant if you're looking to go that route.
You may be surprised at how well you can make vim a comfortable setting for authoring blog posts or any prose for that matter. The following is how I've configured vim (well, neovim but that's another post altogether) for writing pieces other than code.
Building a blog for the command line and vim
For starters, I used jekyll β a ruby based static site generator β to build this blog and I host it via GitHub Pages. This allows me to make any changes to my site with a simple git commit and push. Jekyll really is an amazing tool once you learn your way around. I'm much less likely to reach for a database having learned its quirks and tricks. It makes creating a static site a breeze.
Blogging convenience methods
Out of the box, Jekyll lacks a few convenience methods for common blogging tasks. I recommend using the jekyll-compose gem, which gives you the following easy-to-remember methods that will make your life blogging from the command line much better:
draft # Creates a new draft post with the given NAME
post # Creates a new post with the given NAME
publish # Moves a draft into the _posts directory and sets the date
unpublish # Moves a post back into the _drafts directory
page # Creates a new page with the given NAME
Drafts can be pushed up without showing up on your site, and can be previewed on
localhost via jekyll serve --drafts
.
Kramdown footnotes
While I write my blog posts in markdown, I've actually configured jekyll to use kramdown to get access to more functionality like footnotes.1
Now onto the actual vim related stuff!
Dictionary and Thesaurus
Two things people tend to use while writing are dictionaries and thesauruses. Let's get you set up so both are merely a leader key away.
Now, I'm afraid I this will only work for macOS because it uses Apple's dictionary app. If you are on a mac, the following command will look up the current word underneath your cursor in macOS' dictionary app like so:
" look up the word under the cursor in Apple's dictionary
nnoremap <silent> <Leader>di :!open dict://<cword><cr><cr>
Wunderbar! Now lets grab a fantastic vim plugin from beloglazov that will give us
access to thesaurus.com. This gives vi a couple of new commands for looking up
any word (:Thesaurus <word>
) and the current word under the cursor
(:OnlineThesaurusCurrentWord
). Here I use it to search for synonyms for
"commands":
This plugin will also return a short definition as well, so Linux users rejoice!
Spell-checking
Another feature most of us have come to rely on while writing prose in rich text
editors is a spell-checker. Luckily, vim comes with a spell checking system out
of the box (:help spell
) which you can enable for markdown files by creating a
file in ~/.vim/ftplugin/markdown.vim
with the following configuration
setlocal spell
. We now have spell checking enabled in all markdown files,
but let's take a closer look as to what's going on here.
If we read up on ftplugin
files via :h ftplugin
we'll see that we are
creating a filetype plugin that will automatically be sourced by vim.
A filetype plugin is like a global plugin, except that it sets options and defines mappings for the current buffer only.
Let's also take a look at what setlocal
is doing:
*:setl* *:setlocal*
:setl[ocal] ... Like ":set" but set only the value local to the
current buffer or window. Not all options have a
local value. If the option does not have a local
value the global value is set.
With the "all" argument: display local values for all
local options.
Without argument: Display local values for all local
options which are different from the default.
When displaying a specific local option, show the
local value. For a global/local boolean option, when
the global value is being used, "--" is displayed
before the option name.
For a global option the global value is
shown (but that might change in the future).
This is all well and good, but how much use is a spell checker that doesn't
offer spell correction suggestions? Well, as you probably expected, vim brings
spell suggestions to the party for free. Simply use the z=
mapping when your
cursor is over the misspelled word to receive a list of suggestions to choose
from like so:
Just a few more things on spell checking, I swear.
Vim also provides two mappings for jumping from one misspelled word to the next
with ]s
(next misspelled) and [s
(previous misspelled word).
Here's where you start to feel spoiled. Vim allows you to build a list of words
that you consider "good" (words that are properly spelled but marked as
misspelled by vim's spell checker) and words that you consider "wrong" (words
that vim mistakenly views as correctly spelled). You can achieve this via the
zg
(good words) and zw
(wrong words) when the cursor is on the word you're
targeting.
Where does this list go and how does it work? Again, let's head to vim's
fantastic help documentation, :h spellfile
:
Name of the word list file where words are added for the |zg| and |zw|
commands. It must end in ".{encoding}.add". You need to include the
path, otherwise the file is placed in the current directory.
β¦
For the file name the first language name that appears in 'spelllang' is used,
ignoring the region.
I've created my own spell checking file in ~/.vim/spell/english.utf-8.add
.
Note: every time you add a word to your list using zg
and zw
a
similarly named file with a tacked on .spl
extension file that vim actually
uses for spell checking will be regenerated based on your updated list of words.
Automatically fix words you commonly misspell
One of vim's features that I should use more liberally is its abbreviations.
If you enter a word that is an abbreviation, it is replaced with the word it stands for. This can be used to save typing for often used long words. And you can use it to automatically correct obvious spelling errors.
For example, my brain refuses to type destroy
instead of destory
, and the
same goes for unknown
instead of unkown
. Vim, being a forgiving soul will go
easy on me if I ask it to.
iabbrev destory destroy
augroup markdown
autocmd FileType markdown iabbrev <buffer> ... β¦
augroup END
Since abbreviations can be set for Insert, Replace, and Command-line mode, I
like to restrict my abbreviations to insert mode only with iabbrev
. Also, some
abbreviations I only want to trigger in markdown files when I'm writing
posts. The augroup
above takes care of that for me, and in this case it
replaces three periods with the ellipses symbol. Now, moving onβ¦
Linting your prose
Depending on how much Proust you have in you, you may not give a shit about writing style suggestions. If you feel like you could use it, take a look at setting up proselint with whichever vim plugin you use for linting.
Animated screen captures
I use the oddly named licecap app to capture any gifs I'd like to use in my posts. This is one of those "Dear God, had I known about this sooner" tools.
Markdown links
There are multiple ways of using creating links in markdown that I think you should be aware of when using the file format for your blog posts. Choose whichever you fancy.
Wrap up
That pretty much does it! These are all of the tools I like to use when writing blog posts in my favorite editor.