Ignore child captures of captures with patterns

This commit is contained in:
Kevin Sawicki & Nathan Sobo
2013-04-18 17:18:00 -07:00
committed by Kevin Sawicki
parent b37468871c
commit 1f4febcfaf
2 changed files with 55 additions and 29 deletions

View File

@@ -309,7 +309,7 @@ describe "TextMateGrammar", ->
expect(tokens[4].value).toBe "three(four(five(_param_)))))"
expect(ruleStack).toEqual originalRuleStack
describe "when a grammar's captures has patterns", ->
describe "when a grammar has a capture with patterns", ->
beforeEach ->
atom.activatePackage('php.tmbundle', sync: true)
@@ -331,3 +331,29 @@ describe "TextMateGrammar", ->
expect(tokens[6].value).toBe "function"
expect(tokens[6].scopes).toEqual ["text.html.php", "meta.embedded.line.php", "source.php", "meta.function.php", "storage.type.function.php"]
it "ignores child captures of a capture with patterns", ->
grammar = new TextMateGrammar
name: "test"
scopeName: "source"
repository: {}
patterns: [
{
name: "text"
match: "(a(b))"
captures:
"1":
patterns: [
{
match: "ab"
name: "a"
}
]
"2":
name: "b"
}
]
{tokens} = grammar.tokenizeLine("ab")
expect(tokens[0].value).toBe "ab"
expect(tokens[0].scopes).toEqual ["source", "text", "a"]

View File

@@ -397,11 +397,9 @@ class Pattern
tokens
getTokensForCaptureRule: (rule, line, captureStart, captureEnd, scopes, stack) ->
line = line.substring(captureStart, captureEnd)
{tokens} = rule.grammar.tokenizeLine(line, [stack..., rule])
matchLength = 0
matchLength += token.value.length for token in tokens
{captureTokens: tokens, matchEndPosition: captureStart + matchLength}
captureText = line.substring(captureStart, captureEnd)
{tokens} = rule.grammar.tokenizeLine(captureText, [stack..., rule])
tokens
getTokensForCaptureIndices: (line, captureIndices, scopes, stack) ->
[parentCaptureIndex, parentCaptureStart, parentCaptureEnd] = shiftCapture(captureIndices)
@@ -411,36 +409,38 @@ class Pattern
scopes = scopes.concat(scope)
if captureRule = @captures[parentCaptureIndex]?.rule
{captureTokens, matchEndPosition} = @getTokensForCaptureRule(captureRule, line, parentCaptureStart, parentCaptureEnd, scopes, stack)
captureTokens = @getTokensForCaptureRule(captureRule, line, parentCaptureStart, parentCaptureEnd, scopes, stack)
tokens.push(captureTokens...)
parentCaptureStart = matchEndPosition
previousChildCaptureEnd = parentCaptureStart
while captureIndices.length and captureIndices[1] < parentCaptureEnd
[childCaptureIndex, childCaptureStart, childCaptureEnd] = captureIndices
emptyCapture = childCaptureEnd - childCaptureStart == 0
captureHasNoScope = not @captures[childCaptureIndex]
if emptyCapture or captureHasNoScope
# Consume child captures
while captureIndices.length and captureIndices[1] < parentCaptureEnd
shiftCapture(captureIndices)
continue
else
previousChildCaptureEnd = parentCaptureStart
while captureIndices.length and captureIndices[1] < parentCaptureEnd
[childCaptureIndex, childCaptureStart, childCaptureEnd] = captureIndices
if childCaptureStart > previousChildCaptureEnd
emptyCapture = childCaptureEnd - childCaptureStart == 0
captureHasNoScope = not @captures[childCaptureIndex]
if emptyCapture or captureHasNoScope
shiftCapture(captureIndices)
continue
if childCaptureStart > previousChildCaptureEnd
tokens.push(new Token(
value: line[previousChildCaptureEnd...childCaptureStart]
scopes: scopes
))
captureTokens = @getTokensForCaptureIndices(line, captureIndices, scopes, stack)
tokens.push(captureTokens...)
previousChildCaptureEnd = childCaptureEnd
if parentCaptureEnd > previousChildCaptureEnd
tokens.push(new Token(
value: line[previousChildCaptureEnd...childCaptureStart]
value: line[previousChildCaptureEnd...parentCaptureEnd]
scopes: scopes
))
captureTokens = @getTokensForCaptureIndices(line, captureIndices, scopes, stack)
tokens.push(captureTokens...)
previousChildCaptureEnd = childCaptureEnd
if parentCaptureEnd > previousChildCaptureEnd
tokens.push(new Token(
value: line[previousChildCaptureEnd...parentCaptureEnd]
scopes: scopes
))
tokens
###