Highlight multi-line comments

This commit is contained in:
Timothy Warren 2021-03-16 14:07:39 -04:00
parent 62df35a751
commit 76e1b24855
2 changed files with 60 additions and 18 deletions

View File

@ -17,12 +17,13 @@ impl Document {
pub fn open(filename: &str) -> Result<Self, std::io::Error> { pub fn open(filename: &str) -> Result<Self, std::io::Error> {
let contents = fs::read_to_string(filename)?; let contents = fs::read_to_string(filename)?;
let file_type = FileType::from(filename); let file_type = FileType::from(filename);
let mut start_with_comment = false;
let mut rows = Vec::new(); let mut rows = Vec::new();
for value in contents.lines() { for value in contents.lines() {
let mut row = Row::from(value); let mut row = Row::from(value);
row.highlight(&file_type.highlighting_options(), None); start_with_comment = row.highlight(&file_type.highlighting_options(), None, start_with_comment);
rows.push(row); rows.push(row);
} }
@ -60,20 +61,17 @@ impl Document {
if c == '\n' { if c == '\n' {
self.insert_newline(at); self.insert_newline(at);
return; } else 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(&self.file_type.highlighting_options(), 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(&self.file_type.highlighting_options(), None);
} }
self.highlight(None);
} }
#[allow(clippy::integer_arithmetic, clippy::indexing_slicing)] #[allow(clippy::integer_arithmetic, clippy::indexing_slicing)]
@ -90,23 +88,28 @@ 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(&self.file_type.highlighting_options(), 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(&self.file_type.highlighting_options(), None);
} }
self.highlight(None);
} }
pub fn save(&mut self) -> Result<(), Error> { pub fn save(&mut self) -> Result<(), Error> {
if let Some(file_name) = &self.file_name { if let Some(file_name) = &self.file_name {
let mut file = fs::File::create(file_name)?; let mut file = fs::File::create(file_name)?;
self.file_type = FileType::from(file_name); self.file_type = FileType::from(file_name);
let mut start_with_comment = false;
for row in &mut self.rows { for row in &mut self.rows {
file.write_all(row.as_bytes())?; file.write_all(row.as_bytes())?;
file.write_all(b"\n")?; file.write_all(b"\n")?;
row.highlight(&self.file_type.highlighting_options(), None) start_with_comment = row.highlight(
&self.file_type.highlighting_options(),
None,
start_with_comment,
);
} }
// File has been cleaned! (Saved) // File has been cleaned! (Saved)
@ -117,8 +120,14 @@ impl Document {
} }
pub fn highlight(&mut self, word: Option<&str>) { pub fn highlight(&mut self, word: Option<&str>) {
let mut start_with_comment = false;
for row in &mut self.rows { for row in &mut self.rows {
row.highlight(&self.file_type.highlighting_options(), word); start_with_comment = row.highlight(
&self.file_type.highlighting_options(),
word,
start_with_comment,
);
} }
} }
@ -173,10 +182,7 @@ impl Document {
#[allow(clippy::indexing_slicing)] #[allow(clippy::indexing_slicing)]
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 new_row = current_row.split(at.x);
current_row.highlight(&self.file_type.highlighting_options(), None);
new_row.highlight(&self.file_type.highlighting_options(), 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

@ -450,12 +450,42 @@ impl Row {
false false
} }
pub fn highlight(&mut self, opts: &HighlightingOptions, word: Option<&str>) { #[allow(clippy::indexing_slicing, clippy::integer_arithmetic)]
pub fn highlight(
&mut self,
opts: &HighlightingOptions,
word: Option<&str>,
start_with_comment: bool,
) -> bool {
self.highlighting = Vec::new(); self.highlighting = Vec::new();
let chars: Vec<char> = self.string.chars().collect(); let chars: Vec<char> = self.string.chars().collect();
let mut index = 0; let mut index = 0;
let mut in_ml_comment = start_with_comment;
// Multi-line comments are needy
if in_ml_comment {
let closing_index = if let Some(closing_index) = self.string.find("*/") {
closing_index + 2
} else {
chars.len()
};
for _ in 0..closing_index {
self.highlighting.push(highlighting::Type::MultilineComment);
}
index = closing_index;
}
while let Some(c) = chars.get(index) { while let Some(c) = chars.get(index) {
if self.highlight_multiline_comment(&mut index, &opts, *c, &chars) {
in_ml_comment = true;
continue;
}
in_ml_comment = false;
if self.highlight_char(&mut index, opts, *c, &chars) if self.highlight_char(&mut index, opts, *c, &chars)
|| self.highlight_comment(&mut index, opts, *c, &chars) || self.highlight_comment(&mut index, opts, *c, &chars)
|| self.highlight_multiline_comment(&mut index, opts, *c, &chars) || self.highlight_multiline_comment(&mut index, opts, *c, &chars)
@ -472,6 +502,12 @@ impl Row {
} }
self.highlight_match(word); self.highlight_match(word);
if in_ml_comment && &self.string[self.string.len().saturating_sub(2)..] != "*/" {
return true;
}
false
} }
} }