Use ScopeSelector class from first-mate

Begin migrating TextMate helpers out of src/ and into the first-mate
package.
This commit is contained in:
Kevin Sawicki
2013-08-12 16:22:18 -07:00
parent 0a53e2f7bb
commit 063d48c4ab
8 changed files with 7 additions and 298 deletions

View File

@@ -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 =

View File

@@ -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 ###

View File

@@ -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) ->

View File

@@ -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
}

View File

@@ -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]*

View File

@@ -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()

View File

@@ -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