diff --git a/spec/app/text-mate-scope-selector-spec.coffee b/spec/app/text-mate-scope-selector-spec.coffee deleted file mode 100644 index 5baf2455a..000000000 --- a/spec/app/text-mate-scope-selector-spec.coffee +++ /dev/null @@ -1,79 +0,0 @@ -TextMateScopeSelector = require 'text-mate-scope-selector' - -describe "TextMateScopeSelector", -> - describe ".matches(scopes)", -> - it "matches the asterix", -> - expect(new TextMateScopeSelector('*').matches(['a'])).toBeTruthy() - expect(new TextMateScopeSelector('*').matches(['b', 'c'])).toBeTruthy() - expect(new TextMateScopeSelector('a.*.c').matches(['a.b.c'])).toBeTruthy() - expect(new TextMateScopeSelector('a.*.c').matches(['a.b.c.d'])).toBeTruthy() - expect(new TextMateScopeSelector('a.*.c').matches(['a.b.d.c'])).toBeFalsy() - - it "matches prefixes", -> - expect(new TextMateScopeSelector('a').matches(['a'])).toBeTruthy() - expect(new TextMateScopeSelector('a').matches(['a.b'])).toBeTruthy() - expect(new TextMateScopeSelector('a.b').matches(['a.b.c'])).toBeTruthy() - expect(new TextMateScopeSelector('a').matches(['abc'])).toBeFalsy() - expect(new TextMateScopeSelector('a.b-c').matches(['a.b-c.d'])).toBeTruthy() - expect(new TextMateScopeSelector('a.b').matches(['a.b-d'])).toBeFalsy() - expect(new TextMateScopeSelector('c++').matches(['c++'])).toBeTruthy() - expect(new TextMateScopeSelector('c++').matches(['c'])).toBeFalsy() - expect(new TextMateScopeSelector('a_b_c').matches(['a_b_c'])).toBeTruthy() - expect(new TextMateScopeSelector('a_b_c').matches(['a_b'])).toBeFalsy() - - it "matches filters", -> - expect(new TextMateScopeSelector('R:g').matches(['g'])).toBeTruthy() - - it "matches disjunction", -> - expect(new TextMateScopeSelector('a | b').matches(['b'])).toBeTruthy() - expect(new TextMateScopeSelector('a|b|c').matches(['c'])).toBeTruthy() - expect(new TextMateScopeSelector('a|b|c').matches(['d'])).toBeFalsy() - - it "matches negation", -> - expect(new TextMateScopeSelector('a - c').matches(['a', 'b'])).toBeTruthy() - expect(new TextMateScopeSelector('a - c').matches(['a'])).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() - expect(new TextMateScopeSelector('a-c').matches(['a', 'b'])).toBeFalsy() - - it "matches conjunction", -> - 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() - expect(new TextMateScopeSelector('a, b, c').matches(['d', 'e'])).toBeFalsy() - expect(new TextMateScopeSelector('a, b, c').matches(['d', 'c.e'])).toBeTruthy() - expect(new TextMateScopeSelector('a,').matches(['a', 'c'])).toBeTruthy() - expect(new TextMateScopeSelector('a,').matches(['b', 'c'])).toBeFalsy() - - it "matches groups", -> - expect(new TextMateScopeSelector('(a,b) | (c, d)').matches(['a'])).toBeTruthy() - expect(new TextMateScopeSelector('(a,b) | (c, d)').matches(['b'])).toBeTruthy() - expect(new TextMateScopeSelector('(a,b) | (c, d)').matches(['c'])).toBeTruthy() - expect(new TextMateScopeSelector('(a,b) | (c, d)').matches(['d'])).toBeTruthy() - expect(new TextMateScopeSelector('(a,b) | (c, d)').matches(['e'])).toBeFalsy() - - it "matches paths", -> - expect(new TextMateScopeSelector('a b').matches(['a', 'b'])).toBeTruthy() - expect(new TextMateScopeSelector('a b').matches(['b', 'a'])).toBeFalsy() - expect(new TextMateScopeSelector('a c').matches(['a', 'b', 'c', 'd', 'e'])).toBeTruthy() - expect(new TextMateScopeSelector('a b e').matches(['a', 'b', 'c', 'd', 'e'])).toBeTruthy() - - describe ".toCssSelector()", -> - it "converts the TextMate scope selector to a CSS selector", -> - expect(new TextMateScopeSelector('a b c').toCssSelector()).toBe '.a .b .c' - expect(new TextMateScopeSelector('a.b.c').toCssSelector()).toBe '.a.b.c' - expect(new TextMateScopeSelector('*').toCssSelector()).toBe '*' - expect(new TextMateScopeSelector('a - b').toCssSelector()).toBe '.a:not(.b)' - expect(new TextMateScopeSelector('a & b').toCssSelector()).toBe '.a .b' - expect(new TextMateScopeSelector('a & -b').toCssSelector()).toBe '.a:not(.b)' - expect(new TextMateScopeSelector('a | b').toCssSelector()).toBe '.a, .b' - expect(new TextMateScopeSelector('a - (b.c d)').toCssSelector()).toBe '.a:not(.b.c .d)' - expect(new TextMateScopeSelector('a, b').toCssSelector()).toBe '.a, .b' diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index ea4e086d0..474631ab9 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -11,7 +11,7 @@ Selection = require 'selection' EventEmitter = require 'event-emitter' Subscriber = require 'subscriber' Range = require 'range' -TextMateScopeSelector = require 'text-mate-scope-selector' +TextMateScopeSelector = require('first-mate').ScopeSelector # An `EditSession` manages the states between {Editor}s, {Buffer}s, and the project as a whole. module.exports = diff --git a/src/app/syntax.coffee b/src/app/syntax.coffee index 30d2be92a..95623431d 100644 --- a/src/app/syntax.coffee +++ b/src/app/syntax.coffee @@ -5,7 +5,7 @@ Specificity = require 'specificity' fsUtils = require 'fs-utils' EventEmitter = require 'event-emitter' NullGrammar = require 'null-grammar' -TextMateScopeSelector = require 'text-mate-scope-selector' +TextMateScopeSelector = require('first-mate').ScopeSelector ### Internal ### diff --git a/src/app/text-mate-grammar.coffee b/src/app/text-mate-grammar.coffee index ce5e0c60b..3a76f8e47 100644 --- a/src/app/text-mate-grammar.coffee +++ b/src/app/text-mate-grammar.coffee @@ -5,7 +5,7 @@ Token = require 'token' {OnigRegExp, OnigScanner} = require 'oniguruma' path = require 'path' EventEmitter = require 'event-emitter' -TextMateScopeSelector = require 'text-mate-scope-selector' +{ScopeSelector} = require 'first-mate' pathSplitRegex = new RegExp("[#{path.sep}.]") @@ -40,7 +40,7 @@ class TextMateGrammar @injections = new Injections(this, injections) if injectionSelector? - @injectionSelector = new TextMateScopeSelector(injectionSelector) + @injectionSelector = new ScopeSelector(injectionSelector) @firstLineRegex = new OnigRegExp(firstLineMatch) if firstLineMatch @fileTypes ?= [] @@ -197,7 +197,7 @@ class Injections patterns.push(pattern.getIncludedPatterns(grammar, patterns)...) @injections.push anchored: anchored - selector: new TextMateScopeSelector(selector) + selector: new ScopeSelector(selector) patterns: patterns getScanner: (injection, firstLine, position, anchorPosition) -> diff --git a/src/app/text-mate-scope-selector-matchers.coffee b/src/app/text-mate-scope-selector-matchers.coffee deleted file mode 100644 index 4d58c7e84..000000000 --- a/src/app/text-mate-scope-selector-matchers.coffee +++ /dev/null @@ -1,101 +0,0 @@ -_ = require 'underscore' - -### Internal ### - -class SegmentMatcher - constructor: (segment) -> - @segment = _.flatten(segment).join('') - - matches: (scope) -> scope is @segment - - toCssSelector: -> - @segment.split('.').map((dotFragment) -> - '.' + dotFragment.replace(/\+/g, '\\+') - ).join('') - -class TrueMatcher - constructor: -> - - matches: -> true - - toCssSelector: -> '*' - -class ScopeMatcher - constructor: (first, others) -> - @segments = [first] - @segments.push(segment[1]) for segment in others - - matches: (scope) -> - scopeSegments = scope.split('.') - return false if scopeSegments.length < @segments.length - - for segment, index in @segments - return false unless segment.matches(scopeSegments[index]) - - true - - toCssSelector: -> - @segments.map((matcher) -> matcher.toCssSelector()).join('') - -class PathMatcher - constructor: (first, others) -> - @matchers = [first] - @matchers.push(matcher[1]) for matcher in others - - matches: (scopes) -> - index = 0 - matcher = @matchers[index] - for scope in scopes - matcher = @matchers[++index] if matcher.matches(scope) - return true unless matcher? - false - - toCssSelector: -> - @matchers.map((matcher) -> matcher.toCssSelector()).join(' ') - -class OrMatcher - constructor: (@left, @right) -> - - matches: (scopes) -> @left.matches(scopes) or @right.matches(scopes) - - toCssSelector: -> "#{@left.toCssSelector()}, #{@right.toCssSelector()}" - -class AndMatcher - constructor: (@left, @right) -> - - matches: (scopes) -> @left.matches(scopes) and @right.matches(scopes) - - toCssSelector: -> - if @right instanceof NegateMatcher - "#{@left.toCssSelector()}#{@right.toCssSelector()}" - else - "#{@left.toCssSelector()} #{@right.toCssSelector()}" - -class NegateMatcher - constructor: (@matcher) -> - - matches: (scopes) -> not @matcher.matches(scopes) - - 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 AndMatcher(left, new NegateMatcher(right)) - - matches: (scopes) -> @matcher.matches(scopes) - - toCssSelector: -> @matcher.toCssSelector() - -module.exports = { - AndMatcher - CompositeMatcher - NegateMatcher - OrMatcher - PathMatcher - ScopeMatcher - SegmentMatcher - TrueMatcher -} diff --git a/src/app/text-mate-scope-selector-pattern.pegjs b/src/app/text-mate-scope-selector-pattern.pegjs deleted file mode 100644 index 43d434644..000000000 --- a/src/app/text-mate-scope-selector-pattern.pegjs +++ /dev/null @@ -1,79 +0,0 @@ -{ - var matchers = require('text-mate-scope-selector-matchers'); -} - -start = _ selector:(selector) _ { - return selector; -} - -segment - = _ segment:([a-zA-Z0-9+_]+[a-zA-Z0-9-+_]*) _ { - return new matchers.SegmentMatcher(segment); - } - - / _ scopeName:[\*] _ { - return new matchers.TrueMatcher(); - } - -scope - = first:segment others:("." segment)* { - return new matchers.ScopeMatcher(first, others); - } - -path - = first:scope others:(_ scope)* { - return new matchers.PathMatcher(first, others); - } - -group - = "(" _ selector:selector _ ")" { - return selector; - } - -filter - = prefix:([LRB]":") _ group:group { - return group; - } - - / prefix:([LRB]":") _ path:path { - return path; - } - -expression - = "-" _ filter:filter _ { - return new matchers.NegateMatcher(filter); - } - - / "-" _ group:group _ { - return new matchers.NegateMatcher(group); - } - - / "-" _ path:path _ { - return new matchers.NegateMatcher(path); - } - - / filter - - / group - - / path - -composite - = left:expression _ operator:[|&-] _ right:composite { - return new matchers.CompositeMatcher(left, operator, right); - } - - / expression - -selector - = left:composite _ "," _ right:selector? { - if (right) - return new matchers.OrMatcher(left, right); - else - return left; - } - - / composite - -_ - = [ \t]* diff --git a/src/app/text-mate-scope-selector.coffee b/src/app/text-mate-scope-selector.coffee deleted file mode 100644 index 1e93b9ab7..000000000 --- a/src/app/text-mate-scope-selector.coffee +++ /dev/null @@ -1,32 +0,0 @@ -PEG = require 'pegjs' -fsUtils = require 'fs-utils' - -# Internal: Test a stack of scopes to see if they match a scope selector. -module.exports = -class TextMateScopeSelector - @parser: null - - @createParser: -> - unless TextMateScopeSelector.parser? - patternPath = require.resolve('text-mate-scope-selector-pattern.pegjs') - TextMateScopeSelector.parser = PEG.buildParser(fsUtils.read(patternPath)) - TextMateScopeSelector.parser - - source: null - matcher: null - - # Create a new scope selector. - # - # source - A {String} to parse as a scope selector. - constructor: (@source) -> - @matcher = TextMateScopeSelector.createParser().parse(@source) - - # Check if this scope selector matches the scopes. - # - # scopes - An {Array} of {String}s. - # - # Return a {Boolean}. - matches: (scopes) -> - @matcher.matches(scopes) - - toCssSelector: -> @matcher.toCssSelector() diff --git a/src/packages/link/lib/link.coffee b/src/packages/link/lib/link.coffee index 542fad8da..ddd5301eb 100644 --- a/src/packages/link/lib/link.coffee +++ b/src/packages/link/lib/link.coffee @@ -8,8 +8,8 @@ module.exports = return unless token? unless @selector? - TextMateScopeSelector = require 'text-mate-scope-selector' - @selector = new TextMateScopeSelector('markup.underline.link') + {ScopeSelector} = require 'first-mate' + @selector = new ScopeSelector('markup.underline.link') if @selector.matches(token.scopes) require('shell').openExternal token.value