From 9ece44e76216861fee14df6c8b635982268d254e Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Fri, 10 Jul 2020 21:00:33 +0000 Subject: [PATCH] Add readline bindings to search Fixes #3938. --- alacritty/src/event.rs | 81 ++++++++++++++++++++---------------------- alacritty/src/input.rs | 26 +++++++++++--- 2 files changed, 61 insertions(+), 46 deletions(-) diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index f264aab5..c651fda3 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -395,56 +395,27 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon #[inline] fn push_search(&mut self, c: char) { - let regex = match self.search_state.regex.as_mut() { - Some(regex) => regex, - None => return, - }; - - // Hide cursor while typing into the search bar. - if self.config.ui_config.mouse.hide_when_typing { - self.window.set_mouse_visible(false); + if let Some(regex) = self.search_state.regex.as_mut() { + regex.push(c); + self.update_search(); } - - // Add new char to search string. - regex.push(c); - - // Create terminal search from the new regex string. - self.terminal.start_search(®ex); - - // Update search highlighting. - self.goto_match(MAX_SEARCH_WHILE_TYPING); - - self.terminal.dirty = true; } #[inline] fn pop_search(&mut self) { - let regex = match self.search_state.regex.as_mut() { - Some(regex) => regex, - None => return, - }; - - // Hide cursor while typing into the search bar. - if self.config.ui_config.mouse.hide_when_typing { - self.window.set_mouse_visible(false); + if let Some(regex) = self.search_state.regex.as_mut() { + regex.pop(); + self.update_search(); } + } - // Remove last char from search string. - regex.pop(); - - if regex.is_empty() { - // Stop search if there's nothing to search for. - self.search_reset_state(); - self.terminal.cancel_search(); - } else { - // Create terminal search from the new regex string. - self.terminal.start_search(®ex); - - // Update search highlighting. - self.goto_match(MAX_SEARCH_WHILE_TYPING); + #[inline] + fn pop_word_search(&mut self) { + if let Some(regex) = self.search_state.regex.as_mut() { + *regex = regex.trim_end().to_owned(); + regex.truncate(regex.rfind(' ').map(|i| i + 1).unwrap_or(0)); + self.update_search(); } - - self.terminal.dirty = true; } #[inline] @@ -483,6 +454,32 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon } impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> { + fn update_search(&mut self) { + let regex = match self.search_state.regex.as_mut() { + Some(regex) => regex, + None => return, + }; + + // Hide cursor while typing into the search bar. + if self.config.ui_config.mouse.hide_when_typing { + self.window.set_mouse_visible(false); + } + + if regex.is_empty() { + // Stop search if there's nothing to search for. + self.search_reset_state(); + self.terminal.cancel_search(); + } else { + // Create terminal search from the new regex string. + self.terminal.start_search(®ex); + + // Update search highlighting. + self.goto_match(MAX_SEARCH_WHILE_TYPING); + } + + self.terminal.dirty = true; + } + /// Reset terminal to the state before search was started. fn search_reset_state(&mut self) { // Reset display offset. diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs index cab0f0e2..64b79002 100644 --- a/alacritty/src/input.rs +++ b/alacritty/src/input.rs @@ -99,6 +99,7 @@ pub trait ActionContext { fn cancel_search(&mut self); fn push_search(&mut self, c: char); fn pop_search(&mut self); + fn pop_word_search(&mut self); fn search_direction(&self) -> Direction; fn search_active(&self) -> bool; } @@ -807,19 +808,34 @@ impl<'a, T: EventListener, A: ActionContext> Processor<'a, T, A> { pub fn key_input(&mut self, input: KeyboardInput) { match input.state { ElementState::Pressed if self.ctx.search_active() => { - match input.virtual_keycode { - Some(VirtualKeyCode::Back) => { + match (input.virtual_keycode, *self.ctx.modifiers()) { + (Some(VirtualKeyCode::Back), _) => { self.ctx.pop_search(); *self.ctx.suppress_chars() = true; }, - Some(VirtualKeyCode::Return) => { + (Some(VirtualKeyCode::Return), _) + | (Some(VirtualKeyCode::J), ModifiersState::CTRL) => { self.ctx.confirm_search(); *self.ctx.suppress_chars() = true; }, - Some(VirtualKeyCode::Escape) => { + (Some(VirtualKeyCode::Escape), _) => { self.ctx.cancel_search(); *self.ctx.suppress_chars() = true; }, + (Some(VirtualKeyCode::U), ModifiersState::CTRL) => { + let direction = self.ctx.search_direction(); + self.ctx.cancel_search(); + self.ctx.start_search(direction); + *self.ctx.suppress_chars() = true; + }, + (Some(VirtualKeyCode::H), ModifiersState::CTRL) => { + self.ctx.pop_search(); + *self.ctx.suppress_chars() = true; + }, + (Some(VirtualKeyCode::W), ModifiersState::CTRL) => { + self.ctx.pop_word_search(); + *self.ctx.suppress_chars() = true; + }, _ => (), } @@ -1127,6 +1143,8 @@ mod tests { fn pop_search(&mut self) {} + fn pop_word_search(&mut self) {} + fn search_direction(&self) -> Direction { Direction::Right }