aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/event.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/event.rs')
-rw-r--r--alacritty/src/event.rs46
1 files changed, 34 insertions, 12 deletions
diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs
index 20f087c3..c1f81300 100644
--- a/alacritty/src/event.rs
+++ b/alacritty/src/event.rs
@@ -9,6 +9,7 @@ use std::fs;
use std::fs::File;
use std::io::Write;
use std::mem;
+use std::ops::RangeInclusive;
use std::path::PathBuf;
#[cfg(not(any(target_os = "macos", windows)))]
use std::sync::atomic::Ordering;
@@ -94,6 +95,9 @@ pub struct SearchState {
/// Search origin in viewport coordinates relative to original display offset.
origin: Point,
+
+ /// Focused match during active search.
+ focused_match: Option<RangeInclusive<Point<usize>>>,
}
impl SearchState {
@@ -110,6 +114,11 @@ impl SearchState {
pub fn direction(&self) -> Direction {
self.direction
}
+
+ /// Focused match during vi-less search.
+ pub fn focused_match(&self) -> Option<&RangeInclusive<Point<usize>>> {
+ self.focused_match.as_ref()
+ }
}
impl Default for SearchState {
@@ -118,6 +127,7 @@ impl Default for SearchState {
direction: Direction::Right,
display_offset_delta: 0,
origin: Point::default(),
+ focused_match: None,
regex: None,
}
}
@@ -209,7 +219,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
selection.update(absolute_point, side);
// Move vi cursor and expand selection.
- if self.terminal.mode().contains(TermMode::VI) {
+ if self.terminal.mode().contains(TermMode::VI) && !self.search_active() {
self.terminal.vi_mode_cursor.point = point;
selection.include_all();
}
@@ -385,6 +395,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
let num_lines = self.terminal.screen_lines();
let num_cols = self.terminal.cols();
+ self.search_state.focused_match = None;
self.search_state.regex = Some(String::new());
self.search_state.direction = direction;
@@ -393,9 +404,6 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
self.search_state.origin = if self.terminal.mode().contains(TermMode::VI) {
self.terminal.vi_mode_cursor.point
} else {
- // Clear search, since it is used as the active match.
- self.terminal.selection = None;
-
match direction {
Direction::Right => Point::new(Line(0), Column(0)),
Direction::Left => Point::new(num_lines - 2, num_cols - 1),
@@ -420,9 +428,15 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
fn cancel_search(&mut self) {
self.terminal.cancel_search();
- // Recover pre-search state in vi mode.
if self.terminal.mode().contains(TermMode::VI) {
+ // Recover pre-search state in vi mode.
self.search_reset_state();
+ } else if let Some(focused_match) = &self.search_state.focused_match {
+ // Create a selection for the focused match.
+ let start = self.terminal.grid().clamp_buffer_to_visible(*focused_match.start());
+ let end = self.terminal.grid().clamp_buffer_to_visible(*focused_match.end());
+ self.start_selection(SelectionType::Simple, start, Side::Left);
+ self.update_selection(end, Side::Right);
}
self.exit_search();
@@ -431,8 +445,8 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
#[inline]
fn push_search(&mut self, c: char) {
if let Some(regex) = self.search_state.regex.as_mut() {
- // Prevent previous search selections from sticking around when not in vi mode.
if !self.terminal.mode().contains(TermMode::VI) {
+ // Clear selection so we do not obstruct any matches.
self.terminal.selection = None;
}
@@ -533,8 +547,8 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> {
self.search_reset_state();
self.terminal.cancel_search();
- // Restart search without vi mode to clear the search origin.
if !self.terminal.mode().contains(TermMode::VI) {
+ // Restart search without vi mode to clear the search origin.
self.start_search(self.search_state.direction);
}
} else {
@@ -554,6 +568,9 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> {
self.terminal.scroll_display(Scroll::Delta(self.search_state.display_offset_delta));
self.search_state.display_offset_delta = 0;
+ // Clear focused match.
+ self.search_state.focused_match = None;
+
// Reset vi mode cursor.
let mut origin = self.search_state.origin;
origin.line = min(origin.line, self.terminal.screen_lines() - 1);
@@ -586,12 +603,11 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> {
} else {
// Select the match when vi mode is not active.
self.terminal.scroll_to_point(*regex_match.start());
- let start = self.terminal.grid().clamp_buffer_to_visible(*regex_match.start());
- let end = self.terminal.grid().clamp_buffer_to_visible(*regex_match.end());
- self.start_selection(SelectionType::Simple, start, Side::Left);
- self.update_selection(end, Side::Right);
}
+ // Update the focused match.
+ self.search_state.focused_match = Some(regex_match);
+
// Store number of lines the viewport had to be moved.
let display_offset = self.terminal.grid().display_offset();
self.search_state.display_offset_delta += old_offset - display_offset as isize;
@@ -611,13 +627,16 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> {
TimerId::DelayedSearch,
);
}
+
+ // Clear focused match.
+ self.search_state.focused_match = None;
},
}
self.search_state.regex = Some(regex);
}
- /// Close the search bar.
+ /// Cleanup the search state.
fn exit_search(&mut self) {
// Move vi cursor down if resize will pull content from history.
if self.terminal.history_size() != 0
@@ -630,6 +649,9 @@ impl<'a, N: Notify + 'a, T: EventListener> ActionContext<'a, N, T> {
self.display_update_pending.dirty = true;
self.search_state.regex = None;
self.terminal.dirty = true;
+
+ // Clear focused match.
+ self.search_state.focused_match = None;
}
/// Get the absolute position of the search origin.