diff --git a/src/TextMateSharp.Tests/Internal/Grammars/GrammarTests.cs b/src/TextMateSharp.Tests/Internal/Grammars/GrammarTests.cs index fd8b7a9..6e6c1a1 100644 --- a/src/TextMateSharp.Tests/Internal/Grammars/GrammarTests.cs +++ b/src/TextMateSharp.Tests/Internal/Grammars/GrammarTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using TextMateSharp.Grammars; +using TextMateSharp.Internal.Grammars; using TextMateSharp.Internal.Grammars.Reader; using TextMateSharp.Internal.Themes.Reader; using TextMateSharp.Internal.Types; @@ -15,7 +16,104 @@ namespace TextMateSharp.Tests.Internal.Grammars class GrammarTests { [Test] - public void ParseSimpleTokensTest() + public void StackElementMetadata_Test_Should_Work() + { + int value = StackElementMetadata.Set(0, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, + 102); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102); + } + + [Test] + public void StackElementMetadata_Should_Allow_Overwrite_Language_Id() + { + int value = StackElementMetadata.Set(0, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, + 102); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102); + + value = StackElementMetadata.Set(value, 2, StandardTokenType.Other, FontStyle.NotSet, 0, 0); + AssertMetadataHasProperties(value, 2, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102); + } + + [Test] + public void StackElementMetadata_Should_Allow_Overwrite_Token_Type() + { + int value = StackElementMetadata.Set(0, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, + 102); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102); + + value = StackElementMetadata.Set(value, 0, StandardTokenType.Comment, FontStyle.NotSet, 0, 0); + AssertMetadataHasProperties(value, 1, StandardTokenType.Comment, FontStyle.Underline | FontStyle.Bold, 101, 102); + } + + [Test] + public void StackElementMetadata_Should_Allow_Overwrite_Font_Style() + { + int value = StackElementMetadata.Set(0, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, + 102); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102); + + value = StackElementMetadata.Set(value, 0, StandardTokenType.Other, FontStyle.None, 0, 0); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.None, 101, 102); + } + + [Test] + public void CanOverwriteFontStyleWithStrikethrough() + { + int value = StackElementMetadata.Set(0, 1, StandardTokenType.RegEx, FontStyle.Strikethrough, 101, 102); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.Strikethrough, 101, 102); + + value = StackElementMetadata.Set(value, 0, StandardTokenType.Other, FontStyle.None, 0, 0); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.None, 101, 102); + } + + [Test] + public void StackElementMetadata_Should_Allow_Overwrite_Foreground() + { + int value = StackElementMetadata.Set(0, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, + 102); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102); + + value = StackElementMetadata.Set(value, 0, StandardTokenType.Other, FontStyle.NotSet, 5, 0); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 5, 102); + } + + [Test] + public void StackElementMetadata_Should_Allow_Overwrite_Background() + { + int value = StackElementMetadata.Set(0, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, + 102); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102); + + value = StackElementMetadata.Set(value, 0, StandardTokenType.Other, FontStyle.NotSet, 0, 7); + AssertMetadataHasProperties(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 7); + } + + [Test] + public void StackElementMetadata_Should_Work_At_Max_Values() + { + int maxLangId = 255; + int maxTokenType = StandardTokenType.Comment | StandardTokenType.Other | StandardTokenType.RegEx + | StandardTokenType.String; + int maxFontStyle = FontStyle.Bold | FontStyle.Italic | FontStyle.Underline; + int maxForeground = 511; + int maxBackground = 511; + + int value = StackElementMetadata.Set(0, maxLangId, maxTokenType, maxFontStyle, maxForeground, maxBackground); + AssertMetadataHasProperties(value, maxLangId, maxTokenType, maxFontStyle, maxForeground, maxBackground); + } + + [Test] + public void Convert_To_Binary_String_Should_Work() + { + string binValue1 = StackElementMetadata.ToBinaryStr(StackElementMetadata.Set(0, 0, 0, 0, 0, 511)); + Assert.AreEqual("11111111100000000000000000000000", binValue1); + + string binValue2 = StackElementMetadata.ToBinaryStr(StackElementMetadata.Set(0, 0, 0, 0, 511, 0)); + Assert.AreEqual("00000000011111111100000000000000", binValue2); + } + + [Test] + public void Parse_Simple_Tokens_Should_Work() { string line = "using System;"; @@ -41,7 +139,7 @@ public void ParseSimpleTokensTest() } [Test] - public void ParseCssTokensTest() + public void Parse_Css_Tokens_Should_Work() { string line = "body { margin: 25px; }"; @@ -59,7 +157,7 @@ public void ParseCssTokensTest() } [Test] - public void TestMatchScopeName() + public void Match_Scope_Name_Should_Work() { Registry.Registry registry = new Registry.Registry( new TestRegistry()); @@ -76,7 +174,7 @@ public void TestMatchScopeName() } [Test] - public void TestBatchGrammar() + public void Batch_Grammar_Should_Work() { string line = "REM echo off"; @@ -92,7 +190,7 @@ public void TestBatchGrammar() } [Test] - public void ParseMultilineTokensTest() + public void Multiline_Tokens_Should_Work() { string[] lines = new string[] { @@ -143,12 +241,12 @@ public void ParseMultilineTokensTest() } [Test] - public void TokenizeUnicodeCommentsTest() + public void Tokenize_Unicode_Comments_Should_Work() { string text = "string s = \"chars: 安定させる\";"; Registry.Registry registry = new Registry.Registry( - new TestRegistry()); + new TestRegistry()); IGrammar grammar = registry.LoadGrammar("source.cs"); @@ -164,7 +262,7 @@ public void TokenizeUnicodeCommentsTest() } [Test] - public void TokenizeUnicodeCommentsTest2() + public void Tokenize_Unicode_Comments_Should_Work2() { // TODO: fix parsing unicode characters string text = "\"安安安\""; @@ -179,7 +277,7 @@ public void TokenizeUnicodeCommentsTest2() } [Test] - public void GrammarInjectionTest() + public void Grammar_Should_Inject_Other_Grammars() { Registry.Registry registry = new Registry.Registry( new TestRegistry()); @@ -278,6 +376,33 @@ static void AssertTokenValuesAreEqual(IToken token, int startIndex, int endIndex } } + static void AssertMetadataHasProperties( + int metadata, + int languageId, + int tokenType, + int fontStyle, + int foreground, + int background) + { + string actual = "{\n" + + "languageId: " + StackElementMetadata.GetLanguageId(metadata) + ",\n" + + "tokenType: " + StackElementMetadata.GetTokenType(metadata) + ",\n" + + "fontStyle: " + StackElementMetadata.GetFontStyle(metadata) + ",\n" + + "foreground: " + StackElementMetadata.GetForeground(metadata) + ",\n" + + "background: " + StackElementMetadata.GetBackground(metadata) + ",\n" + + "}"; + + string expected = "{\n" + + "languageId: " + languageId + ",\n" + + "tokenType: " + tokenType + ",\n" + + "fontStyle: " + fontStyle + ",\n" + + "foreground: " + foreground + ",\n" + + "background: " + background + ",\n" + + "}"; + + Assert.AreEqual(expected, actual, "equals for " + StackElementMetadata.ToBinaryStr(metadata)); + } + class TestRegistry : IRegistryOptions { public IRawTheme GetTheme(string scopeName) diff --git a/src/TextMateSharp/Internal/Grammars/Grammar.cs b/src/TextMateSharp/Internal/Grammars/Grammar.cs index 102ec5c..1ccf440 100644 --- a/src/TextMateSharp/Internal/Grammars/Grammar.cs +++ b/src/TextMateSharp/Internal/Grammars/Grammar.cs @@ -18,7 +18,7 @@ public class Grammar : IGrammar, IRuleFactoryHelper private Dictionary _ruleId2desc; private Dictionary _includedGrammars; private IGrammarRepository _grammarRepository; - private IRawGrammar _grammar; + private IRawGrammar _rawGrammar; private List _injections; private ScopeMetadataProvider _scopeMetadataProvider; @@ -30,7 +30,7 @@ public Grammar(IRawGrammar grammar, int initialLanguage, Dictionary _lastRuleId = 0; _includedGrammars = new Dictionary(); _grammarRepository = grammarRepository; - _grammar = InitGrammar(grammar, null); + _rawGrammar = InitGrammar(grammar, null); _ruleId2desc = new Dictionary(); _injections = null; } @@ -53,13 +53,13 @@ public List GetInjections() { this._injections = new List(); // add injections from the current grammar - Dictionary rawInjections = this._grammar.GetInjections(); + Dictionary rawInjections = this._rawGrammar.GetInjections(); if (rawInjections != null) { foreach (string expression in rawInjections.Keys) { IRawRule rule = rawInjections[expression]; - CollectInjections(this._injections, expression, rule, this, this._grammar); + CollectInjections(this._injections, expression, rule, this, this._rawGrammar); } } @@ -67,7 +67,7 @@ public List GetInjections() if (this._grammarRepository != null) { ICollection injectionScopeNames = this._grammarRepository - .Injections(this._grammar.GetScopeName()); + .Injections(this._rawGrammar.GetScopeName()); if (injectionScopeNames != null) { foreach (string injectionScopeName in injectionScopeNames) @@ -149,7 +149,7 @@ public IRawGrammar GetExternalGrammar(string scopeName, IRawRepository repositor private IRawGrammar InitGrammar(IRawGrammar grammar, IRawRule ruleBase) { - grammar = Clone(grammar); + grammar = grammar.Clone(); if (grammar.GetRepository() == null) { ((Raw)grammar).SetRepository(new Raw()); @@ -215,7 +215,7 @@ private object Tokenize(string lineText, StackElement prevState, bool emitBinary if (rootScopeName == null) return null; ScopeMetadata rawRootMetadata = this._scopeMetadataProvider.GetMetadataForScope(rootScopeName); - int rootMetadata = ScopeListElement.mergeMetadata(defaultMetadata, null, rawRootMetadata); + int rootMetadata = ScopeListElement.MergeMetadata(defaultMetadata, null, rawRootMetadata); ScopeListElement scopeList = new ScopeListElement(null, rootScopeName, rootMetadata); @@ -249,8 +249,8 @@ private void GenerateRootId() _isCompiling = true; try { - this._rootId = RuleFactory.GetCompiledRuleId(this._grammar.GetRepository().GetSelf(), this, - this._grammar.GetRepository()); + this._rootId = RuleFactory.GetCompiledRuleId(this._rawGrammar.GetRepository().GetSelf(), this, + this._rawGrammar.GetRepository()); } finally { @@ -260,17 +260,17 @@ private void GenerateRootId() public string GetName() { - return _grammar.GetName(); + return _rawGrammar.GetName(); } public string GetScopeName() { - return _grammar.GetScopeName(); + return _rawGrammar.GetScopeName(); } public ICollection GetFileTypes() { - return _grammar.GetFileTypes(); + return _rawGrammar.GetFileTypes(); } } } \ No newline at end of file diff --git a/src/TextMateSharp/Internal/Grammars/LineTokenizer.cs b/src/TextMateSharp/Internal/Grammars/LineTokenizer.cs index bf12df5..2c0abab 100644 --- a/src/TextMateSharp/Internal/Grammars/LineTokenizer.cs +++ b/src/TextMateSharp/Internal/Grammars/LineTokenizer.cs @@ -97,9 +97,8 @@ private void ScanNext() IOnigCaptureIndex[] captureIndices = r.CaptureIndexes; int? matchedRuleId = r.MatchedRuleId; - bool hasAdvanced = (captureIndices != null && captureIndices.Length > 0) - ? (captureIndices[0].End > _linePos) - : false; + bool hasAdvanced = captureIndices != null && captureIndices.Length > 0 + && captureIndices[0].End > _linePos; if (matchedRuleId == -1) { @@ -107,9 +106,9 @@ private void ScanNext() BeginEndRule poppedRule = (BeginEndRule)_stack.GetRule(_grammar); /* - * if (logger.isEnabled()) { logger.log(" popping " + poppedRule.debugName + - * " - " + poppedRule.debugEndRegExp); } - */ + * if (logger.isEnabled()) { logger.log(" popping " + poppedRule.debugName + + * " - " + poppedRule.debugEndRegExp); } + */ _lineTokens.Produce(_stack, captureIndices[0].Start); _stack = _stack.setContentNameScopesList(_stack.NameScopesList); @@ -251,7 +250,7 @@ private IMatchResult MatchRule(Grammar grammar, string lineText, in bool isFirst if (rule == null) return null; - ICompiledRule ruleScanner = rule.Compile(grammar, stack.EndRule, isFirstLine, linePos == anchorPosition); + CompiledRule ruleScanner = rule.Compile(grammar, stack.EndRule, isFirstLine, linePos == anchorPosition); if (ruleScanner == null) return null; @@ -328,7 +327,7 @@ private IMatchInjectionsResult MatchInjections(List injections, Gramm continue; } - ICompiledRule ruleScanner = grammar.GetRule(injection.RuleId).Compile(grammar, null, isFirstLine, + CompiledRule ruleScanner = grammar.GetRule(injection.RuleId).Compile(grammar, null, isFirstLine, linePos == anchorPosition); IOnigNextMatchResult matchResult = ruleScanner.Scanner.FindNextMatchSync(lineText, linePos); @@ -487,7 +486,7 @@ private WhileCheckResult CheckWhileConditions(Grammar grammar, string lineText, for (int i = whileRules.Count - 1; i >= 0; i--) { WhileStack whileRule = whileRules[i]; - ICompiledRule ruleScanner = whileRule.Rule.CompileWhile(grammar, whileRule.Stack.EndRule, isFirstLine, + CompiledRule ruleScanner = whileRule.Rule.CompileWhile(whileRule.Stack.EndRule, isFirstLine, currentanchorPosition == linePos); IOnigNextMatchResult r = ruleScanner.Scanner.FindNextMatchSync(lineText, linePos); diff --git a/src/TextMateSharp/Internal/Grammars/LineTokens.cs b/src/TextMateSharp/Internal/Grammars/LineTokens.cs index 6883ef8..9150a07 100644 --- a/src/TextMateSharp/Internal/Grammars/LineTokens.cs +++ b/src/TextMateSharp/Internal/Grammars/LineTokens.cs @@ -1,8 +1,5 @@ -using System; using System.Collections.Generic; - using TextMateSharp.Grammars; -using TextMateSharp.Internal.Utils; namespace TextMateSharp.Internal.Grammars { @@ -68,7 +65,7 @@ public void ProduceFromScopes(ScopeListElement scopesList, int endIndex) List scopes = scopesList.GenerateScopes(); - this._tokens.Add(new Token(this._lastTokenEndIndex, endIndex, scopes)); + this._tokens.Add(new Token(this._lastTokenEndIndex >= 0 ? this._lastTokenEndIndex : 0, endIndex, scopes)); this._lastTokenEndIndex = endIndex; } diff --git a/src/TextMateSharp/Internal/Grammars/MetadataConsts.cs b/src/TextMateSharp/Internal/Grammars/MetadataConsts.cs index c45fa8b..8e812b0 100644 --- a/src/TextMateSharp/Internal/Grammars/MetadataConsts.cs +++ b/src/TextMateSharp/Internal/Grammars/MetadataConsts.cs @@ -16,22 +16,22 @@ namespace TextMateSharp.Internal.Grammars * bbbb bbbb bfff ffff ffFF FTTT LLLL LLLL * - ------------------------------------------- * - L = LanguageId (8 bits) - * - T = StandardTokenType (3 bits) - * - F = FontStyle (3 bits) + * - T = StandardTokenType (2 bits) + * - F = FontStyle (4 bits) * - f = foreground color (9 bits) * - b = background color (9 bits) */ public class MetadataConsts { public static uint LANGUAGEID_MASK = 0b00000000000000000000000011111111; - public static uint TOKEN_TYPE_MASK = 0b00000000000000000000011100000000; - public static uint FONT_STYLE_MASK = 0b00000000000000000011100000000000; + public static uint TOKEN_TYPE_MASK = 0b00000000000000000000001100000000; + public static uint FONT_STYLE_MASK = 0b00000000000000000011110000000000; public static uint FOREGROUND_MASK = 0b00000000011111111100000000000000; public static uint BACKGROUND_MASK = 0b11111111100000000000000000000000; public const int LANGUAGEID_OFFSET = 0; public const int TOKEN_TYPE_OFFSET = 8; - public const int FONT_STYLE_OFFSET = 11; + public const int FONT_STYLE_OFFSET = 10; public const int FOREGROUND_OFFSET = 14; public const int BACKGROUND_OFFSET = 23; } diff --git a/src/TextMateSharp/Internal/Grammars/ScopeListElement.cs b/src/TextMateSharp/Internal/Grammars/ScopeListElement.cs index ed84443..a0880ba 100644 --- a/src/TextMateSharp/Internal/Grammars/ScopeListElement.cs +++ b/src/TextMateSharp/Internal/Grammars/ScopeListElement.cs @@ -18,6 +18,38 @@ public ScopeListElement(ScopeListElement parent, string scope, int metadata) Metadata = metadata; } + private static bool StructuralEquals(ScopeListElement a, ScopeListElement b) + { + do + { + if (a == b) + { + return true; + } + + if (a == null && b == null) + { + // End of list reached for both + return true; + } + + if (a == null || b == null) + { + // End of list reached only for one + return false; + } + + if (a.Scope != b.Scope || a.Metadata != b.Metadata) + { + return false; + } + + // Go to previous pair + a = a.Parent; + b = b.Parent; + } while (true); + } + private static bool Equals(ScopeListElement a, ScopeListElement b) { if (a == b) @@ -28,31 +60,22 @@ private static bool Equals(ScopeListElement a, ScopeListElement b) { return false; } - return Object.Equals(a.Scope, b.Scope) && a.Metadata == b.Metadata && Equals(a.Parent, b.Parent); + return StructuralEquals(a, b); } public override bool Equals(object other) { - if (other == this) - { - return true; - } - if (other == null) - { - return false; - } - if (!(other is ScopeListElement)) - { + if (other == null || (other is ScopeListElement)) return false; - } - return ScopeListElement.Equals(this, (ScopeListElement)other); + + return Equals(this, (ScopeListElement)other); } public override int GetHashCode() { - return Scope.GetHashCode() + - Metadata.GetHashCode() + - Parent.GetHashCode(); + return Parent.GetHashCode() + + Scope.GetHashCode() + + Metadata.GetHashCode(); } @@ -91,7 +114,7 @@ static bool Matches(ScopeListElement target, List parentScopes) return false; } - public static int mergeMetadata(int metadata, ScopeListElement scopesList, ScopeMetadata source) + public static int MergeMetadata(int metadata, ScopeListElement scopesList, ScopeMetadata source) { if (source == null) { @@ -126,7 +149,7 @@ private static ScopeListElement Push(ScopeListElement target, Grammar grammar, L foreach (string scope in scopes) { ScopeMetadata rawMetadata = grammar.GetMetadataForScope(scope); - int metadata = ScopeListElement.mergeMetadata(target.Metadata, target, rawMetadata); + int metadata = ScopeListElement.MergeMetadata(target.Metadata, target, rawMetadata); target = new ScopeListElement(target, scope, metadata); } return target; diff --git a/src/TextMateSharp/Internal/Grammars/StackElementMetadata.cs b/src/TextMateSharp/Internal/Grammars/StackElementMetadata.cs index 0d19005..531cd9f 100644 --- a/src/TextMateSharp/Internal/Grammars/StackElementMetadata.cs +++ b/src/TextMateSharp/Internal/Grammars/StackElementMetadata.cs @@ -1,3 +1,7 @@ +using System; +using System.Collections.Generic; +using System.Text; + using TextMateSharp.Themes; namespace TextMateSharp.Internal.Grammars @@ -6,43 +10,43 @@ public static class StackElementMetadata { public static string ToBinaryStr(int metadata) { - /* - * let r = metadata.toString(2); while (r.length < 32) { r = '0' + r; } - * return r; - */ - // TODO!!! - return null; + List builder = new List(Convert.ToString((uint)metadata, 2)); + + while (builder.Count < 32) + builder.Insert(0, '0'); + + return new string(builder.ToArray()); } public static int GetLanguageId(int metadata) { uint unitValue = (uint)metadata; - return (int)(unitValue & MetadataConsts.LANGUAGEID_MASK) >> MetadataConsts.LANGUAGEID_OFFSET; + return (int)((unitValue & MetadataConsts.LANGUAGEID_MASK) >> MetadataConsts.LANGUAGEID_OFFSET); } public static int GetTokenType(int metadata) { uint unitValue = (uint)metadata; - return (int)(unitValue & MetadataConsts.TOKEN_TYPE_MASK) >> MetadataConsts.TOKEN_TYPE_OFFSET; + return (int)((unitValue & MetadataConsts.TOKEN_TYPE_MASK) >> MetadataConsts.TOKEN_TYPE_OFFSET); } public static int GetFontStyle(int metadata) { uint unitValue = (uint)metadata; - return (int)(unitValue & MetadataConsts.FONT_STYLE_MASK) >> MetadataConsts.FONT_STYLE_OFFSET; + return (int)((unitValue & MetadataConsts.FONT_STYLE_MASK) >> MetadataConsts.FONT_STYLE_OFFSET); } public static int GetForeground(int metadata) { uint unitValue = (uint)metadata; - return (int)(unitValue & MetadataConsts.FOREGROUND_MASK) >> MetadataConsts.FOREGROUND_OFFSET; + return (int)((unitValue & MetadataConsts.FOREGROUND_MASK) >> MetadataConsts.FOREGROUND_OFFSET); } public static int GetBackground(int metadata) { - uint unitValue = (uint)metadata; - return (int)(unitValue & MetadataConsts.BACKGROUND_MASK) >> MetadataConsts.BACKGROUND_OFFSET; + ulong unitValue = (ulong)metadata; + return (int)((unitValue & MetadataConsts.BACKGROUND_MASK) >> MetadataConsts.BACKGROUND_OFFSET); } public static int Set(int metadata, int languageId, int tokenType, int fontStyle, int foreground, int background) diff --git a/src/TextMateSharp/Internal/Grammars/StandardTokenType.cs b/src/TextMateSharp/Internal/Grammars/StandardTokenType.cs index bb63ad8..65e2249 100644 --- a/src/TextMateSharp/Internal/Grammars/StandardTokenType.cs +++ b/src/TextMateSharp/Internal/Grammars/StandardTokenType.cs @@ -5,6 +5,6 @@ public class StandardTokenType public const int Other = 0; public const int Comment = 1; public const int String = 2; - public const int RegEx = 4; + public const int RegEx = 3; } } diff --git a/src/TextMateSharp/Internal/Grammars/parser/Raw.cs b/src/TextMateSharp/Internal/Grammars/parser/Raw.cs index 5d7ba91..d002e04 100644 --- a/src/TextMateSharp/Internal/Grammars/parser/Raw.cs +++ b/src/TextMateSharp/Internal/Grammars/parser/Raw.cs @@ -33,6 +33,20 @@ public class Raw : Dictionary, IRawRepository, IRawRule, IRawGra private static string DOLLAR_BASE = "$base"; private List fileTypes; + public IRawRepository Merge(params IRawRepository[] sources) + { + Raw target = new Raw(); + foreach (IRawRepository source in sources) + { + Raw sourceRaw = ((Raw)source); + foreach (string key in sourceRaw.Keys) + { + target[key] = sourceRaw[key]; + } + } + return target; + } + public IRawRule GetProp(string name) { return TryGetObject(name); @@ -83,21 +97,11 @@ public string GetContentName() return TryGetObject(CONTENT_NAME); } - public void SetContentName(string name) - { - this[CONTENT_NAME] = name; - } - public string GetMatch() { return TryGetObject(MATCH); } - public void SetMatch(string match) - { - this[MATCH] = match; - } - public IRawCaptures GetCaptures() { UpdateCaptures(CAPTURES); @@ -120,21 +124,11 @@ private void UpdateCaptures(string name) } } - public void SetCaptures(IRawCaptures captures) - { - this[CAPTURES] = captures; - } - public string GetBegin() { return TryGetObject(BEGIN); } - public void SetBegin(string begin) - { - this[BEGIN] = begin; - } - public string GetWhile() { return TryGetObject(WHILE); @@ -166,22 +160,12 @@ public string GetEnd() return TryGetObject(END); } - public void SetEnd(string end) - { - this[END] = end; - } - public IRawCaptures GetEndCaptures() { UpdateCaptures(END_CAPTURES); return TryGetObject(END_CAPTURES); } - public void SetEndCaptures(IRawCaptures endCaptures) - { - this[END_CAPTURES] = endCaptures; - } - public IRawCaptures GetWhileCaptures() { UpdateCaptures(WHILE_CAPTURES); @@ -290,9 +274,46 @@ public IRawRule GetCapture(string captureId) return GetProp(captureId); } - public object Clone() + public IRawGrammar Clone() + { + return (IRawGrammar)Clone(this); + } + + public object Clone(object value) { - return CloneUtils.Clone(this); + if (value is Raw) + { + Raw rawToClone = (Raw)value; + Raw raw = new Raw(); + + foreach (string key in rawToClone.Keys) + { + raw[key] = Clone(rawToClone[key]); + } + return raw; + } + else if (value is IList) + { + List result = new List(); + foreach (object obj in (IList)value) + { + result.Add(Clone(obj)); + } + return result; + } + else if (value is string) + { + return value; + } + else if (value is int) + { + return value; + } + else if (value is bool) + { + return value; + } + return value; } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/TextMateSharp/Internal/Matcher/Matcher.cs b/src/TextMateSharp/Internal/Matcher/Matcher.cs index 778116b..a7f8ae3 100644 --- a/src/TextMateSharp/Internal/Matcher/Matcher.cs +++ b/src/TextMateSharp/Internal/Matcher/Matcher.cs @@ -61,13 +61,13 @@ private Predicate parseInnerExpression() while (matcher != null) { matchers.Add(matcher); - if (_token.Equals("|") || _token.Equals(",")) + if ("|".Equals(_token) || ",".Equals(_token)) { do { _token = _tokenizer.Next(); - } while (_token.Equals("|") || _token.Equals(",")); // ignore subsequent - // commas + } while ("|".Equals(_token) || ",".Equals(_token)); // ignore subsequent + // commas } else { diff --git a/src/TextMateSharp/Internal/Oniguruma/OnigResult.cs b/src/TextMateSharp/Internal/Oniguruma/OnigResult.cs index 95775b1..b315cb6 100644 --- a/src/TextMateSharp/Internal/Oniguruma/OnigResult.cs +++ b/src/TextMateSharp/Internal/Oniguruma/OnigResult.cs @@ -25,13 +25,9 @@ public int LocationAt(int index) { int bytes = _region.Start[index]; if (bytes > 0) - { return bytes; - } - else - { - return 0; - } + + return 0; } public int Count() @@ -43,13 +39,9 @@ public int LengthAt(int index) { int bytes = _region.End[index] - _region.Start[index]; if (bytes > 0) - { return bytes; - } - else - { - return 0; - } + + return 0; } } } \ No newline at end of file diff --git a/src/TextMateSharp/Internal/Parser/Json/JSONPListParser.cs b/src/TextMateSharp/Internal/Parser/Json/JSONPListParser.cs index 90f94d6..26cf076 100644 --- a/src/TextMateSharp/Internal/Parser/Json/JSONPListParser.cs +++ b/src/TextMateSharp/Internal/Parser/Json/JSONPListParser.cs @@ -41,15 +41,13 @@ public T Parse(StreamReader contents) pList.EndElement("dict"); break; case JsonToken.PropertyName: - string lastName = (string)reader.Value; pList.StartElement("key"); - pList.AddString(lastName); + pList.AddString((string)reader.Value); pList.EndElement("key"); break; case JsonToken.String: - string value = (string)reader.Value; pList.StartElement("string"); - pList.AddString(value); + pList.AddString((string)reader.Value); pList.EndElement("string"); break; case JsonToken.Null: diff --git a/src/TextMateSharp/Internal/Rules/BeginEndRule.cs b/src/TextMateSharp/Internal/Rules/BeginEndRule.cs index bd8f99a..4f0b715 100644 --- a/src/TextMateSharp/Internal/Rules/BeginEndRule.cs +++ b/src/TextMateSharp/Internal/Rules/BeginEndRule.cs @@ -18,7 +18,7 @@ public class BeginEndRule : Rule private RegExpSourceList _cachedCompiledPatterns; public BeginEndRule(int? id, string name, string contentName, string begin, List beginCaptures, - string end, List endCaptures, bool applyEndPatternLast, ICompilePatternsResult patterns) + string end, List endCaptures, bool applyEndPatternLast, CompilePatternsResult patterns) : base(id, name, contentName) { _begin = new RegExpSource(begin, this.Id); @@ -55,7 +55,7 @@ public override void CollectPatternsRecursive(IRuleRegistry grammar, RegExpSourc } } - public override ICompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) + public override CompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) { RegExpSourceList precompiled = this.Precompile(grammar); if (this._end.HasBackReferences()) @@ -69,7 +69,7 @@ public override ICompiledRule Compile(IRuleRegistry grammar, string endRegexSour precompiled.SetSource(0, endRegexSource); } } - return this._cachedCompiledPatterns.Compile(grammar, allowA, allowG); + return this._cachedCompiledPatterns.Compile(allowA, allowG); } private RegExpSourceList Precompile(IRuleRegistry grammar) diff --git a/src/TextMateSharp/Internal/Rules/BeginWhileRule.cs b/src/TextMateSharp/Internal/Rules/BeginWhileRule.cs index 1ff870c..020863a 100644 --- a/src/TextMateSharp/Internal/Rules/BeginWhileRule.cs +++ b/src/TextMateSharp/Internal/Rules/BeginWhileRule.cs @@ -19,7 +19,7 @@ public class BeginWhileRule : Rule public BeginWhileRule(int? id, string name, string contentName, string begin, List beginCaptures, string whileStr, List whileCaptures, - ICompilePatternsResult patterns) : base(id, name, contentName) + CompilePatternsResult patterns) : base(id, name, contentName) { _begin = new RegExpSource(begin, this.Id); _while = new RegExpSource(whileStr, -2); @@ -56,10 +56,10 @@ public override void CollectPatternsRecursive(IRuleRegistry grammar, RegExpSourc } } - public override ICompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) + public override CompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) { this.Precompile(grammar); - return this._cachedCompiledPatterns.Compile(grammar, allowA, allowG); + return this._cachedCompiledPatterns.Compile(allowA, allowG); } private void Precompile(IRuleRegistry grammar) @@ -71,14 +71,14 @@ private void Precompile(IRuleRegistry grammar) } } - public ICompiledRule CompileWhile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) + public CompiledRule CompileWhile(string endRegexSource, bool allowA, bool allowG) { this.PrecompileWhile(); if (this._while.HasBackReferences()) { this._cachedCompiledWhilePatterns.SetSource(0, endRegexSource); } - return this._cachedCompiledWhilePatterns.Compile(grammar, allowA, allowG); + return this._cachedCompiledWhilePatterns.Compile(allowA, allowG); } private void PrecompileWhile() diff --git a/src/TextMateSharp/Internal/Rules/CaptureRule.cs b/src/TextMateSharp/Internal/Rules/CaptureRule.cs index b616774..1fa26cb 100644 --- a/src/TextMateSharp/Internal/Rules/CaptureRule.cs +++ b/src/TextMateSharp/Internal/Rules/CaptureRule.cs @@ -16,7 +16,7 @@ public override void CollectPatternsRecursive(IRuleRegistry grammar, RegExpSourc } - public override ICompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) + public override CompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) { return null; } diff --git a/src/TextMateSharp/Internal/Rules/ICompilePatternsResult.cs b/src/TextMateSharp/Internal/Rules/ICompilePatternsResult.cs index 59fbf89..ff0973c 100644 --- a/src/TextMateSharp/Internal/Rules/ICompilePatternsResult.cs +++ b/src/TextMateSharp/Internal/Rules/ICompilePatternsResult.cs @@ -2,12 +2,12 @@ namespace TextMateSharp.Internal.Rules { - public class ICompilePatternsResult + public class CompilePatternsResult { public int?[] Patterns { get; private set; } public bool HasMissingPatterns { get; private set; } - public ICompilePatternsResult(IEnumerable patterns, bool hasMissingPatterns) + public CompilePatternsResult(IEnumerable patterns, bool hasMissingPatterns) { HasMissingPatterns = hasMissingPatterns; Patterns = new List(patterns).ToArray(); diff --git a/src/TextMateSharp/Internal/Rules/ICompiledRule.cs b/src/TextMateSharp/Internal/Rules/ICompiledRule.cs index f7d9239..abe3eb9 100644 --- a/src/TextMateSharp/Internal/Rules/ICompiledRule.cs +++ b/src/TextMateSharp/Internal/Rules/ICompiledRule.cs @@ -2,12 +2,12 @@ namespace TextMateSharp.Internal.Rules { - public class ICompiledRule + public class CompiledRule { public OnigScanner Scanner { get; private set; } public int?[] Rules { get; private set; } - public ICompiledRule(OnigScanner scanner, int?[] rules) + public CompiledRule(OnigScanner scanner, int?[] rules) { Scanner = scanner; Rules = rules; diff --git a/src/TextMateSharp/Internal/Rules/IRegExpSourceAnchorCache.cs b/src/TextMateSharp/Internal/Rules/IRegExpSourceAnchorCache.cs index d36a2b2..aaccd03 100644 --- a/src/TextMateSharp/Internal/Rules/IRegExpSourceAnchorCache.cs +++ b/src/TextMateSharp/Internal/Rules/IRegExpSourceAnchorCache.cs @@ -1,13 +1,13 @@ namespace TextMateSharp.Internal.Rules { - public class IRegExpSourceAnchorCache + public class RegExpSourceAnchorCache { public string A0_G0 { get; private set; } public string A0_G1 { get; private set; } public string A1_G0 { get; private set; } public string A1_G1 { get; private set; } - public IRegExpSourceAnchorCache(string a0_G0, string a0_G1, string a1_G0, string a1_G1) + public RegExpSourceAnchorCache(string a0_G0, string a0_G1, string a1_G0, string a1_G1) { A0_G0 = a0_G0; A0_G1 = a0_G1; diff --git a/src/TextMateSharp/Internal/Rules/IncludeOnlyRule.cs b/src/TextMateSharp/Internal/Rules/IncludeOnlyRule.cs index 34cb929..80f761c 100644 --- a/src/TextMateSharp/Internal/Rules/IncludeOnlyRule.cs +++ b/src/TextMateSharp/Internal/Rules/IncludeOnlyRule.cs @@ -7,7 +7,7 @@ public class IncludeOnlyRule : Rule private RegExpSourceList _cachedCompiledPatterns; - public IncludeOnlyRule(int? id, string name, string contentName, ICompilePatternsResult patterns) : base(id, name, contentName) + public IncludeOnlyRule(int? id, string name, string contentName, CompilePatternsResult patterns) : base(id, name, contentName) { Patterns = patterns.Patterns; HasMissingPatterns = patterns.HasMissingPatterns; @@ -24,14 +24,14 @@ public override void CollectPatternsRecursive(IRuleRegistry grammar, RegExpSourc } } - public override ICompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) + public override CompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) { if (this._cachedCompiledPatterns == null) { this._cachedCompiledPatterns = new RegExpSourceList(); this.CollectPatternsRecursive(grammar, this._cachedCompiledPatterns, true); } - return this._cachedCompiledPatterns.Compile(grammar, allowA, allowG); + return this._cachedCompiledPatterns.Compile(allowA, allowG); } } } \ No newline at end of file diff --git a/src/TextMateSharp/Internal/Rules/MatchRule.cs b/src/TextMateSharp/Internal/Rules/MatchRule.cs index fc852a1..403375f 100644 --- a/src/TextMateSharp/Internal/Rules/MatchRule.cs +++ b/src/TextMateSharp/Internal/Rules/MatchRule.cs @@ -21,14 +21,14 @@ public override void CollectPatternsRecursive(IRuleRegistry grammar, RegExpSourc sourceList.Push(this._match); } - public override ICompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) + public override CompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG) { if (this._cachedCompiledPatterns == null) { this._cachedCompiledPatterns = new RegExpSourceList(); this.CollectPatternsRecursive(grammar, this._cachedCompiledPatterns, true); } - return this._cachedCompiledPatterns.Compile(grammar, allowA, allowG); + return this._cachedCompiledPatterns.Compile(allowA, allowG); } } } \ No newline at end of file diff --git a/src/TextMateSharp/Internal/Rules/RegExpSource.cs b/src/TextMateSharp/Internal/Rules/RegExpSource.cs index fe0839b..44a9cd6 100644 --- a/src/TextMateSharp/Internal/Rules/RegExpSource.cs +++ b/src/TextMateSharp/Internal/Rules/RegExpSource.cs @@ -13,12 +13,11 @@ public class RegExpSource private static Regex HAS_BACK_REFERENCES = new Regex("\\\\(\\d+)"); private static Regex BACK_REFERENCING_END = new Regex("\\\\(\\d+)"); - private static Regex REGEXP_CHARACTERS = new Regex("[\\-\\\\\\{\\}\\*\\+\\?\\|\\^\\$\\.\\,\\[\\]\\(\\)\\#\\s]"); private int? _ruleId; private bool _hasAnchor; private bool _hasBackReferences; - private IRegExpSourceAnchorCache _anchorCache; + private RegExpSourceAnchorCache _anchorCache; private string _source; public RegExpSource(string regExpSource, int? ruleId) : @@ -135,9 +134,16 @@ public string ResolveBackReferences(string lineText, IOnigCaptureIndex[] capture return BACK_REFERENCING_END.Replace(this._source, m => { - string value = m.Value; - int index = int.Parse(m.Value.SubstringAtIndexes(1, value.Length)); - return EscapeRegExpCharacters(capturedValues.Count > index ? capturedValues[index] : ""); + try + { + string value = m.Value; + int index = int.Parse(m.Value.SubstringAtIndexes(1, value.Length)); + return EscapeRegExpCharacters(capturedValues.Count > index ? capturedValues[index] : ""); + } + catch (Exception) + { + return ""; + } }); } catch (Exception ex) @@ -150,26 +156,64 @@ public string ResolveBackReferences(string lineText, IOnigCaptureIndex[] capture private string EscapeRegExpCharacters(string value) { - return REGEXP_CHARACTERS.Replace(value, m => + int valueLen = value.Length; + var sb = new StringBuilder(valueLen); + for (int i = 0; i < valueLen; i++) { - return "\\\\\\\\" + m.Value; - }); + char ch = value[i]; + switch (ch) + { + case '-': + case '\\': + case '{': + case '}': + case '*': + case '+': + case '?': + case '|': + case '^': + case '$': + case '.': + case ',': + case '[': + case ']': + case '(': + case ')': + case '#': + /* escaping white space chars is actually not necessary: + case ' ': + case '\t': + case '\n': + case '\f': + case '\r': + case 0x0B: // vertical tab \v + */ + sb.Append('\\'); + break; + } + sb.Append(ch); + } + return sb.ToString(); } - private IRegExpSourceAnchorCache BuildAnchorCache() + private RegExpSourceAnchorCache BuildAnchorCache() { - StringBuilder A0_G0_result = new StringBuilder(); - StringBuilder A0_G1_result = new StringBuilder(); - StringBuilder A1_G0_result = new StringBuilder(); - StringBuilder A1_G1_result = new StringBuilder(); + string source = this._source; + var sourceLen = source.Length; + + StringBuilder A0_G0_result = new StringBuilder(sourceLen); + StringBuilder A0_G1_result = new StringBuilder(sourceLen); + StringBuilder A1_G0_result = new StringBuilder(sourceLen); + StringBuilder A1_G1_result = new StringBuilder(sourceLen); + int pos; int len; char ch; char nextCh; - for (pos = 0, len = this._source.Length; pos < len; pos++) + for (pos = 0, len = sourceLen; pos < len; pos++) { - ch = this._source[pos]; + ch = source[pos]; A0_G0_result.Append(ch); A0_G1_result.Append(ch); A1_G0_result.Append(ch); @@ -179,7 +223,7 @@ private IRegExpSourceAnchorCache BuildAnchorCache() { if (pos + 1 < len) { - nextCh = this._source[pos + 1]; + nextCh = source[pos + 1]; if (nextCh == 'A') { A0_G0_result.Append('\uFFFF'); @@ -206,7 +250,7 @@ private IRegExpSourceAnchorCache BuildAnchorCache() } } - return new IRegExpSourceAnchorCache( + return new RegExpSourceAnchorCache( A0_G0_result.ToString(), A0_G1_result.ToString(), A1_G0_result.ToString(), @@ -216,32 +260,20 @@ private IRegExpSourceAnchorCache BuildAnchorCache() public string ResolveAnchors(bool allowA, bool allowG) { if (!this._hasAnchor) - { return this._source; - } if (allowA) { if (allowG) - { return this._anchorCache.A1_G1; - } - else - { - return this._anchorCache.A1_G0; - } - } - else - { - if (allowG) - { - return this._anchorCache.A0_G1; - } - else - { - return this._anchorCache.A0_G0; - } + + return this._anchorCache.A1_G0; } + + if (allowG) + return this._anchorCache.A0_G1; + + return this._anchorCache.A0_G0; } public bool HasAnchor() diff --git a/src/TextMateSharp/Internal/Rules/RegExpSourceList.cs b/src/TextMateSharp/Internal/Rules/RegExpSourceList.cs index e28a70e..7d07680 100644 --- a/src/TextMateSharp/Internal/Rules/RegExpSourceList.cs +++ b/src/TextMateSharp/Internal/Rules/RegExpSourceList.cs @@ -9,16 +9,16 @@ public class RegExpSourceList private class RegExpSourceListAnchorCache { - public ICompiledRule A0_G0; - public ICompiledRule A0_G1; - public ICompiledRule A1_G0; - public ICompiledRule A1_G1; + public CompiledRule A0_G0; + public CompiledRule A0_G1; + public CompiledRule A1_G0; + public CompiledRule A1_G1; } private List _items; private bool _hasAnchors; - private ICompiledRule _cached; + private CompiledRule _cached; private RegExpSourceListAnchorCache _anchorCache; public RegExpSourceList() @@ -62,7 +62,7 @@ public void SetSource(int index, string newSource) } } - public ICompiledRule Compile(IRuleRegistry grammar, bool allowA, bool allowG) + public CompiledRule Compile(bool allowA, bool allowG) { if (!this._hasAnchors) { @@ -73,66 +73,53 @@ public ICompiledRule Compile(IRuleRegistry grammar, bool allowA, bool allowG) { regexps.Add(regExpSource.GetSource()); } - this._cached = new ICompiledRule(CreateOnigScanner(regexps.ToArray()), GetRules()); + this._cached = new CompiledRule(CreateOnigScanner(regexps.ToArray()), GetRules()); } return this._cached; } - else + + if (this._anchorCache.A0_G0 == null) { - if (this._anchorCache.A0_G0 == null) - { - this._anchorCache.A0_G0 = (allowA == false && allowG == false) ? this.ResolveAnchors(allowA, allowG) - : null; - } - if (this._anchorCache.A0_G1 == null) - { - this._anchorCache.A0_G1 = (allowA == false && allowG == true) ? this.ResolveAnchors(allowA, allowG) - : null; - } - if (this._anchorCache.A1_G0 == null) - { - this._anchorCache.A1_G0 = (allowA == true && allowG == false) ? this.ResolveAnchors(allowA, allowG) - : null; - } - if (this._anchorCache.A1_G1 == null) - { - this._anchorCache.A1_G1 = (allowA == true && allowG == true) ? this.ResolveAnchors(allowA, allowG) - : null; - } - if (allowA) - { - if (allowG) - { - return this._anchorCache.A1_G1; - } - else - { - return this._anchorCache.A1_G0; - } - } - else - { - if (allowG) - { - return this._anchorCache.A0_G1; - } - else - { - return this._anchorCache.A0_G0; - } - } + this._anchorCache.A0_G0 = (allowA == false && allowG == false) ? this.ResolveAnchors(allowA, allowG) + : null; + } + if (this._anchorCache.A0_G1 == null) + { + this._anchorCache.A0_G1 = (allowA == false && allowG == true) ? this.ResolveAnchors(allowA, allowG) + : null; } + if (this._anchorCache.A1_G0 == null) + { + this._anchorCache.A1_G0 = (allowA == true && allowG == false) ? this.ResolveAnchors(allowA, allowG) + : null; + } + if (this._anchorCache.A1_G1 == null) + { + this._anchorCache.A1_G1 = (allowA == true && allowG == true) ? this.ResolveAnchors(allowA, allowG) + : null; + } + if (allowA) + { + if (allowG) + return this._anchorCache.A1_G1; + + return this._anchorCache.A1_G0; + } + + if (allowG) + return this._anchorCache.A0_G1; + return this._anchorCache.A0_G0; } - private ICompiledRule ResolveAnchors(bool allowA, bool allowG) + private CompiledRule ResolveAnchors(bool allowA, bool allowG) { List regexps = new List(); foreach (RegExpSource regExpSource in _items) { regexps.Add(regExpSource.ResolveAnchors(allowA, allowG)); } - return new ICompiledRule(CreateOnigScanner(regexps.ToArray()), GetRules()); + return new CompiledRule(CreateOnigScanner(regexps.ToArray()), GetRules()); } private OnigScanner CreateOnigScanner(string[] regexps) diff --git a/src/TextMateSharp/Internal/Rules/Rule.cs b/src/TextMateSharp/Internal/Rules/Rule.cs index 0c206ba..ce332a0 100644 --- a/src/TextMateSharp/Internal/Rules/Rule.cs +++ b/src/TextMateSharp/Internal/Rules/Rule.cs @@ -44,6 +44,6 @@ public string GetContentName(string lineText, IOnigCaptureIndex[] captureIndices public abstract void CollectPatternsRecursive(IRuleRegistry grammar, RegExpSourceList sourceList, bool isFirst); - public abstract ICompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG); + public abstract CompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG); } } \ No newline at end of file diff --git a/src/TextMateSharp/Internal/Rules/RuleFactory.cs b/src/TextMateSharp/Internal/Rules/RuleFactory.cs index ef68ea9..47a76da 100644 --- a/src/TextMateSharp/Internal/Rules/RuleFactory.cs +++ b/src/TextMateSharp/Internal/Rules/RuleFactory.cs @@ -35,7 +35,7 @@ public static CaptureRule CreateCaptureRule(IRuleFactoryHelper helper, string na IRawRepository r = repository; if (desc.GetRepository() != null) { - r = CloneUtils.MergeObjects(repository, desc.GetRepository()); + r = repository.Merge(desc.GetRepository()); } return new IncludeOnlyRule(desc.GetId(), desc.GetName(), desc.GetContentName(), RuleFactory.CompilePatterns(desc.GetPatterns(), helper, r)); @@ -126,7 +126,7 @@ private static int ParseInt(string str) return result; } - private static ICompilePatternsResult CompilePatterns(ICollection patterns, IRuleFactoryHelper helper, + private static CompilePatternsResult CompilePatterns(ICollection patterns, IRuleFactoryHelper helper, IRawRepository repository) { List r = new List(); @@ -261,7 +261,7 @@ private static ICompilePatternsResult CompilePatterns(ICollection patt } } - return new ICompilePatternsResult(r, ((patterns != null ? patterns.Count : 0) != r.Count)); + return new CompilePatternsResult(r, ((patterns != null ? patterns.Count : 0) != r.Count)); } } } \ No newline at end of file diff --git a/src/TextMateSharp/Internal/Types/IBaseRaw.cs b/src/TextMateSharp/Internal/Types/IBaseRaw.cs deleted file mode 100644 index 7aefefe..0000000 --- a/src/TextMateSharp/Internal/Types/IBaseRaw.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; - -namespace TextMateSharp.Internal.Types -{ - public interface IBaseRaw : IEnumerable - { - - } -} diff --git a/src/TextMateSharp/Internal/Types/IRawCaptures.cs b/src/TextMateSharp/Internal/Types/IRawCaptures.cs index 17f75d2..481fbbc 100644 --- a/src/TextMateSharp/Internal/Types/IRawCaptures.cs +++ b/src/TextMateSharp/Internal/Types/IRawCaptures.cs @@ -1,6 +1,8 @@ +using System.Collections.Generic; + namespace TextMateSharp.Internal.Types { - public interface IRawCaptures : IBaseRaw + public interface IRawCaptures : IEnumerable { IRawRule GetCapture(string captureId); } diff --git a/src/TextMateSharp/Internal/Types/IRawGrammar.cs b/src/TextMateSharp/Internal/Types/IRawGrammar.cs index aa0eebd..bfb0c8c 100644 --- a/src/TextMateSharp/Internal/Types/IRawGrammar.cs +++ b/src/TextMateSharp/Internal/Types/IRawGrammar.cs @@ -4,6 +4,7 @@ namespace TextMateSharp.Internal.Types { public interface IRawGrammar { + IRawGrammar Clone(); IRawRepository GetRepository(); string GetScopeName(); diff --git a/src/TextMateSharp/Internal/Types/IRawRepository.cs b/src/TextMateSharp/Internal/Types/IRawRepository.cs index f207308..1a9f5a9 100644 --- a/src/TextMateSharp/Internal/Types/IRawRepository.cs +++ b/src/TextMateSharp/Internal/Types/IRawRepository.cs @@ -3,6 +3,7 @@ namespace TextMateSharp.Internal.Types public interface IRawRepository { // IRawRule GetRule(string name); + IRawRepository Merge(params IRawRepository[] sources); IRawRule GetProp(string name); diff --git a/src/TextMateSharp/Internal/Types/IRawRule.cs b/src/TextMateSharp/Internal/Types/IRawRule.cs index 40ab96e..bd10d72 100644 --- a/src/TextMateSharp/Internal/Types/IRawRule.cs +++ b/src/TextMateSharp/Internal/Types/IRawRule.cs @@ -18,34 +18,22 @@ public interface IRawRule string GetContentName(); - void SetContentName(string name); - string GetMatch(); - void SetMatch(string match); - IRawCaptures GetCaptures(); - void SetCaptures(IRawCaptures captures); - string GetBegin(); - void SetBegin(string begin); - IRawCaptures GetBeginCaptures(); void SetBeginCaptures(IRawCaptures beginCaptures); string GetEnd(); - void SetEnd(string end); - string GetWhile(); IRawCaptures GetEndCaptures(); - void SetEndCaptures(IRawCaptures endCaptures); - IRawCaptures GetWhileCaptures(); ICollection GetPatterns(); @@ -57,7 +45,5 @@ public interface IRawRule void SetRepository(IRawRepository repository); bool IsApplyEndPatternLast(); - - void SetApplyEndPatternLast(bool applyEndPatternLast); } } \ No newline at end of file diff --git a/src/TextMateSharp/Internal/Utils/CloneUtils.cs b/src/TextMateSharp/Internal/Utils/CloneUtils.cs index 55a7a65..b1a1438 100644 --- a/src/TextMateSharp/Internal/Utils/CloneUtils.cs +++ b/src/TextMateSharp/Internal/Utils/CloneUtils.cs @@ -9,7 +9,7 @@ namespace TextMateSharp.Internal.Utils { public static class CloneUtils { - public static object Clone(object value) + /*public static object Clone(object value) { if (value is Raw) { @@ -44,9 +44,9 @@ public static object Clone(object value) return value; } return value; - } + }*/ - public static IRawRepository MergeObjects(params IRawRepository[] sources) + /*public static IRawRepository MergeObjects(params IRawRepository[] sources) { Raw target = new Raw(); foreach (IRawRepository source in sources) @@ -58,6 +58,6 @@ public static IRawRepository MergeObjects(params IRawRepository[] sources) } } return target; - } + }*/ } } \ No newline at end of file diff --git a/src/TextMateSharp/Model/TMModel.cs b/src/TextMateSharp/Model/TMModel.cs index 06a663a..8147d00 100644 --- a/src/TextMateSharp/Model/TMModel.cs +++ b/src/TextMateSharp/Model/TMModel.cs @@ -298,19 +298,25 @@ public void AddModelTokensChangedListener(IModelTokensChangedListener listener) if (this._grammar != null) Start(); - if (!listeners.Contains(listener)) + lock (listeners) { - listeners.Add(listener); + if (!listeners.Contains(listener)) + { + listeners.Add(listener); + } } } public void RemoveModelTokensChangedListener(IModelTokensChangedListener listener) { - listeners.Remove(listener); - if (listeners.Count == 0) + lock (listeners) { - // no need to keep tokenizing if no-one cares - Stop(); + listeners.Remove(listener); + if (listeners.Count == 0) + { + // no need to keep tokenizing if no-one cares + Stop(); + } } } @@ -379,12 +385,7 @@ private void Emit(ModelTokensChangedEvent e) public void ForceTokenization(int lineIndex) { - if (_grammar == null) - return; - - this.BuildEventWithCallback(eventBuilder => - this._thread.UpdateTokensInRange(eventBuilder, lineIndex, lineIndex) - ); + ForceTokenization(lineIndex, lineIndex); } public void ForceTokenization(int startLineIndex, int endLineIndex) @@ -392,8 +393,13 @@ public void ForceTokenization(int startLineIndex, int endLineIndex) if (_grammar == null) return; + var tokenizerThread = this._thread; + + if (tokenizerThread != null || tokenizerThread.IsStopped) + return; + this.BuildEventWithCallback(eventBuilder => - this._thread.UpdateTokensInRange(eventBuilder, startLineIndex, endLineIndex) + tokenizerThread.UpdateTokensInRange(eventBuilder, startLineIndex, endLineIndex) ); } diff --git a/src/TextMateSharp/Model/Tokenizer.cs b/src/TextMateSharp/Model/Tokenizer.cs index d1e0323..e9e05a4 100644 --- a/src/TextMateSharp/Model/Tokenizer.cs +++ b/src/TextMateSharp/Model/Tokenizer.cs @@ -57,7 +57,6 @@ public LineTokens Tokenize(string line, TMState state, int offsetDelta, int maxL } } return new LineTokens(tokens, offsetDelta + line.Length, freshState); - } private string DecodeTextMateToken(DecodeMap decodeMap, List scopes) diff --git a/src/TextMateSharp/Themes/FontStyle.cs b/src/TextMateSharp/Themes/FontStyle.cs index f0f23e6..02edf56 100644 --- a/src/TextMateSharp/Themes/FontStyle.cs +++ b/src/TextMateSharp/Themes/FontStyle.cs @@ -9,5 +9,6 @@ public class FontStyle public const int Italic = 1; public const int Bold = 2; public const int Underline = 4; + public const int Strikethrough = 8; } } \ No newline at end of file diff --git a/src/TextMateSharp/Themes/Theme.cs b/src/TextMateSharp/Themes/Theme.cs index ac7c0fe..90ad364 100644 --- a/src/TextMateSharp/Themes/Theme.cs +++ b/src/TextMateSharp/Themes/Theme.cs @@ -161,17 +161,20 @@ static void LookupThemeRules( string[] segments = ((string)settingsFontStyle).Split(new[] { " " }, StringSplitOptions.None); foreach (string segment in segments) { - if ("italic".Equals(segment)) + switch (segment) { - fontStyle = fontStyle | FontStyle.Italic; - } - else if ("bold".Equals(segment)) - { - fontStyle = fontStyle | FontStyle.Bold; - } - else if ("underline".Equals(segment)) - { - fontStyle = fontStyle | FontStyle.Underline; + case "italic": + fontStyle = fontStyle | FontStyle.Italic; + break; + case "bold": + fontStyle = fontStyle | FontStyle.Bold; + break; + case "underline": + fontStyle = fontStyle | FontStyle.Underline; + break; + case "strikethrough": + fontStyle = fontStyle | FontStyle.Strikethrough; + break; } } }