33
33
using System.Threading;
35
35
using System.Xml.Schema;
37
38
namespace Mono.TextEditor.Highlighting
39
40
public static class SyntaxModeService
41
static Dictionary<string, SyntaxMode> syntaxModes = new Dictionary<string, SyntaxMode> ();
42
static Dictionary<string, ColorSheme> styles = new Dictionary<string, ColorSheme> ();
42
static Dictionary<string, ISyntaxModeProvider> syntaxModes = new Dictionary<string, ISyntaxModeProvider> ();
43
static Dictionary<string, ColorScheme> styles = new Dictionary<string, ColorScheme> ();
43
44
static Dictionary<string, IXmlProvider> syntaxModeLookup = new Dictionary<string, IXmlProvider> ();
44
45
static Dictionary<string, IXmlProvider> styleLookup = new Dictionary<string, IXmlProvider> ();
45
46
static Dictionary<string, string> isLoadedFromFile = new Dictionary<string, string> ();
70
public static void InstallSyntaxMode (string mimeType, SyntaxMode mode)
71
public static void InstallSyntaxMode (string mimeType, ISyntaxModeProvider modeProvider)
72
73
if (syntaxModeLookup.ContainsKey (mimeType))
73
74
syntaxModeLookup.Remove (mimeType);
74
syntaxModes[mimeType] = mode;
75
syntaxModes[mimeType] = modeProvider;
77
public static ColorSheme GetColorStyle (Gtk.Style widgetStyle, string name)
78
public static ColorScheme GetColorStyle (Gtk.Style widgetStyle, string name)
79
80
if (styles.ContainsKey (name))
80
81
return styles [name];
107
108
throw new System.ArgumentException ("Style " + name + " not found", "name");
108
109
XmlReader reader = styleLookup [name].Open ();
110
styles [name] = ColorSheme.LoadFrom (reader);
111
styles [name] = ColorScheme.LoadFrom (reader);
111
112
} catch (Exception e) {
112
113
throw new IOException ("Error while loading style :" + name, e);
121
122
throw new System.ArgumentException ("Syntax mode for mime:" + mimeType + " not found", "mimeType");
122
123
XmlReader reader = syntaxModeLookup [mimeType].Open ();
124
SyntaxMode mode = SyntaxMode.Read (reader);
125
var mode = SyntaxMode.Read (reader);
125
126
foreach (string mime in mode.MimeType.Split (';')) {
126
syntaxModes [mime] = mode;
127
syntaxModes [mime] = new ProtoTypeSyntaxModeProvider (mode);
128
129
} catch (Exception e) {
129
130
throw new IOException ("Error while syntax mode for mime:" + mimeType, e);
135
public static SyntaxMode GetSyntaxMode (string mimeType)
137
if (syntaxModes.ContainsKey (mimeType))
138
return syntaxModes[mimeType];
139
if (syntaxModeLookup.ContainsKey (mimeType)) {
136
public static SyntaxMode GetSyntaxMode (TextDocument doc)
138
return GetSyntaxMode (doc, doc.MimeType);
141
public static SyntaxMode GetSyntaxMode (TextDocument doc, string mimeType)
143
SyntaxMode result = null;
144
if (syntaxModes.ContainsKey (mimeType)) {
145
result = syntaxModes [mimeType].Create (doc);
146
} else if (syntaxModeLookup.ContainsKey (mimeType)) {
140
147
LoadSyntaxMode (mimeType);
141
148
syntaxModeLookup.Remove (mimeType);
142
return GetSyntaxMode (mimeType);
149
result = GetSyntaxMode (doc, mimeType);
151
if (result != null) {
152
foreach (var rule in semanticRules.Where (r => r.Item1 == mimeType)) {
153
result.AddSemanticRule (rule.Item2, rule.Item3);
147
159
public static bool ValidateAllSyntaxModes ()
161
var doc = new TextDocument ();
149
162
foreach (string mime in new List<string> (syntaxModeLookup.Keys)) {
150
GetSyntaxMode (mime);
163
GetSyntaxMode (doc, mime);
152
165
syntaxModeLookup.Clear ();
153
166
foreach (string style in new List<string> (styleLookup.Keys)) {
156
169
styleLookup.Clear ();
157
170
bool result = true;
158
foreach (KeyValuePair<string, ColorSheme> style in styles) {
159
HashSet<SyntaxMode> checkedModes = new HashSet<SyntaxMode> ();
160
foreach (KeyValuePair<string, SyntaxMode> mode in syntaxModes) {
171
foreach (KeyValuePair<string, ColorScheme> style in styles) {
172
var checkedModes = new HashSet<ISyntaxModeProvider> ();
173
foreach (var mode in syntaxModes) {
161
174
if (checkedModes.Contains (mode.Value))
163
if (!mode.Value.Validate (style.Value)) {
164
System.Console.WriteLine(mode.Key + " failed to validate against:" + style.Key);
176
if (!mode.Value.Create (doc).Validate (style.Value)) {
177
System.Console.WriteLine (mode.Key + " failed to validate against:" + style.Key);
167
180
checkedModes.Add (mode.Value);
191
public static void ScanSpans (Document doc, SyntaxMode mode, Rule rule, CloneableStack<Span> spanStack, int start, int end)
204
public static void ScanSpans (TextDocument doc, SyntaxMode mode, Rule rule, CloneableStack<Span> spanStack, int start, int end)
193
SyntaxMode.SpanParser parser = mode.CreateSpanParser (doc, mode, null, spanStack);
206
SyntaxMode.SpanParser parser = mode.CreateSpanParser (null, spanStack);
194
207
parser.ParseSpans (start, end - start);
219
public UpdateWorker (Document doc, SyntaxMode mode, int startOffset, int endOffset)
232
public UpdateWorker (TextDocument doc, SyntaxMode mode, int startOffset, int endOffset)
222
235
this.mode = mode;
230
bool EndsWithContinuation (Span span, LineSegment line)
243
bool EndsWithContinuation (Span span, DocumentLine line)
232
245
return !span.StopAtEol || span.StopAtEol && !string.IsNullOrEmpty (span.Continuation) &&
233
246
line != null && doc.GetTextAt (line).Trim ().EndsWith (span.Continuation);
247
260
if (span == null)
249
262
var spanStack = span.Clone ();
250
SyntaxMode.SpanParser parser = mode.CreateSpanParser(doc, mode, null, spanStack);
263
SyntaxMode.SpanParser parser = mode.CreateSpanParser(null, spanStack);
251
264
foreach (var line in doc.GetLinesStartingAt (startLine)) {
252
265
if (line == null)
263
276
line.StartSpan = spanStack.Clone();
264
parser.ParseSpans(line.Offset, line.Length);
277
parser.ParseSpans(line.Offset, line.LengthIncludingDelimiter);
265
278
while (spanStack.Count > 0 && !EndsWithContinuation(spanStack.Peek(), line))
266
279
parser.PopSpan();
314
public static void StartUpdate (Document doc, SyntaxMode mode, int startOffset, int endOffset)
327
public static void StartUpdate (TextDocument doc, SyntaxMode mode, int startOffset, int endOffset)
316
329
lock (updateQueue) {
317
330
updateQueue.Enqueue (new UpdateWorker (doc, mode, startOffset, endOffset));
404
417
} else if (file.EndsWith ("Style.xml")) {
405
418
using (XmlTextReader reader = new XmlTextReader (file)) {
406
string styleName = Scan (reader, ColorSheme.NameAttribute);
419
string styleName = Scan (reader, ColorScheme.NameAttribute);
407
420
styleLookup [styleName] = new UrlXmlProvider (file);
408
421
isLoadedFromFile [styleName] = file;
427
440
} else if (resource.EndsWith ("Style.xml")) {
428
441
using (Stream stream = assembly.GetManifestResourceStream (resource))
429
442
using (XmlTextReader reader = new XmlTextReader (stream)) {
430
string styleName = Scan (reader, ColorSheme.NameAttribute);
443
string styleName = Scan (reader, ColorScheme.NameAttribute);
431
444
styleLookup [styleName] = new ResourceXmlProvider (assembly, resource);
457
public static void AddStyle (string fileName, ColorSheme style)
470
public static void AddStyle (string fileName, ColorScheme style)
459
472
isLoadedFromFile [style.Name] = fileName;
460
473
styles [style.Name] = style;
462
475
public static void AddStyle (IXmlProvider provider)
464
477
using (XmlReader reader = provider.Open ()) {
465
string styleName = Scan (reader, ColorSheme.NameAttribute);
478
string styleName = Scan (reader, ColorScheme.NameAttribute);
466
479
styleLookup [styleName] = provider;
469
482
public static void RemoveStyle (IXmlProvider provider)
471
484
using (XmlReader reader = provider.Open ()) {
472
string styleName = Scan (reader, ColorSheme.NameAttribute);
485
string styleName = Scan (reader, ColorScheme.NameAttribute);
473
486
styleLookup.Remove (styleName);
490
static List<Tuple<string, string, SemanticRule>> semanticRules = new List<Tuple<string, string, SemanticRule>> ();
492
public static void AddSemanticRule (string mime, string ruleName, SemanticRule rule)
494
semanticRules.Add (Tuple.Create (mime, ruleName, rule));
477
497
static SyntaxModeService ()
479
499
StartUpdateThread ();
480
LoadStylesAndModes (typeof (SyntaxModeService).Assembly);
481
SyntaxModeService.GetSyntaxMode ("text/x-csharp").AddSemanticRule ("Comment", new HighlightUrlSemanticRule ("comment"));
482
SyntaxModeService.GetSyntaxMode ("text/x-csharp").AddSemanticRule ("XmlDocumentation", new HighlightUrlSemanticRule ("comment"));
483
SyntaxModeService.GetSyntaxMode ("text/x-csharp").AddSemanticRule ("String", new HighlightUrlSemanticRule ("string"));
500
LoadStylesAndModes (typeof(SyntaxModeService).Assembly);
501
SyntaxModeService.AddSemanticRule ("text/x-csharp", "Comment", new HighlightUrlSemanticRule ("comment"));
502
SyntaxModeService.AddSemanticRule ("text/x-csharp", "XmlDocumentation", new HighlightUrlSemanticRule ("comment"));
503
SyntaxModeService.AddSemanticRule ("text/x-csharp", "String", new HighlightUrlSemanticRule ("string"));
485
InstallSyntaxMode ("text/x-jay", new JaySyntaxMode ());
505
InstallSyntaxMode ("text/x-jay", new SyntaxModeProvider (doc => new JaySyntaxMode (doc)));