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
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.
|
||
|
|
||
|
|