mirror of
https://github.com/atom/atom.git
synced 2026-01-22 21:38:10 -05:00
Port scope selector matchers to CoffeeScript
This commit is contained in:
78
src/app/text-mate-scope-selector-matchers.coffee
Normal file
78
src/app/text-mate-scope-selector-matchers.coffee
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -15,4 +15,4 @@ class TextMateScopeSelector
|
||||
@matcher = TextMateScopeSelector.createParser().parse(@selector)
|
||||
|
||||
matches: (scopes) ->
|
||||
@matcher(scopes)
|
||||
@matcher.matches(scopes)
|
||||
|
||||
Reference in New Issue
Block a user