Writing in Vim
vim unix writing

Vim is a tremendous tool for text manipulation, but it is not configured properly for writing right out of the box. This drawback alone is enough to dissuade some people from ever using Vim.1 This is unfortunate. The idiosyncrasies that make Vim awkward for word processing exist because Vim is principally configured to operate as a code editor. However, with only a few customizations Vim can become a power writing tool. This post is about my experiences with optimizing Vim for writing.

Before diving into specialized customizations, it's import to remember a few key Vim commands that are vital to efficient word processing. Without owning these commands, word processing in Vim is difficult. This list is by no means comprehensive, but these examples highlight some of the commands I find most useful while writing:

  • 3diw—delete inside the current word and the next two words
  • dwwP—swap the current word with the next word
  • d?foo—delete from the cursor to the previous string “foo”
  • ct.—change from the cursor until the next period
  • d^—delete from the cursor to the beginning of the line
  • d>D—delete from the cursor to the end of the line
  • 2J—join the current line with the line below
  • das—delete around the current sentence
  • c(—change from the cursor to the begining of a sentence
  • >}—go to the end of the current paragraph
  • dapP—swap current paragraph with the next paragraph

To setup Vim for writing, I find it best to make a few modifications to my vimrc. I've found the best way to configure a writing environment is to map several customizations to a single function. Using this method, the writing environment can be toggled on or off by issuing one command. My core writing function is bound to :WP. This mapping calls the WordProcessorMode() function, which looks like this:

func! WordProcessorMode() 
  setlocal formatoptions=1 
  setlocal noexpandtab 
  map j gj 
  map k gk
  setlocal spell spelllang=en_us 
  set thesaurus+=/Users/sbrown/.vim/thesaurus/mthesaur.txt
  set complete+=s
  set formatprg=par
  setlocal wrap 
  setlocal linebreak 
com! WP call WordProcessorMode()

This function goes a long way to setting up a functional writing environment. Perhaps the most interesting line in this function is set formatprg=par. This line tells Vim to use the Unix utility par to format text.2 par is an excellent text formatting tool that improves readability over Vim's default formatting engine. In writing mode, issuing the command gq on highlighted text will reformat text using par. The output of text formatted with Vim (on top) compared to par (on bottom) looks like this:

Several of the lines in the WordProcessorMode function control spelling and thesaurus preferences. With spelling turned on, typing 1z= will correct a misspelled word to Vim's first suggested correction.3 I also add a lot of obscure words that Vim thinks are incorrect to my own spelling file by executing the zg so that these words are subsequently displayed as spelled correctly. The thesaurus is something I use frequently. I keep a local copy of the Merriam-Webster Thesaurus in the ~/.vim/thesaurus/ directory on my system. This configuration allows me to use the built-in thesaurus to write offline in airplanes, buses, or cars. In insert mode, a list of synonyms for a give word can be triggered by typing ctrl-x ctrl-t.

I classify all my writing into one of four document types—plain text, outlines, HTML, or LaTeX. The above tools are basically all I use for writing plain text, but for outlining I like to use the excellent vim outliner plugin. By default, this plugin acts on files with the .otl extension. The documentation is thorough and using vimoutliner is straight-forward. The command I use most often is ,,(int) where (int) is the level of indentation within an outline for which the user would like to be visible. Code folds are also very helpful for working with especially large outline files. Another handy feature of vimoutliner is the built-in sub-tree sorting feature, which sorts a given indentation block within an outline in ascending or descend order with ,,s or ,,S respectively.4

vimoutliner uses a custom color scheme composed of a different primary colors for each level of indentation within an outline. This is a nice feature because the color helps to demarcate indentation levels in outlines. Unfortunately, the default colors used by vimoutliner clashes horribly with the solarized theme I use in MacVim. To reconcile the color clash, vimoutliner provides the user with an easy method to define custom color themes for outlines. For outlines, I've created a simplified solarized outline theme that resides within my ~/.vim/colors directory. A basic outline with my color theme looks like this:

In the next Writing In Vim post, I will go over my HTML and LaTeX writing work flows. Although I use many of the same writing customization I've discussed here, I also use several additional commands and plugins to work with these languages and associated file types.

  1. Dr. Drang is one person who comes to mind that finds Vim very difficult to use for writing. ↩

  2. par can be installed with Homebrew. Simply type brew install par. Special thanks to Drew Neil for introducing me to the par/vim hack at Vimcasts. ↩

  3. For spelling, I include an additional line in my vimrc to toggle spelling on and off. I've found that seeing incorrect spellings is sometimes distracting, so it's convenient to be about turn spelling on and off independent of whether WordProcessorMode is toggled on or off. ↩

  4. If you are unfamiliar with Vim's code folding, see :help folding within Vim internal documentation. I find the OPEN AND CLOSING FOLDS section the most instructive. ↩