Sunday, May 8, 2016

Make auto-completion insert multi-line text at one selection

It seems the auto-completion feature does not allow multi-line text to be inserted at this point:

function! g:MultiLineCompletion(findstart, basetext)
if a:findstart == 1
return col('.')
else
return ["multi-\nline\ncompletion"]
endif
endfunction

tabedit tmp.txt
setlocal omnifunc=g:MultiLineCompletion

After sourcing this snipet, trigger Omni-completion inside the "tmp.txt" buffer (default <C-x><C-o>), and select the only option (default <C-y>). I was expecting three lines to be inserted at one time:

multi-
line
completion

But instead I got this:

multi-^@line^@completion

'^@' is the Nul character.

I didn't know <newline> would be replaced in the completion list, after numerous try I finally came up with this really tedious solution:

function! s:PostCompletionWork()
if pumvisible()
return "\<C-Y>\<Esc>:if getline('.')=~'\\n'\|s/\<Nul>/\<C-v>\<CR>/ge\|call setpos('.', [0, line('.'), len(getline('.')), 0])\|endif\<CR>a"
else
return ' '
endif
endfunction

inoremap <expr> <Space> <SID>PostCompletionWork()

This worked.

---------------------------------------------------------------------------

The current custom completion feature has some limitations:

*. Can only be invoked under Insert Mode, custom key mapping has to be made to trigger it.

*. Can only insert the user selection to the current buffer, not possible to obtain the selection as a return value (like input()).

*. Multi-line insertion is not easily done (as shown)

*. Not possible to tell which the current selection is until the text is actually inserted (i.e. when the pop-up menu is still visible).

*. Does not allow abbreviation of the option text. When the text is long, the pop-up menu looks really messy.

*. Mysterious type E523 Error prevents you from doing meaningful modification after the text was inserted. i.e. this won't work:

inoremap <expr> <Space> "<C-Y>" . <SID>PostCompletionWork()
function! s:PostCompletionWork()
s/^@/^M/ge " do some modification to the inserted text
return ''
endfunction

A E523 Error will show up telling you such operations inside the function s:PostCompletionWork() is not safe and shall be prohibited


Can someone familiar with the implementation of Vim tell whether the custom-completion feature can be enhanced to become a general UI feature for user selection? The most useful IMHO would be:

*. Allow normal mode invocation

*. Pass the selection as a return value, instead of inserting it to the current buffer

Thanks ~




--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment