diff --git a/src/document.rs b/src/document.rs index 9516794..5a04c44 100644 --- a/src/document.rs +++ b/src/document.rs @@ -16,7 +16,9 @@ impl Document { let contents = fs::read_to_string(filename)?; let mut rows = Vec::new(); for value in contents.lines() { - rows.push(Row::from(value)); + let mut row = Row::from(value); + row.highlight(); + rows.push(row); } Ok(Self { rows, @@ -45,11 +47,13 @@ impl Document { if at.y == self.rows.len() { let mut row = Row::default(); row.insert(0, c); + row.highlight(); self.rows.push(row); } else { #[allow(clippy::indexing_slicing)] let row = &mut self.rows[at.y]; row.insert(at.x, c); + row.highlight(); } } #[allow(clippy::indexing_slicing)] @@ -64,9 +68,11 @@ impl Document { let next_row = self.rows.remove(at.y + 1); let row = &mut self.rows[at.y]; row.append(&next_row); + row.highlight(); } else { let row = &mut self.rows[at.y]; row.delete(at.x); + row.highlight(); } } fn insert_newline(&mut self, at: &Position) { @@ -78,7 +84,10 @@ impl Document { return; } #[allow(clippy::indexing_slicing)] - let new_row = self.rows[at.y].split(at.x); + let current_row = &mut self.rows[at.y]; + let mut new_row = current_row.split(at.x); + current_row.highlight(); + new_row.highlight(); self.rows.insert(at.y + 1, new_row); } pub fn save(&mut self) -> Result<(), Error> { diff --git a/src/highlighting.rs b/src/highlighting.rs new file mode 100644 index 0000000..c56fdcc --- /dev/null +++ b/src/highlighting.rs @@ -0,0 +1,16 @@ +use termion::color; + +#[derive(PartialEq)] +pub enum Type { + None, + Number +} + +impl Type { + pub fn to_color(&self) -> impl color::Color { + match self { + Type::Number => color::Rgb(220, 163, 163), + _ => color::Rgb(255, 255, 255) + } + } +} diff --git a/src/main.rs b/src/main.rs index a59fd6d..d85e3f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ mod document; mod editor; mod row; mod terminal; +mod highlighting; pub use document::Document; pub use row::Row; pub use editor::SearchDirection; diff --git a/src/row.rs b/src/row.rs index e30c1e2..d15b540 100644 --- a/src/row.rs +++ b/src/row.rs @@ -1,18 +1,22 @@ +use crate::highlighting; use crate::SearchDirection; use std::{cmp, usize}; +use termion::color; use unicode_segmentation::UnicodeSegmentation; #[derive(Default)] pub struct Row { string: String, - len: usize + len: usize, + highlighting: Vec } impl From<&str> for Row { fn from(slice: &str) -> Self { Self { string: String::from(slice), - len: slice.graphemes(true).count() + len: slice.graphemes(true).count(), + highlighting: Vec::new() } } } @@ -22,13 +26,27 @@ impl Row { let end = cmp::min(end, self.string.len()); let start = cmp::min(start, end); let mut result = String::new(); - for grapheme in self.string[..].graphemes(true).skip(start).take(end-start) { - if grapheme == "\t" { - result.push_str(" "); - } else { - result.push_str(grapheme); + let mut current_highlighting = &highlighting::Type::None; + for (index, grapheme) in self.string[..].graphemes(true).enumerate().skip(start).take(end-start) { + if let Some(c) = grapheme.chars().next() { + let highlighting_type = self + .highlighting + .get(index) + .unwrap_or(&highlighting::Type::None); + if highlighting_type != current_highlighting { + current_highlighting = highlighting_type; + let start_highlight = format!("{}", termion::color::Fg(highlighting_type.to_color())); + result.push_str(&start_highlight[..]); + } + if c == '\t' { + result.push_str(" "); + } else { + result.push(c); + } } } + let end_highlight = format!("{}", termion::color::Fg(color::Reset)); + result.push_str(&end_highlight[..]); result } pub fn len(&self) -> usize { @@ -93,7 +111,8 @@ impl Row { self.len = length; Self { string: splitted_row, - len: splitted_length + len: splitted_length, + highlighting: Vec::new() } } pub fn as_bytes(&self) -> &[u8] { @@ -132,4 +151,15 @@ impl Row { } None } + pub fn highlight(&mut self) { + let mut highlighting = Vec::new(); + for c in self.string.chars() { + if c.is_ascii_digit() { + highlighting.push(highlighting::Type::Number); + } else { + highlighting.push(highlighting::Type::None); + } + } + self.highlighting = highlighting; + } }