I want Vim's completion menu to work more like the one in Visual Studio. I want to be able to write the start of a variable (or something which completion is available), hit the omni-completion keys and get the completion menu. Now I want the completion menu to highlight the best match but not add it to the buffer. Now I want to be able to either hit ENTER to input the selected element or enter more letters to filter the completion menu even more (possibly highlighting a new item in the completion menu) and then hit enter to insert.
The wiki page/tips at http://vim.wikia.com/wiki/Make_Vim_completion_popup_menu_work_just_like_in_an_IDE is supposed to do this but I can't get it to work. Has someone else tried the code from that tip and made it work as I describe?
The referenced wiki page contained broken mappings. A user (Spiiph) changed the Vim code to something that looked better to him, but was not right. I reversed the changes he made and now the inoremap statements should work.
To avoid confusion these are IMHO the right commands:
inoremap <expr> <c-n> pumvisible() ? "\<lt>c-n>" : "\<lt>c-n>\<lt>c-r>=pumvisible() ? \"\\<lt>down>\" : \"\"\<lt>cr>"
inoremap <expr> <m-;> pumvisible() ? "\<lt>c-n>" : "\<lt>c-x>\<lt>c-o>\<lt>c-n>\<lt>c-p>\<lt>c-r>=pumvisible() ? \"\\<lt>down>\" : \"\"\<lt>cr>"
PS: When it comes to using Vim's completion feature I found the SuperTab script
very convenient. Maybe this script is also interesting for you in this context...
I use supertab, which I really like, and the following seems to work great:
imap <expr> <Tab> pumvisible() ? "<Tab>" : "<Tab><Down>"
For reference: I'm running debian sid, and this works both for vim 7.2.245 and for my patched 7.2.259.
Related
I'm using the CoC plugin for which works great.
This command remaps the enter key so we can use enter to confirm selection of the suggestion popover.
This mapping works great, except that it stays in insert mode after accepting the selection:
inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"`
From https://github.com/neoclide/coc.nvim/wiki/Completion-with-sources#use-cr-to-confirm-completion
How can I modify this to return back to normal mode after I hit enter?
Any ideas? Thanks!
First, let's deconstruct the mapping you got from that page:
inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
inoremap makes it a non-recursive insert mode mapping. i means "insert mode" and nore means "non-recursive". I know the remap at the end makes it tempting to call those things "remaps" or "remappings" but they are not. They are just "mappings".
<expr> makes it an expression mapping. It means that the right-hand side is an expression that is going to be evaluated at runtime to produce the actual RHS.
pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>" is what Vim calls a "trinary operator" (AKA ternary operator): :help trinary. In plain english, it reads like this: "if the popup menu is visible, return <C-y>, if not, return <C-g>u<CR>".
:help complete_ctrl-y accepts the current suggestion in the popup menu.
:help ctrl-g_u prevents Vim from inserting an undo point before <CR>. It is not strictly necessary but good practice.
You want to adjust the mapping's behaviour when you accept a suggestion so it is the "\<C-y>" part that must be changed.
Now…
you already know what key to press to leave insert mode,
you can take a look at :help key-notation if you are unsure how to represent that key,
you know what part of the mapping you need to change,
you should get an idea of how to proceed just by looking at the two last parts of the "trinary" operator.
I'm Neovim user
and I use Plugin neoclide/coc.vim for autocompletion
but when my cursor focus out, I can not get suggestion box again
(How can I call this box? suggest box or hint box? I want to know this box name)
I want to trigger it and see again, Is there any command or variable for this?
Yes, the answer is on the front page of CoC's github project. You need to map something to coc#refresh(). For instance, to use Ctrl + Space to trigger completion, you need to put the following in your vimrc:
inoremap <silent><expr> <c-space> coc#refresh()
There are more examples on the project's page.
TLDR: try this Ctrl+#
I found this in README of neoclide/coc.nvim:
" Use <c-space> to trigger completion.
if has('nvim')
inoremap <silent><expr> <c-space> coc#refresh()
else
inoremap <silent><expr> <c-#> coc#refresh()
endif
The weirdness here is that, Ctrl+Space is not working, despite using neovim NOT vim.
But there is a good trick to get your desired key binding as it appears from your terminal emulator point of view:
Enter insert mode
Press Ctrl+v
Then press your keys you want to bind, Ctrl+Space
Ops! nothing is inserted in my case. It seems that my terminal doesn't recognize using Ctrl and Space or understands this keybinding differently and intercepts it. So this is the real problem!
Things I tried to solve the problem:
I changed the default coc config a little bit:
inoremap <silent><expr> <c-space> coc#refresh()
inoremap <silent><expr> <c-#> coc#refresh()
I tried bash as I was using zsh as a shell, but the problem is still there.
Then I tried another terminal emulator and the problem is solved, alhamdulillah.
I've commented in https://github.com/neoclide/coc.nvim/issues/2299#issuecomment-686293001
The suggestion box in your image is signatureHelp. If you want to reopen it, you need to trigger triggerCharacters in your function, usually is ( and ,. The triggerCharacters is defined by LS.
To Browse from suggestion box:
- <Tab >
- <Ctrl - x> <Ctrl -f>
- <Ctrl - p ><Ctrl -n>
- <Ctrl - n ><Ctrl -n>
To Confirm selection
- <Ctrl - y>
I'm using a plugin that performs multiple *noremap operations in its initialization. After I added the following mapping to YCM/UltiSnips:
inoremap <expr> <CR> pumvisible() ? "<C-R>=<SID>ExpandSnippetOrReturn()<CR>" : "\<CR>"
I've broken the other plugin's ability to see the <Enter> key, or rather I overrode/destroyed the original inoremap. I want to reenable that functionality, but without disabling ability to pick snippets from the auto-complete menu using Enter key. This keymap is effectively saying "if the menu is visible, select the option, otherwise simulate <Enter> key". What I need it to say instead is "if the menu is visible, select the option, otherwise perform whatever command <Enter> key is already mapped to". So basically, at the time of declaration of this inoremap, I need to expand existing inoremap for this key into the else.
I've looked at <C-R>=feedkeys('<CR>')<CR> and <C-R>=mapcheck('\<CR>', 'i')<CR> but couldn't get either to work. Can someone help me out?
Finally figured it out... this was way more vim troubleshooting than I needed for one day.
function! LoadPumvisibleEnter()
let smartmap = maparg("<Enter>", "i")
execute printf('inoremap <script> <expr> <CR> pumvisible() ? "<C-R>=<SID>ExpandSnippetOrReturn()<CR>" : %s', smartmap)
endfunction
au VimEnter * :execute LoadPumvisibleEnter()
throwing it in a function allowed me to stay sane with escapes and which mode I was in
autocommand is needed because vim apparently runs vimrc BEFORE loading any plugins (Does Vim load plugins after loading vimrc?), so without it the map will not yet be set
So in insert mode if you hit ctrl-x s on a misspelled word you get a nicely formatted popup menu of spelling suggestions. This is awesome.
The comparable command in normal mode (z=), however, gives a bland plain-text list that eats the whole screen.
I've partially solved this by adding the following keybinding in my .vimrc:
nnoremap <Leader>s ea<C-X><C-S>
This works perfectly and hitting s in normal mode gives me the same drop down... The only problem is I'm now left in insert mode at the end of everything. Is there some way to get the drop down style selection and end up in normal mode after the replace is all said and done?
You can't do it directly. The popup menu you're thinking of is specifically referred to as "insert mode completion".
However, you're halfway there, by mapping a key that enters insert mode and starts the completion. Now all you need is to map a key that selects the entry (like the 'enter' key) to also exit insert mode.
You should test the return value of pumvisible() in your mapping, to prevent it firing when you don't want. Example (from comments):
inoremap <expr> <CR> pumvisible() ? "\<C-y><Esc>" : "\<CR>"
Perhaps you could also set a variable or something, or use a key you won't use to end actual insert mode completion.
Somehow my macvim/vim instance is expanding every tab to the autocomplete menu, this prevents me from tabbing my code.. I really dont have a clue about the why.
My vimrc is here: https://github.com/jvanbaarsen/dotfiles/blob/master/vimrc
a screenshot of the problem:
(the "happens" text, is the first appearance in the autocomplete list, i tabbed on a newline though)
I hope someone can help me, this is driving me insane!
I had found this online and used it in my vimrc to "fix" the problem. But it was still kinda a pain, so I just retrained myself to use ctrl-p. not the url in the comment was valid at one time, but is not longer..
" Remap the tab key to do autocompletion or indentation depending on the
" context (from http://www.vim.org/tips/tip.php?tip_id=102)
function! InsertTabWrapper()
let col = col('.') - 1
if !col || getline('.')[col - 1] !~ '\k'
return "\<tab>"
else
return "\<c-p>"
endif
endfunction
inoremap <silent> <tab> <c-r>=InsertTabWrapper()<cr>
inoremap <s-tab> <c-n>
I think i found the problem, it was the 'ervandew/supertab' bundle, after removing it, i was able to use vim normally.
The supertab plugin aims at both keeping usual indentation functionality of <Tab> key and completing with it. I personally don’t use it using self-written function instead, but possible causes of your issue are described in the very first question in the FAQ placed in the README file available right at project homepage:
Why isn't supertab honoring my configured settings (attempts to complete at the start of a line, always performs keyword completion instead of my configured default, etc.)?
Chances are that you have a very old version of snipmate installed, or something similar, which will issue a <c-n> when no snippet is found. Supertab use to map to <c-n>, so this behavior would act as a fallback to supertab, but current versions of supertab no longer do so, resulting in snipmate bypassing supertab entirely.
You can check if this is the case by running the following in vim to see what is mapped to <tab>:
:verbose imap <tab>
To resolve the issue you can either:
Install my fork or
Upgrade to a more recent snipmate fork, like garbase/vim-snipmate
See #74 for additional details.