From 5bd297ba273d93aefa075b8d123a54efcb5d3c3b Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 12 Mar 2021 12:17:32 -0500 Subject: [PATCH] Search forward --- src/document.rs | 10 ++++++--- src/editor.rs | 57 +++++++++++++++++++++++++++++++++---------------- src/row.rs | 10 +++++---- 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/document.rs b/src/document.rs index f65062e..08564f6 100644 --- a/src/document.rs +++ b/src/document.rs @@ -103,11 +103,15 @@ impl Document { self.dirty } - pub fn find(&self, query: &str) -> Option { - for (y, row) in self.rows.iter().enumerate() { - if let Some(x) = row.find(query) { + pub fn find(&self, query: &str, after: &Position) -> Option { + let mut x = after.x; + + for (y, row) in self.rows.iter().enumerate().skip(after.y) { + if let Some(x) = row.find(query, x) { return Some(Position { x, y }) } + + x = 0; } None diff --git a/src/editor.rs b/src/editor.rs index 1b866b3..04ab07b 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -12,7 +12,7 @@ const STATUS_BG_COLOR: color::Rgb = color::Rgb(239, 239, 239); const VERSION: &str = env!("CARGO_PKG_VERSION"); const QUIT_TIMES: u8 = 3; -#[derive(Default)] +#[derive(Default, Clone)] pub struct Position { pub x: usize, pub y: usize, @@ -177,6 +177,43 @@ impl Editor { } } + fn search(&mut self) { + let old_position = self.cursor_position.clone(); + + if let Some(query) = self + .prompt( + "Search (ESC to cancel, arrows to navigate): ", + |editor, key, query| { + let mut moved = false; + + match key { + Key::Right | Key::Down => { + editor.move_cursor(Key::Right); + moved = true; + } + _ => (), + } + + if let Some(position) = editor.document.find(&query, &editor.cursor_position) { + editor.cursor_position = position; + editor.scroll(); + } else { + editor.move_cursor(Key::Left); + } + }) + .unwrap_or(None) + { + if let Some(position) = self.document.find(&query[..], &old_position) { + self.cursor_position = position; + } else { + self.status_message = StatusMessage::from(format!("Not found: {}", query)); + } + } else { + self.cursor_position = old_position; + self.scroll(); + } + } + fn process_keypress(&mut self) -> Result<(), std::io::Error> { let pressed_key = Terminal::read_key()?; match pressed_key { @@ -195,23 +232,7 @@ impl Editor { self.should_quit = true }, Key::Ctrl('s') => self.save(), - Key::Ctrl('f') => { - if let Some(query) = self - .prompt("Search: ", |editor, _, query| { - if let Some(position) = editor.document.find(&query) { - editor.cursor_position = position; - editor.scroll(); - } - }) - .unwrap_or(None) - { - if let Some(position) = self.document.find(&query[..]) { - self.cursor_position = position; - } else { - self.status_message = StatusMessage::from(format!("Not found: {}", query)); - } - } - } + Key::Ctrl('f') => self.search(), Key::Char(c) => { self.document.insert(&self.cursor_position, c); self.move_cursor(Key::Right); diff --git a/src/row.rs b/src/row.rs index cb04a19..9794252 100644 --- a/src/row.rs +++ b/src/row.rs @@ -127,14 +127,16 @@ impl Row { self.string.as_bytes() } - pub fn find(&self, query: &str) -> Option { - let matching_byte_index = self.string.find(query); + pub fn find(&self, query: &str, after: usize) -> Option { + let substring: String = self.string[..].graphemes(true).skip(after).collect(); + let matching_byte_index = substring.find(query); + if let Some(matching_byte_index) = matching_byte_index { for (grapheme_index, (byte_index, _)) in - self.string[..].grapheme_indices(true).enumerate() + substring[..].grapheme_indices(true).enumerate() { if matching_byte_index == byte_index { - return Some(grapheme_index); + return Some(after + grapheme_index); } } }