From 3a8fe2b24ead9753d7fa2da8ab8cf7c252c64d96 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 28 Sep 2012 17:00:31 -0600 Subject: [PATCH] Spans have a class for each dot-separated portion of their token's scope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, we were rendering every prefix of the dot-separated scope as its own class. So the scope meta.delimiter.method.period.coffee would make a token w/ classes: class="meta, meta-delimiter, meta-delimiter-method, meta-delimiter-method-period…" Now we just give the token each piece of the scope as a class: class="meta delimiter method period coffee" We lose a bit of meaning, in that a scope selector method.period.coffee would match this element in CSS even though it *wouldn't* in TextMate. But we also gain the behavior where longer prefixes are more specific by naturally producing more specific css selectors. So '.meta.delimiter.method' is always more specific than '.meta.delimiter', whereas '.meta-delimiter-method' ties with '.meta-delimiter'. If prefix ambiguities become a problem later we may need to revisit this approach, but I think it's good enough for now. --- spec/app/editor-spec.coffee | 22 +++++++++++----------- spec/app/text-mate-theme-spec.coffee | 4 ++-- src/app/editor.coffee | 5 +---- src/app/text-mate-theme.coffee | 2 +- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index 2de3d1205..45f942ca7 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -997,25 +997,25 @@ describe "Editor", -> it "syntax highlights code based on the file type", -> line0 = editor.renderedLines.find('.line:first') span0 = line0.children('span:eq(0)') - expect(span0).toMatchSelector '.source-js' - expect(span0.children('span:eq(0)')).toMatchSelector '.storage-type-js' + expect(span0).toMatchSelector '.source.js' + expect(span0.children('span:eq(0)')).toMatchSelector '.storage.type.js' expect(span0.children('span:eq(0)').text()).toBe 'var' span0_1 = span0.children('span:eq(1)') - expect(span0_1).toMatchSelector '.meta-function-js' + expect(span0_1).toMatchSelector '.meta.function.js' expect(span0_1.text()).toBe 'quicksort = function ()' - expect(span0_1.children('span:eq(0)')).toMatchSelector '.entity-name-function-js' + expect(span0_1.children('span:eq(0)')).toMatchSelector '.entity.name.function.js' expect(span0_1.children('span:eq(0)').text()).toBe "quicksort" - expect(span0_1.children('span:eq(1)')).toMatchSelector '.keyword-operator-js' + expect(span0_1.children('span:eq(1)')).toMatchSelector '.keyword.operator.js' expect(span0_1.children('span:eq(1)').text()).toBe "=" - expect(span0_1.children('span:eq(2)')).toMatchSelector '.storage-type-function-js' + expect(span0_1.children('span:eq(2)')).toMatchSelector '.storage.type.function.js' expect(span0_1.children('span:eq(2)').text()).toBe "function" - expect(span0_1.children('span:eq(3)')).toMatchSelector '.punctuation-definition-parameters-begin-js' + expect(span0_1.children('span:eq(3)')).toMatchSelector '.punctuation.definition.parameters.begin.js' expect(span0_1.children('span:eq(3)').text()).toBe "(" - expect(span0_1.children('span:eq(4)')).toMatchSelector '.punctuation-definition-parameters-end-js' + expect(span0_1.children('span:eq(4)')).toMatchSelector '.punctuation.definition.parameters.end.js' expect(span0_1.children('span:eq(4)').text()).toBe ")" - expect(span0.children('span:eq(2)')).toMatchSelector '.meta-brace-curly-js' + expect(span0.children('span:eq(2)')).toMatchSelector '.meta.brace.curly.js' expect(span0.children('span:eq(2)').text()).toBe "{" line12 = editor.renderedLines.find('.line:eq(11)') @@ -1023,9 +1023,9 @@ describe "Editor", -> describe "when lines are updated in the buffer", -> it "syntax highlights the updated lines", -> - expect(editor.renderedLines.find('.line:eq(0) > span:first > span:first')).toMatchSelector '.storage-type-js' + expect(editor.renderedLines.find('.line:eq(0) > span:first > span:first')).toMatchSelector '.storage.type.js' buffer.insert([0, 0], "q") - expect(editor.renderedLines.find('.line:eq(0) > span:first > span:first')).not.toMatchSelector '.storage-type-js' + expect(editor.renderedLines.find('.line:eq(0) > span:first > span:first')).not.toMatchSelector '.storage.type.js' # verify that re-highlighting can occur below the changed line buffer.insert([5,0], "/* */") diff --git a/spec/app/text-mate-theme-spec.coffee b/spec/app/text-mate-theme-spec.coffee index 7ac04b1fd..8d6866f66 100644 --- a/spec/app/text-mate-theme-spec.coffee +++ b/spec/app/text-mate-theme-spec.coffee @@ -51,7 +51,7 @@ describe "TextMateTheme", -> it "returns an array of objects representing the theme's scope selectors", -> expect(rulesets[11]).toEqual comment: "Invalid – Deprecated" - selector: ".invalid-deprecated" + selector: ".invalid.deprecated" properties: 'color': "#D2A8A1" # 'font-style': 'italic' @@ -59,7 +59,7 @@ describe "TextMateTheme", -> expect(rulesets[12]).toEqual comment: "Invalid – Illegal" - selector: ".invalid-illegal" + selector: ".invalid.illegal" properties: 'color': "#F8F8F8" 'background-color': 'rgba(86, 45, 86, 0.75)' diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 122bd87af..2946bd866 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -832,10 +832,7 @@ class Editor extends View pushScope = (scope) -> scopeStack.push(scope) - classes = [] - scopeComponents = scope.split('.') - classes.push scopeComponents[0..i].join('-') for i in [0...scopeComponents.length] - line.push("") + line.push("") popScope = -> scopeStack.pop() diff --git a/src/app/text-mate-theme.coffee b/src/app/text-mate-theme.coffee index ec55d3b69..c040bce68 100644 --- a/src/app/text-mate-theme.coffee +++ b/src/app/text-mate-theme.coffee @@ -81,7 +81,7 @@ class TextMateTheme properties: @translateScopeSelectorSettings(settings) translateScopeSelector: (textmateScopeSelector) -> - scopes = textmateScopeSelector.replace(/\./g, '-').split(/\s+/).map (scope) -> '.' + scope + scopes = textmateScopeSelector.split(/\s+/).map (scope) -> '.' + scope scopes.join(' ') translateScopeSelectorSettings: ({ foreground, background, fontStyle }) ->