Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enter should close popupmenu and enter a line break (default / completeopt+=noselect) #492

Closed
blueyed opened this issue Jun 6, 2017 · 31 comments

Comments

@blueyed
Copy link
Contributor

blueyed commented Jun 6, 2017

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.

@Shougo
Copy link
Owner

Shougo commented Jun 7, 2017

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.

@Shougo
Copy link
Owner

Shougo commented Jun 7, 2017

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.

@Shougo
Copy link
Owner

Shougo commented Jun 7, 2017

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.

@blueyed
Copy link
Contributor Author

blueyed commented Jun 7, 2017

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.

@blueyed
Copy link
Contributor Author

blueyed commented Jun 7, 2017

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

@Shougo
Copy link
Owner

Shougo commented Jun 7, 2017

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.

@Shougo
Copy link
Owner

Shougo commented Jun 7, 2017

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

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

@Shougo
Copy link
Owner

Shougo commented Jun 7, 2017

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.

@Shougo Shougo closed this as completed Jun 7, 2017
@Shougo
Copy link
Owner

Shougo commented Jun 7, 2017

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

@Shougo
Copy link
Owner

Shougo commented Jun 7, 2017

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.

@Shougo
Copy link
Owner

Shougo commented Jun 7, 2017

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

@roxma
Copy link
Contributor

roxma commented Jun 7, 2017

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

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

@Shougo
Copy link
Owner

Shougo commented Jun 7, 2017

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.

@blueyed
Copy link
Contributor Author

blueyed commented Jun 7, 2017

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.

@blueyed
Copy link
Contributor Author

blueyed commented Jun 7, 2017

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

@blueyed
Copy link
Contributor Author

blueyed commented Jun 7, 2017

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

@Shougo
Copy link
Owner

Shougo commented Jun 8, 2017

Something to play with maybe?!

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

@Shougo
Copy link
Owner

Shougo commented Jun 11, 2017

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

Yes.

@balta2ar
Copy link
Contributor

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

Why?

@Shougo
Copy link
Owner

Shougo commented Mar 20, 2018

Why?

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

@woahdae
Copy link

woahdae commented Jun 10, 2020

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.

@Shougo
Copy link
Owner

Shougo commented Jun 10, 2020

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)

@Shougo
Copy link
Owner

Shougo commented Jun 10, 2020

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

@Shougo
Copy link
Owner

Shougo commented Jun 10, 2020

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

@Shougo
Copy link
Owner

Shougo commented Jun 10, 2020

It seems workaround exists.

cohama/lexima.vim#65 (comment)

@Shougo
Copy link
Owner

Shougo commented Jun 10, 2020

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

@Shougo
Copy link
Owner

Shougo commented Jun 10, 2020

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.
#1043 (comment)

@Shougo
Copy link
Owner

Shougo commented Jun 10, 2020

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

@woahdae
Copy link

woahdae commented Jun 10, 2020

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.

@Shougo
Copy link
Owner

Shougo commented Jun 10, 2020

OK. I get it.
I have updated FAQ.

@Blake-LeBlanc
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants