Port scope selector matchers to CoffeeScript

This commit is contained in:
Kevin Sawicki
2013-04-18 13:26:24 -07:00
parent 1dffb9237a
commit d5723aa18d
3 changed files with 93 additions and 57 deletions

View File

@@ -0,0 +1,78 @@
class SegmentMatcher
constructor: (segment) ->
@segment = segment.join('')
matches: (scope) ->
scope is @segment
class AsterixMatcher
constructor: ->
matches: ->
true
class ScopeMatcher
constructor: (first, others) ->
@segments = [first]
@segments.push(segment[1]) for segment in others
matches: (scope) ->
scopeSegments = scope.split('.')
if scopeSegments.length < @segments.length
return false
for segment, index in @segments
unless segment.matches(scopeSegments[index])
return false
true
class PathMatcher
constructor: (first, others) ->
@matchers = [first]
@matchers.push(matcher[1]) for matcher in others
matches: (scopes) ->
matcher = @matchers.shift()
for scope in scopes
matcher = @matchers.shift() if matcher.matches(scope)
return true unless matcher?
false
class OrMatcher
constructor: (@left, @right) ->
matches: (scopes) ->
@left.matches(scopes) or @right.matches(scopes)
class AndMatcher
constructor: (@left, @right) ->
matches: (scopes) ->
@left.matches(scopes) and @right.matches(scopes)
class NegateMatcher
constructor: (@left, @right) ->
matches: (scopes) ->
@left.matches(scopes) and not @right.matches(scopes)
class CompositeMatcher
constructor: (left, operator, right) ->
switch operator
when '|' then @matcher = new OrMatcher(left, right)
when '&' then @matcher = new AndMatcher(left, right)
when '-' then @matcher = new NegateMatcher(left, right)
matches: (scopes) ->
@matcher.matches(scopes)
module.exports = {
AndMatcher
AsterixMatcher
CompositeMatcher
NegateMatcher
OrMatcher
PathMatcher
ScopeMatcher
SegmentMatcher
}

View File

@@ -1,55 +1,28 @@
start = _ match:(selector) _ {
return match;
{
var matchers = require('text-mate-scope-selector-matchers');
}
start = _ selector:(selector) _ {
return selector;
}
segment
= _ segment:[a-zA-Z0-9]+ _ {
var segment = segment.join("");
return function(scope) {
return scope === segment;
};
return new matchers.SegmentMatcher(segment);
}
/ _ scopeName:[\*] _ {
return function() {
return true;
};
return new matchers.AsterixMatcher();
}
scope
= first:segment others:("." segment)* {
return function(scope) {
var segments = [first];
for (var i = 0; i < others.length; i++)
segments.push(others[i][1]);
var scopeSegments = scope.split(".");
if (scopeSegments.length < segments.length)
return false;
for (var i = 0; i < segments.length; i++)
if (!segments[i](scopeSegments[i]))
return false;
return true;
}
return new matchers.ScopeMatcher(first, others);
}
path
= first:scope others:(_ scope)* {
return function(scopes) {
var scopeMatchers = [first];
for (var i = 0; i < others.length; i++)
scopeMatchers.push(others[i][1]);
var matcher = scopeMatchers.shift();
for (var i = 0; i < scopes.length; i++) {
if (matcher(scopes[i]))
matcher = scopeMatchers.shift();
if (!matcher)
return true;
}
return false;
}
return new matchers.PathMatcher(first, others);
}
expression
@@ -61,30 +34,15 @@ expression
composite
= left:expression _ operator:[|&-] _ right:composite {
switch(operator) {
case "|":
return function(scopes) {
return left(scopes) || right(scopes);
};
case "&":
return function(scopes) {
return left(scopes) && right(scopes);
};
case "-":
return function(scopes) {
return left(scopes) && !right(scopes);
};
}
}
return new matchers.CompositeMatcher(left, operator, right);
}
/ expression
selector
= left:composite _ "," _ right:selector {
return function(scopes) {
return left(scopes) || right(scopes);
};
}
return new matchers.OrMatcher(left, right);
}
/ composite

View File

@@ -15,4 +15,4 @@ class TextMateScopeSelector
@matcher = TextMateScopeSelector.createParser().parse(@selector)
matches: (scopes) ->
@matcher(scopes)
@matcher.matches(scopes)