Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
Support interpolation in custom selectors
Browse files Browse the repository at this point in the history
Fixes #208
  • Loading branch information
Wliu authored and Wliu committed Jul 20, 2017
1 parent 290980e commit c0a9ccf
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
43 changes: 35 additions & 8 deletions grammars/scss.cson
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
'include': '#at_rule_import'
}
{
'include': '#general'
'include': '#rules'
}
{
'include': '#flow_control'
'include': '#general'
}
{
'include': '#rules'
'include': '#flow_control'
}
{
'include': '#property_list'
Expand Down Expand Up @@ -1092,9 +1092,6 @@
]
'rules':
'patterns': [
{
'include': '#general'
}
{
'include': '#at_rule_extend'
}
Expand All @@ -1110,6 +1107,9 @@
{
'include': '#selectors'
}
{
'include': '#general'
}
]
'selector_attribute':
'match': '''(?xi)
Expand Down Expand Up @@ -1263,8 +1263,35 @@
}
]
'selector_custom':
'match': '\\b([a-zA-Z0-9]+(-[a-zA-Z0-9]+)+)(?=\\.|\\s++[^:]|\\s*[,\\[{]|:(link|visited|hover|active|focus|target|lang|disabled|enabled|checked|indeterminate|root|nth-(child|last-child|of-type|last-of-type)|first-child|last-child|first-of-type|last-of-type|only-child|only-of-type|empty|not|valid|invalid)(\\([0-9A-Za-z]*\\))?)'
'name': 'entity.name.tag.custom.scss'
'match': '''(?x) (?<![@\\w-])
([a-z]|\\#\\{) # Custom element names must start with a lowercase letter or interpolation
(
[\\w&-] # Allow any word character, &, or dash
| \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)
| \\$ # Possible start of interpolation variable
| } # Possible end of interpolation
)+
(?= # Followed by one of:
[.\\#\\[] # Start of class, id, or attribute selector
| \\s*[,{] # Start of another selector or property-list
| \\s++[^:] # Whitespace followed by anything but :
| :(link|visited|hover|active|focus|target|lang|disabled|enabled|checked|indeterminate|root|
nth-(child|last-child|of-type|last-of-type)|first-child|last-child|first-of-type|
last-of-type|only-child|only-of-type|empty|not|valid|invalid)
(\\([0-9A-Za-z]*\\))?) # pseudo-class/element
'''
'name': 'entity.name.tag.custom.css'
'captures':
'0':
'patterns': [
{
'include': '#interpolation'
}
{
'match': '[A-Z]'
'name': 'invalid.illegal.identifier.css'
}
]
'selector_id':
'match': '''(?x)
(\\#) # Valid id-name
Expand Down
24 changes: 16 additions & 8 deletions spec/scss-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ describe 'SCSS grammar', ->
{tokens} = grammar.tokenizeLine 'very-custom { very-very-custom { color: inherit; } margin: top; }'

expect(tokens[2]).toEqual value: '{', scopes: ['source.css.scss', 'meta.property-list.scss', 'punctuation.section.property-list.begin.bracket.curly.scss']
expect(tokens[4]).toEqual value: 'very-very-custom', scopes: ['source.css.scss', 'meta.property-list.scss', 'entity.name.tag.custom.scss']
expect(tokens[4]).toEqual value: 'very-very-custom', scopes: ['source.css.scss', 'meta.property-list.scss', 'entity.name.tag.custom.css']
expect(tokens[6]).toEqual value: '{', scopes: ['source.css.scss', 'meta.property-list.scss', 'meta.property-list.scss', 'punctuation.section.property-list.begin.bracket.curly.scss']
expect(tokens[8]).toEqual value: 'color', scopes: ['source.css.scss', 'meta.property-list.scss', 'meta.property-list.scss', 'meta.property-name.scss', 'support.type.property-name.css']
expect(tokens[11]).toEqual value: 'inherit', scopes: ['source.css.scss', 'meta.property-list.scss', 'meta.property-list.scss', 'meta.property-value.scss', 'support.constant.property-value.css']
Expand All @@ -332,11 +332,11 @@ describe 'SCSS grammar', ->
another-one { display: none; }
'''

expect(tokens[0][0]).toEqual value: 'very-custom', scopes: ['source.css.scss', 'entity.name.tag.custom.scss']
expect(tokens[0][0]).toEqual value: 'very-custom', scopes: ['source.css.scss', 'entity.name.tag.custom.css']
expect(tokens[0][4]).toEqual value: 'color', scopes: ['source.css.scss', 'meta.property-list.scss', 'meta.property-name.scss', 'support.type.property-name.css']
expect(tokens[0][7]).toEqual value: 'inherit', scopes: ['source.css.scss', 'meta.property-list.scss', 'meta.property-value.scss', 'support.constant.property-value.css']
expect(tokens[0][9]).toEqual value: '}', scopes: ['source.css.scss', 'meta.property-list.scss', 'punctuation.section.property-list.end.bracket.curly.scss']
expect(tokens[1][0]).toEqual value: 'another-one', scopes: ['source.css.scss', 'entity.name.tag.custom.scss']
expect(tokens[1][0]).toEqual value: 'another-one', scopes: ['source.css.scss', 'entity.name.tag.custom.css']
expect(tokens[1][10]).toEqual value: '}', scopes: ['source.css.scss', 'meta.property-list.scss', 'punctuation.section.property-list.end.bracket.curly.scss']

describe 'property values', ->
Expand Down Expand Up @@ -398,30 +398,30 @@ describe 'SCSS grammar', ->
it 'tokenizes them as tags', ->
{tokens} = grammar.tokenizeLine 'very-custom { color: red; }'

expect(tokens[0]).toEqual value: 'very-custom', scopes: ['source.css.scss', 'entity.name.tag.custom.scss']
expect(tokens[0]).toEqual value: 'very-custom', scopes: ['source.css.scss', 'entity.name.tag.custom.css']

{tokens} = grammar.tokenizeLine 'very-very-custom { color: red; }'

expect(tokens[0]).toEqual value: 'very-very-custom', scopes: ['source.css.scss', 'entity.name.tag.custom.scss']
expect(tokens[0]).toEqual value: 'very-very-custom', scopes: ['source.css.scss', 'entity.name.tag.custom.css']

it 'tokenizes them with pseudo selectors', ->
{tokens} = grammar.tokenizeLine 'very-custom:hover { color: red; }'

expect(tokens[0]).toEqual value: 'very-custom', scopes: ['source.css.scss', 'entity.name.tag.custom.scss']
expect(tokens[0]).toEqual value: 'very-custom', scopes: ['source.css.scss', 'entity.name.tag.custom.css']
expect(tokens[1]).toEqual value: ':', scopes: ['source.css.scss', 'entity.other.attribute-name.pseudo-class.css', 'punctuation.definition.entity.css']
expect(tokens[2]).toEqual value: 'hover', scopes: ['source.css.scss', 'entity.other.attribute-name.pseudo-class.css']

it 'tokenizes them with class selectors', ->
{tokens} = grammar.tokenizeLine 'very-custom.class { color: red; }'

expect(tokens[0]).toEqual value: 'very-custom', scopes: ['source.css.scss', 'entity.name.tag.custom.scss']
expect(tokens[0]).toEqual value: 'very-custom', scopes: ['source.css.scss', 'entity.name.tag.custom.css']
expect(tokens[1]).toEqual value: '.', scopes: ['source.css.scss', 'entity.other.attribute-name.class.css', 'punctuation.definition.entity.css']
expect(tokens[2]).toEqual value: 'class', scopes: ['source.css.scss', 'entity.other.attribute-name.class.css']

it "tokenizes them with attribute selectors", ->
{tokens} = grammar.tokenizeLine "md-toolbar[color='primary']"

expect(tokens[0]).toEqual value: "md-toolbar", scopes: ["source.css.scss", "entity.name.tag.custom.scss"]
expect(tokens[0]).toEqual value: "md-toolbar", scopes: ["source.css.scss", "entity.name.tag.custom.css"]
expect(tokens[1]).toEqual value: "[", scopes: ["source.css.scss", "meta.attribute-selector.scss", "punctuation.definition.attribute-selector.begin.bracket.square.scss"]
expect(tokens[2]).toEqual value: "color", scopes: ["source.css.scss", "meta.attribute-selector.scss", "entity.other.attribute-name.attribute.scss"]
expect(tokens[3]).toEqual value: "=", scopes: ["source.css.scss", "meta.attribute-selector.scss", "keyword.operator.scss"]
Expand All @@ -430,6 +430,14 @@ describe 'SCSS grammar', ->
expect(tokens[6]).toEqual value: "'", scopes: ["source.css.scss", "meta.attribute-selector.scss", "string.quoted.single.attribute-value.scss", "punctuation.definition.string.end.scss"]
expect(tokens[7]).toEqual value: ']', scopes: ["source.css.scss", "meta.attribute-selector.scss", "punctuation.definition.attribute-selector.end.bracket.square.scss"]

it "tokenizes them with interpolation", ->
{tokens} = grammar.tokenizeLine "#\{&}__foo { color: red }"

expect(tokens[0]).toEqual value: "#\{", scopes: ["source.css.scss", "entity.name.tag.custom.css", "variable.interpolation.scss", "punctuation.definition.interpolation.begin.bracket.curly.scss"]
expect(tokens[1]).toEqual value: "&", scopes: ["source.css.scss", "entity.name.tag.custom.css", "variable.interpolation.scss"]
expect(tokens[2]).toEqual value: "}", scopes: ["source.css.scss", "entity.name.tag.custom.css", "variable.interpolation.scss", "punctuation.definition.interpolation.end.bracket.curly.scss"]
expect(tokens[3]).toEqual value: "__foo", scopes: ["source.css.scss", "entity.name.tag.custom.css"]

it 'does not confuse them with properties', ->
tokens = grammar.tokenizeLines '''
body {
Expand Down

0 comments on commit c0a9ccf

Please sign in to comment.