diff --git a/src/core_editor/editor.rs b/src/core_editor/editor.rs index 66ab7b0b..0c4298ab 100644 --- a/src/core_editor/editor.rs +++ b/src/core_editor/editor.rs @@ -55,6 +55,7 @@ impl Editor { EditCommand::MoveWordRightEnd => self.line_buffer.move_word_right_end(), EditCommand::MoveBigWordRightEnd => self.line_buffer.move_big_word_right_end(), EditCommand::InsertChar(c) => self.line_buffer.insert_char(*c), + EditCommand::Complete => {} EditCommand::InsertString(str) => self.line_buffer.insert_str(str), EditCommand::InsertNewline => self.line_buffer.insert_newline(), EditCommand::ReplaceChar(chr) => self.replace_char(*chr), diff --git a/src/engine.rs b/src/engine.rs index 177dc563..8b301bc7 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -915,25 +915,43 @@ impl Reedline { self.run_edit_commands(&commands); if let Some(menu) = self.menus.iter_mut().find(|men| men.is_active()) { if self.quick_completions && menu.can_quick_complete() { - menu.menu_event(MenuEvent::Edit(self.quick_completions)); - menu.update_values( - &mut self.editor, - self.completer.as_mut(), - self.history.as_ref(), - ); - - if menu.get_values().len() == 1 { - return self.handle_editor_event(prompt, ReedlineEvent::Enter); + match commands.first() { + Some(&EditCommand::Backspace) + | Some(&EditCommand::BackspaceWord) + | Some(&EditCommand::MoveToLineStart) => { + menu.menu_event(MenuEvent::Deactivate) + } + _ => { + menu.menu_event(MenuEvent::Edit(self.quick_completions)); + menu.update_values( + &mut self.editor, + self.completer.as_mut(), + self.history.as_ref(), + ); + if let Some(&EditCommand::Complete) = commands.first() { + if menu.get_values().len() == 1 { + return self + .handle_editor_event(prompt, ReedlineEvent::Enter); + } else if self.partial_completions + && menu.can_partially_complete( + self.quick_completions, + &mut self.editor, + self.completer.as_mut(), + self.history.as_ref(), + ) + { + return Ok(EventStatus::Handled); + } + } + } } } - if self.editor.line_buffer().get_buffer().is_empty() { menu.menu_event(MenuEvent::Deactivate); } else { menu.menu_event(MenuEvent::Edit(self.quick_completions)); } } - Ok(EventStatus::Handled) } ReedlineEvent::OpenEditor => self.open_editor().map(|_| EventStatus::Handled), diff --git a/src/enums.rs b/src/enums.rs index d89b0be1..ec6375d4 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -99,6 +99,9 @@ pub enum EditCommand { /// Clear to the end of the current line ClearToLineEnd, + /// Insert completion: entire completion if there is only one possibility, or else up to shared prefix. + Complete, + /// Cut the current line CutCurrentLine, @@ -216,6 +219,7 @@ impl Display for EditCommand { EditCommand::DeleteWord => write!(f, "DeleteWord"), EditCommand::Clear => write!(f, "Clear"), EditCommand::ClearToLineEnd => write!(f, "ClearToLineEnd"), + EditCommand::Complete => write!(f, "Complete"), EditCommand::CutCurrentLine => write!(f, "CutCurrentLine"), EditCommand::CutFromStart => write!(f, "CutFromStart"), EditCommand::CutFromLineStart => write!(f, "CutFromLineStart"), @@ -287,6 +291,7 @@ impl EditCommand { | EditCommand::DeleteWord | EditCommand::Clear | EditCommand::ClearToLineEnd + | EditCommand::Complete | EditCommand::CutCurrentLine | EditCommand::CutFromStart | EditCommand::CutFromLineStart diff --git a/src/main.rs b/src/main.rs index c9bf364c..8add9505 100644 --- a/src/main.rs +++ b/src/main.rs @@ -262,7 +262,7 @@ fn add_menu_keybindings(keybindings: &mut Keybindings) { KeyCode::Tab, ReedlineEvent::UntilFound(vec![ ReedlineEvent::Menu("completion_menu".to_string()), - ReedlineEvent::MenuNext, + ReedlineEvent::Edit(vec![EditCommand::Complete]), ]), );