From 4117bb663b736294aeebefefa8385946b931606e Mon Sep 17 00:00:00 2001 From: Maxim Onciul Date: Thu, 29 Aug 2024 16:39:30 +0200 Subject: [PATCH 1/4] feat: support external event queue This helps nushell to implement `commandline edit --accept`, the same thing that `zle accept-line` does for zsh. --- src/engine.rs | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/src/engine.rs b/src/engine.rs index 3c4fa2a0..45365f9e 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,4 +1,7 @@ -use std::path::PathBuf; +use std::{ + path::PathBuf, + sync::{Arc, Mutex}, +}; use itertools::Itertools; use nu_ansi_term::{Color, Style}; @@ -163,6 +166,9 @@ pub struct Reedline { #[cfg(feature = "external_printer")] external_printer: Option>, + + crossterm_events: Arc>>, + reedline_events: Arc>>, } struct BufferEditor { @@ -236,9 +242,29 @@ impl Reedline { kitty_protocol: KittyProtocolGuard::default(), #[cfg(feature = "external_printer")] external_printer: None, + crossterm_events: Arc::new(Vec::new().into()), + reedline_events: Arc::new(Vec::new().into()), } } + /// Setup a queue for reedline events that can be written from other places. + pub fn with_reedline_event_queue( + mut self, + reedline_events: Arc>>, + ) -> Self { + self.reedline_events = reedline_events; + self + } + + /// Setup a queue for reedline events that can be written from other places. + pub fn with_crossterm_event_queue( + mut self, + crossterm_events: Arc>>, + ) -> Self { + self.crossterm_events = crossterm_events; + self + } + /// Get a new history session id based on the current time and the first commit datetime of reedline pub fn create_history_session_id() -> Option { let nanos = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { @@ -718,6 +744,9 @@ impl Reedline { let mut latest_resize = None; loop { + if !self.reedline_events.lock().unwrap().is_empty() { + break; + } match event::read()? { Event::Resize(x, y) => { latest_resize = Some((x, y)); @@ -763,6 +792,11 @@ impl Reedline { // // (Text should only be `EditCommand::InsertChar`s) let mut last_edit_commands = None; + + for event in self.crossterm_events.lock().unwrap().drain(..) { + crossterm_events.push(event); + } + for event in crossterm_events.drain(..) { match (&mut last_edit_commands, self.edit_mode.parse_event(event)) { (None, ReedlineEvent::Edit(ec)) => { @@ -785,6 +819,11 @@ impl Reedline { reedline_events.push(ReedlineEvent::Edit(ec)); } + for event in self.reedline_events.lock().unwrap().drain(..) { + println!("Got event from queue: {}", event); + reedline_events.push(event); + } + for event in reedline_events.drain(..) { match self.handle_event(prompt, event)? { EventStatus::Exits(signal) => { From 4c05b6896ad381b94cc01badca9c91bdaf37758f Mon Sep 17 00:00:00 2001 From: Maxim Onciul Date: Thu, 29 Aug 2024 18:29:57 +0200 Subject: [PATCH 2/4] fix: remove unnecessary queue for raw events and rename queue for actual events --- src/engine.rs | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index 45365f9e..1425dc7d 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -167,8 +167,7 @@ pub struct Reedline { #[cfg(feature = "external_printer")] external_printer: Option>, - crossterm_events: Arc>>, - reedline_events: Arc>>, + reedline_event_queue: Arc>>, } struct BufferEditor { @@ -242,8 +241,7 @@ impl Reedline { kitty_protocol: KittyProtocolGuard::default(), #[cfg(feature = "external_printer")] external_printer: None, - crossterm_events: Arc::new(Vec::new().into()), - reedline_events: Arc::new(Vec::new().into()), + reedline_event_queue: Arc::new(Vec::new().into()), } } @@ -252,16 +250,7 @@ impl Reedline { mut self, reedline_events: Arc>>, ) -> Self { - self.reedline_events = reedline_events; - self - } - - /// Setup a queue for reedline events that can be written from other places. - pub fn with_crossterm_event_queue( - mut self, - crossterm_events: Arc>>, - ) -> Self { - self.crossterm_events = crossterm_events; + self.reedline_event_queue = reedline_events; self } @@ -744,7 +733,7 @@ impl Reedline { let mut latest_resize = None; loop { - if !self.reedline_events.lock().unwrap().is_empty() { + if !self.reedline_event_queue.lock().unwrap().is_empty() { break; } match event::read()? { @@ -793,10 +782,6 @@ impl Reedline { // (Text should only be `EditCommand::InsertChar`s) let mut last_edit_commands = None; - for event in self.crossterm_events.lock().unwrap().drain(..) { - crossterm_events.push(event); - } - for event in crossterm_events.drain(..) { match (&mut last_edit_commands, self.edit_mode.parse_event(event)) { (None, ReedlineEvent::Edit(ec)) => { @@ -819,7 +804,7 @@ impl Reedline { reedline_events.push(ReedlineEvent::Edit(ec)); } - for event in self.reedline_events.lock().unwrap().drain(..) { + for event in self.reedline_event_queue.lock().unwrap().drain(..) { println!("Got event from queue: {}", event); reedline_events.push(event); } From 651120acfcbe2a27faa09728ca34efac61de9f6c Mon Sep 17 00:00:00 2001 From: Maxim Onciul Date: Fri, 30 Aug 2024 07:33:39 +0200 Subject: [PATCH 3/4] fix: `unwrap()`-less implementation --- src/engine.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index 1425dc7d..d9b8c85d 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -733,8 +733,10 @@ impl Reedline { let mut latest_resize = None; loop { - if !self.reedline_event_queue.lock().unwrap().is_empty() { - break; + if let Ok(queue) = self.reedline_event_queue.lock() { + if !queue.is_empty() { + break; + } } match event::read()? { Event::Resize(x, y) => { @@ -804,9 +806,11 @@ impl Reedline { reedline_events.push(ReedlineEvent::Edit(ec)); } - for event in self.reedline_event_queue.lock().unwrap().drain(..) { - println!("Got event from queue: {}", event); - reedline_events.push(event); + if let Ok(mut queue) = self.reedline_event_queue.lock() { + for event in queue.drain(..) { + println!("Got event from queue: {}", event); + reedline_events.push(event); + } } for event in reedline_events.drain(..) { From b450164214101ac7f045338ce8386a486893ad1e Mon Sep 17 00:00:00 2001 From: Maxim Onciul Date: Fri, 30 Aug 2024 10:07:45 +0200 Subject: [PATCH 4/4] fix: remove debug print statement --- src/engine.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/engine.rs b/src/engine.rs index d9b8c85d..f4db4bce 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -808,7 +808,6 @@ impl Reedline { if let Ok(mut queue) = self.reedline_event_queue.lock() { for event in queue.drain(..) { - println!("Got event from queue: {}", event); reedline_events.push(event); } }