Tab inline completion (#498)

* On backspace, deactivate menu and do not complete

Fixes #5497

* Make Tab insert (partial) completion instead of select next menu item

* Fix history search filtering
This commit is contained in:
Dan Davison 2022-10-22 16:52:11 -04:00 committed by GitHub
parent da27f0041a
commit 30713abe87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 12 deletions

View File

@ -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),

View File

@ -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),

View File

@ -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

View File

@ -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]),
]),
);