Stuff in my vimrc: 04 Spelling and Natural Language
I use vim for almost everything I write, regardless of that being a program, data file, email, blog post, research paper, etc. To write such things I need to use natural languages such as English. A blog post or documentation, for example, will be almost entirely in English. A program, while being a very different form of text, will still have variable names, comments, and so on, in English.
The thing is… Natural language is hard to spell, and I tend to make a few more typos then I would like. (I’m sure you will find some example in my blog posts).
Luckily, Vim comes with a built in spell check feature that works very well! In particular, it can do spell check in certain sections of code files. For example, while editing a Python file, it will do spell check in comments and identifier names. It will even spell check the individual words in an underscored identifier
Vim will also give the user correction options by pressing
Like this, while using Vim, I can have a very high degree of certainty that what I’m writing is correctly spelled.
Basics In Vim
To get the basics working is pretty easy. To enable spell check we use the following command:
We can set a language by using the command:
Or, just join both:
:set spell spelllang=en
If all you want if to have English spell check enabled at startup, them simple place that last command in your
vimrc, and your done. You might want to, at some point, change the language or turn off spell check, and when that happens, simple run these commands:
:set spelllang=pt :set nospell
Off course, we can go a bit further then that. But first, I must speak about my usage of language in Vim.
My Natural Languages
The vast majority of time that I use Vim, I use it to write in English. But sometimes I want to write a text in another language, those languages being my native Portuguese or the language which I’m currently learning, German.
Because I use these three languages, it is very common that I open a new vim instance and want to quickly change the current spell checked languages from the default English to either Portuguese or German. So I’ve implemented a state machine that lets me alternate from English, to Portuguese, to German, back to English. The alternation happens when I press
It is also common for me to want to turn off spell check. This may happen because I might open some plain text file that may not contain an actual natural language text, or a language which I don’t use. It also may be that a given file type doesn’t have proper spell check like a Python file, so it happens that Vim identifies every ASCII character as a spelling mistake. To turn spell check off, and back on, I press
On The vimrc
This is the language section in the
fu! InitLanguage() set spell spelllang=en let b:language = 0 endfu fu! ToggleSpell() set spell! endfu " Function to toggle between the used languages fu! ToggleLanguage() if b:language == 0 set spelllang=pt let b:language = 1 elseif b:language == 1 set spelllang=de let b:language = 2 else set spelllang=en let b:language = 0 endif endfu " Initialize language variables for every new buffer autocmd BufWinEnter,FileType * :call InitLanguage() " Toggle between the languages, or just toggle the spell functionality nnoremap <silent> <leader>a :call ToggleLanguage()<CR> nnoremap <silent> <leader>s :call ToggleSpell()<CR> " Underline spelling mistakes hi clear SpellBad hi SpellBad cterm=underline " Remove spell check from some files autocmd BufEnter *.sql :set nospell autocmd BufEnter *.erl :set nospell autocmd BufEnter *.asm :set nospell autocmd BufEnter *.s :set nospell autocmd BufEnter *.go :set nospell
Functions and State Machine
To begin with, we define the functions
ToggleLanguage. The first function simply sets spell check using the single liner like stated before and initializes the state machine. The second function toggles the value of the
spell setting. So every time this is called, spell check either turns off or on. The third function alternated the three states of the state machine, making spell check go from EN, to PT, to DE, back to EN.
The state is kept by the variable
b:language. It is a buffer variable (the leading
b: indicates that). This because spell checking is kept at a buffer level, meaning that, different files in vim might be set to different spell checking languages.
Continuing in the
vimrc, we have the auto command:
" Initialize language variables for every new buffer autocmd BufWinEnter,FileType * :call InitLanguage()
This makes Vim set our default spell check and initialize our state machine by running the
init function. The function executes when a buffer is displayed in a window or when the file type for that buffer changes.
Next, we set the already mention key binds. They are
<leader>s. Both are key binds for normal mode only:
" Toggle between the languages, or just toggle the spell functionality nnoremap <silent> <leader>a :call ToggleLanguage()<CR> nnoremap <silent> <leader>s :call ToggleSpell()<CR>
To display the actual errors, we need to tell vim to underline them using the following lines:
" Underline spelling mistakes hi clear SpellBad hi SpellBad cterm=underline
I only need this because there is a plugin that interferes with spelling underlining. Without these lines in my file, I don’t see spelling errors underlined.
Remove Spell Check For Certain File Types
With some file types, I prefer to simply have spell check off by default. This might happen because the spell checking in those files might not be good enough, or not exist at all.
To do this, I have the following auto commands
" Remove spell check from some files autocmd BufEnter *.sql :set nospell autocmd BufEnter *.erl :set nospell autocmd BufEnter *.asm :set nospell autocmd BufEnter *.s :set nospell autocmd BufEnter *.go :set nospell
In order, we have files of types: SQL, Erlang, Assembly, Assembly* again, and Go. With Erlang and Assembly, the native syntax support does not distinguish what should be spell checked and what should not, so opening a file with spell check on will lead to having everything marked as an error.
With SQL and Go, spell checking works, but it happens that I see far to much code written in camel case, or having identifier names that are not regular words and are instead abbreviations. Because of this, a file in SQL or Go will be marked with many spelling errors, even if they are not technically an error.
Beside, I can simply do
<leader>s to turn on spell checking to see if a comment, for example, is correctly written, and turn the thing off again to continue working.
(* By Assembly files with extensions
.s, I mean programs written for the x86 instruction set using the AT&T syntax, since that was what I used when writing Assembly)
This is how I use spell checking in Vim. There are other native shortcuts that allow a user to jump to the next/previous error. I actually never use these, so I don’t even remember them.