Search forward
This commit is contained in:
parent
0d3ed442e4
commit
5bd297ba27
@ -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
|
||||||
|
@ -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);
|
||||||
|
10
src/row.rs
10
src/row.rs
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user