--- title: Writing Prose in Vim tags: - Vim description: Vim is a popular text editor among programmers, it is not limited to programming though. In this blog I will discuss how I write just about everything in vim date: 2021-10-06 --- If you know me at all, you probably know I am a fan of vim. I have written [more than a few](/tag/vim.html) blog posts on it already. Most vim users use vim for programming. That is, after all, what most people use plain text editors for. However, since learning vim, I have tried to use it for as much as I can. Everything from emails to blog posts to letters. Of course, programming as well, but certainly not only that. "Why?", you might ask. Because it makes my life easier. I have said before that Vim is not as difficult as many vim users would like you to think it is. ## Spellcheck I need a spell check. My spelling is atrocious. This is not helped by the fact that I am dyslexic. Having a decent spell checker is essential if I am writing anything that is going to be read by another human. Incidently, I count future me as another human in this regard. Vim has a built-in spell check. ```vim set spell set spelllang=en_gb ``` How it will look will depend on your colour scheme but in my case it is an underline. Basic usage consists of the following keyboard shortcuts: * `[s` or `]s` to move between misspelled words * `z=` to get a list of suggestions * `zg` to add the current word to your custom dictionary As with anything in vim, these shortcuts can be changed, although I have never felt the need to. Vim's insert completion can be used to look up words in the internal dictionary as well. To use this, start writing a word and complete it with `ctrl-x ctrl-k`. This will present you with a list of words that start with what you have typed. You can select one, as normal, with `ctrl-n` and `ctrl-p`. Finally, on the topic of spell checking, I have added an insert mode mapping that is used to correct the previous misspelled word. The mapping is as follows: ```vim inoremap u[s1z=`]au ``` 1. `u` - break undo sequence (new change) 1. `` - go into normal mode 1. `[s` - go to previous spelling mistake 1. `1z=` - change to the top spelling suggestion 1. ```]`` - go to the end of the last changed word 1. `a` - enter insert mode 1. `u` - break undo sequence (new change) This was shamelessly stolen from [Gilles Castel's excellent blog post on using vim for LaTeX](https://castel.dev/post/lecture-notes-1/#correcting-spelling-mistakes-on-the-fly) ## Undo Points When programming in vim, a lot of time is spent in both normal mode and insert mode. However, when writing prose, much more time is spent in insert mode. As a result, each undo point tends to be much larger. This can result in the rather annoying behaviour that undoing anything can remove a huge amount of writing. To minimize this annoyance, I add undo points whenever I type punctuation points. ```vim inoremap ! !u inoremap , ,u inoremap . .u inoremap : :u inoremap ; ;u inoremap ? ?u inoremap ( u( inoremap ) )u ``` The only point I really need to elaborate on here is that for the opening bracket: I add the undo-point before inserting the character. This results in what I consider preferable behaviour whereby a whole bracket group is removed at once when undoing, rather than leaving the opening bracket. ## Distraction Free Writing Distraction free writing seems to be quite a fashionable / desirable feature in a lot of editors at the moment. I have tried and used [Goyo](https://github.com/junegunn/goyo.vim) and [limelight](https://github.com/junegunn/limelight.vim) which go some way to reproducing the distraction free environment of many other editors. However, I no longer use them. Both worked well, but vim doesn't have that many distractions without them. When I am writing, I open vim in a full screen terminal. I don't even have a clock visible. Being able to highlight the paragraph I am currently working on or putting the text in the middle of the screen wasn't worth it for me. ## Proselint [Proselint](https://github.com/amperser/proselint), as the name suggests, is a linter for prose. It points out areas where my writing could be better. To use it with vim, I have the following autofunction: ```vim function! mine#functions#proselint() abort let oldmakeprg = &l:makeprg " set new value of makeprg and call the function set makeprg=proselint\ % make copen " set makeprg back to old value let &l:makeprg = oldmakeprg endfunction ``` and a mapping: ```vim nnoremap p :call mine#functions#proselint() ``` This allows me to fill the quickfix list with a list of suggestions from proselint. ## LanguageTool LanguageTool is similar in concept to Proselint although seems to have a lot more checks under its hood. It can be intergrated into vim in a similar way to Proselint, with an autofunction. ```vim function! mine#functions#languagetool() abort let oldmakeprg = &l:makeprg let olderrformat = &l:errorformat " set new value of makeprg and call the function set makeprg=languagetool\ -l\ en-GB\ % let &l:errorformat = \ '%-GPicked up _JAVA_OPTIONS: %.%#,' . \ '%-GExpected text language: %.%#,' . \ '%-PWorking on %f...,' . \ '%-I%.%# [main] DEBUG %.%#,' . \ '%+IUsing %.%# for file %.%#,' . \ '%I%\d%\+.) Line %l\, column %c\, Rule ID: %m,' . \ '%-CMessage%m,' . \ '%-CSuggestion%m,' . \ '%-CMore info%m,' . \ '%-C%\s%#^%\+%\s%#,' . \ '%-C%.%#,' . \ '%-Z%\s%#,' . \ '%-Q,' . \ '%-GTime: %.%#' make copen " set makeprg back to old value let &l:makeprg = oldmakeprg let &l:makeprg = olderrformat endfunction ``` You will notice that this is slightly longer because the error format used by Proselint is compatible with Vim's default. LanguageTool's is not.