Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 21 additions & 15 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,7 @@ impl Reedline {
| ReedlineEvent::MenuRight
| ReedlineEvent::MenuPageNext
| ReedlineEvent::MenuPagePrevious
| ReedlineEvent::PartialComplete
| ReedlineEvent::ViChangeMode(_) => Ok(EventStatus::Inapplicable),
}
}
Expand All @@ -954,6 +955,22 @@ impl Reedline {
event: ReedlineEvent,
) -> io::Result<EventStatus> {
match event {
ReedlineEvent::PartialComplete => {
let Some(menu) = self.menus.iter_mut().find(|menu| menu.is_active()) else {
return Ok(EventStatus::Inapplicable);
};
if self.partial_completions
&& menu.can_partially_complete(
&mut self.editor,
self.completer.as_mut(),
self.history.as_ref(),
)
{
Ok(EventStatus::Handled)
} else {
Ok(EventStatus::Inapplicable)
}
}
ReedlineEvent::Menu(name) => {
if self.active_menu().is_none() {
if let Some(menu) = self.menus.iter_mut().find(|menu| menu.name() == name) {
Expand All @@ -973,7 +990,6 @@ impl Reedline {

if self.partial_completions
&& menu.can_partially_complete(
self.quick_completions,
&mut self.editor,
self.completer.as_mut(),
self.history.as_ref(),
Expand All @@ -987,26 +1003,17 @@ impl Reedline {
}
Ok(EventStatus::Inapplicable)
}
ReedlineEvent::MenuNext => {
if let Some(menu) = self.menus.iter_mut().find(|menu| menu.is_active()) {
ReedlineEvent::MenuNext => match self.active_menu() {
None => Ok(EventStatus::Inapplicable),
Some(menu) => {
if menu.get_values().len() == 1 && menu.can_quick_complete() {
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(),
);
}
menu.menu_event(MenuEvent::NextElement);
Ok(EventStatus::Handled)
}
} else {
Ok(EventStatus::Inapplicable)
}
}
},
ReedlineEvent::MenuPrevious => {
self.active_menu()
.map_or(Ok(EventStatus::Inapplicable), |menu| {
Expand Down Expand Up @@ -1197,7 +1204,6 @@ impl Reedline {
.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(),
Expand Down
4 changes: 4 additions & 0 deletions src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,9 @@ pub enum ReedlineEvent {

/// Change mode (vi mode only)
ViChangeMode(String),

/// Complete the command given the common prefix of items in current open menu
PartialComplete,
}

impl Display for ReedlineEvent {
Expand Down Expand Up @@ -877,6 +880,7 @@ impl Display for ReedlineEvent {
ReedlineEvent::ExecuteHostCommand(_) => write!(f, "ExecuteHostCommand"),
ReedlineEvent::OpenEditor => write!(f, "OpenEditor"),
ReedlineEvent::ViChangeMode(_) => write!(f, "ViChangeMode mode: <string>"),
ReedlineEvent::PartialComplete => write!(f, "PartialComplete"),
}
}
}
Expand Down
11 changes: 3 additions & 8 deletions src/menu/columnar_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,19 +501,13 @@ impl Menu for ColumnarMenu {
/// in the given line buffer
fn can_partially_complete(
&mut self,
values_updated: bool,
editor: &mut Editor,
completer: &mut dyn Completer,
) -> bool {
// If the values were already updated (e.g. quick completions are true)
// there is no need to update the values from the menu
if !values_updated {
self.update_values(editor, completer);
}

Comment on lines -508 to -513
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very sure that it's safe to remove this. But I think it's a bad idea to handle quick completion related menu updates here.

if can_partially_complete(self.get_values(), editor) {
// The values need to be updated because the spans need to be
// recalculated for accurate replacement in the string
// TODO: recalculate the spans instead of calling the completer 1 more time
self.update_values(editor, completer);

true
Expand Down Expand Up @@ -785,7 +779,8 @@ mod tests {
editor.set_buffer(input.to_string(), UndoBehavior::CreateUndoPoint);
let mut completer = FakeCompleter::new(&$completions);

menu.can_partially_complete(false, &mut editor, &mut completer);
menu.update_values(&mut editor, &mut completer);
menu.can_partially_complete(&mut editor, &mut completer);

assert_eq!(editor.get_buffer(), expected);
}
Expand Down
1 change: 0 additions & 1 deletion src/menu/description_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,6 @@ impl Menu for DescriptionMenu {
/// The menu does not need to partially complete
fn can_partially_complete(
&mut self,
_values_updated: bool,
_editor: &mut Editor,
_completer: &mut dyn Completer,
) -> bool {
Expand Down
11 changes: 3 additions & 8 deletions src/menu/ide_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,19 +601,13 @@ impl Menu for IdeMenu {

fn can_partially_complete(
&mut self,
values_updated: bool,
editor: &mut Editor,
completer: &mut dyn Completer,
) -> bool {
// If the values were already updated (e.g. quick completions are true)
// there is no need to update the values from the menu
if !values_updated {
self.update_values(editor, completer);
}

if can_partially_complete(self.get_values(), editor) {
// The values need to be updated because the spans need to be
// recalculated for accurate replacement in the string
// TODO: recalculate the spans instead of calling the completer 1 more time
self.update_values(editor, completer);

true
Expand Down Expand Up @@ -1342,7 +1336,8 @@ mod tests {
editor.set_buffer(input.to_string(), UndoBehavior::CreateUndoPoint);
let mut completer = FakeCompleter::new(&$completions);

menu.can_partially_complete(false, &mut editor, &mut completer);
menu.update_values(&mut editor, &mut completer);
menu.can_partially_complete(&mut editor, &mut completer);

assert_eq!(editor.get_buffer(), expected);
}
Expand Down
1 change: 0 additions & 1 deletion src/menu/list_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,6 @@ impl Menu for ListMenu {
/// all registered values
fn can_partially_complete(
&mut self,
_values_updated: bool,
_editor: &mut Editor,
_completer: &mut dyn Completer,
) -> bool {
Expand Down
15 changes: 5 additions & 10 deletions src/menu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ pub trait Menu: Send {
/// in the given line buffer
fn can_partially_complete(
&mut self,
values_updated: bool,
editor: &mut Editor,
completer: &mut dyn Completer,
) -> bool;
Expand Down Expand Up @@ -305,23 +304,20 @@ impl ReedlineMenu {

pub(crate) fn can_partially_complete(
&mut self,
values_updated: bool,
editor: &mut Editor,
completer: &mut dyn Completer,
history: &dyn History,
) -> bool {
match self {
Self::EngineCompleter(menu) => {
menu.can_partially_complete(values_updated, editor, completer)
}
Self::EngineCompleter(menu) => menu.can_partially_complete(editor, completer),
Self::HistoryMenu(menu) => {
let mut history_completer = HistoryCompleter::new(history);
menu.can_partially_complete(values_updated, editor, &mut history_completer)
menu.can_partially_complete(editor, &mut history_completer)
}
Self::WithCompleter {
menu,
completer: own_completer,
} => menu.can_partially_complete(values_updated, editor, own_completer.as_mut()),
} => menu.can_partially_complete(editor, own_completer.as_mut()),
}
}

Expand Down Expand Up @@ -398,18 +394,17 @@ impl Menu for ReedlineMenu {

fn can_partially_complete(
&mut self,
values_updated: bool,
editor: &mut Editor,
completer: &mut dyn Completer,
) -> bool {
match self {
Self::EngineCompleter(menu) | Self::HistoryMenu(menu) => {
menu.can_partially_complete(values_updated, editor, completer)
menu.can_partially_complete(editor, completer)
}
Self::WithCompleter {
menu,
completer: own_completer,
} => menu.can_partially_complete(values_updated, editor, own_completer.as_mut()),
} => menu.can_partially_complete(editor, own_completer.as_mut()),
}
}

Expand Down