You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
5.8 KiB

3 years ago
---
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 <C-l> <c-g>u<Esc>[s1z=`]a<c-g>u
```
1. `<c-g>u` - break undo sequence (new change)
1. `<Esc>` - 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. `<c-g>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 ! !<C-g>u
inoremap , ,<C-g>u
inoremap . .<C-g>u
inoremap : :<C-g>u
inoremap ; ;<C-g>u
inoremap ? ?<C-g>u
inoremap ( <C-g>u(
inoremap ) )<C-g>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 <leader>p :call mine#functions#proselint()<CR>
```
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.