« Home


How to Configure Vim for Writing

Posted by Elnu on
, ,

There are a lot of tools that are, for the most part, only used in the programming sphere that could do a lot of good if they received adoption among the wider non-technical community. Git and Markdown especially. Version control is useful to anyone who works on text files and needs to be able to revert back to a previous version, and Markdown is a simple and succinct way to format simple text documents — especially compared with Microsoft Office.

Another tool that could see wider adoption is Vim, especially among writers looking for a powerful yet minimal text editor, and are willing to invest some time into learning it.

I switched over to Vim a couple weeks ago from GNU nano and VSCodium (a free and open source build of VS Code), and I haven’t looked back since. However, out of the box, Vim isn’t configured to excel at anything, besides perhaps basic configuration file editing. In this guide, I’ll go over how to configure Vim for writing, assuming you’re writing in Markdown files.

When you’re done, your Vim will look something like this:

Screenshot

I will cover the following, assuming you are slightly familiar with basic editing in Vim:

With the introduction out of the way, let’s get right into it!

Soft line breaks

Most Vim configurations are done in the user’s ~/.vimrc file, which applies to all Vim sessions regardless of file type. However, we want our customizations to only apply to Markdown text files. Luckily, Vim has a feature that handles this. Filetype plugins allow you to create Vim configurations that only apply to certain filetypes, and are stored in the directory ~/.vim/ftplugin/. We are going to create one for our Markdown files: ~/.vim/ftplugin/markdown.vim.

Inside this file, add the following:

setlocal linebreak

We want to use setlocal (or its shorthand setl) over the usual set because this only sets linebreak on the current buffer. If we have multiple files open in Vim, we want to make sure that this setting only applies to open Markdown files.

Thanks to u/habamax for pointing this out!

And you’re done! Vim will now no longer split words across soft-wrapped lines. Now, let’s move on to typographic quotes.

Typographic quotes

Vim doesn’t have any native support for typographic quotes, so we’ll need to install the plugin preservim/vim-textobj-quote. There are a few different ways to install plugins in Vim, but in my opinion the easiest one to use is Vundle. If you are on Arch Linux, there is an AUR package, otherwise, see the quick start guide on Vundle’s GitHub repository.

Now that we have a package manager for Vim installed, we need to install the plugin itself. Open your ~/.vimrc, or create it if it doesn’t exist yet, and add the following:

filetype off
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'kana/vim-textobj-user' " essential dependency for typographic quotes
Plugin 'preservim/vim-textobj-quote' " typographic quotes
call vundle#end()
filetype plugin indent on

If you are unfamilar with Vundle, between vundle#begin() and vundle#end() is where all of the Vim plugins you want installed with Vundle are listed; the rest of the lines are various requirements for Vundle to work properly (for more information, see Vundle’s quick start guide). By default, Vundle assumes the plugins to be GitHub repositories, so all you need to write down is the repository name. kana/vim-textobj-user is an essential dependency for our typographic quote plugin that will handle text objects.

Now that you’ve listed the necessary plugins, you need to have Vundle install them. Save and exit ~/.vimrc, open Vim, type :PluginInstall, and press enter. If you’ve done everything correctly, Vundle should pull all of the necessary plugins from GitHub, and once it’s done you can type :q to exit the installation window.

The typographic quotes plugin is now installed, but it won’t start up by default. Since we only want it to run on Markdown files, we open up ~/.vim/ftplugins/markdown.vim again and add the following:

call textobj#quote#init()

This will initialize the typographic quote plugin whenever you enter a Markdown file.

Useful commands

Spellcheck

To enable spellcheck, add the following to your ~/.vim/ftplugin/.markdown.md:

set spell spelllang=en
set spelllang+=cjk " prevent CJK characters from being spellchecked

Of course, if you want spellchecking in another language, change en to whatever your language code is. The second line is optional, however if you often work with documents including Chinese, Japanese, or Korean (CJK) characters like me, this is handy since otherwise Vim will mark them all as spelling mistakes.

Useful commands

Patching dictionary for typographic quotes

If you decided to skip the typographic quotes configuration from earlier, you can stop here, but otherwise we’re going to have to patch our Vim spellcheck dictionary to include words with typographic apostrophes/single quotes (e.g. doesn’t) which will be marked as incorrect otherwise.

This thread on the Vi and Vim Stack Exchange was very helpful, so if you’re having any trouble please refer to the two answers there.

First, create the directory ~/.vim/spell and enter it. We’re going to need two dictionary files, which are available here. Please check to see if there has been a newer version on the website and wget that instead, if the one I’m using (2020.12.07) has become out of date. I’m going to use the American English (setting _LANG to en_US) dictionary file, but Canadian (en_CA) and Australian (en_AU) English dictionaries are also available. If you need British English or larger word list, more archive downloads are available here, although I haven’t tested them.

$ mkdir -p ~/.vim/spell && cd ~/.vim/spell
$ _LANG=en_US # language variable for future commands, replace if needed
$ wget http://downloads.sourceforge.net/wordlist/hunspell-$_LANG-2020.12.07.zip
$ unzip *.zip $_LANG* && rm *.zip

In order to patch the dictionary, run the following command (see this for an explanation of how it works). It takes all occurrences of words with apostrophes in the dictionary file and appends a version with the typographic version.

$ grep "'" $_LANG.dic | sed "s/'/’/g" >> $_LANG.dic

Then, still in the ~/.vim/spell directory, start Vim, and run the :mkspell! en en_US command, which should create an en.utf-8.spl file. You’re done!

If you find more compatible dictionary files besides English that are confirmed working, please let me know and I’ll add them to this article.

Custom status bar

Now, for the cherry on top: a custom status bar!

Add the following to your ~/.vim/ftplugin/markdown.vim:

function! Characters()
        return strchars(join(getline(1, '$'), "\n"))
endfunction

function! Words()
        return wordcount().words
endfunction

function! Minutes()
        let wpm = 200
        return (Words() + wpm / 2) / wpm
endfunction

set laststatus=2 " enable status line
set statusline+=%=%{Words()}\ words,
set statusline+=\ %{Characters()}\ characters,\ about
set statusline+=\ %{Minutes()}\ minutes
" remove ugly white background
hi StatusLine ctermfg=0 ctermbg=none cterm=bold " 0 for the terminal color 0

I haven’t done any Vimscript before working on this configuration, so this is mostly cobbled this together from a few Stack Overflow threads. There might be better ways of doing some things!

The main things of note are the following:

Conclusion

That’s all for this tutorial! I hope it was useful to you. For the last couple of weeks, I’ve been learning to use and configure Vim, and it’s been a lot of fun. I made this article to share what I’ve learned, and also as a future reference for myself. Writing can be a good way of solidifying your knowledge, and I learned a lot writing this. This is my first “proper” blog post, so I hope it was alright. I’ll be writing more in the future!

Oh, and one more bonus tip. The normal j and k navigation commands for going up or and down a line in Vim go over “hard” lines in the document, not soft-wrapped visual lines. If you want to go over visual lines as one often does when writing, prefix the command with g (for graphical, I guess?). So, for example, to go down one graphical line, use gj. You can even prefix the chord with a number to repeat it multiple times, so to go up three visual lines, use 3gk! If you need to do this a lot, you might want to look into creating a custom mapping.

See you in the next post!