static Regex CreateHighlightingRegex(GrammarEnum grammar) { var pb = new PatternBuilder( ); if (grammar == GrammarEnum.extended || grammar == GrammarEnum.ECMAScript || grammar == GrammarEnum.egrep || grammar == GrammarEnum.awk) { pb.Add(@"(?'left_par'\()"); // '(' pb.Add(@"(?'right_par'\))"); // ')' pb.Add(@"(?'left_brace'\{).*?((?'right_brace'\})|$)"); // '{...}' } if (grammar == GrammarEnum.basic || grammar == GrammarEnum.grep) { pb.Add(@"(?'left_par'\\\()"); // '\)' pb.Add(@"(?'right_par'\\\))"); // '\(' pb.Add(@"(?'left_brace'\\{).*?((?'right_brace'\\})|$)"); // '\{...\}' } pb.Add(@"((?'left_bracket'\[) ((\[:.*? (:\]|$)) | \\. | .)*? ((?'right_bracket'\])|$) )"); // [...] pb.Add(@"\\."); // '\...' return(pb.ToRegex( )); }
static Regex CreateColouringRegex(GrammarEnum grammar) { var pb_escape = new PatternBuilder( ); pb_escape.BeginGroup("escape"); if (grammar == GrammarEnum.ECMAScript) { pb_escape.Add(@"\\c[A-Za-z]"); } if (grammar == GrammarEnum.ECMAScript) { pb_escape.Add(@"\\x[0-9A-Fa-f]{1,2}"); // (two digits required) } if (grammar == GrammarEnum.awk) { pb_escape.Add(@"\\[0-7]{1,3}"); // octal code } if (grammar == GrammarEnum.ECMAScript) { pb_escape.Add(@"\\u[0-9A-Fa-f]{1,4}"); // (four digits required) } if (grammar == GrammarEnum.basic || grammar == GrammarEnum.grep) { pb_escape.Add(@"(?!\\\( | \\\) | \\\{ | \\\})\\."); } else { pb_escape.Add(@"\\."); } pb_escape.EndGroup( ); // var pb_class = new PatternBuilder( ).AddGroup("class", @"\[(?'c'[:=.]) .*? (\k<c>\] | $)"); // var pb = new PatternBuilder( ); pb.Add(pb_escape.ToPattern( )); pb.AddGroup(null, $@"( \[ ({pb_class.ToPattern( )} | {pb_escape.ToPattern( )} | . )*? (\]|$) )"); // (group names and comments are not supported by C++ Regex) return(pb.ToRegex( )); }
static Regex GetCachedHighlightingRegex(GrammarEnum grammar) { lock ( CachedHighlightingRegexes ) { if (CachedHighlightingRegexes.TryGetValue(grammar, out Regex regex)) { return(regex); } regex = CreateHighlightingRegex(grammar); CachedHighlightingRegexes.Add(grammar, regex); return(regex); } }
public void HighlightPattern(ICancellable cnc, Highlights highlights, string pattern, int selectionStart, int selectionEnd, Segment visibleSegment) { GrammarEnum grammar = OptionsControl.GetGrammar( ); int par_size = 1; int bracket_size = 1; if (grammar == GrammarEnum.basic || grammar == GrammarEnum.grep) { par_size = 2; } var regex = GetCachedHighlightingRegex(grammar); HighlightHelper.CommonHighlighting(cnc, highlights, pattern, selectionStart, selectionEnd, visibleSegment, regex, par_size, bracket_size); }
static Regex GetCachedHighlightingRegex(GrammarEnum grammar, bool modX) { var key = new Key { Grammar = grammar, ModX = modX }; lock ( CachedHighlightingRegexes ) { if (CachedHighlightingRegexes.TryGetValue(key, out Regex regex)) { return(regex); } regex = CreateHighlightingRegex(grammar, modX); CachedHighlightingRegexes.Add(key, regex); return(regex); } }
public void HighlightPattern(ICancellable cnc, Highlights highlights, string pattern, int selectionStart, int selectionEnd, Segment visibleSegment) { GrammarEnum grammar = OptionsControl.GetGrammar( ); bool mod_x = OptionsControl.GetModX( ); int par_size = 1; int bracket_size = 1; bool is_POSIX_basic = grammar == GrammarEnum.basic || grammar == GrammarEnum.sed || grammar == GrammarEnum.grep || grammar == GrammarEnum.emacs; if (is_POSIX_basic) { par_size = 2; } Regex regex = GetCachedHighlightingRegex(grammar, mod_x); HighlightHelper.CommonHighlighting(cnc, highlights, pattern, selectionStart, selectionEnd, visibleSegment, regex, par_size, bracket_size); }
public void ColourisePattern(ICancellable cnc, ColouredSegments colouredSegments, string pattern, Segment visibleSegment) { GrammarEnum grammar = OptionsControl.GetGrammar( ); bool mod_x = OptionsControl.GetModX( ); Regex regex = GetCachedColouringRegex(grammar, mod_x); foreach (Match m in regex.Matches(pattern)) { Debug.Assert(m.Success); if (cnc.IsCancellationRequested) { return; } // escapes, '\...' { var g = m.Groups["escape"]; if (g.Success) { if (cnc.IsCancellationRequested) { return; } foreach (Capture c in g.Captures) { if (cnc.IsCancellationRequested) { return; } var intersection = Segment.Intersection(visibleSegment, c.Index, c.Length); if (!intersection.IsEmpty) { colouredSegments.Escapes.Add(intersection); } } } } if (cnc.IsCancellationRequested) { return; } // comments, '(?#...)', '#...' { var g = m.Groups["comment"]; if (g.Success) { if (cnc.IsCancellationRequested) { return; } foreach (Capture c in g.Captures) { if (cnc.IsCancellationRequested) { return; } var intersection = Segment.Intersection(visibleSegment, c.Index, c.Length); if (!intersection.IsEmpty) { colouredSegments.Comments.Add(intersection); } } } } if (cnc.IsCancellationRequested) { return; } // class (within [...] groups), '[:...:]', '[=...=]', '[. ... .]' { var g = m.Groups["class"]; if (g.Success) { if (cnc.IsCancellationRequested) { return; } foreach (Capture c in g.Captures) { if (cnc.IsCancellationRequested) { return; } var intersection = Segment.Intersection(visibleSegment, c.Index, c.Length); if (!intersection.IsEmpty) { colouredSegments.Escapes.Add(intersection); } } } } if (cnc.IsCancellationRequested) { return; } // named group, '(?<name>...)' or '(?'name'...)' { var g = m.Groups["name"]; if (g.Success) { if (cnc.IsCancellationRequested) { return; } foreach (Capture c in g.Captures) { if (cnc.IsCancellationRequested) { return; } var intersection = Segment.Intersection(visibleSegment, c.Index, c.Length); if (!intersection.IsEmpty) { colouredSegments.GroupNames.Add(intersection); } } } } } }
static Regex CreateHighlightingRegex(GrammarEnum grammar, bool modX) { bool is_perl = grammar == GrammarEnum.perl || grammar == GrammarEnum.ECMAScript || grammar == GrammarEnum.normal || grammar == GrammarEnum.JavaScript || grammar == GrammarEnum.JScript; bool is_POSIX_extended = grammar == GrammarEnum.extended || grammar == GrammarEnum.egrep || grammar == GrammarEnum.awk; bool is_POSIX_basic = grammar == GrammarEnum.basic || grammar == GrammarEnum.sed || grammar == GrammarEnum.grep || grammar == GrammarEnum.emacs; bool is_emacs = grammar == GrammarEnum.emacs; var pb = new PatternBuilder( ); if (is_perl) { pb.Add(@"(\(\?\#.*?(\)|$))"); // comment } if (is_perl && modX) { pb.Add(@"(\#[^\n]*)"); // line comment } if (is_perl || is_POSIX_extended) { pb.Add(@"\\Q.*?(\\E|$)"); // skip \Q...\E pb.Add(@"\\[xNpPgk]\{.*?(\}|$)"); // (skip) } if (is_perl || is_POSIX_extended) { pb.AddGroup("left_par", @"\("); // '(' pb.AddGroup("right_par", @"\)"); // ')' pb.Add(@"(?'left_brace'\{) \s* \d+ \s* (, \s* \d*)? \s* ((?'right_brace'\})|$)"); // '{...}' (spaces are allowed) } if (is_POSIX_basic) { pb.AddGroup("left_par", @"\\\("); // '\(' pb.AddGroup("right_par", @"\\\)"); // '\)' pb.Add(@"(?'left_brace'\\{).*?((?'right_brace'\\})|$)"); // '\{...\}' } if (is_perl || is_POSIX_extended || is_POSIX_basic) { pb.Add(@"((?'left_bracket'\[) \]? ((\[:.*? (:\]|$)) | \\. | .)*? ((?'right_bracket'\])|$) )"); // [...] pb.Add(@"\\."); // '\...' } return(pb.ToRegex( )); }
static Regex CreateColouringRegex(GrammarEnum grammar, bool modX) { bool is_perl = grammar == GrammarEnum.perl || grammar == GrammarEnum.ECMAScript || grammar == GrammarEnum.normal || grammar == GrammarEnum.JavaScript || grammar == GrammarEnum.JScript; bool is_POSIX_extended = grammar == GrammarEnum.extended || grammar == GrammarEnum.egrep || grammar == GrammarEnum.awk; bool is_POSIX_basic = grammar == GrammarEnum.basic || grammar == GrammarEnum.sed || grammar == GrammarEnum.grep || grammar == GrammarEnum.emacs; bool is_emacs = grammar == GrammarEnum.emacs; var pb_escape = new PatternBuilder( ); pb_escape.BeginGroup("escape"); if (is_perl || is_POSIX_extended || is_POSIX_basic) { pb_escape.Add(@"\\[1-9]"); // back reference } if (is_perl || is_POSIX_extended) { pb_escape.Add(@"\\c[A-Za-z]"); // ASCII escape } if (is_perl || is_POSIX_extended) { pb_escape.Add(@"\\x[0-9A-Fa-f]{1,2}"); // hex, two digits } if (is_perl || is_POSIX_extended) { pb_escape.Add(@"\\x\{[0-9A-Fa-f]+(\}|$)"); // hex, four digits } if (is_perl || is_POSIX_extended) { pb_escape.Add(@"\\0[0-7]{1,3}"); // octal, three digits } if (is_perl || is_POSIX_extended) { pb_escape.Add(@"\\N\{.*?(\}|$)"); // symbolic name } if (is_perl || is_POSIX_extended) { pb_escape.Add(@"\\[pP]\{.*?(\}|$)"); // property } if (is_perl || is_POSIX_extended) { pb_escape.Add(@"\\[pP]."); // property, short name } if (is_perl || is_POSIX_extended) { pb_escape.Add(@"\\Q.*?(\\E|$)"); } ; // quoted sequence if (is_emacs) { pb_escape.Add(@"\\[sS]."); // syntax group } if (is_perl || is_POSIX_extended) { pb_escape.Add(@"\\."); // various } if (is_POSIX_basic) { pb_escape.Add(@"(?!\\\( | \\\) | \\\{ | \\\})\\."); // various } pb_escape.EndGroup( ); var pb_class = new PatternBuilder( ); pb_class.BeginGroup("class"); if (is_perl || is_POSIX_extended || is_POSIX_basic) { pb_class.Add(@"\[(?'c'[:=.]) .*? (\k<c>\] | $)"); } pb_class.EndGroup( ); var pb = new PatternBuilder( ); pb.BeginGroup("comment"); if (is_perl) { pb.Add(@"\(\?\#.*?(\)|$)"); // comment } if (is_perl && modX) { pb.Add(@"\#.*?(\n|$)"); // line-comment*/ } pb.EndGroup( ); if (is_perl) { pb.Add(@"\(\?(?'name'<(?![=!]).*?(>|$)) | \(\?(?'name''.*?('|$))"); } if (is_perl) { pb.Add(@"(?'name'\\g-?[1-9]) | (?'name'\\g\{.*?(\}|$))"); // back reference } if (is_perl) { pb.Add(@"(?'name'\\[gk]<.*?(>|$)) | (?'name'\\[gk]'.*?('|$))"); // back reference } if (is_perl || is_POSIX_extended || is_POSIX_basic) { pb.AddGroup(null, $@"\[ \]? ({pb_class.ToPattern( )} | {pb_escape.ToPattern( )} | . )*? (\]|$)"); } pb.Add(pb_escape.ToPattern( )); return(pb.ToRegex( )); }
public void ColourisePattern(ICancellable cnc, ColouredSegments colouredSegments, string pattern, Segment visibleSegment) { GrammarEnum grammar = OptionsControl.GetGrammar( ); Regex regex = GetCachedColouringRegex(grammar); foreach (Match m in regex.Matches(pattern)) { Debug.Assert(m.Success); if (cnc.IsCancellationRequested) { return; } // escapes, '\...' { var g = m.Groups["escape"]; if (g.Success) { if (cnc.IsCancellationRequested) { return; } foreach (Capture c in g.Captures) { if (cnc.IsCancellationRequested) { return; } var intersection = Segment.Intersection(visibleSegment, c.Index, c.Length); if (!intersection.IsEmpty) { colouredSegments.Escapes.Add(intersection); } } } } if (cnc.IsCancellationRequested) { return; } // classes within character groups, [ ... [:...:] ... ] { var g = m.Groups["class"]; if (g.Success) { if (cnc.IsCancellationRequested) { return; } foreach (Capture c in g.Captures) { if (cnc.IsCancellationRequested) { return; } var intersection = Segment.Intersection(visibleSegment, c.Index, c.Length); if (!intersection.IsEmpty) { colouredSegments.Escapes.Add(intersection); } } } } } }