From c73ed9310d8162b71183688de62bf8c1fc8420df Mon Sep 17 00:00:00 2001 From: Jonas Maier Date: Mon, 1 Jun 2026 21:55:53 +0200 Subject: syntax highlighting for regex; syntax highlighting syntax errors --- src/parse/regex/mod.rs | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'src/parse/regex') diff --git a/src/parse/regex/mod.rs b/src/parse/regex/mod.rs index d5e4cdf..98056cb 100644 --- a/src/parse/regex/mod.rs +++ b/src/parse/regex/mod.rs @@ -1,3 +1,5 @@ +use crate::parse::OtherHighlights; + use super::{Parse, ParseError, Result}; mod byte_range; @@ -16,10 +18,19 @@ pub enum Pattern { impl Parse for Pattern { fn parse(b: &mut super::Cursor<'_>) -> super::Result { - parse_alt(b) + let begin = b.loc(); + let result = parse0(b); + if result.is_ok() { + b.highlight_from(begin, OtherHighlights::Regex); + } + result } } +fn parse0(s: &mut super::Cursor<'_>) -> Result { + parse_alt(s) +} + fn parse_alt(s: &mut super::Cursor<'_>) -> Result { let mut seqs = vec![]; loop { @@ -27,8 +38,10 @@ fn parse_alt(s: &mut super::Cursor<'_>) -> Result { if seq != Pattern::Nothing { seqs.push(seq); } + let begin = s.loc(); if s.has() && s.peek() == b'|' { s.adv(); + s.highlight_from(begin, OtherHighlights::RegexSymbol); } else { break; } @@ -70,17 +83,22 @@ fn parse_rep(s: &mut super::Cursor<'_>) -> Result { return Ok(atom); } + let begin = s.loc(); + match s.peek() { b'*' => { s.adv(); + s.highlight_from(begin, OtherHighlights::RegexSymbol); Ok(Pattern::Rep(Box::new(atom), 0, None)) } b'+' => { s.adv(); + s.highlight_from(begin, OtherHighlights::RegexSymbol); Ok(Pattern::Rep(Box::new(atom), 1, None)) } b'?' => { s.adv(); + s.highlight_from(begin, OtherHighlights::RegexSymbol); Ok(Pattern::Rep(Box::new(atom), 0, Some(1))) } _ => Ok(atom), @@ -99,21 +117,26 @@ fn parse_atom(s: &mut super::Cursor<'_>) -> Result { return Ok(Pattern::Nothing); } + let begin = s.loc(); + match s.peek() { b'[' => { s.adv(); + s.highlight_from(begin, OtherHighlights::RegexSymbol); let mut ranges = Vec::new(); loop { if !s.has() { return Err(ParseError::Eof); } + let begin = s.loc(); let tok = s.adv(); if tok == b']' { if ranges.is_empty() { todo!("error handling for empty alternative list"); } + s.highlight_from(begin, OtherHighlights::RegexSymbol); return Ok(Pattern::Alt(ranges)); } @@ -121,8 +144,10 @@ fn parse_atom(s: &mut super::Cursor<'_>) -> Result { return Err(ParseError::Unknown(tok)); } + let begin = s.loc(); if s.has() && s.peek() == b'-' { s.adv(); + s.highlight_from(begin, OtherHighlights::RegexSymbol); if !s.has() { return Err(ParseError::Eof); @@ -141,17 +166,21 @@ fn parse_atom(s: &mut super::Cursor<'_>) -> Result { } b'(' => { s.adv(); - let inner = Pattern::parse(s)?; + s.highlight_from(begin, OtherHighlights::RegexSymbol); + let inner = parse0(s)?; if !s.has() { return Err(ParseError::Eof); } + let begin = s.loc(); if s.adv() != b')' { return Err(ParseError::Expected(')')); } + s.highlight_from(begin, OtherHighlights::RegexSymbol); Ok(inner) } b'.' => { s.adv(); + s.highlight_from(begin, OtherHighlights::RegexSymbol); Ok(Pattern::Range(0, 127)) } x if is_symbol(x) => Ok(Pattern::Nothing), -- cgit v1.2.3