From 262d1d76012dab0e58aec4479cdfb02e74a95078 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 23 Feb 2022 17:35:46 -0600 Subject: [PATCH 1/4] ignore Enter keypress when menu has no selection supersedes #1622 Builds on the work in #1285. I want to allow Enter to create a newline when there is no selection in the autocomplete menu. This occurs somewhat often when using LSP autocomplete in Elixir which uses `do/end` blocks (and I set the autocomplete menu delay to 0 which exacerbates the problem): ```elixir defmodule MyModule do def do_foo(x) do x end def other_function(y) do| end ``` Here the cursor is `|` in insert mode. The LSP suggests `do_foo` but I want to create a newline. Hitting Enter currently closes the menu, so I end up having to hit Enter twice when the module contains any local with a `do` prefix, which can be inconsistent. With this change, we ignore the Enter keypress to end up creating the newline in this case. --- helix-term/src/ui/menu.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index 1839da470c36..4631992f778f 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -231,8 +231,10 @@ impl Component for Menu { key!(Enter) => { if let Some(selection) = self.selection() { (self.callback_fn)(cx.editor, Some(selection), MenuEvent::Validate); + return close_fn; + } else { + return EventResult::Ignored(None); } - return close_fn; } // KeyEvent { // code: KeyCode::Char(c), From e04c3a050306df989fa5ad8a9bbc91e8e056e782 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 25 Feb 2022 05:54:43 -0600 Subject: [PATCH 2/4] pop compositor layer when ignoring Enter keypress --- helix-term/src/ui/menu.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index 4631992f778f..399ed463e148 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -233,7 +233,11 @@ impl Component for Menu { (self.callback_fn)(cx.editor, Some(selection), MenuEvent::Validate); return close_fn; } else { - return EventResult::Ignored(None); + return EventResult::Ignored(Some(Box::new( + |compositor: &mut Compositor, _| { + compositor.pop(); + }, + ))); } } // KeyEvent { From 038aaa1b3f46d478875b4c85a1382aa12226f70a Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 25 Feb 2022 12:07:22 -0600 Subject: [PATCH 3/4] move closing function out of consumed event result closure --- helix-term/src/ui/menu.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index 399ed463e148..236fd247218c 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -205,16 +205,16 @@ impl Component for Menu { _ => return EventResult::Ignored(None), }; - let close_fn = EventResult::Consumed(Some(Box::new(|compositor: &mut Compositor, _| { + let close_fn = Some(Box::new(|compositor: &mut Compositor, _| { // remove the layer compositor.pop(); - }))); + })); match event.into() { // esc or ctrl-c aborts the completion and closes the menu key!(Esc) | ctrl!('c') => { (self.callback_fn)(cx.editor, self.selection(), MenuEvent::Abort); - return close_fn; + return EventResult::Consumed(close_fn); } // arrow up/ctrl-p/shift-tab prev completion choice (including updating the doc) shift!(Tab) | key!(Up) | ctrl!('p') | ctrl!('k') => { @@ -231,13 +231,9 @@ impl Component for Menu { key!(Enter) => { if let Some(selection) = self.selection() { (self.callback_fn)(cx.editor, Some(selection), MenuEvent::Validate); - return close_fn; + return EventResult::Consumed(close_fn); } else { - return EventResult::Ignored(Some(Box::new( - |compositor: &mut Compositor, _| { - compositor.pop(); - }, - ))); + return EventResult::Ignored(close_fn); } } // KeyEvent { From 1324e4094ba9ccf318d9d2bb4385edc063e262fa Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sat, 26 Feb 2022 05:17:33 -0600 Subject: [PATCH 4/4] explicitly label close_fn as an 'Option' --- helix-term/src/ui/menu.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helix-term/src/ui/menu.rs b/helix-term/src/ui/menu.rs index 236fd247218c..d67a429e37f3 100644 --- a/helix-term/src/ui/menu.rs +++ b/helix-term/src/ui/menu.rs @@ -1,5 +1,5 @@ use crate::{ - compositor::{Component, Compositor, Context, EventResult}, + compositor::{Callback, Component, Compositor, Context, EventResult}, ctrl, key, shift, }; use crossterm::event::Event; @@ -205,7 +205,7 @@ impl Component for Menu { _ => return EventResult::Ignored(None), }; - let close_fn = Some(Box::new(|compositor: &mut Compositor, _| { + let close_fn: Option = Some(Box::new(|compositor: &mut Compositor, _| { // remove the layer compositor.pop(); }));