5

I use the complete function a lot. I have not found a solution to complete a WORD yet. For example, in LaTeX, I use the following expression:

T_{R_{delta}}

If I type T and then Ctrl+xCtrl+n, it wouldn't complete the whole thing.

I know I could use

:set iskeyword+=_:; etc.

but I want this behaviour just in this situation.

I am looking for a complete mechanism which completes everything like vW would visualize.

0

1 Answer 1

2

I asked a similar question a few weeks ago (how to complete a tag name containing a colon) and here was the answer.


Your question is slightly different as you don't want to temporarily add a colon to the value of 'iskeyword' but all characters which can appear inside a WORD.

Here's a different version of the original answer which redefines the behavior of <C-X><C-N> to autocomplete WORDS instead of words:

inoremap <C-X><C-N> <C-O>:call <SID>CustomKeyword(join(map(range(char2nr('!'),char2nr('~')), 'nr2char(v:val)'), ''))<CR><C-X><C-N>

function! s:CustomKeyword(chars) abort
    for char in split(a:chars, '\zs')
        execute 'setlocal iskeyword+=' . char2nr(char)
    endfor
    augroup custom_keyword
        autocmd!
        autocmd CompleteDone * setlocal iskeyword< | autocmd! custom_keyword
    augroup END
endfunction

The characters inside the string that you pass as an argument to the function CustomKeyword() will be added to the buffer-local value of 'isk', and the autocmd will reset the option once the completion is done by copying the global value into the buffer-local one (setlocal iskeyword<), as well as remove itself (| autocmd! custom_keyword).

Besides, you want to complete WORDS whose characters should be any printable character except a whitespace. According to this chart, it seems the first printable character is the exclamation mark ! and the last is the tilde ~. Thus, the string of printable characters could be obtained with the following code:

join(map(range(char2nr('!'),char2nr('~')), 'nr2char(v:val)'), '')

Which is the string passed as an argument to CustomKeyword() inside the {rhs} of the previous mapping whose {lhs} is <C-X><C-N>.


Note that you could reuse the CustomKeyword() function to change 'isk' in any way.
For example, if you wanted to autocomplete tag names containing a colon, you could install the following mapping:

inoremap <C-X><C-]> <C-O>:call <SID>CustomKeyword(':')<CR><C-X><C-]>

The general syntax would be:

inoremap {lhs} <C-O>:call <SID>CustomKeyword('characters_to_add_to_isk')<CR>{lhs}

Where {lhs} is the keys you hit to trigger the completion (<C-X><C-N>, <C-X><C-]>, ...).


If you want to preserve the original behavior of <C-X><C-N>, and use another {lhs} to trigger the custom completion, for example <C-X><C-A>, you could use this mapping:

inoremap <C-X><C-A> <C-O>:call <SID>CustomKeyword(join(map(range(char2nr('!'),char2nr('~')), 'nr2char(v:val)'), ''))<CR><C-X><C-N>

You just have to change the first <C-X><C-N> in the original {lhs}, but not the second one in the {rhs}.

4
  • Thanks. I would like to not map it to <C-X><C-N> in order to maintain its original function. I would like to use a combination which isnt used by the completion system like <C-X><C-A>. Unfortunately this doesnt work.
    – BananaJoe
    Commented Mar 23, 2016 at 11:11
  • Maybe <C-X><C-U> would work. Usually it's used in combination with a custom completion function whose name is defined by the option 'completefunc'. Edit: ah no it doesn't seem to work. I'm gonna try something else, sorry.
    – saginaw
    Commented Mar 23, 2016 at 11:15
  • @user3394244 I've edited the answer to include a mapping which uses <C-X><C-A>, it seems to work. You just have to change the first <C-X><C-N> in the original {lhs}, but not the second one in the {rhs}.
    – saginaw
    Commented Mar 23, 2016 at 11:21
  • WORD completion with "@" in it doesn't work. Although its in the ASCII chart.
    – BananaJoe
    Commented Mar 26, 2016 at 11:58

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