Support stand-alone negation in selector grammar

Previously negation was only supported as the right hand side
of an composite.
This commit is contained in:
Kevin Sawicki
2013-08-06 16:54:32 -07:00
parent fe9ffbeb12
commit a72e1813e9
3 changed files with 24 additions and 9 deletions

View File

@@ -28,6 +28,8 @@ describe "TextMateScopeSelector", ->
it "matches negation", ->
expect(new TextMateScopeSelector('a - c').matches(['a', 'b'])).toBeTruthy()
expect(new TextMateScopeSelector('-c').matches(['b'])).toBeTruthy()
expect(new TextMateScopeSelector('-c').matches(['c', 'b'])).toBeFalsy()
expect(new TextMateScopeSelector('a-b').matches(['a', 'b'])).toBeFalsy()
expect(new TextMateScopeSelector('a -b').matches(['a', 'b'])).toBeFalsy()
expect(new TextMateScopeSelector('a -c').matches(['a', 'b'])).toBeTruthy()
@@ -37,6 +39,8 @@ describe "TextMateScopeSelector", ->
expect(new TextMateScopeSelector('a & b').matches(['b', 'a'])).toBeTruthy()
expect(new TextMateScopeSelector('a&b&c').matches(['c'])).toBeFalsy()
expect(new TextMateScopeSelector('a&b&c').matches(['a', 'b', 'd'])).toBeFalsy()
expect(new TextMateScopeSelector('a & -b').matches(['a', 'b', 'd'])).toBeFalsy()
expect(new TextMateScopeSelector('a & -b').matches(['a', 'd'])).toBeTruthy()
it "matches composites", ->
expect(new TextMateScopeSelector('a,b,c').matches(['b', 'c'])).toBeTruthy()

View File

@@ -72,20 +72,20 @@ class AndMatcher
"#{@left.toCssSelector()} #{@right.toCssSelector()}"
class NegateMatcher
constructor: (@left, @right) ->
constructor: (@matcher) ->
matches: (scopes) ->
@left.matches(scopes) and not @right.matches(scopes)
not @matcher.matches(scopes)
toCssSelector: ->
"#{@left.toCssSelector()} :not(#{@right.toCssSelector()})"
":not(#{@matcher.toCssSelector()})"
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)
when '-' then @matcher = new AndMatcher(left, new NegateMatcher(right))
matches: (scopes) ->
@matcher.matches(scopes)

View File

@@ -25,15 +25,26 @@ path
return new matchers.PathMatcher(first, others);
}
expression
= path
/ "(" _ selector:selector _ ")" {
group
= "(" _ selector:selector _ ")" {
return selector;
}
expression
= "-" _ group:group _ {
return new matchers.NegateMatcher(group);
}
/ "-" _ path:path _ {
return new matchers.NegateMatcher(path);
}
/ group
/ path
composite
= left:expression _ operator:[|&-] _ right:composite {
= left:expression _ operator:[|&-] _ right:composite {
return new matchers.CompositeMatcher(left, operator, right);
}