diff options
| author | Jonas Maier <jonas@x77.dev> | 2026-06-01 20:50:42 +0200 |
|---|---|---|
| committer | Jonas Maier <jonas@x77.dev> | 2026-06-01 20:50:42 +0200 |
| commit | 632d4ab219715cd3a4bc012f4d4fa71f7a2deb31 (patch) | |
| tree | 328ecb7462e1be08300a43a31e2eb60b181a9e36 /src/parse/mod.rs | |
| parent | 53774d619c2b5c078d6c166b596664691f3c93d0 (diff) | |
| download | pish-632d4ab219715cd3a4bc012f4d4fa71f7a2deb31.tar.gz | |
syntax highlighting for variable interpolation and escape codes
Diffstat (limited to 'src/parse/mod.rs')
| -rw-r--r-- | src/parse/mod.rs | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 4cba0fd..449df98 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -972,11 +972,13 @@ impl Parse for ExpString { } } + let begin = b.loc(); let x = b.adv(); if x == b'\\' && !delim.is_strict() { if let Some(x) = parse_escape_code(b)? { add_char(p, x); + b.highlight_from(begin, OtherHighlights::Escapes); } } else if x == b'$' && !delim.is_strict() { if !b.has() { @@ -989,13 +991,17 @@ impl Parse for ExpString { if is_var_begin(x) { let v = VarName::parse(b)?; p.push(StringPart::Var(Var::new(v))); + b.highlight_from(begin, OtherHighlights::Variable); continue; } b.adv(); match x { - b'?' | b'!' => p.push(StringPart::Var(Var::new(VarName { name: vec![x] }))), + b'?' | b'!' => { + b.highlight_from(begin, OtherHighlights::Variable); + p.push(StringPart::Var(Var::new(VarName { name: vec![x] }))) + } b'{' => { let v = VarName::parse(b)?; let mut default = None; @@ -1031,6 +1037,7 @@ impl Parse for ExpString { b.adv(); } + b.highlight_from(begin, OtherHighlights::Variable); p.push(StringPart::Var(Var { name: v, default, @@ -1077,6 +1084,7 @@ impl Parse for ExpString { default: None, already_complete: true, })); + b.highlight_from(begin, OtherHighlights::Variable); } else { add_char(p, x); } @@ -1348,15 +1356,31 @@ pub enum HighlightKind { Other(OtherHighlights), } +impl From<Keyword> for HighlightKind { + fn from(value: Keyword) -> Self { + Self::Keyword(value) + } +} + +impl From<OtherHighlights> for HighlightKind { + fn from(value: OtherHighlights) -> Self { + Self::Other(value) + } +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Variants)] pub enum OtherHighlights { String, + Variable, + Escapes, } impl OtherHighlights { pub fn identifier(&self) -> &bstr { match self { OtherHighlights::String => b"string", + OtherHighlights::Variable => b"var", + OtherHighlights::Escapes => b"escape", } } } @@ -1574,6 +1598,17 @@ impl<'a> Cursor<'a> { self.file.from(self.loc_u32()) } + fn highlight_from(&mut self, from: span::SpanFrom, kind: impl Into<HighlightKind>) { + self.highlight(from.to(self.loc_u32()), kind) + } + + fn highlight(&mut self, span: span::Span, kind: impl Into<HighlightKind>) { + self.highlights.push(Highlight { + span, + kind: kind.into(), + }); + } + fn spaces_stats(&mut self) -> SpaceStats { let mut stats = SpaceStats::default(); while self.has() && b" \t\n\r".contains(&self.buf[0]) { @@ -1623,7 +1658,7 @@ impl<'a> Cursor<'a> { self.spaces(); Ok(()) } else { - if self.is_completion() { + if self.is_completion() && self.buf.len() == bytes.len() { self.buf = &self.buf[bytes.len()..]; Ok(()) } else { |
