diff options
| -rw-r--r-- | src/lib.rs | 4 | ||||
| -rw-r--r-- | src/line/mod.rs | 4 | ||||
| -rw-r--r-- | src/parse/mod.rs | 8 | ||||
| -rw-r--r-- | src/syntax_highlighting.rs | 49 |
4 files changed, 53 insertions, 12 deletions
@@ -222,9 +222,11 @@ impl Session { fn reprint_prompt(this: Arc<Mutex<Self>>) { io::stdout().write_all(&Self::prompt(this.clone())).unwrap(); - let this = this.lock().unwrap(); + let mut this = this.lock().unwrap(); this.line.display_pre(); this.line.display_post(b""); + this.line.mark_dirty(); + this.cohere().unwrap(); } fn display_historic_entry(&mut self) { diff --git a/src/line/mod.rs b/src/line/mod.rs index 72f2fe1..75a4508 100644 --- a/src/line/mod.rs +++ b/src/line/mod.rs @@ -30,6 +30,10 @@ impl Line { self.dirty = false; } + pub fn mark_dirty(&mut self) { + self.dirty = true; + } + pub fn is_dirty(&self) -> bool { self.dirty } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 1c1b184..10ec666 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -1296,11 +1296,11 @@ pub enum ParseMode { Completion, } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum HighlightKind { - Keyword(Keyword), - String, None, + String, + Keyword(Keyword), } pub struct Highlight { @@ -1504,7 +1504,7 @@ impl<'a> Cursor<'a> { } } -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum Keyword { If, While, diff --git a/src/syntax_highlighting.rs b/src/syntax_highlighting.rs index 8a369da..0b1e8c5 100644 --- a/src/syntax_highlighting.rs +++ b/src/syntax_highlighting.rs @@ -31,30 +31,65 @@ impl Highlighter { colors: Vec<Highlight>, stdout: &mut dyn std::io::Write, ) -> std::io::Result<()> { + #[derive(PartialEq, Eq, Debug, Clone)] + struct ColorBoundary { + loc: usize, + is_end: bool, + kind: HighlightKind, + } + + impl PartialOrd for ColorBoundary { + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + Some(self.cmp(other)) + } + } + + impl Ord for ColorBoundary { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + match self.loc.cmp(&other.loc) { + std::cmp::Ordering::Equal => (), + ord => return ord, + } + match self.kind.cmp(&other.kind) { + std::cmp::Ordering::Equal => (), + ord => return ord, + } + self.is_end.cmp(&other.is_end) + } + } + let mut coloring: Vec<_> = colors .into_iter() .flat_map(|hi| { [ - (hi.span.start as usize, false, hi.kind), - (hi.span.end as usize, true, hi.kind), + ColorBoundary { + loc: hi.span.start as usize, + is_end: false, + kind: hi.kind, + }, + ColorBoundary { + loc: hi.span.end as usize, + is_end: true, + kind: hi.kind, + }, ] }) .collect(); - coloring.sort_by_key(|x| (x.0, x.1)); + coloring.sort(); let mut coloring = &coloring[..]; let mut color_stack = Vec::new(); let mut current_color = self.color(HighlightKind::None); for (i, x) in bytes.iter().cloned().enumerate() { - while let Some((k, is_end, kind)) = coloring.first().cloned() - && k == i + while let Some(color_boundary) = coloring.first().cloned() + && color_boundary.loc <= i { coloring = &coloring[1..]; - if is_end { + if color_boundary.is_end { color_stack.pop(); } else { - color_stack.push(kind); + color_stack.push(color_boundary.kind); } let new_color = |
