I can complete functions with omnicomplete using c-x c-o
but it only adds the opening parenthesis, is it possible to make it add the closing parenthesis and put my cursor between them? Seems unaffected by auto-pairs and delimitmate, which work fine when I type the opening parenthesis, but not when it's inserted during completion.
You could try the following code:
inoremap <C-x><C-o> <C-r>=<SID>close_paren()<CR><C-x><C-o>
function! s:close_paren() abort
augroup close_paren
autocmd!
autocmd CompleteDone <buffer> if v:completed_item.word =~# '($'
\| call feedkeys(")\<Left>", 'in')
\| endif
\| autocmd! close_paren
\| augroup! close_paren
augroup END
return ''
endfunction
It should remap the key sequence C-x C-o
, so that the custom function s:close_paren()
is evaluated before invoking omni completion.
The function installs a fire-once autocmd, watching the CompleteDone
event, described in :h completedone
:
CompleteDone After Insert mode completion is done. Either
when something was completed or abandoning
completion. |ins-completion|
The |v:completed_item| variable contains
information about the completed item.
The autocmd inserts the keys:
)<Left>
... in the typeahead buffer. That is a closing parenthesis, then the Left
key to position the cursor between the 2 parentheses.
If you want to change the inserted keys, you can do so by changing them inside the first argument passed to the feedkeys()
function, whose usage is explained in :h feedkeys()
:
feedkeys({string} [, {mode}]) *feedkeys()*
Characters in {string} are queued for processing as if they
come from a mapping or were typed by the user.
By default the string is added to the end of the typeahead
buffer, thus if a mapping is still being executed the
characters come after them. Use the 'i' flag to insert before
other characters, they will be executed next, before any
characters from a mapping.
The function does not wait for processing of keys contained in
{string}.
To include special keys into {string}, use double-quotes
and "\..." notation |expr-quote|. For example,
feedkeys("\<CR>") simulates pressing of the <Enter> key. But
feedkeys('\<CR>') pushes 5 characters.
The 2nd argument ('in'
) contains 2 flags whose meaning is explained like this:
'n' Do not remap keys.
'i' Insert the string instead of appending (see above).
The autocmd should be local to the buffer because of the pattern <buffer>
, and delete itself once the completion has been performed, because of these commands:
autocmd! close_paren
augroup! close_paren
The first one removes the autocmd from the augroup, the 2nd one removes the augroup. You can't remove an augroup if it's not empty, as explained in :h augroup-delete
:
:aug[roup]! {name} Delete the autocmd group {name}. Don't use
this if there is still an autocommand using
this group! You will get a warning if doing
it anyway. when the group is the current group
you will get error E936.
The reason why the autocmd removes itself is because even though you want to close a parenthesis when invoking omni completion, you may not want this behavior for every other kind of completion.
If you use the mapping, don't like any suggestion in the popup menu, and exit the latter by hitting C-e
, or if you don't complete a function name but another kind of syntax element, the autocmd shouldn't insert anything, because it checks whether the last character is an open parenthesis:
if v:completed_item.word =~# '($'
v:completed_item
is an internal variable containing a dictionary with various information related to the last text you completed. Here, you only use the key word
to be sure the last character is an open parenthesis, but if you wanted more info, maybe to build a more complex condition before deciding to call feedkeys()
, you could use other keys.
Currently there seems to be 5 of them:
word
menu
info
kind
abbr
The meaning of their values is given in :h complete-items
:
word the text that will be inserted, mandatory
abbr abbreviation of "word"; when not empty it is used in
the menu instead of "word"
menu extra text for the popup menu, displayed after "word"
or "abbr"
info more information about the item, can be displayed in a
preview window
kind single letter indicating the type of completion