Deoplete.nvim: Enter should close popupmenu and enter a line break (default / completeopt+=noselect)

Created on 7 Jun 2017  路  31Comments  路  Source: Shougo/deoplete.nvim

vimrc:

set rtp+=~/.vim/plugged/deoplete.nvim
call deoplete#enable()
foo.bar
foo.baz
foo.

Typing b after foo. will offer bar and baz (with "[M]") hint.
Pressing Enter then will close the popup menu, and the cursor will stay there.
But since by default completeopt+=noinsert gets used (and not 'noselect'), the cursor should move to the next line.

After typing ba followed by <Backspace> <Enter> will close the popup (leaving "foo.b"), and jump to the next line (as expected).

It seems like 'noselect' gets used by default, but if the user had 'noinsert' already, then Enter should probably select the first entry when pressing Enter?! (and this seems to work as expected)

It seems to be related to what eeda83b does, since that fixed an intermediate problem, where the popup would need two Enter presses before being closed even.

I am using Neovim master, let me know if you need more information, and/or cannot reproduce it.

Most helpful comment

Why not use a mapping to workaround this on your own?

inoremap <expr> <CR> (pumvisible() ? "\<c-y>\<cr>" : "\<CR>")

All 31 comments

Pressing Enter then will close the popup menu, and the cursor will stay there.
But since by default completeopt+=noinsert gets used (and not 'noselect'), the cursor should move to the next line.

This is Vim's feature. I cannot fix it.
You can map the behavior.

I think Vim/neovim cannot change the behavior.
It breaks the backward compatibility.

After typing ba followed by will close the popup (leaving "foo.b"), and jump to the next line (as expected).

I don't understand. Please describe the reproduce ways like this.

  • :2iba<Backspace>
  • Blah
  • Blah

I am using Neovim master, let me know if you need more information, and/or cannot reproduce it.

Please add more detailed information.

It seems like 'noselect' gets used by default, but if the user had 'noinsert' already, then Enter should probably select the first entry when pressing Enter?! (and this seems to work as expected)

I don't understand it.

With this minimal.vimrc, run nvim -u minimal.vimrc:

set rtp+=~/.vim/plugged/deoplete.nvim
call deoplete#enable()

set cmdheight=2
set shortmess+=c

norm! ifoo.bar
norm! ofoo.baz
norm! ofoo

OK (closes popup and goes to line 4)

  1. a.ba<Backspace><Enter> will go to line 4
  2. a.barbar<Enter>

NOT OK (closes popup, but stays in line 4)

  1. a.ba<Enter> (v:completed_item.word is ba?!)
  2. a.b<Enter> (v:completed_item.word is b?!)

It seems like 'noselect' gets used by default, but if the user had 'noinsert' already, then Enter should probably select the first entry when pressing Enter?! (and this seems to work as expected)
I don't understand it.

If you set completeopt+=noinsert, deoplete will not add noselect there, and then <Enter> will always select the first popup entry (like expected), and not go to the next line.

You can see (especially with noinsert) that <Backspace> seems to rebuild/redraw the popupmenu menu, and that's maybe where deoplete gets it wrong: the <Backspace> seems to trigger CompleteDone.

When pressing <Enter> after foo.b v:completed_item is completed: {'word': 'b', 'menu': '', 'info': '', 'kind': '', 'abbr': ''}, while it is {} when pressing <Backspace> triggers CompleteDone, or pressing <Enter> after foo.ba.

btw: what do you think about having tests for those nasty issues?
I could imagine doing those in tmux (see https://github.com/junegunn/vader.vim/pull/124 for where I've worked on adding this for Vader).

btw: what do you think about having tests for those nasty issues?
I could imagine doing those in tmux (see junegunn/vader.vim#124 for where I've worked on adding this for Vader).

To add the tests is better.
But I don't want to use Vader.
Please use themis instead.

a.ba<Backspace><Enter> will go to line 4

It is not expected behavior. Not OK.
I will check the behavior.

I have checked the behavior.

  • If the candidate is selected or noinsert, not go to the next line
  • If the candidate is not selected or noselect, go to the next line
  • If narrowing, not go to the next line

This is Vim/neovim feature. Closing.

a.ba<Enter> (v:completed_item.word is ba?!)
a.b<Enter> (v:completed_item.word is b?!)

narrowing pattern.

a.ba<Backspace><Enter> will go to line 4

noselect pattern. The completion window is re-generated by deoplete.

a.barbar<Enter>

no completion window pattern

The behavior of the key depends on the state you are in:
first state: Use the text as it is and insert a line break.
second state: Insert the currently selected match.
third state: Use the text as it is and insert a line break.

In other words: If you used the cursor keys to select another entry in the
list of matches then the key inserts that match. If you typed
something else then inserts a line break.

I don't want to change the <CR> behavior.

Why not use a mapping to workaround this on your own?

inoremap <expr> <CR> (pumvisible() ? "\<c-y>\<cr>" : "\<CR>")

Why not use a mapping to workaround this on your own?

It means deoplete should change <CR> behavior?

Because, it is easy to conflict with other plugins and other configurations.
<CR> is easily mapped.

second state: Insert the currently selected match.

There is never a currently selected match.. it uses completeopt=noselect, and I am not selecting a word.

But it indeed happens with Neovim itself, when using completeopt=menu,preview,noselect: it will also not insert a line break after backspacing.

Using Ctrl-P on foo.b, entering a to narrow it down and the using >Enter> will go back to foo.b however!
So it seems to be a feature in Vim to close the popupmenu and dismiss the text entered during completion?!

I think deoplete could detect this, since it gets a word in v:completed_item that is not in the completions:

completed: {'word': 'ba', 'menu': '', 'info': '', 'kind': '', 'abbr': ''}

It could look for empty abbr here, given that it would be present always?!

The behavior seems to get triggered by narrowing down the selection, and using <Backspace> seems to reset this, so that <Enter> after it adds a line break, since no narrowing down happened then.

A workaround is to use let g:deoplete#enable_refresh_always = 1, but that seems to be resource intensive?!

Something to play with maybe?!

diff --git i/autoload/deoplete/handler.vim w/autoload/deoplete/handler.vim
index 925ca9b..edac4bf 100644
--- i/autoload/deoplete/handler.vim
+++ w/autoload/deoplete/handler.vim
@@ -22,6 +22,7 @@ function! deoplete#handler#_init() abort
   if g:deoplete#enable_refresh_always
     autocmd deoplete InsertCharPre * call s:completion_begin('InsertCharPre')
   endif
+  autocmd deoplete InsertCharPre * let s:last_insertchar = pumvisible() ? v:char : 0

   call s:on_event('Init')
 endfunction
@@ -207,6 +208,10 @@ function! s:complete_done() abort
     endif
   endif

+  if !empty(v:completed_item) && empty(v:completed_item.abbr) && v:char == 29
+    call feedkeys("\<cr>")
+  endif
+
   if !g:deoplete#enable_refresh_always
     call deoplete#handler#_skip_next_completion()
   endif

Something to play with maybe?!

This is ugly hack. I don't want to change it.
The <CR> mapping is better.

So it seems to be a feature in Vim to close the popupmenu and dismiss the text entered during completion?!

Yes.

But I don't want to use Vader.
Please use themis instead

Why?

Why?

Because, I don't learn other DSL for testing.
And I know themis' author.
I trust him.

I think the Vim/NeoVim docs (:help popupmenu-completion) do specify the behavior @blueyed is suggesting. From the docs:

There are three states:

1. A complete match has been inserted, e.g., after using CTRL-N or CTRL-P.
2. A cursor key has been used to select another match.  The match was not
   inserted then, only the entry in the popup menu is highlighted.
3. Only part of a match has been inserted and characters were typed or the
   backspace key was used.  The list of matches was then adjusted for what is
   in front of the cursor.

[...]

The behavior of the <Enter> key depends on the state you are in:
first state:      Use the text as it is and insert a line break.
second state:     Insert the currently selected match.
third state:      Use the text as it is and insert a line break.

This makes sense, because otherwise the menu is very obtrusive/annoying.

If I don't need the suggestion, ex. ending a line of Ruby with ... do and hit enter, but it has a suggestion for "do", my eyes have already moved to the next line but my cursor hasn't moved. "Oh, there was a suggestion. <cr> again" I have to think. It's inconsistent though, because if I end a line with ... { there won't be a suggestion and <cr> works.

It only makes sense to steal <cr> if the user has interacted with the menu, which is what is specified by the popupmenu-completion docs.

Yes, there are workarounds, but so far they've broken at least lexima.vim (a plugin that auto-closes braces, including moving your cursor to the correct spot after auto-closing followed by <cr>). Maybe a different workaround or a different plugin would work, but it seems like the root issue is deoplete has non-standard behavior here.

but it seems like the root issue is deoplete has non-standard behavior here.

Really???
deoplete need to map <CR> mapping?
Please describe it more clearly.
(Please describe your suggestion)

deoplete can map <CR> behavior, but it conflicts with lexima.vim.
So it does not fix your problem.

And please describe the conflict with lexima behavior with minimal vimrc with reproduce instruction.
I don't work without them.

It seems workaround exists.

https://github.com/cohama/lexima.vim/issues/65#issuecomment-339338677

I don't want to steal <CR> behavior, other plugins may overwrite it and user may overwrite it.
It is easy to conflict.

It only makes sense to steal if the user has interacted with the menu, which is what is specified by the popupmenu-completion docs.

It is this.
https://github.com/Shougo/deoplete.nvim/issues/1043#issuecomment-560909021

I think user should choose the behavior using <CR> maps.
Plugin cannot select what is the best.

I'm sorry, my apologies, the issues is entirely lexima.vim's fault. Based on the answers in these tickets, I thought it was an unresolved deoplete issue based on a misreading of the documentation.

I read the response to this ticket as "not going to fix it" but I think the answer is it does work this way. With a fresh config that doesn't include lexima.vim, deoplete works as expected with respect to newline behavior.

Sorry again.

OK. I get it.
I have updated FAQ.

Thank you @woahdae for pointing this out!

I recently switched over to lexima as well and I could never find out why the popup menu selection with would always insert a new line. It was driving me crazy!

Thank you for including the note in your FAQ @Shougo ! That is the ONLY I eventually discovered the issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

callmekohei picture callmekohei  路  4Comments

firedev picture firedev  路  4Comments

tomspeak picture tomspeak  路  5Comments

markers16123 picture markers16123  路  3Comments

westlywright picture westlywright  路  6Comments