diff --git a/grammars/scss.cson b/grammars/scss.cson index c9ea0ff..194126b 100644 --- a/grammars/scss.cson +++ b/grammars/scss.cson @@ -396,16 +396,16 @@ 'at_rule_mixin': 'patterns': [ { - 'begin': '\\s*((@)mixin) ([\\w-]*)\\s*\\(' - 'captures': + 'begin': '(?<=@mixin)\\s+([\\w-]+)\\s*(\\()' + 'beginCaptures': '1': - 'name': 'keyword.control.at-rule.mixin.scss' - '2': - 'name': 'punctuation.definition.keyword.scss' - '3': 'name': 'entity.name.function.scss' - 'comment': 'Mixin with Attributes' + '2': + 'name': 'punctuation.definition.parameters.begin.bracket.round.scss' 'end': '\\)' + 'endCaptures': + '0': + 'name': 'punctuation.definition.parameters.end.bracket.round.scss' 'name': 'meta.at-rule.mixin.scss' 'patterns': [ { @@ -414,31 +414,29 @@ ] } { + 'match': '(?<=@mixin)\\s+([\\w-]+)' + 'captures': + '1': + 'name': 'entity.name.function.scss' + 'name': 'meta.at-rule.mixin.scss' + } + { + 'match': '((@)mixin)\\b' 'captures': '1': 'name': 'keyword.control.at-rule.mixin.scss' '2': 'name': 'punctuation.definition.keyword.scss' - '3': - 'name': 'entity.name.function.scss' - 'comment': 'Simple Mixin' - 'match': '^\\s*((@)mixin) ([\\w-]{1,})' 'name': 'meta.at-rule.mixin.scss' } ] 'at_rule_namespace': 'patterns': [ { - 'begin': '\\s*((@)namespace)\\s+(?=url)' - 'captures': - '1': - 'name': 'keyword.control.at-rule.namespace.scss' - '2': - 'name': 'punctuation.definition.keyword.scss' - '3': - 'name': 'support.function.misc.scss' - 'comment': 'Namespace without prefix' - 'end': '\\s*((?=;|$))' + # Define the default namespace with url() + # MUST be on the top + 'begin': '(?<=@namespace)\\s+(?=url)' + 'end': '(?=;|$)' 'name': 'meta.at-rule.namespace.scss' 'patterns': [ { @@ -453,16 +451,13 @@ ] } { - 'begin': '\\s*((@)namespace) ([\\w-]*)\\s*' + # Define the default namespace with string, or + # a namespace prefix with string or url() + 'begin': '(?<=@namespace)\\s+([\\w-]*)' 'captures': '1': - 'name': 'keyword.control.at-rule.namespace.scss' - '2': - 'name': 'punctuation.definition.keyword.scss' - '3': - 'name': 'entity.name.function.scss' - 'comment': 'Namespace' - 'end': '\\s*((?=;|$))' + 'name': 'entity.name.namespace-prefix.scss' + 'end': '(?=;|$)' 'name': 'meta.at-rule.namespace.scss' 'patterns': [ { @@ -479,6 +474,15 @@ } ] } + { + 'match': '((@)namespace)\\b' + 'captures': + '1': + 'name': 'keyword.control.at-rule.namespace.scss' + '2': + 'name': 'punctuation.definition.keyword.scss' + 'name': 'meta.at-rule.namespace.scss' + } ] 'at_rule_option': 'captures': diff --git a/spec/scss-spec.coffee b/spec/scss-spec.coffee index a8f33a5..66bb9a2 100644 --- a/spec/scss-spec.coffee +++ b/spec/scss-spec.coffee @@ -40,6 +40,51 @@ describe 'SCSS grammar', -> expect(tokens[0]).toEqual value: '@', scopes: ['source.css.scss', 'meta.at-rule.at-root.scss', 'keyword.control.at-rule.at-root.scss', 'punctuation.definition.keyword.scss'] expect(tokens[1]).toEqual value: 'at-root', scopes: ['source.css.scss', 'meta.at-rule.at-root.scss', 'keyword.control.at-rule.at-root.scss'] + describe '@mixin', -> + it 'tokenizes solitary @mixin correctly', -> + {tokens} = grammar.tokenizeLine '@mixin' + + expect(tokens[0]).toEqual value: '@', scopes: ['source.css.scss', 'meta.at-rule.mixin.scss', 'keyword.control.at-rule.mixin.scss', 'punctuation.definition.keyword.scss'] + expect(tokens[1]).toEqual value: 'mixin', scopes: ['source.css.scss', 'meta.at-rule.mixin.scss', 'keyword.control.at-rule.mixin.scss'] + + it 'tokenizes @mixin with no arguments correctly', -> + {tokens} = grammar.tokenizeLine '@mixin media{}' + + expect(tokens[0]).toEqual value: '@', scopes: ['source.css.scss', 'meta.at-rule.mixin.scss', 'keyword.control.at-rule.mixin.scss', 'punctuation.definition.keyword.scss'] + expect(tokens[1]).toEqual value: 'mixin', scopes: ['source.css.scss', 'meta.at-rule.mixin.scss', 'keyword.control.at-rule.mixin.scss'] + expect(tokens[3]).toEqual value: 'media', scopes: ['source.css.scss', 'meta.at-rule.mixin.scss', 'entity.name.function.scss'] + expect(tokens[4]).toEqual value: '{', scopes: ['source.css.scss', 'meta.property-list.scss', 'punctuation.section.property-list.begin.bracket.curly.scss'] + + it 'tokenizes @mixin with arguments correctly', -> + {tokens} = grammar.tokenizeLine '@mixin media ($width){}' + + expect(tokens[3]).toEqual value: 'media', scopes: ['source.css.scss', 'meta.at-rule.mixin.scss', 'entity.name.function.scss'] + expect(tokens[5]).toEqual value: '(', scopes: ['source.css.scss', 'meta.at-rule.mixin.scss', 'punctuation.definition.parameters.begin.bracket.round.scss'] + expect(tokens[7]).toEqual value: ')', scopes: ['source.css.scss', 'meta.at-rule.mixin.scss', 'punctuation.definition.parameters.end.bracket.round.scss'] + expect(tokens[8]).toEqual value: '{', scopes: ['source.css.scss', 'meta.property-list.scss', 'punctuation.section.property-list.begin.bracket.curly.scss'] + + describe '@namespace', -> + it 'tokenizes solitary @namespace correctly', -> + {tokens} = grammar.tokenizeLine '@namespace' + + expect(tokens[0]).toEqual value: '@', scopes: ['source.css.scss', 'meta.at-rule.namespace.scss', 'keyword.control.at-rule.namespace.scss', 'punctuation.definition.keyword.scss'] + expect(tokens[1]).toEqual value: 'namespace', scopes: ['source.css.scss', 'meta.at-rule.namespace.scss', 'keyword.control.at-rule.namespace.scss'] + + it 'tokenizes default namespace definition with url() correctly', -> + {tokens} = grammar.tokenizeLine '@namespace url(XML-namespace-URL);' + + expect(tokens[0]).toEqual value: '@', scopes: ['source.css.scss', 'meta.at-rule.namespace.scss', 'keyword.control.at-rule.namespace.scss', 'punctuation.definition.keyword.scss'] + expect(tokens[1]).toEqual value: 'namespace', scopes: ['source.css.scss', 'meta.at-rule.namespace.scss', 'keyword.control.at-rule.namespace.scss'] + expect(tokens[3]).toEqual value: 'url', scopes: ['source.css.scss', 'meta.at-rule.namespace.scss', 'support.function.misc.scss'] + + it 'tokenizes namespace prefix definition with url() correctly', -> + {tokens} = grammar.tokenizeLine '@namespace prefix url(XML-namespace-URL);' + + expect(tokens[0]).toEqual value: '@', scopes: ['source.css.scss', 'meta.at-rule.namespace.scss', 'keyword.control.at-rule.namespace.scss', 'punctuation.definition.keyword.scss'] + expect(tokens[1]).toEqual value: 'namespace', scopes: ['source.css.scss', 'meta.at-rule.namespace.scss', 'keyword.control.at-rule.namespace.scss'] + expect(tokens[3]).toEqual value: 'prefix', scopes: ['source.css.scss', 'meta.at-rule.namespace.scss', 'entity.name.namespace-prefix.scss'] + expect(tokens[5]).toEqual value: 'url', scopes: ['source.css.scss', 'meta.at-rule.namespace.scss', 'support.function.misc.scss'] + describe '@page', -> it 'tokenizes it correctly', -> tokens = grammar.tokenizeLines """