8

If I'm editing a text file with :set spell, is there any way to have vim not check words within the boundaries of certain characters against the word list? I want to be able to write things like proper nouns or technical vocabulary (or even 'sic' quotations) but not have to add them to the wordlist.

3
  • 1
    I think this needs proper syntax support. Commented May 16, 2019 at 10:00
  • @ChristianBrabandt I take it to mean this is not possible then ? Or, at least not with what capacity vim has already for handling (highlighting, indentation, etc.) different syntax ?
    – myc3lium
    Commented May 16, 2019 at 11:09
  • 1
    What Christian means is that you can do it, but only through the @nospell keyword in syntax highlight files (see :help syn-spell). What kind of file are you editing? Does it already have existing syntax highlighting? Commented May 16, 2019 at 12:00

2 Answers 2

5

You can add your own syntax element (probably overriding existing one):

syntax match quoteblock /"[^"]\+"/ contains=@NoSpell
  • syntax match: Tells vim this is a syntax command
  • quoteblock: The name of our match (Could be anything)
  • /"..."/: Match things between quotes
  • [^"]\+: Match anything that's not a quote
  • contains=@NoSpell: Tells vim not to use spell check on this match

It is just an example and not very smart :). In my case it stops checking spelling inside quotes:

enter image description here

UPD

You can add to your vimrc the mapping such as:

nnoremap <leader>s :syntax match quoteblock /"[^"]\+"/ contains=@NoSpell<CR>

Then press <leader>s (you know what <leader> is right?) to add this syntax element to the current buffer.

Another option is to add a command:

command! TurnOffSpellcheckForQuotes :syntax match quoteblock /"[^"]\+"/ contains=@NoSpell

Then just run this command from vim :TurnOffSpellcheckForQuotes

4
  • Do I just put this into my rc file then ?
    – myc3lium
    Commented May 16, 2019 at 14:01
  • Yes, this should work in your vimrc.
    – Tumbler41
    Commented May 16, 2019 at 14:16
  • @myc3lium make sure it works for your files (text? c++? latex? markdown?) -- open your file and enter the command from the answer :syntax.... Then if it works it would be better to create an autocommand that will source :syntax.. for you specific filetypes. And this should be in your vimrc
    – Maxim Kim
    Commented May 16, 2019 at 17:10
  • You can also enable it upon opening each file by putting :au Syntax * :syntax match … in your vimrc, provided that you did :syntax enable before that.
    – Maëlan
    Commented Jun 7, 2022 at 23:17
1

If your file already have a syntax highlight, such as vim. You can do it like this:

Preparation

Add following function and command to your vimrc:

function! s:synstack()
  if !exists('*synstack') | return | endif
  return map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')
endfunc
command! Synstack echo s:synstack()

Assume current file content like this:

function! Foo()
  return "balabala"
endfunction

Get Syntax name

place your cursor at balabala, execute :Synstack, output is:

['vimFuncBody', 'vimString']

It's stack of current syntax, from outside function to current string. vimString is syntax name of string in vim.

Get Syntax definition

syntax list vimString
--- Syntax items ---
vimString      xxx start=/[^a-zA-Z>!\\@]"/ms=s+1,lc=1 skip=/\\\\\|\\"/ matchgroup=vimStringEnd end=/"/  oneline keepend contains=@vimStringGroup 
                   start=/[^a-zA-Z>!\\@]'/ms=s+1,lc=1 end=/'/  oneline keepend 
                   start=/=!/ms=s+1,lc=1 skip=/\\\\\|\\!/ end=/!/  oneline contains=@vimStringGroup 
                   start=/=+/ms=s+1,lc=1 skip=/\\\\\|\\+/ end=/+/  oneline contains=@vimStringGroup 
                   start=+\s/\s*\A+ms=s+1,lc=1 skip=/\\\\\|\\+/ end=+/+  oneline contains=@vimStringGroup 
                   match /"[^"]*\\$/  contained nextgroup=vimStringCont skipnl 
                   match /[^(,]'[^']\{-}\zs'/  
                   start=/^\s*\\\z(['"]\)/ skip=/\\\\\|\\\z1/ end=/\z1/  oneline keepend contains=@vimStringGroup,vimContinue 
                   links to String

I don't understand above output, the only thing matters is contains=@vimStringGroup. So this syntax contains a cluster called vimStringGroup

Add NoSpell to cluster

syntax cluster vimStringGroup add=@NoSpell

Done.

  • :h :syn-contain
  • :h :syn-cluster
  • :h :spell-syntax
1
  • Thanks, this was helpful, I think i found a general approach if you want your pattern to match regardless of surrounding groups: add containedin=ALL to the same line as syn match ... contains=@NoSpell
    – PLATO
    Commented Jul 27 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.