NeoVim has a built in spell checker. However, it tends to only check comments and not the code itself. To some, this is ideal. However, I am a really bad speller and want to make sure I am not calling my variable names something crazy. So, I want to spell check even my code, not just the comments.

:set spell

The first thing you will find when looking into this, is :set spell. However, this will not highlight syntax words. The culprit for this, is https://github.com/lewis6991/spellsitter.nvim and therefore the merging of this functionality into the core at https://github.com/neovim/neovim/pull/19419

With set spell before spellsitter merge:

Settings Result
syntax off, Treesitter disabled syntax off no treesitter
syntax on, Treesitter disabled syntax_on_no_treesitter
Treesitter enabled ts_no_spellsitter
Treesitter (with spellsitter), ts_plus_spellsitter

If you want the Treesitter enabled option (spellcheck my code,) then you will have to disable this functionality.

The Fix

Treesitter has a config option that will work around this issue.

require('nvim-treesitter.configs').setup {
  highlight = {
    enable = true,
    -- Setting this to true will run `:h syntax` and tree-sitter at the same time.
    -- Set this to `true` if you depend on 'syntax' being enabled (like for indentation).
    -- Using this option may slow down your editor, and you may see some duplicate highlights.
    -- Instead of true it can also be a list of languages
    additional_vim_regex_highlighting = true, -- defaults to `false`
  },

As you can see, one issue with this, is that it may slow down you editor. If you find that to be an issue, there isn’t much that can be done about it.

Additional Settings

For a full, but short, guide on setting up and using the built in spell feature, please read NeoVim: Using the spellchecker by John McBride.

The only additional thing I think is worth bringing up, is spelloptions. More specifically, camel case. Meaning, my config will end up setting up the dictionary (language) you want to use, and camel case.

vim.o.spelllang = 'en_us'
vim.o.spell = true
vim.o.spelloptions = "camel"

There are other interesting options you can explore in the docs, as always.

Alternative Options

Alternatively, you can skip the native spell and use a plugin. The VSCode one, seems to be the only decent alternative.

https://github.com/iamcco/coc-spell-checker

There are some pros and cons to this option. For one, it doesn’t use the built in system and is written in TypeScript. But it does have easier to configure exceptions and dictionaries already exist for your favorite language. Another big thing, is that it ignores words shorter than 4 characters. I have tried to setup rules to achieve this functionality with the native system, but it did not work out.

Disclaimer: I do not know how this plugin handles large files, compared to the above proposed solution. It might be better or worse. But please, try it out and configure your very own PDE.