aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonas Maier <jonas@x77.dev>2026-05-22 21:59:51 +0200
committerJonas Maier <jonas@x77.dev>2026-05-22 21:59:51 +0200
commit40e64a767a70ea5c04e4ab9fa6dd7ceac0ea882b (patch)
tree73fd4642f1d7b89c8fc3e8df06642ff6bfd3eeb8
parente4132ff564c59be72c6546752077a8f33bb4c00f (diff)
downloadpish-40e64a767a70ea5c04e4ab9fa6dd7ceac0ea882b.tar.gz
syntax highlighting bug fixes
-rw-r--r--src/lib.rs4
-rw-r--r--src/line/mod.rs4
-rw-r--r--src/parse/mod.rs8
-rw-r--r--src/syntax_highlighting.rs49
4 files changed, 53 insertions, 12 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 47dbdf5..3f3daf2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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 =