I have an insert mode mapping which calls a function to select some text and leave vim in select mode.
inoremap <silent> <C-J> <C-\><C-O>:call MyFunction()<CR>
This works in regular insert mode; and it works when the insert-mode completion popup window is visible and I haven't pressed ctrl-p or ctrl-n.
It doesn't work when the insert-mode completion popup window is visible and I have pressed ctrl-p or ctrl-n. In this case:
- the cursor moves to the expected location;
- the literal text
:call MyFunction()with a newline is inserted in place of the text I wanted to be selected;
- vim remains in insert mode instead of switching to select mode.
I believe this is because the
C-\ at the start of the RHS is not part of the current completion option, so it has the effect of accepting the completion, which triggers
CompleteDone, which executes
MyFunction() (I listen for the
CompleteDone event and in my listener call
MyFunction()), and then the rest of the RHS is taken literally.
function! MyFunction() ... stopinsert call setpos("'<", ...) call setpos("'>", ...) execute "normal! gv\<C-G>" endfunction
I tried this variation instead:
inoremap <silent> <C-J> <C-R>=pumvisible() ? '<C-Y>' : MyFunction()<CR>
This works when the completion window is open, both when I have and haven't pressed ctrl-p / ctrl-n; but it doesn't work in regular insert mode (it moves the cursor to the start of the line and switches to normal mode – I suspect because
MyFunction() doesn't have an explicit
return, and so implicitly returns
0, which takes the cursor to the start of the line).
How can I get the mapping to work all the time?