Add file specific good words to internal vim wordlist (via modeline)

spell-checkvim

Is it possible to add correctly spelled words to vim's internal wordlist via modeline? Or another file specific method?

Vim can add words to the temporary internal-wordlist via key command zG or :spellgood! {word}. Can the same be done on the modeline?

An example would be following text where I want the acronyms "RAS" and "RAP" to be considered good words when using vim's spell checking.

RAS syndrome (short for "redundant acronym syndrome syndrome"), also
known as PNS syndrome ("PIN number syndrome syndrome", which expands
to "personal identification number number syndrome syndrome") or RAP
phrases ("redundant acronym phrase phrases"), refers to the use of one
or more of the words that make up an acronym or initialism in
conjunction with the abbreviated form, thus in effect repeating one or
more words.

Text was copied from http://en.wikipedia.org/wiki/RAS_syndrome

Best Answer

Currently Vim provides no "native" mechanism to do this, although I think it is a good idea. The only thing I can think of is an :autocmd that calls a function that searches for a special section in the file and then moves the cursor over the words in that section and triggers zG with :normal commands. This would be messy and I would be reluctant to bother with it.

Edit: Of course, somehow I overlooked the existence of :spellgood!, even though it is in your question. This makes the job much more feasible. I came up with a basic implementation which you can tweak to fit your needs:

function! AutoSpellGoodWords()
    let l:goodwords_start = search('\C-\*-SpellGoodWordsStart-\*-', 'wcn')
    let l:goodwords_end = search('\C-\*-SpellGoodWordsEnd-\*-', 'wcn')
    if l:goodwords_start == 0 || l:goodwords_end == 0
        return
    endif
    let l:lines = getline(l:goodwords_start + 1, l:goodwords_end - 1)
    let l:words = []
    call map(l:lines, "extend(l:words, split(v:val, '\\W\\+'))")
    for l:word in l:words
        silent execute ':spellgood! ' . l:word
    endfor
endfunction

autocmd BufReadPost * call AutoSpellGoodWords()

This will search for a block that looks something like this:

-*-SpellGoodWordsStart-*-
word1 word2 word3
word4 word5 ...
-*-SpellGoodWordsEnd-*-

And each word it finds--in this case, word1, word2, word3, word4, and word5--within the block it will add to the temporary good words list.

Just be aware that I have not stress-tested this.