diff --git a/src/document.rs b/src/document.rs index 2b94193..a6ca1e5 100644 --- a/src/document.rs +++ b/src/document.rs @@ -94,4 +94,12 @@ impl Document { pub fn is_dirty(&self) -> bool { self.dirty } + pub fn find(&self, query: &str) -> Option { + for (y, row) in self.rows.iter().enumerate() { + if let Some(x) = row.find(query) { + return Some(Position {x, y}); + } + } + None + } } diff --git a/src/editor.rs b/src/editor.rs index d07607d..56494b2 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -60,7 +60,7 @@ impl Editor { } pub fn default() -> Self { let args: Vec = env::args().collect(); - let mut initial_status = String::from("HELP: Ctrl-S = save | Ctrl-Q = quit"); + let mut initial_status = String::from("HELP: Ctrl-F = find | Ctrl-S = save | Ctrl-Q = quit"); let document = if let Some(file_name) = args.get(1) { let doc = Document::open(file_name); if let Ok(doc) = doc { @@ -106,6 +106,15 @@ impl Editor { let pressed_key = Terminal::read_key()?; match pressed_key { Key::Ctrl('s') => self.save(), + Key::Ctrl('f') => { + if let Some(query) = self.prompt("Search: ").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('q') => { if self.quit_times > 0 && self.document.is_dirty() { self.status_message = StatusMessage::from(format!( diff --git a/src/row.rs b/src/row.rs index f69fc2d..bc86e56 100644 --- a/src/row.rs +++ b/src/row.rs @@ -1,4 +1,4 @@ -use std::cmp; +use std::{cmp, usize}; use unicode_segmentation::UnicodeSegmentation; #[derive(Default)] @@ -98,4 +98,15 @@ impl Row { pub fn as_bytes(&self) -> &[u8] { self.string.as_bytes() } + pub fn find(&self, query: &str) -> Option { + let matching_byte_index = self.string.find(query); + if let Some(matching_byte_index) = matching_byte_index { + for (grapheme_index, (byte_index, _)) in self.string[..].grapheme_indices(true).enumerate() { + if matching_byte_index == byte_index { + return Some(grapheme_index); + } + } + } + None + } }