I do most of my daily work in Vim, and by this point I find it quite hard to use anything else, but for writing that isn’t code (or, let’s be real, mostly YAML these days) it could be a lot better.
A good writing environment should free me from worrying unnecessarily about Computer Things like line numbers, line wrapping and file formats. I should be able to just type words and not think about the other stuff - at least, until after I’m finished.
I’ve used a few tools in the past that went some way towards this - Sublime Text has quite a nice distraction-free writing mode, which centres text and removes all other UI elements. It’s neat, but I don’t really like Sublime that much these days.
I wanted to take some of those elements and transplant them into Vim. Thankfully, as is often the way, someone’s done a plugin. Two, in this case.
goyo.vim provides a distraction-free writing environment much like the one in Sublime. It centres the text, limits it to a small width so you don’t have to scan horizontally, and removes all other distractions from the UI. It’s great.
limelight.vim is something of a companion to Goyo - it dims all text other than the bit you’re focused on. It’s even smart enough to distinguish paragraphs regardless of how your line breaking works in your file, which I’ll get to in a minute.
You can install these two in the usual way and they make a big difference just
by themselves. It looks like the image at the top of this post, which I think is
great. I’ve made a few additions. Here’s the relevant bit of my
explain it, don’t worry):
noremap <Leader>g :Goyo<CR> "1 set colorcolumn=81 "2 set scrolloff=5 "3 let g:goyo_width=81 "4 function! s:goyo_enter() "5 set scrolloff=999 "6 set linebreak "7 set textwidth=80 "8 CocDisable "9 Limelight "10 endfunction function! s:goyo_leave() "11 set scrolloff=5 set nolinebreak set textwidth=0 CocEnable Limelight! endfunction autocmd! User GoyoEnter nested call <SID>goyo_enter() "12 autocmd! User GoyoLeave nested call <SID>goyo_leave() noremap <Leader>s :set spell! spelllang=en_gb<CR> "13
Let’s go through the numbered lines:
This toggles my “writing mode” (using goyo.vim) on Leader+G. I have my leader key mapped to the space bar - if you’ve not remapped your leader key it’s probably my number one recommendation for getting productive with Vim.
This adds a column marker at column 81 (so max width 80) when not in the writing mode. You can see what it looks like here:
scrolloffrefers to how far away from the screen edge your cursor needs to be before it starts scrolling. I have mine set to 5 as a reasonable default; this is very much personal preference.
This setting tells goyo.vim how many columns on your screen to take up. The default is 80, though I found this actually matches up to a max width of 79, which isn’t quite what I want.
The next chunk, inside
goyo_enter, are the things that get run when goyo.vim is turned on. I think of this as “writing-mode settings”.
scrolloff=999basically ensures that, while in writing mode, the cursor stays in the middle of the screen; I find this, along with limelight.vim, helps me focus on the paragraph I’m currently working on.
linebreakon. This makes sure that goyo.vim (or Vim generally) doesn’t break lines in the middle of words.
textwidth=80forces Vim to auto-format my writing such that it stays within the 80-character limit. I only really want this on when I’m writing - for code I do sometimes need to go over that limit (Java is a verbose language).
coc.nvim, a plugin I use for code completion. This prevents the suggestions popup from appearing, which is almost never helpful when writing prose.
Turns limelight.vim on.
goyo_leave, acts as the inverse of the other function, putting all my settings back to normal when leaving writing mode.
These lines connect up Goyo’s events to the functions we just defined.
A bonus one - this toggles spellcheck off and on using Leader+S.
As always, all this is available in my public dotfiles. I wrote this post using my new writing mode and it genuinely did make a big difference.