From 00a26ae4dadef74537d80901fbd10fa13fc31964 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 7 Nov 2012 16:18:05 -0800 Subject: [PATCH] Fix how repositories work in TextMate grammars Previously, we treated all grammar repositories as rules, but some grammars have repositories that are a single pattern. If it is a single pattern, transform it into a rule with one pattern. Fix how repositories work in TextMate grammars Previously, we treated all grammar repositories as rules, but some grammars have repositories that are a single pattern. If it is a single pattern, transform it into a rule with one pattern. --- spec/app/text-mate-grammar-spec.coffee | 45 +++++++++++++++----------- src/app/text-mate-grammar.coffee | 2 +- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/spec/app/text-mate-grammar-spec.coffee b/spec/app/text-mate-grammar-spec.coffee index e694eb302..34e570c10 100644 --- a/spec/app/text-mate-grammar-spec.coffee +++ b/spec/app/text-mate-grammar-spec.coffee @@ -197,25 +197,27 @@ describe "TextMateGrammar", -> expect(tokens[0]).toEqual value: '<', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.begin.html"] expect(tokens[1]).toEqual value: 'div', scopes: ["text.html.ruby","meta.tag.block.any.html","entity.name.tag.block.any.html"] - expect(tokens[2]).toEqual value: ' class=', scopes: ["text.html.ruby","meta.tag.block.any.html"] - expect(tokens[3]).toEqual value: '\'', scopes: ["text.html.ruby","meta.tag.block.any.html","string.quoted.single.html","punctuation.definition.string.begin.html"] - expect(tokens[4]).toEqual value: 'name', scopes: ["text.html.ruby","meta.tag.block.any.html","string.quoted.single.html"] - expect(tokens[5]).toEqual value: '\'', scopes: ["text.html.ruby","meta.tag.block.any.html","string.quoted.single.html","punctuation.definition.string.end.html"] - expect(tokens[6]).toEqual value: '>', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.end.html"] - expect(tokens[7]).toEqual value: '<%=', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.section.embedded.ruby"] - expect(tokens[8]).toEqual value: ' ', scopes: ["text.html.ruby","source.ruby.rails.embedded.html"] - expect(tokens[9]).toEqual value: 'User', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","support.class.ruby"] - expect(tokens[10]).toEqual value: '.', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.separator.method.ruby"] - expect(tokens[11]).toEqual value: 'find', scopes: ["text.html.ruby","source.ruby.rails.embedded.html"] - expect(tokens[12]).toEqual value: '(', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.section.function.ruby"] - expect(tokens[13]).toEqual value: '2', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","constant.numeric.ruby"] - expect(tokens[14]).toEqual value: ')', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.section.function.ruby"] - expect(tokens[15]).toEqual value: '.', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.separator.method.ruby"] - expect(tokens[16]).toEqual value: 'full_name ', scopes: ["text.html.ruby","source.ruby.rails.embedded.html"] - expect(tokens[17]).toEqual value: '%>', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.section.embedded.ruby"] - expect(tokens[18]).toEqual value: '', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.end.html"] + expect(tokens[2]).toEqual value: ' ', scopes: ["text.html.ruby","meta.tag.block.any.html"] + expect(tokens[3]).toEqual value: 'class', scopes: ["text.html.ruby","meta.tag.block.any.html", "entity.other.attribute-name.html"] + expect(tokens[4]).toEqual value: '=', scopes: ["text.html.ruby","meta.tag.block.any.html"] + expect(tokens[5]).toEqual value: '\'', scopes: ["text.html.ruby","meta.tag.block.any.html","string.quoted.single.html","punctuation.definition.string.begin.html"] + expect(tokens[6]).toEqual value: 'name', scopes: ["text.html.ruby","meta.tag.block.any.html","string.quoted.single.html"] + expect(tokens[7]).toEqual value: '\'', scopes: ["text.html.ruby","meta.tag.block.any.html","string.quoted.single.html","punctuation.definition.string.end.html"] + expect(tokens[8]).toEqual value: '>', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.end.html"] + expect(tokens[9]).toEqual value: '<%=', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.section.embedded.ruby"] + expect(tokens[10]).toEqual value: ' ', scopes: ["text.html.ruby","source.ruby.rails.embedded.html"] + expect(tokens[11]).toEqual value: 'User', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","support.class.ruby"] + expect(tokens[12]).toEqual value: '.', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.separator.method.ruby"] + expect(tokens[13]).toEqual value: 'find', scopes: ["text.html.ruby","source.ruby.rails.embedded.html"] + expect(tokens[14]).toEqual value: '(', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.section.function.ruby"] + expect(tokens[15]).toEqual value: '2', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","constant.numeric.ruby"] + expect(tokens[16]).toEqual value: ')', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.section.function.ruby"] + expect(tokens[17]).toEqual value: '.', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.separator.method.ruby"] + expect(tokens[18]).toEqual value: 'full_name ', scopes: ["text.html.ruby","source.ruby.rails.embedded.html"] + expect(tokens[19]).toEqual value: '%>', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.section.embedded.ruby"] + expect(tokens[20]).toEqual value: '', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.end.html"] it "can parse a grammar with newline charachters in its regular expressions (regression)", -> grammar = new TextMateGrammar @@ -244,3 +246,8 @@ describe "TextMateGrammar", -> grammar = TextMateBundle.grammarForFilePath("hello.js") {tokens, ruleStack} = grammar.tokenizeLine("// line comment") {tokens, ruleStack} = grammar.tokenizeLine(" // second line comment with a single leading space", ruleStack) + + it "correctly parses content inside an c if block. (regression)", -> + grammar = TextMateBundle.grammarForFilePath("hello.c") + {tokens, ruleStack} = grammar.tokenizeLine("if(1){m()}") + expect(tokens[5].scopes).toEqual ["source.c", "meta.block.c", "meta.function-call.c", "support.function.any-method.c"] diff --git a/src/app/text-mate-grammar.coffee b/src/app/text-mate-grammar.coffee index 38549d0a7..ebecfe5a3 100644 --- a/src/app/text-mate-grammar.coffee +++ b/src/app/text-mate-grammar.coffee @@ -26,6 +26,7 @@ class TextMateGrammar @firstLineRegex = new OnigRegExp(firstLineMatch) if firstLineMatch for name, data of repository + data = {patterns: [data], tempName: name} if data.begin? or data.match? @repository[name] = new Rule(this, data) tokenizeLine: (line, {ruleStack, tabLength}={}) -> @@ -111,7 +112,6 @@ class Rule # Add a `\n` to appease patterns that contain '\n' explicitly return null unless result = @getScanner().findNextMatch(line + "\n", position) { index, captureIndices } = result - # Since the `\n' (added above) is not part of the line, truncate captures to the line's actual length lineLength = line.length captureIndices = captureIndices.map (value, index) ->