Skip to content

Commit

Permalink
Add config for keeping menu always open
Browse files Browse the repository at this point in the history
  • Loading branch information
HKalbasi committed Aug 24, 2024
1 parent 020142f commit eece782
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 6 deletions.
7 changes: 5 additions & 2 deletions examples/ide_completions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn add_menu_keybindings(keybindings: &mut Keybindings) {
KeyCode::Tab,
ReedlineEvent::UntilFound(vec![
ReedlineEvent::Menu("completion_menu".to_string()),
ReedlineEvent::MenuNext,
ReedlineEvent::MenuAccept,
]),
);
keybindings.add_binding(
Expand Down Expand Up @@ -96,7 +96,10 @@ fn main() -> io::Result<()> {
.with_min_description_width(min_description_width)
.with_max_description_width(max_description_width)
.with_description_offset(description_offset)
.with_correct_cursor_pos(correct_cursor_pos);
.with_correct_cursor_pos(correct_cursor_pos)
.with_activate_on_start(true)
.with_keep_active_after_accept(true)
.with_treat_submit_as_accept(false);

if border {
ide_menu = ide_menu.with_default_border();
Expand Down
10 changes: 10 additions & 0 deletions src/completion/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ impl Completer for DefaultCompleter {
}
}
}
} else {
let span = Span::new(0, 0);
completions.extend(self.root.collect("").into_iter().map(|value| Suggestion {
value,
description: None,
style: None,
extra: None,
span,
append_whitespace: false,
}));
}
completions.dedup();
completions
Expand Down
48 changes: 44 additions & 4 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,9 @@ impl Reedline {
#[must_use]
pub fn with_menu(mut self, menu: ReedlineMenu) -> Self {
self.menus.push(menu);
if self.active_menu().is_none() {
self.activate_menus_on_start();
}
self
}

Expand Down Expand Up @@ -915,6 +918,7 @@ impl Reedline {
| ReedlineEvent::HistoryHintWordComplete
| ReedlineEvent::OpenEditor
| ReedlineEvent::Menu(_)
| ReedlineEvent::MenuAccept
| ReedlineEvent::MenuNext
| ReedlineEvent::MenuPrevious
| ReedlineEvent::MenuUp
Expand Down Expand Up @@ -965,6 +969,24 @@ impl Reedline {
}
Ok(EventStatus::Inapplicable)
}
ReedlineEvent::MenuAccept => {
match self.menus.iter_mut().find(|menu| menu.is_active()) {
None => Ok(EventStatus::Inapplicable),
Some(menu) => {
menu.replace_in_buffer(&mut self.editor);
if !menu.settings().keep_active_after_accept {
menu.menu_event(MenuEvent::Deactivate);
} else {
menu.update_values(
&mut self.editor,
self.completer.as_mut(),
self.history.as_ref(),
);
}
Ok(EventStatus::Handled)
}
}
}
ReedlineEvent::MenuNext => match self.active_menu() {
None => Ok(EventStatus::Inapplicable),
Some(menu) => {
Expand Down Expand Up @@ -1083,13 +1105,23 @@ impl Reedline {
Ok(EventStatus::Handled)
}
ReedlineEvent::Enter | ReedlineEvent::Submit | ReedlineEvent::SubmitOrNewline
if self.menus.iter().any(|menu| menu.is_active()) =>
if self
.menus
.iter()
.any(|menu| menu.is_active() && menu.settings().treat_submit_as_accept) =>
{
for menu in self.menus.iter_mut() {
if menu.is_active() {
if menu.is_active() && menu.settings().treat_submit_as_accept {
menu.replace_in_buffer(&mut self.editor);
menu.menu_event(MenuEvent::Deactivate);

if !menu.settings().keep_active_after_accept {
menu.menu_event(MenuEvent::Deactivate);
} else {
menu.update_values(
&mut self.editor,
self.completer.as_mut(),
self.history.as_ref(),
);
}
return Ok(EventStatus::Handled);
}
}
Expand Down Expand Up @@ -1271,6 +1303,13 @@ impl Reedline {
.for_each(|menu| menu.menu_event(MenuEvent::Deactivate));
}

fn activate_menus_on_start(&mut self) {
self.menus
.iter_mut()
.filter(|menu| menu.settings().activate_on_start)
.for_each(|menu| menu.menu_event(MenuEvent::Activate(false)));
}

fn previous_history(&mut self) {
if self.history_cursor_on_excluded {
self.history_cursor_on_excluded = false;
Expand Down Expand Up @@ -1875,6 +1914,7 @@ impl Reedline {
}
self.run_edit_commands(&[EditCommand::Clear]);
self.editor.reset_undo_stack();
self.activate_menus_on_start();

Ok(EventStatus::Exits(Signal::Success(buffer)))
}
Expand Down
4 changes: 4 additions & 0 deletions src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,9 @@ pub enum ReedlineEvent {
/// Trigger a menu event. It activates a menu with the event name
Menu(String),

/// Accepts the current menu suggestion
MenuAccept,

/// Next element in the menu
MenuNext,

Expand Down Expand Up @@ -677,6 +680,7 @@ impl Display for ReedlineEvent {
ReedlineEvent::Multiple(_) => write!(f, "Multiple[ {{ ReedLineEvents, }} ]"),
ReedlineEvent::UntilFound(_) => write!(f, "UntilFound [ {{ ReedLineEvents, }} ]"),
ReedlineEvent::Menu(_) => write!(f, "Menu Name: <string>"),
ReedlineEvent::MenuAccept => write!(f, "MenuAccept"),
ReedlineEvent::MenuNext => write!(f, "MenuNext"),
ReedlineEvent::MenuPrevious => write!(f, "MenuPrevious"),
ReedlineEvent::MenuUp => write!(f, "MenuUp"),
Expand Down
27 changes: 27 additions & 0 deletions src/menu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ pub struct MenuSettings {
/// Calls the completer using only the line buffer difference difference
/// after the menu was activated
only_buffer_difference: bool,
pub(crate) activate_on_start: bool,
pub(crate) keep_active_after_accept: bool,
pub(crate) treat_submit_as_accept: bool,
}

impl Default for MenuSettings {
Expand All @@ -169,6 +172,9 @@ impl Default for MenuSettings {
color: MenuTextStyle::default(),
marker: "| ".to_string(),
only_buffer_difference: false,
activate_on_start: false,
keep_active_after_accept: false,
treat_submit_as_accept: true,
}
}
}
Expand Down Expand Up @@ -268,6 +274,27 @@ pub trait MenuBuilder: Menu + Sized {
self.settings_mut().only_buffer_difference = only_buffer_difference;
self
}

/// Menu builder with new value for activate_on_start
#[must_use]
fn with_activate_on_start(mut self, activate_on_start: bool) -> Self {
self.settings_mut().activate_on_start = activate_on_start;
self
}

/// Menu builder with new value for keep_active_after_accept
#[must_use]
fn with_keep_active_after_accept(mut self, keep_active_after_accept: bool) -> Self {
self.settings_mut().keep_active_after_accept = keep_active_after_accept;
self
}

/// Menu builder with new value for treat_submit_as_accept
#[must_use]
fn with_treat_submit_as_accept(mut self, treat_submit_as_accept: bool) -> Self {
self.settings_mut().treat_submit_as_accept = treat_submit_as_accept;
self
}
}

/// Allowed menus in Reedline
Expand Down

0 comments on commit eece782

Please sign in to comment.