64
63
if (doc == null || doc.SuppressHighlightUpdate)
66
Mono.TextEditor.Highlighting.SyntaxModeService.StartUpdate (doc, this, e.Offset, e.Offset + e.InsertionLength);
65
SyntaxModeService.StartUpdate (doc, this, e.Offset, e.Offset + e.InsertionLength);
69
68
void HandleTextSet (object sender, EventArgs e)
71
70
if (doc == null || doc.SuppressHighlightUpdate)
73
Mono.TextEditor.Highlighting.SyntaxModeService.StartUpdate (doc, this, 0, doc.TextLength);
72
SyntaxModeService.StartUpdate (doc, this, 0, doc.TextLength);
76
75
public event EventHandler DocumentSet;
78
77
protected virtual void OnDocumentSet (EventArgs e)
80
EventHandler handler = this.DocumentSet;
79
var handler = DocumentSet;
81
80
if (handler != null)
134
133
if (result != null) {
136
if (result.Offset != offset) {
137
while (result != null && result.EndOffset < offset)
135
if (result.Offset < offset) {
136
while (result != null && result.EndOffset < offset) {
138
137
result = result.Next;
139
139
if (result != null) {
140
140
int endOffset = result.EndOffset;
141
141
result.Offset = offset;
142
142
result.Length = endOffset - offset;
146
if (result != null && offset + length != chunkParser.lineOffset + line.Length) {
149
while (cur != null && cur.EndOffset < offset + length) {
153
cur.Length = offset + length - cur.Offset;
158
146
while (result != null) {
148
if (result.EndOffset >= offset + length) {
149
result.Length = offset + length - result.Offset;
151
if (result.Length < 0) {
159
156
yield return result;
160
157
result = result.Next;
166
163
return string.Format ("#{0:X2}{1:X2}{2:X2}", color.Red >> 8, color.Green >> 8, color.Blue >> 8);
165
public static string ColorToPangoMarkup (Cairo.Color color)
167
return ColorToPangoMarkup ((Gdk.Color)((HslColor)color));
169
170
public static int GetIndentLength (TextDocument doc, int offset, int length, bool skipFirstLine)
237
238
Rule rule = mode;
238
239
result.Push (mode);
239
foreach (Span span in this.spanStack.Reverse ()) {
240
Rule tmp = rule.GetRule (doc, span.Rule) ?? this.CurRule;
240
foreach (Span span in spanStack.Reverse ()) {
241
Rule tmp = rule.GetRule (doc, span.Rule) ?? CurRule;
241
242
result.Push (tmp);
338
339
RegexMatch match = span.Begin.TryMatch (CurText, textOffset);
340
if (!match.Success) {
341
343
// scan for span exit which cancels the span.
342
344
if ((span.ExitFlags & SpanExitFlags.CancelSpan) == SpanExitFlags.CancelSpan && span.Exit != null) {
343
345
bool foundEnd = false;
344
346
for (int k = i + match.Length; k < CurText.Length; k++) {
345
347
if (span.Exit.TryMatch (CurText, k - StartOffset).Success)
347
349
if (span.End.TryMatch (CurText, k - StartOffset).Success) {
356
358
bool mismatch = false;
361
363
FoundSpanBegin (span, i, match.Length);
362
i += match.Length - 1;
364
i += System.Math.Max (0, match.Length - 1);
367
370
protected virtual bool ScanSpanEnd (Span cur, ref int i)
372
375
RegexMatch match = cur.End.TryMatch (CurText, textOffset);
373
376
if (match.Success) {
374
377
FoundSpanEnd (cur, i, match.Length);
375
i += match.Length - 1;
378
i += System.Math.Max (0, match.Length - 1);
381
384
RegexMatch match = cur.Exit.TryMatch (CurText, textOffset);
382
385
if (match.Success) {
383
386
FoundSpanExit (cur, i, match.Length);
384
i += match.Length - 1;
387
i += System.Math.Max (0, match.Length - 1);
420
i += cur.Escape.Length;
421
if (cur.Escape.Length > 1)
423
int j = i + cur.Escape.Length - 1;
424
ParseChar (ref i, CurText [textIndex]);
426
429
if (ScanSpanEnd (cur, ref i))
430
if (i < doc.TextLength)
431
ParseChar (ref i, CurText [textIndex]);
433
if (!ScanSpan (ref i)) {
434
if (i < doc.TextLength)
435
ParseChar (ref i, CurText [textIndex]);
436
441
public class ChunkParser
438
readonly string defaultStyle = "text";
443
readonly string defaultStyle = "Plain Text";
439
444
protected SpanParser spanParser;
440
445
protected TextDocument doc;
441
446
protected DocumentLine line;
519
524
string rule = spanParser.SpanStack.Peek ().Rule;
520
if (!string.IsNullOrEmpty (rule) && rule.StartsWith ("mode:"))
525
if (!string.IsNullOrEmpty (rule) && rule.StartsWith ("mode:", StringComparison.Ordinal))
521
526
return spanParser.CurRule.DefaultColor ?? defaultStyle;
522
527
return spanParser.SpanStack.Peek ().Color;
555
560
curChunk.SpanStack.Push (span);
556
561
AddChunk (ref curChunk, 0, curChunk.Style);
557
562
foreach (SemanticRule semanticRule in spanRule.SemanticRules) {
558
semanticRule.Analyze (this.doc, line, curChunk, offset, line.EndOffsetIncludingDelimiter);
563
semanticRule.Analyze (doc, line, curChunk, offset, line.EndOffsetIncludingDelimiter);
580
585
spanParser.PopSpan ();
582
587
protected StringBuilder wordbuilder = new StringBuilder ();
584
589
public void ParseChar (ref int i, char ch)
586
int textOffset = i - spanParser.StartOffset;
588
591
Rule cur = spanParser.CurRule;
589
592
bool isWordPart = cur.Delimiter.IndexOf (ch) < 0;
591
593
if (inWord && !isWordPart || !inWord && isWordPart)
592
594
AddChunk (ref curChunk, 0, curChunk.Style = GetStyle (curChunk) ?? GetSpanStyle ());
594
596
inWord = isWordPart;
596
if (cur.HasMatches && i - curChunk.Offset == 0) {
598
if (cur.HasMatches && (i - curChunk.Offset == 0 || string.IsNullOrEmpty (cur.Delimiter))) {
597
599
Match foundMatch = null;
598
int foundMatchLength = 0;
600
var foundMatchLength = new int[0];
601
int textOffset = i - spanParser.StartOffset;
599
602
foreach (Match ruleMatch in cur.Matches) {
600
int matchLength = ruleMatch.TryMatch (spanParser.CurText, textOffset);
601
if (foundMatchLength < matchLength) {
603
var matchLength = ruleMatch.TryMatch (spanParser.CurText, textOffset);
604
if (foundMatchLength.Length < matchLength.Length) {
602
605
foundMatch = ruleMatch;
603
606
foundMatchLength = matchLength;
606
609
if (foundMatch != null) {
607
AddChunk (ref curChunk, foundMatchLength, GetChunkStyleColor (foundMatch.Color));
608
i += foundMatchLength - 1;
609
curChunk.Length = i - curChunk.Offset + 1;
610
if (foundMatch.IsGroupMatch) {
611
for (int j = 1; j < foundMatchLength.Length; j++) {
612
var len = foundMatchLength [j];
614
AddChunk (ref curChunk, len, GetChunkStyleColor (foundMatch.Groups [j - 1]));
621
if (foundMatchLength[0] > 0) {
622
AddChunk (ref curChunk, foundMatchLength[0], GetChunkStyleColor (foundMatch.Color));
623
i += foundMatchLength[0] - 1;
613
629
wordbuilder.Append (ch);
614
630
curChunk.Length = i - curChunk.Offset + 1;
632
AddChunk (ref curChunk, 0, curChunk.Style = GetStyle (curChunk) ?? GetSpanStyle ());
617
637
protected virtual string GetStyle (Chunk chunk)
643
public override Rule GetRule (TextDocument doc, string name)
663
public override Rule GetRule (TextDocument document, string name)
645
665
if (name == null || name == "<root>") {
648
if (name.StartsWith ("mode:"))
649
return SyntaxModeService.GetSyntaxMode (doc, name.Substring ("mode:".Length));
668
if (name.StartsWith ("mode:", StringComparison.Ordinal))
669
return SyntaxModeService.GetSyntaxMode (document, name.Substring ("mode:".Length));
651
671
foreach (Rule rule in rules) {
652
672
if (rule.Name == name)
701
721
public const string MimeTypesAttribute = "mimeTypes";
703
public static SyntaxMode Read (XmlReader reader)
723
public static SyntaxMode Read (Stream stream)
725
var reader = XmlReader.Create (stream);
705
726
var result = new SyntaxMode (null);
706
List<Match> matches = new List<Match> ();
707
List<Span> spanList = new List<Span> ();
708
List<Marker> prevMarkerList = new List<Marker> ();
727
var matches = new List<Match> ();
728
var spanList = new List<Span> ();
729
var prevMarkerList = new List<Marker> ();
709
730
XmlReadHelper.ReadList (reader, Node, delegate () {
710
731
if (reader == null)
778
799
Rule DeepCopy (TextDocument doc, SyntaxMode mode, Rule rule)
780
Rule newRule = new Rule (mode);
801
var newRule = new Rule (mode);
781
802
newRule.spans = new Span[rule.Spans.Length];
782
803
for (int i = 0; i < rule.Spans.Length; i++) {
783
804
newRule.spans [i] = rule.Spans [i].Clone ();