Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/TextMateSharp.Tests/Internal/Matcher/MatcherTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Linq;
using NUnit.Framework;

using System.Collections.Generic;

using TextMateSharp.Internal.Matcher;

namespace TextMateSharp.Tests.Internal.MatcherTest
{
[TestFixture]
internal class MatcherTests
{
[TestCase("foo", new string[] { "foo" }, true)]
[TestCase("foo", new string[] { "bar" }, false)]
[TestCase("- foo", new string[] { "foo" }, false)]
[TestCase("- foo", new string[] { "bar" }, true)]
[TestCase("- - foo", new string[] { "bar" }, false)]
[TestCase("bar foo", new string[] { "foo" }, false)]
[TestCase("bar foo", new string[] { "bar" }, false)]
[TestCase("bar foo", new string[] { "bar", "foo" }, true)]
[TestCase("bar - foo", new string[] { "bar" }, true)]
[TestCase("bar - foo", new string[] { "foo", "bar" }, false)]
[TestCase("bar - foo", new string[] { "foo" }, false)]
[TestCase("bar, foo", new string[] { "foo" }, true)]
[TestCase("bar, foo", new string[] { "bar" }, true)]
[TestCase("bar, foo", new string[] { "bar", "foo" }, true)]
[TestCase("bar, -foo", new string[] { "bar", "foo" }, true)]
[TestCase("bar, -foo", new string[] { "yo" }, true)]
[TestCase("bar, -foo", new string[] { "foo" }, false)]
[TestCase("(foo)", new string[] { "foo" }, true)]
[TestCase("(foo - bar)", new string[] { "foo" }, true)]
[TestCase("(foo - bar)", new string[] { "foo", "bar" }, false)]
[TestCase("foo bar - (yo man)", new string[] { "foo", "bar" }, true)]
[TestCase("foo bar - (yo man)", new string[] { "foo", "bar", "yo" }, true)]
[TestCase("foo bar - (yo man)", new string[] { "foo", "bar", "yo", "man" }, false)]
[TestCase("foo bar - (yo | man)", new string[] { "foo", "bar", "yo", "man" }, false)]
[TestCase("foo bar - (yo | man)", new string[] { "foo", "bar", "yo" }, false)]
public void Matcher_Should_Work(string expression, string[] input, bool expectedResult)
{
var matchers = Matcher.CreateMatchers(expression);
bool actualResult = false;
foreach (var item in matchers)
{
actualResult |= item.Matcher.Invoke(new List<string>(input));
}

Assert.AreEqual(expectedResult, actualResult);
}
}
}
37 changes: 37 additions & 0 deletions src/TextMateSharp.Tests/Internal/Themes/StrCmpTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using NUnit.Framework;

using System.Collections.Generic;

using TextMateSharp.Internal.Utils;
using TextMateSharp.Themes;

namespace TextMateSharp.Tests.Internal.Themes
{
[TestFixture]
internal class StrCmpTests
{
[Test]
public void Str_Arr_Cmp_Should_Work()
{
AssertStrArrCmp(null, null, 0);
AssertStrArrCmp(null, new List<string>(), -1);
AssertStrArrCmp(null, new List<string>() { "a" }, -1);
AssertStrArrCmp(new List<string>(), null, 1);
AssertStrArrCmp(new List<string>() { "a" }, null, 1);
AssertStrArrCmp(new List<string>(), new List<string>(), 0);
AssertStrArrCmp(new List<string>(), new List<string>() { "a" }, -1);
AssertStrArrCmp(new List<string>() { "a" }, new List<string>(), 1);
AssertStrArrCmp(new List<string>() { "a" }, new List<string>() { "a" }, 0);
AssertStrArrCmp(new List<string>() { "a", "b" }, new List<string>() { "a" }, 1);
AssertStrArrCmp(new List<string>() { "a" }, new List<string>() { "a", "b" }, -1);
AssertStrArrCmp(new List<string>() { "a", "b" }, new List<string>() { "a", "b" }, 0);
AssertStrArrCmp(new List<string>() { "a", "b" }, new List<string>() { "a", "c" }, -1);
AssertStrArrCmp(new List<string>() { "a", "c" }, new List<string>() { "a", "b" }, 1);
}

static void AssertStrArrCmp(List<string> a, List<string> b, int expected)
{
Assert.AreEqual(expected, StringUtils.StrArrCmp(a, b));
}
}
}
67 changes: 67 additions & 0 deletions src/TextMateSharp.Tests/Internal/Themes/ThemeParsingTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using NUnit.Framework;

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using TextMateSharp.Internal.Themes.Reader;
using TextMateSharp.Themes;

namespace TextMateSharp.Tests.Internal.Themes
{
[TestFixture]
internal class ThemeParsingTest
{
[TestCase()]
public void Parse_Theme_Rule_Should_Work()
{
MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(THEME_JSON));

StreamReader reader = new StreamReader(memoryStream);
var theme = ThemeReader.ReadThemeSync(reader);

var actualThemeRules = ParsedTheme.ParseTheme(theme, 0);

var expectedThemeRules = new ParsedThemeRule[] {
new ParsedThemeRule("", null, 0, FontStyle.NotSet, "#F8F8F2", "#272822"),
new ParsedThemeRule("source", null, 1, FontStyle.NotSet, null, "#100000"),
new ParsedThemeRule("something", null, 1, FontStyle.NotSet, null, "#100000"),
new ParsedThemeRule("bar", null, 2, FontStyle.NotSet, null, "#010000"),
new ParsedThemeRule("baz", null, 2, FontStyle.NotSet, null, "#010000"),
new ParsedThemeRule("bar", new List<string>() {"bar", "selector", "source.css" }, 3, FontStyle.Bold, null, null),
new ParsedThemeRule("constant", null, 4, FontStyle.Italic, "#ff0000", null),
new ParsedThemeRule("constant.numeric", null, 5, FontStyle.NotSet, "#00ff00", null),
new ParsedThemeRule("constant.numeric.hex", null, 6, FontStyle.Bold, null, null),
new ParsedThemeRule("constant.numeric.oct", null, 7, FontStyle.Bold | FontStyle.Italic | FontStyle.Underline, null, null),
new ParsedThemeRule("constant.numeric.bin", null, 8, FontStyle.Bold | FontStyle.Strikethrough, null, null),
new ParsedThemeRule("constant.numeric.dec", null, 9, FontStyle.None, "#0000ff", null),
new ParsedThemeRule("foo", null, 10, FontStyle.None, "#CFA", null)
};

Assert.AreEqual(expectedThemeRules.Length, actualThemeRules.Count);

for (int i = 0; i< actualThemeRules.Count; i++)
{
Assert.AreEqual(expectedThemeRules[i], actualThemeRules[i]);
}
}

const string THEME_JSON =
"{ \"settings\": [" +
"{ \"settings\": { \"foreground\": \"#F8F8F2\", \"background\": \"#272822\" } }," +
"{ \"scope\": \"source, something\", \"settings\": { \"background\": \"#100000\" } }," +
"{ \"scope\": [\"bar\", \"baz\"], \"settings\": { \"background\": \"#010000\" } }," +
"{ \"scope\": \"source.css selector bar\", \"settings\": { \"fontStyle\": \"bold\" } }," +
"{ \"scope\": \"constant\", \"settings\": { \"fontStyle\": \"italic\", \"foreground\": \"#ff0000\" } }," +
"{ \"scope\": \"constant.numeric\", \"settings\": { \"foreground\": \"#00ff00\" } }," +
"{ \"scope\": \"constant.numeric.hex\", \"settings\": { \"fontStyle\": \"bold\" } }," +
"{ \"scope\": \"constant.numeric.oct\", \"settings\": { \"fontStyle\": \"bold italic underline\" } }," +
"{ \"scope\": \"constant.numeric.bin\", \"settings\": { \"fontStyle\": \"bold strikethrough\" } }," +
"{ \"scope\": \"constant.numeric.dec\", \"settings\": { \"fontStyle\": \"\", \"foreground\": \"#0000ff\" } }," +
"{ \"scope\": \"foo\", \"settings\": { \"fontStyle\": \"\", \"foreground\": \"#CFA\" } }" +
"]}";
}
}
18 changes: 11 additions & 7 deletions src/TextMateSharp/Internal/Matcher/IMatchesName.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Collections.Generic;

using System.Linq;
using TextMateSharp.Internal.Utils;

namespace TextMateSharp.Internal.Matcher
Expand All @@ -20,16 +20,20 @@ public bool Match(ICollection<string> identifers, List<string> scopes)
return false;
}

for (int i = 0; i < scopes.Count; i++)
int lastIndex = 0;
return identifers.All(identifier =>
{
foreach (string identifier in identifers)
for (int i = lastIndex; i < scopes.Count; i++)
{
if (!ScopesAreMatching(scopes[i], identifier))
return false;
if (ScopesAreMatching(scopes[i], identifier))
{
lastIndex++;
return true;
}
}
}

return true;
return false;
});
}

private bool ScopesAreMatching(string thisScopeName, string scopeName)
Expand Down
50 changes: 36 additions & 14 deletions src/TextMateSharp/Internal/Matcher/MatcherBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ namespace TextMateSharp.Internal.Matcher
{
public class MatcherBuilder<T>
{
private static Regex IDENTIFIER_REGEXP = new Regex("[\\w\\.:]+");

public List<MatcherWithPriority<T>> Results;
private Tokenizer _tokenizer;
private IMatchesName<T> _matchesName;
Expand Down Expand Up @@ -139,38 +137,62 @@ private Predicate<T> ParseOperand()
{
identifiers.Add(_token);
_token = _tokenizer.Next();
} while (IsIdentifier(_token));
} while (_token != null && IsIdentifier(_token));
return matcherInput => this._matchesName.Match(identifiers, matcherInput);
}
return null;
}

private bool IsIdentifier(string token)
{
return token != null && IDENTIFIER_REGEXP.Match(token).Success;
if (string.IsNullOrEmpty(token))
return false;

/* Aprox. 2-3 times faster than:
* static final Pattern IDENTIFIER_REGEXP = Pattern.compile("[\\w\\.:]+");
* IDENTIFIER_REGEXP.matcher(token).matches();
*
* Aprox. 10% faster than:
* token.chars().allMatch(ch -> ... )
*/
for (int i = 0; i < token.Length; i++)
{
char ch = token[i];
if (ch == '.' || ch == ':' || ch == '_'
|| ch >= 'a' && ch <= 'z'
|| ch >= 'A' && ch <= 'Z'
|| ch >= '0' && ch <= '9')
continue;
return false;
}
return true;
}

class Tokenizer
{

private static Regex REGEXP = new Regex("([LR]:|[\\w\\.:]+|[\\,\\|\\-\\(\\)])");

Match match;
private static Regex REGEXP = new Regex("([LR]:|[\\w\\.:][\\w\\.:\\-]*|[\\,\\|\\-\\(\\)])");
private string _input;
Match _currentMatch;

public Tokenizer(string input)
{
this.match = REGEXP.Match(input);
_input = input;
}

public string Next()
{
if (match == null)
return null;

match = match.NextMatch();
if (_currentMatch == null)
{
_currentMatch = REGEXP.Match(_input);
}
else
{
_currentMatch = _currentMatch.NextMatch();
}

if (match != null)
return match.Value;
if (_currentMatch.Success)
return _currentMatch.Value;

return null;
}
Expand Down
3 changes: 3 additions & 0 deletions src/TextMateSharp/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("TextMateSharp.Tests")]
9 changes: 8 additions & 1 deletion src/TextMateSharp/Themes/ParsedThemeRule.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;

namespace TextMateSharp.Themes
{
Expand Down Expand Up @@ -37,6 +38,12 @@ public override int GetHashCode()
return result;
}

public override string ToString()
{
return "ParsedThemeRule [scope=" + scope + ", parentScopes=" + string.Join(", ", parentScopes) + ", index=" + index
+ ", fontStyle=" + fontStyle + ", foreground=" + foreground + ", background=" + background + "]";
}

public override bool Equals(object obj)
{
if (this == obj)
Expand Down Expand Up @@ -69,7 +76,7 @@ public override bool Equals(object obj)
if (other.parentScopes != null)
return false;
}
else if (!parentScopes.Equals(other.parentScopes))
else if (!Enumerable.SequenceEqual(parentScopes, other.parentScopes))
return false;
if (scope == null)
{
Expand Down
3 changes: 2 additions & 1 deletion src/TextMateSharp/Themes/Theme.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ static void LookupThemeRules(
if (settingScope is string)
{
string scope = (string)settingScope;

// remove leading and trailing commas
scope = scope.Trim(',');
scopes = new List<string>(scope.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries));
}
else if (settingScope is IList<object>)
Expand Down