Sunday, May 8, 2016

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

2016-05-08 16:39 GMT+03:00 Jacky Liu <bluegene8210@gmail.com>:
> 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.

This is NUL character only when written to the file. Internally this
is the NL character: Vim uses NUL-terminated strings that cannot
contain NUL. So the result is not surprising.

See :h NL-used-for-Nul.

>
> 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 ~

AFAIR some snippet plugins like UltiSnips have something like this.
You may want to check how this is implemented.

>
>
>
>
> --
> --
> 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.

--
--
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: