Spell Checking with an Autocommand in Vim
After decades of using Vim, I still need to get back to basics: today, how options have a scope and the consequences when enabling them from autocommands.
1 Enabling Spell Checking when Opening a File or Creating a New One
For files in some locations of my filesystem, I like having spell checking turned on automatically. Files such as this post I'm in the process of writing now. For this, I have a line similar to this one in my ~/.vimrc
:
autocmd BufNewFile,BufRead ~/posts/*.md set spell spelllang=en_gb
Without much surprise, this will work out of the box: spell checking will be enabled and the language set to British English whenever I create a new Markdown file or open an existing one somewhere under the ~/posts
directory, e.g. when running vim ~/posts/foo.md
. Specifying BufNewFile
and BufRead
as events is in fact a common practice. So far, so good.
2 Enabling Spell Checking when Vimgrepping
My curiosity was piqued when I noticed that spell checking wasn't turned on whenever a Markdown file under ~/posts
was opened using :vimgrep
. However, the language was correctly set to en_gb
from that same autocommand. There seems to be a special interaction with specifically :vimgrep
and the 'spell'
option. And that interaction is scope.
I regularly read the Vim documentation, but there's something I'd blatantly overlooked all these years: in addition to their type, availability in different Vi flavours and required compile-time options, options can be marked as e.g. global, local to buffer or, as is the case for the 'spell'
option, local to window.
And so I went trying all the autocommand events pertaining to windows, considering WinNew
, WinEnter
, WinLeave
, CmdwinEnter
, CmdwinLeave
, BufWinLeave
and, crucially, BufWinEnter
, which indeed happened to do the job for enabling spell checking from :vimgrep
:
autocmd BufNewFile,BufRead,BufWinEnter ~/posts/*.md set spell spelllang=en_gb
The reason why that hadn't been necessary for the 'spelllang'
option is because it is local to buffer, and therefore covered by the BufNewFile
and BufRead
events which we had already been using.
This isn't the whole story, clearly. Why in particular is it that just running vim ~/posts/foo.md
without the BufWinEnter
event did work? What is it that executing the vim
command does that running :vimgrep
doesn't do? I may have found a way to have spell checking enabled with :vimgrep
, but I haven't gotten to the bottom of it all yet.