I have a thesaurus file which contains synonyms for the word iterate. I would like to add an alternative phrase for iterate like loop over so I added it to the thesaurus. Unfortunately, this doesn't work. Vim displays "loop over" as two entries.

This is from :help thesaurus

'thesaurus' 'tsr'   string  (default "")
        global or local to buffer |global-local|
        {not in Vi}
List of file names, separated by commas, that are used to lookup words
for thesaurus completion commands |i_CTRL-X_CTRL-T|.

Each line in the file should contain words with similar meaning,
separated by non-keyword characters (white space is preferred).
Maximum line length is 510 bytes.

It looks like whitespace is used to separate entries of the thesaurus. Which is weird because, up until this point, I had only been using a comma-separated list for the thesaurus and that worked fine.

Escaping the space character doesn't work unfortunately.

Does anyone know how I can get a phrase as a thesaurus option for a specific word?


To add sentences as thesaurus, you need the 'iskeyword' option to contain the space character (32 in ascii). Your thesaurus file should then contain spaces only to separate words in a thesaurus sentence and not to separate entries :

iterate,loop,loop over

I found this post that works well to add 32 to 'iskeyword' just before launching the popup menu, then removes it after a short time period. The trick is to set iskeyword+=32 after setting a self-destructing autocmd that restores it after 200ms, so you keep your iskeyword clean.

Here is an updated version :

function! Keyword32()
    let s:saved_iskeyword = &iskeyword
    let s:saved_updatetime = &updatetime
    if &updatetime > 200 | let &updatetime = 200 | endif
    augroup Keyword32
        autocmd CursorHold,CursorHoldI <buffer>
                    \ let &updatetime = s:saved_updatetime |
                    \ let &iskeyword = s:saved_iskeyword |
                    \ autocmd! Keyword32
    augroup END
    set iskeyword+=32
inoremap <c-x><c-t> <C-O>:call Keyword32()<CR><c-x><c-t>

Note that with this mapping, when you would like to use the ^X submode, it will take 'timeoutlen'ms until it shows you the -- ^X mode (^]^D...) line. You could map something else if you want. Also make sure you have a reasonable timeoutlen in insert mode.

Update : since vim 8.0, you can use a timer instead of the autocmd :

function! Thesaurus32()
    if has('timers') && !empty(&thesaurus)
        call timer_start(200, {_->execute('set iskeyword-=32')})
        set iskeyword+=32
    return "\<c-x>\<c-t>"
inoremap <expr> <c-x><c-t> Thesaurus32()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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