Add readline bindings to search

Fixes #3938.
This commit is contained in:
Christian Duerr 2020-07-10 21:00:33 +00:00 committed by GitHub
parent 1e595431c0
commit 9ece44e762
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 46 deletions

View File

@ -395,56 +395,27 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> 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(&regex);
// 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(&regex);
// 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<T> 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(&regex);
// 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.

View File

@ -99,6 +99,7 @@ pub trait ActionContext<T: EventListener> {
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<T>> 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
}