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

Vim will also give the user correction options by pressing z=.

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:

:set spell

We can set a language by using the command:

:set spelllang=en

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

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

On The vimrc

This is the language section in the vimrc:

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 InitLanguage, ToggleSpell, and 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.

Initialize Language

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.

Key Binds

Next, we set the already mention key binds. They are <leader>a and <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>

Display

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 .asm and .s, I mean programs written for the x86 instruction set using the AT&T syntax, since that was what I used when writing Assembly)

Closing

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.

<- Prev – 03 Folds and why I don’t use them

Tags:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: