Highlight search results

This commit is contained in:
Timothy Warren 2021-03-15 14:53:08 -04:00
parent 689a45de36
commit 872253edc2
4 changed files with 52 additions and 10 deletions

View File

@ -19,7 +19,7 @@ impl Document {
for value in contents.lines() { for value in contents.lines() {
let mut row = Row::from(value); let mut row = Row::from(value);
row.highlight(); row.highlight(None);
rows.push(row); rows.push(row);
} }
@ -58,13 +58,13 @@ impl Document {
if at.y == self.rows.len() { if at.y == self.rows.len() {
let mut row = Row::default(); let mut row = Row::default();
row.insert(0, c); row.insert(0, c);
row.highlight(); row.highlight(None);
self.rows.push(row); self.rows.push(row);
} else { } else {
#[allow(clippy::indexing_slicing)] #[allow(clippy::indexing_slicing)]
let row = &mut self.rows[at.y]; let row = &mut self.rows[at.y];
row.insert(at.x, c); row.insert(at.x, c);
row.highlight(); row.highlight(None);
} }
} }
@ -82,11 +82,11 @@ impl Document {
let next_row = self.rows.remove(at.y + 1); let next_row = self.rows.remove(at.y + 1);
let row = &mut self.rows[at.y]; let row = &mut self.rows[at.y];
row.append(&next_row); row.append(&next_row);
row.highlight(); row.highlight(None);
} else { } else {
let row = &mut self.rows[at.y]; let row = &mut self.rows[at.y];
row.delete(at.x); row.delete(at.x);
row.highlight(); row.highlight(None);
} }
} }
@ -106,6 +106,12 @@ impl Document {
Ok(()) Ok(())
} }
pub fn highlight(&mut self, word: Option<&str>) {
for row in &mut self.rows {
row.highlight(word);
}
}
pub fn is_dirty(&self) -> bool { pub fn is_dirty(&self) -> bool {
self.dirty self.dirty
} }
@ -159,8 +165,8 @@ impl Document {
let current_row = &mut self.rows[at.y]; let current_row = &mut self.rows[at.y];
let mut new_row = current_row.split(at.x); let mut new_row = current_row.split(at.x);
current_row.highlight(); current_row.highlight(None);
new_row.highlight(); new_row.highlight(None);
#[allow(clippy::integer_arithmetic)] #[allow(clippy::integer_arithmetic)]
self.rows.insert(at.y + 1, new_row); self.rows.insert(at.y + 1, new_row);

View File

@ -215,6 +215,8 @@ impl Editor {
} else if moved { } else if moved {
editor.move_cursor(Key::Left); editor.move_cursor(Key::Left);
} }
editor.document.highlight(Some(query));
}, },
) )
.unwrap_or(None); .unwrap_or(None);
@ -223,6 +225,8 @@ impl Editor {
self.cursor_position = old_position; self.cursor_position = old_position;
self.scroll(); self.scroll();
} }
self.document.highlight(None);
} }
fn process_keypress(&mut self) -> Result<(), std::io::Error> { fn process_keypress(&mut self) -> Result<(), std::io::Error> {

View File

@ -4,12 +4,14 @@ use termion::color;
pub enum Type { pub enum Type {
None, None,
Number, Number,
Match,
} }
impl Type { impl Type {
pub fn to_color(&self) -> impl color::Color { pub fn to_color(&self) -> impl color::Color {
match self { match self {
Type::Number => color::Rgb(220, 163, 163), Type::Number => color::Rgb(220, 163, 163),
Type::Match => color::Rgb(38, 139, 210),
_ => color::Rgb(255, 255, 255), _ => color::Rgb(255, 255, 255),
} }
} }

View File

@ -155,7 +155,7 @@ impl Row {
} }
pub fn find(&self, query: &str, at: usize, direction: SearchDirection) -> Option<usize> { pub fn find(&self, query: &str, at: usize, direction: SearchDirection) -> Option<usize> {
if at > self.len { if at > self.len || query.is_empty() {
return None; return None;
} }
@ -189,15 +189,45 @@ impl Row {
None None
} }
pub fn highlight(&mut self) { pub fn highlight(&mut self, word: Option<&str>) {
let mut highlighting = Vec::new(); let mut highlighting = Vec::new();
let chars: Vec<char> = self.string.chars().collect();
let mut matches = Vec::new();
let mut search_index = 0;
if let Some(word) = word {
while let Some(search_match) = self.find(word, search_index, SearchDirection::Forward) {
matches.push(search_match);
if let Some(next_index) = search_match.checked_add(word[..].graphemes(true).count())
{
search_index = next_index
} else {
break;
}
}
}
let mut index = 0;
while let Some(c) = chars.get(index) {
if let Some(word) = word {
if matches.contains(&index) {
for _ in word[..].graphemes(true) {
index += 1;
highlighting.push(highlighting::Type::Match);
}
continue;
}
}
for c in self.string.chars() {
if c.is_ascii_digit() { if c.is_ascii_digit() {
highlighting.push(highlighting::Type::Number) highlighting.push(highlighting::Type::Number)
} else { } else {
highlighting.push(highlighting::Type::None) highlighting.push(highlighting::Type::None)
} }
index += 1;
} }
self.highlighting = highlighting; self.highlighting = highlighting;