Search forward

This commit is contained in:
Timothy Warren 2021-03-12 12:17:32 -05:00
parent 0d3ed442e4
commit 5bd297ba27
3 changed files with 52 additions and 25 deletions

View File

@ -103,11 +103,15 @@ impl Document {
self.dirty self.dirty
} }
pub fn find(&self, query: &str) -> Option<Position> { pub fn find(&self, query: &str, after: &Position) -> Option<Position> {
for (y, row) in self.rows.iter().enumerate() { let mut x = after.x;
if let Some(x) = row.find(query) {
for (y, row) in self.rows.iter().enumerate().skip(after.y) {
if let Some(x) = row.find(query, x) {
return Some(Position { x, y }) return Some(Position { x, y })
} }
x = 0;
} }
None None

View File

@ -12,7 +12,7 @@ const STATUS_BG_COLOR: color::Rgb = color::Rgb(239, 239, 239);
const VERSION: &str = env!("CARGO_PKG_VERSION"); const VERSION: &str = env!("CARGO_PKG_VERSION");
const QUIT_TIMES: u8 = 3; const QUIT_TIMES: u8 = 3;
#[derive(Default)] #[derive(Default, Clone)]
pub struct Position { pub struct Position {
pub x: usize, pub x: usize,
pub y: 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> { fn process_keypress(&mut self) -> Result<(), std::io::Error> {
let pressed_key = Terminal::read_key()?; let pressed_key = Terminal::read_key()?;
match pressed_key { match pressed_key {
@ -195,23 +232,7 @@ impl Editor {
self.should_quit = true self.should_quit = true
}, },
Key::Ctrl('s') => self.save(), Key::Ctrl('s') => self.save(),
Key::Ctrl('f') => { Key::Ctrl('f') => self.search(),
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::Char(c) => { Key::Char(c) => {
self.document.insert(&self.cursor_position, c); self.document.insert(&self.cursor_position, c);
self.move_cursor(Key::Right); self.move_cursor(Key::Right);

View File

@ -127,14 +127,16 @@ impl Row {
self.string.as_bytes() self.string.as_bytes()
} }
pub fn find(&self, query: &str) -> Option<usize> { pub fn find(&self, query: &str, after: usize) -> Option<usize> {
let matching_byte_index = self.string.find(query); 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 { if let Some(matching_byte_index) = matching_byte_index {
for (grapheme_index, (byte_index, _)) in for (grapheme_index, (byte_index, _)) in
self.string[..].grapheme_indices(true).enumerate() substring[..].grapheme_indices(true).enumerate()
{ {
if matching_byte_index == byte_index { if matching_byte_index == byte_index {
return Some(grapheme_index); return Some(after + grapheme_index);
} }
} }
} }