From 0548abacdce8e26f2692d3e0e2c224c014f58113 Mon Sep 17 00:00:00 2001 From: Daniel Bonofiglio Date: Tue, 15 Jul 2025 21:42:56 -0300 Subject: [PATCH 1/4] feat: add `ViChangeMode` event --- src/edit_mode/base.rs | 7 ++++++- src/edit_mode/vi/mod.rs | 26 +++++++++++++++++++++++++- src/engine.rs | 4 +++- src/enums.rs | 6 +++++- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/edit_mode/base.rs b/src/edit_mode/base.rs index 455e2c80e..408098b32 100644 --- a/src/edit_mode/base.rs +++ b/src/edit_mode/base.rs @@ -1,5 +1,5 @@ use crate::{ - enums::{ReedlineEvent, ReedlineRawEvent}, + enums::{EventStatus, ReedlineEvent, ReedlineRawEvent}, PromptEditMode, }; @@ -13,4 +13,9 @@ pub trait EditMode: Send { /// What to display in the prompt indicator fn edit_mode(&self) -> PromptEditMode; + + /// Handles events that apply only to specific edit modes (e.g changing vi mode) + fn handle_mode_specific_event(&mut self, _event: ReedlineEvent) -> EventStatus { + EventStatus::Inapplicable + } } diff --git a/src/edit_mode/vi/mod.rs b/src/edit_mode/vi/mod.rs index 8d92c5e7d..08ab841ec 100644 --- a/src/edit_mode/vi/mod.rs +++ b/src/edit_mode/vi/mod.rs @@ -11,7 +11,7 @@ use self::motion::ViCharSearch; use super::EditMode; use crate::{ edit_mode::{keybindings::Keybindings, vi::parser::parse}, - enums::{EditCommand, ReedlineEvent, ReedlineRawEvent}, + enums::{EditCommand, EventStatus, ReedlineEvent, ReedlineRawEvent}, PromptEditMode, PromptViMode, }; @@ -22,6 +22,17 @@ enum ViMode { Visual, } +impl ViMode { + pub fn from_str>(s: S) -> Option { + match s.as_ref() { + "normal" => Some(ViMode::Normal), + "insert" => Some(ViMode::Insert), + "visual" => Some(ViMode::Visual), + _ => None, + } + } +} + /// This parses incoming input `Event`s like a Vi-Style editor pub struct Vi { cache: Vec, @@ -174,6 +185,19 @@ impl EditMode for Vi { ViMode::Insert => PromptEditMode::Vi(PromptViMode::Insert), } } + + fn handle_mode_specific_event(&mut self, event: ReedlineEvent) -> EventStatus { + match event { + ReedlineEvent::ViChangeMode(mode_str) => match ViMode::from_str(mode_str) { + Some(mode) => { + self.mode = mode; + EventStatus::Handled + } + None => EventStatus::Inapplicable, + }, + _ => EventStatus::Inapplicable, + } + } } #[cfg(test)] diff --git a/src/engine.rs b/src/engine.rs index b5f6958a3..e13e9184e 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -928,7 +928,8 @@ impl Reedline { | ReedlineEvent::MenuLeft | ReedlineEvent::MenuRight | ReedlineEvent::MenuPageNext - | ReedlineEvent::MenuPagePrevious => Ok(EventStatus::Inapplicable), + | ReedlineEvent::MenuPagePrevious + | ReedlineEvent::ViChangeMode(_) => Ok(EventStatus::Inapplicable), } } @@ -1273,6 +1274,7 @@ impl Reedline { // Exhausting the event handlers is still considered handled Ok(EventStatus::Inapplicable) } + ReedlineEvent::ViChangeMode(_) => Ok(self.edit_mode.handle_mode_specific_event(event)), ReedlineEvent::None | ReedlineEvent::Mouse => Ok(EventStatus::Inapplicable), } } diff --git a/src/enums.rs b/src/enums.rs index 643afb485..f03ae301e 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -758,6 +758,9 @@ pub enum ReedlineEvent { /// Open text editor OpenEditor, + + /// Change mode (vi mode only) + ViChangeMode(String), } impl Display for ReedlineEvent { @@ -801,11 +804,12 @@ impl Display for ReedlineEvent { ReedlineEvent::MenuPagePrevious => write!(f, "MenuPagePrevious"), ReedlineEvent::ExecuteHostCommand(_) => write!(f, "ExecuteHostCommand"), ReedlineEvent::OpenEditor => write!(f, "OpenEditor"), + ReedlineEvent::ViChangeMode(_) => write!(f, "ViChangeMode mode: "), } } } -pub(crate) enum EventStatus { +pub enum EventStatus { Handled, Inapplicable, Exits(Signal), From f8d925724ffa8af4ddc93c0cfaa3a1c92c947ecc Mon Sep 17 00:00:00 2001 From: Daniel Bonofiglio Date: Tue, 29 Jul 2025 20:21:14 -0300 Subject: [PATCH 2/4] fix: use `FromStr` trait --- src/edit_mode/vi/mod.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/edit_mode/vi/mod.rs b/src/edit_mode/vi/mod.rs index 08ab841ec..09e0cb94e 100644 --- a/src/edit_mode/vi/mod.rs +++ b/src/edit_mode/vi/mod.rs @@ -3,6 +3,8 @@ mod motion; mod parser; mod vi_keybindings; +use std::str::FromStr; + use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers}; pub use vi_keybindings::{default_vi_insert_keybindings, default_vi_normal_keybindings}; @@ -22,13 +24,15 @@ enum ViMode { Visual, } -impl ViMode { - pub fn from_str>(s: S) -> Option { +impl FromStr for ViMode { + type Err = (); + + fn from_str(s: &str) -> Result { match s.as_ref() { - "normal" => Some(ViMode::Normal), - "insert" => Some(ViMode::Insert), - "visual" => Some(ViMode::Visual), - _ => None, + "normal" => Ok(ViMode::Normal), + "insert" => Ok(ViMode::Insert), + "visual" => Ok(ViMode::Visual), + _ => Err(()), } } } @@ -188,12 +192,12 @@ impl EditMode for Vi { fn handle_mode_specific_event(&mut self, event: ReedlineEvent) -> EventStatus { match event { - ReedlineEvent::ViChangeMode(mode_str) => match ViMode::from_str(mode_str) { - Some(mode) => { + ReedlineEvent::ViChangeMode(mode_str) => match ViMode::from_str(&mode_str) { + Ok(mode) => { self.mode = mode; EventStatus::Handled } - None => EventStatus::Inapplicable, + Err(_) => EventStatus::Inapplicable, }, _ => EventStatus::Inapplicable, } From 395a5e6f41b0e26d06d15812af8e013a831840a3 Mon Sep 17 00:00:00 2001 From: Daniel Bonofiglio Date: Tue, 29 Jul 2025 20:27:44 -0300 Subject: [PATCH 3/4] fix: undo unused change --- src/enums.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/enums.rs b/src/enums.rs index f03ae301e..0f4128609 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -809,7 +809,7 @@ impl Display for ReedlineEvent { } } -pub enum EventStatus { +pub(crate) enum EventStatus { Handled, Inapplicable, Exits(Signal), From 57e2b37d5613d60d5d88eb9a6dbfb18b3e43223a Mon Sep 17 00:00:00 2001 From: Daniel Bonofiglio Date: Wed, 30 Jul 2025 09:15:19 -0300 Subject: [PATCH 4/4] fix: clippy --- src/edit_mode/vi/mod.rs | 2 +- src/enums.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/edit_mode/vi/mod.rs b/src/edit_mode/vi/mod.rs index 09e0cb94e..de6bf7227 100644 --- a/src/edit_mode/vi/mod.rs +++ b/src/edit_mode/vi/mod.rs @@ -28,7 +28,7 @@ impl FromStr for ViMode { type Err = (); fn from_str(s: &str) -> Result { - match s.as_ref() { + match s { "normal" => Ok(ViMode::Normal), "insert" => Ok(ViMode::Insert), "visual" => Ok(ViMode::Visual), diff --git a/src/enums.rs b/src/enums.rs index 0f4128609..f03ae301e 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -809,7 +809,7 @@ impl Display for ReedlineEvent { } } -pub(crate) enum EventStatus { +pub enum EventStatus { Handled, Inapplicable, Exits(Signal),