From 91bb5bbea46fa2191bd9e31049c70c3809aceda6 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 13:29:28 +0700 Subject: [PATCH 01/25] Add `#nesting-selector` --- grammars/css.cson | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index 2664a9f..24e3d96 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -34,6 +34,9 @@ { 'include': '#rule-list' } + { + 'include': '#nesting-selector' + } ] 'repository': 'at-rules': @@ -1380,6 +1383,9 @@ ) (?=$|[{,\\s;]|/\\*) ''' + 'nesting-selector': + 'match': '&' + 'name': 'entity.name.tag.nesting.selector.css' 'numeric-values': 'patterns': [ { @@ -1766,6 +1772,9 @@ ] 'selector-innards': 'patterns': [ + { + 'include': '#nesting-selector' + } { 'include': '#comment-block' } From 659d68e20b1ff622476f9e7993a7bfc280eb1d9b Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 13:35:54 +0700 Subject: [PATCH 02/25] Add `#nesting-rules` --- grammars/css.cson | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index 24e3d96..f85c499 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -1383,6 +1383,19 @@ ) (?=$|[{,\\s;]|/\\*) ''' + 'nesting-rules': + 'patterns': [ + { + 'match': '(?xi) (?\\s,.\\#|&){:\\[]|/\\*|$)', + 'name': 'entity.name.tag.css' + } + { + 'include': '#property-names' + } + { + 'include': '#selector-innards' + } + ] 'nesting-selector': 'match': '&' 'name': 'entity.name.tag.nesting.selector.css' @@ -1689,9 +1702,15 @@ 'name': 'punctuation.section.property-list.end.bracket.curly.css' 'name': 'meta.property-list.css' 'patterns': [ + { + 'include': '#nesting-rules' + } { 'include': '#rule-list-innards' } + { + 'include': '$self' + } ] 'rule-list-innards': 'patterns': [ From 97a1e73e7ae7bd9deb0da1f0a56b407b22c8bf05 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 13:39:59 +0700 Subject: [PATCH 03/25] Add `#nesting-at-rules` --- grammars/css.cson | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index f85c499..7b7813f 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -217,6 +217,9 @@ 'name': 'punctuation.section.media.end.bracket.curly.css' 'name': 'meta.at-rule.media.body.css' 'patterns': [ + { + 'include': '#nesting-at-rules' + } { 'include': '$self' } @@ -1383,6 +1386,18 @@ ) (?=$|[{,\\s;]|/\\*) ''' + 'nesting-at-rules': + 'patterns': [ + { + 'include': '#commas' + } + { + 'include': '#nesting-rules' + } + { + 'include': '#rule-list-innards' + } + ] 'nesting-rules': 'patterns': [ { From cdba27c402a446c8223217b0c8db99b4b42b06b5 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 13:45:13 +0700 Subject: [PATCH 04/25] Allow `&` to be append to end of tag, class, or ID --- grammars/css.cson | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index 7b7813f..f3829a3 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -1876,7 +1876,7 @@ # Consists of a hyphen only - # Terminated by either: (?= $ # - End-of-line - | [\\s,.\\#)\\[:{>+~|] # - Followed by another selector + | [\\s,.\\#)\\[:{>+~|&] # - Followed by another selector | /\\* # - Followed by a block comment ) | @@ -1917,7 +1917,7 @@ )+ ) # Followed by either: (?= $ # - End of the line - | [\\s,.\\#)\\[:{>+~|] # - Another selector + | [\\s,.\\#)\\[:{>+~|&] # - Another selector | /\\* # - A block comment ) ''' @@ -1940,7 +1940,7 @@ (?![0-9]) (?:[-a-zA-Z0-9_]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+ ) - (?=$|[\\s,.\\#)\\[:{>+~|]|/\\*) + (?=$|[\\s,.\\#)\\[:{>+~|&]|/\\*) ''' 'name': 'entity.other.attribute-name.id.css' } @@ -2143,7 +2143,7 @@ | mrow|ms|mscarries|mscarry|msgroup|msline|mspace|msqrt|msrow|mstack|mstyle|msub|msubsup | msup|mtable|mtd|mtext|mtr|munder|munderover|semantics ) - (?=[+~>\\s,.\\#|){:\\[]|/\\*|$) + (?=[+~>\\s,.\\#|&){:\\[]|/\\*|$) ''' 'name': 'entity.name.tag.css' 'unicode-range': From f633daba4ec1fccae5159b031c569d5532ba6421 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 14:00:25 +0700 Subject: [PATCH 05/25] Add `#function-nesting` --- grammars/css.cson | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index f3829a3..25cad7b 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -830,6 +830,9 @@ { 'include': '#property-values' } + { + 'include': '#function-nesting' + } ] } # Colours @@ -1055,6 +1058,30 @@ } ] } + 'function-nesting': { + 'patterns': [ + { + 'begin': '\\(', + 'beginCaptures': + '0': + 'name': 'punctuation.definition.begin.bracket.round.scss' + 'end': '\\)', + 'endCaptures': + '0': + 'name': 'punctuation.definition.end.bracket.round.scss' + 'patterns': [ + { + 'match': '[*/]|(?<=\\s|^)[-+](?=\\s|$)', + 'name': 'keyword.operator.arithmetic.css' + } + { + 'include': '#property-values' + }, + { + 'include': '#function-nesting' + } + ] + } ] 'functional-pseudo-classes': 'patterns': [ From 44a40b7c3b884d269d33e08b64a86945f8baf113 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 14:02:43 +0700 Subject: [PATCH 06/25] Add function syntax highlighting to `media-query` --- grammars/css.cson | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index 25cad7b..5dd46c4 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -1385,6 +1385,9 @@ { 'include': '#comment-block' } + { + "include": "#functions" + } ] } ] From 317bdbe924b24c0e7520f96a9a517dc8771dc929 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 14:12:25 +0700 Subject: [PATCH 07/25] Add '#arithmetic-operators' to replace dup code --- grammars/css.cson | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index 5dd46c4..d3fc10f 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -39,6 +39,9 @@ } ] 'repository': + 'arithmetic-operators': + 'match': '[*/]|(?<=\\s|^)[-+](?=\\s|$)', + 'name': 'keyword.operator.arithmetic.css' 'at-rules': 'patterns': [ { @@ -824,8 +827,7 @@ 'name': 'meta.function.calc.css' 'patterns': [ { - 'match': '[*/]|(?<=\\s|^)[-+](?=\\s|$)' - 'name': 'keyword.operator.arithmetic.css' + 'include': '#arithmetic-operators' } { 'include': '#property-values' @@ -946,6 +948,9 @@ 'match': '(?i)(?<=[,\\s"]|\\*/|^)\\d+x(?=[\\s,"\')]|/\\*|$)' 'name': 'constant.numeric.other.density.css' } + { + 'include': '#arithmetic-operators' + } { 'include': '#property-values' } @@ -1071,8 +1076,7 @@ 'name': 'punctuation.definition.end.bracket.round.scss' 'patterns': [ { - 'match': '[*/]|(?<=\\s|^)[-+](?=\\s|$)', - 'name': 'keyword.operator.arithmetic.css' + 'include': '#arithmetic-operators' } { 'include': '#property-values' From cb0ea96593dbcf47ad52c00b620852fc52fd1c89 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 14:15:03 +0700 Subject: [PATCH 08/25] Remove unneeded commas in grammar --- grammars/css.cson | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index d3fc10f..366fefa 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -40,7 +40,7 @@ ] 'repository': 'arithmetic-operators': - 'match': '[*/]|(?<=\\s|^)[-+](?=\\s|$)', + 'match': '[*/]|(?<=\\s|^)[-+](?=\\s|$)' 'name': 'keyword.operator.arithmetic.css' 'at-rules': 'patterns': [ @@ -1066,11 +1066,11 @@ 'function-nesting': { 'patterns': [ { - 'begin': '\\(', + 'begin': '\\(' 'beginCaptures': '0': 'name': 'punctuation.definition.begin.bracket.round.scss' - 'end': '\\)', + 'end': '\\)' 'endCaptures': '0': 'name': 'punctuation.definition.end.bracket.round.scss' @@ -1435,7 +1435,7 @@ 'nesting-rules': 'patterns': [ { - 'match': '(?xi) (?\\s,.\\#|&){:\\[]|/\\*|$)', + 'match': '(?xi) (?\\s,.\\#|&){:\\[]|/\\*|$)' 'name': 'entity.name.tag.css' } { From b5d04a3f40903dbd9f3a184e0bd061aae8032ddf Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 14:16:41 +0700 Subject: [PATCH 09/25] Add '#nesting-at-rules` to custom `at-rules` --- grammars/css.cson | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index 366fefa..361ba32 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -641,6 +641,9 @@ 'name': 'punctuation.section.end.bracket.curly.css' 'name': 'meta.at-rule.body.css' 'patterns': [ + { + 'include': '#nesting-at-rules' + } { 'include': '$self' } From d2c80352770c2792f091a9e466aaf9e9b42253c8 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 14:32:40 +0700 Subject: [PATCH 10/25] Add `@container` nesting rules and tokens --- grammars/css.cson | 177 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index 361ba32..05c55f0 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -44,6 +44,41 @@ 'name': 'keyword.operator.arithmetic.css' 'at-rules': 'patterns': [ + # @container + { + 'begin': '(?i)\\G(@)container' + 'beginCaptures': + '0': + 'name': 'keyword.control.at-rule.container.css' + '1': + 'name': 'punctuation.definition.keyword.css' + 'end': '(?=\\s*[{;])' + 'name': 'meta.at-rule.container.header.css' + 'patterns': [ + { + 'include': '#container-condition' + } + ] + } + { + 'begin': '{' + 'beginCaptures': + '0': + 'name': 'punctuation.section.container.begin.bracket.curly.css' + 'end': '}' + 'endCaptures': + '0': + 'name': 'punctuation.section.container.end.bracket.curly.css' + 'name': 'meta.at-rule.container.body.css' + 'patterns': [ + { + 'include': '#nesting-at-rules' + } + { + 'include': '$self' + } + ] + } { # @charset, with possible preceding BOM sequence 'begin': '\\A(?:\\xEF\\xBB\\xBF)?(?i:(?=\\s*@charset\\b))' @@ -722,6 +757,148 @@ '0': 'name': 'punctuation.definition.comment.end.css' 'name': 'comment.block.css' + 'container-condition': + 'begin': '\\G' + 'end': '(?=\\s*[{;])' + 'patterns': [ + { + 'include': '#comment-block' + } + { + 'include': '#escapes' + } + { + 'match': '(?xi)\n (?<=not.*)not\n # Only one `not` in allowed' + 'name': 'invalid.illegal.multiple-not.container.css' + } + { + 'match': '(?i)(?<=\\s|^|,|\\*/)(and|or|not)(?=\\s|{|/\\*|$)' + 'name': 'keyword.operator.logical.$1.container.css' + } + { + 'include': '#container-name' + } + { + 'include': '#container-query' + } + ] + } + 'container-name': + 'begin': '\\G' + 'end': '(?xi)\n (?=(?:\\(|not)|style\\()\n # Ends when `(`, `not`, or `style(` is reached' + 'patterns': [ + { + 'include': '#comment-block' + } + { + 'captures': + '1': + 'name': 'invalid.illegal.constant.container-name.container.css' + '2': + 'name': 'support.constant.container-name.container.css' + 'match': '(?xi)\n (?<=^|\\s|\\*/)\n(?:\n # Invalid name\n (default|none)\n |\n # Valid names\n ([a-zA-Z0-9\\-_\\\\]+)\n )\n(?=$|[({\\s;]|/\\*)' + } + ] + 'container-query': + 'begin': '((?<=\\s)\\()|(style)(\\()' + 'beginCaptures': + '1': + 'name': 'punctuation.definition.parameters.begin.bracket.round.css' + '2': + 'name': 'support.style-query.container.css' + '3': + 'name': 'punctuation.definition.parameters.begin.bracket.round.css' + 'end': '\\)' + 'endCaptures': + '0': + 'name': 'punctuation.definition.parameters.end.bracket.round.css' + 'patterns': [ + { + 'begin': '(?xi)\n (?<=\\s\\()\n # Rules for size ' + 'end': '(?=\\))' + 'patterns': [ + { + 'include': '#container-query-features' + } + { + 'include': '#container-size-features' + } + { + 'include': '#container-size-feature-keywords' + } + ] + } + { + 'begin': '(?xi)\n (?<=style\\()\n # Rules for container-query ' + 'end': '(?=\\))' + 'name': 'style-query.container.css' + 'patterns': [ + { + 'include': '#container-query-features' + } + { + 'include': '#container-style-features' + } + { + 'include': '#container-style-feature-keywords' + } + ] + } + ] + 'container-query-features': + 'patterns': [ + { + 'match': ':' + 'name': 'punctuation.separator.key-value.css' + } + { + 'match': '>=|<=|=|<|>' + 'name': 'keyword.operator.comparison.css' + } + { + 'include': '#numeric-values' + } + { + 'include': '#comment-block' + } + ] + 'container-size-features': + 'match': '(?xi)\n (?<=^|\\s|\\(|\\*/) # Preceded by whitespace, bracket or comment\n (?:\n # Standardised features\n (\n (?:min-|max-)? # Range features\n (?: aspect-ratio\n | block-size\n | height\n | inline-size\n | width\n )\n | orientation\n )\n )\n (?=\\s|$|[><:=]|\\)|/\\*) # Terminates cleanly' + 'name': 'support.size.property-name.container.css' + 'container-size-feature-keywords': + 'patterns': [ + { + 'match': '(?xi)\n (?<=^|\\s|:|\\*/)\n # Preceded by whitespace, colon, or comment\n (?: portrait\n | landscape\n # Orientation\n )\n (?=\\s|\\)|$)' + 'name': 'support.constant.property-value.container.css' + } + { + 'include': '#functions' + } + ] + 'container-style-features': + 'match': '(?x)\n # Custom Property Name\n (?<=^|\\s|\\(|\\*/) # Preceded by whitespace, bracket or comment\n (? Date: Wed, 18 Sep 2024 14:39:46 +0700 Subject: [PATCH 11/25] Format tabs to spaces --- grammars/css.cson | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index 05c55f0..3175a55 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -1601,17 +1601,17 @@ (?=$|[{,\\s;]|/\\*) ''' 'nesting-at-rules': - 'patterns': [ - { - 'include': '#commas' - } - { - 'include': '#nesting-rules' - } - { - 'include': '#rule-list-innards' - } - ] + 'patterns': [ + { + 'include': '#commas' + } + { + 'include': '#nesting-rules' + } + { + 'include': '#rule-list-innards' + } + ] 'nesting-rules': 'patterns': [ { From 16f5857d893980090f07d1a4295af0447a13f02f Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 16:18:46 +0700 Subject: [PATCH 12/25] Fix punctuation --- grammars/css.cson | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index 3175a55..c5281f6 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -782,7 +782,6 @@ 'include': '#container-query' } ] - } 'container-name': 'begin': '\\G' 'end': '(?xi)\n (?=(?:\\(|not)|style\\()\n # Ends when `(`, `not`, or `style(` is reached' @@ -1243,7 +1242,8 @@ } ] } - 'function-nesting': { + ] + 'function-nesting': 'patterns': [ { 'begin': '\\(' From be30f26415fe432cd72e2ed7b0dc3cfa22be82c9 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Wed, 18 Sep 2024 16:29:02 +0700 Subject: [PATCH 13/25] Add ignore rule for `no_implicit_braces` --- coffeelint.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coffeelint.json b/coffeelint.json index a5dd715..e0da626 100644 --- a/coffeelint.json +++ b/coffeelint.json @@ -33,5 +33,8 @@ }, "no_stand_alone_at": { "level": "error" + }, + "no_implicit_braces": { + "level": "ignore" } } From 4809fc9b64584162878f40e1119b0cca60684705 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Sun, 1 Jun 2025 10:05:14 +0700 Subject: [PATCH 14/25] Reset `css.cson` to original official file --- grammars/css.cson | 269 ++-------------------------------------------- 1 file changed, 6 insertions(+), 263 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index 84981a0..6256e55 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -34,51 +34,10 @@ { 'include': '#rule-list' } - { - 'include': '#nesting-selector' - } ] 'repository': - 'arithmetic-operators': - 'match': '[*/]|(?<=\\s|^)[-+](?=\\s|$)' - 'name': 'keyword.operator.arithmetic.css' 'at-rules': 'patterns': [ - # @container - { - 'begin': '(?i)\\G(@)container' - 'beginCaptures': - '0': - 'name': 'keyword.control.at-rule.container.css' - '1': - 'name': 'punctuation.definition.keyword.css' - 'end': '(?=\\s*[{;])' - 'name': 'meta.at-rule.container.header.css' - 'patterns': [ - { - 'include': '#container-condition' - } - ] - } - { - 'begin': '{' - 'beginCaptures': - '0': - 'name': 'punctuation.section.container.begin.bracket.curly.css' - 'end': '}' - 'endCaptures': - '0': - 'name': 'punctuation.section.container.end.bracket.curly.css' - 'name': 'meta.at-rule.container.body.css' - 'patterns': [ - { - 'include': '#nesting-at-rules' - } - { - 'include': '$self' - } - ] - } { # @charset, with possible preceding BOM sequence 'begin': '\\A(?:\\xEF\\xBB\\xBF)?(?i:(?=\\s*@charset\\b))' @@ -255,9 +214,6 @@ 'name': 'punctuation.section.media.end.bracket.curly.css' 'name': 'meta.at-rule.media.body.css' 'patterns': [ - { - 'include': '#nesting-at-rules' - } { 'include': '$self' } @@ -676,9 +632,6 @@ 'name': 'punctuation.section.end.bracket.curly.css' 'name': 'meta.at-rule.body.css' 'patterns': [ - { - 'include': '#nesting-at-rules' - } { 'include': '$self' } @@ -757,147 +710,6 @@ '0': 'name': 'punctuation.definition.comment.end.css' 'name': 'comment.block.css' - 'container-condition': - 'begin': '\\G' - 'end': '(?=\\s*[{;])' - 'patterns': [ - { - 'include': '#comment-block' - } - { - 'include': '#escapes' - } - { - 'match': '(?xi)\n (?<=not.*)not\n # Only one `not` in allowed' - 'name': 'invalid.illegal.multiple-not.container.css' - } - { - 'match': '(?i)(?<=\\s|^|,|\\*/)(and|or|not)(?=\\s|{|/\\*|$)' - 'name': 'keyword.operator.logical.$1.container.css' - } - { - 'include': '#container-name' - } - { - 'include': '#container-query' - } - ] - 'container-name': - 'begin': '\\G' - 'end': '(?xi)\n (?=(?:\\(|not)|style\\()\n # Ends when `(`, `not`, or `style(` is reached' - 'patterns': [ - { - 'include': '#comment-block' - } - { - 'captures': - '1': - 'name': 'invalid.illegal.constant.container-name.container.css' - '2': - 'name': 'support.constant.container-name.container.css' - 'match': '(?xi)\n (?<=^|\\s|\\*/)\n(?:\n # Invalid name\n (default|none)\n |\n # Valid names\n ([a-zA-Z0-9\\-_\\\\]+)\n )\n(?=$|[({\\s;]|/\\*)' - } - ] - 'container-query': - 'begin': '((?<=\\s)\\()|(style)(\\()' - 'beginCaptures': - '1': - 'name': 'punctuation.definition.parameters.begin.bracket.round.css' - '2': - 'name': 'support.style-query.container.css' - '3': - 'name': 'punctuation.definition.parameters.begin.bracket.round.css' - 'end': '\\)' - 'endCaptures': - '0': - 'name': 'punctuation.definition.parameters.end.bracket.round.css' - 'patterns': [ - { - 'begin': '(?xi)\n (?<=\\s\\()\n # Rules for size ' - 'end': '(?=\\))' - 'patterns': [ - { - 'include': '#container-query-features' - } - { - 'include': '#container-size-features' - } - { - 'include': '#container-size-feature-keywords' - } - ] - } - { - 'begin': '(?xi)\n (?<=style\\()\n # Rules for container-query ' - 'end': '(?=\\))' - 'name': 'style-query.container.css' - 'patterns': [ - { - 'include': '#container-query-features' - } - { - 'include': '#container-style-features' - } - { - 'include': '#container-style-feature-keywords' - } - ] - } - ] - 'container-query-features': - 'patterns': [ - { - 'match': ':' - 'name': 'punctuation.separator.key-value.css' - } - { - 'match': '>=|<=|=|<|>' - 'name': 'keyword.operator.comparison.css' - } - { - 'include': '#numeric-values' - } - { - 'include': '#comment-block' - } - ] - 'container-size-features': - 'match': '(?xi)\n (?<=^|\\s|\\(|\\*/) # Preceded by whitespace, bracket or comment\n (?:\n # Standardised features\n (\n (?:min-|max-)? # Range features\n (?: aspect-ratio\n | block-size\n | height\n | inline-size\n | width\n )\n | orientation\n )\n )\n (?=\\s|$|[><:=]|\\)|/\\*) # Terminates cleanly' - 'name': 'support.size.property-name.container.css' - 'container-size-feature-keywords': - 'patterns': [ - { - 'match': '(?xi)\n (?<=^|\\s|:|\\*/)\n # Preceded by whitespace, colon, or comment\n (?: portrait\n | landscape\n # Orientation\n )\n (?=\\s|\\)|$)' - 'name': 'support.constant.property-value.container.css' - } - { - 'include': '#functions' - } - ] - 'container-style-features': - 'match': '(?x)\n # Custom Property Name\n (?<=^|\\s|\\(|\\*/) # Preceded by whitespace, bracket or comment\n (?\\s,.\\#|&){:\\[]|/\\*|$)' - 'name': 'entity.name.tag.css' - } - { - 'include': '#property-names' - } - { - 'include': '#selector-innards' - } - ] - 'nesting-selector': - 'match': '&' - 'name': 'entity.name.tag.nesting.selector.css' 'numeric-values': 'patterns': [ { @@ -1931,15 +1683,9 @@ 'name': 'punctuation.section.property-list.end.bracket.curly.css' 'name': 'meta.property-list.css' 'patterns': [ - { - 'include': '#nesting-rules' - } { 'include': '#rule-list-innards' } - { - 'include': '$self' - } ] 'rule-list-innards': 'patterns': [ @@ -2020,9 +1766,6 @@ ] 'selector-innards': 'patterns': [ - { - 'include': '#nesting-selector' - } { 'include': '#comment-block' } @@ -2090,7 +1833,7 @@ # Consists of a hyphen only - # Terminated by either: (?= $ # - End-of-line - | [\\s,.\\#)\\[:{>+~|&] # - Followed by another selector + | [\\s,.\\#)\\[:{>+~|] # - Followed by another selector | /\\* # - Followed by a block comment ) | @@ -2131,7 +1874,7 @@ )+ ) # Followed by either: (?= $ # - End of the line - | [\\s,.\\#)\\[:{>+~|&] # - Another selector + | [\\s,.\\#)\\[:{>+~|] # - Another selector | /\\* # - A block comment ) ''' @@ -2154,7 +1897,7 @@ (?![0-9]) (?:[-a-zA-Z0-9_]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+ ) - (?=$|[\\s,.\\#)\\[:{>+~|&]|/\\*) + (?=$|[\\s,.\\#)\\[:{>+~|]|/\\*) ''' 'name': 'entity.other.attribute-name.id.css' } @@ -2357,7 +2100,7 @@ | mrow|ms|mscarries|mscarry|msgroup|msline|mspace|msqrt|msrow|mstack|mstyle|msub|msubsup | msup|mtable|mtd|mtext|mtr|munder|munderover|semantics ) - (?=[+~>\\s,.\\#|&){:\\[]|/\\*|$) + (?=[+~>\\s,.\\#|){:\\[]|/\\*|$) ''' 'name': 'entity.name.tag.css' 'unicode-range': From 26d25aa03dadc2adba015e58fda8f2c3259d6ac8 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Sun, 1 Jun 2025 11:45:56 +0700 Subject: [PATCH 15/25] Include `$self` for `rule-list` nesting --- grammars/css.cson | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index 6256e55..e659200 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -1686,6 +1686,9 @@ { 'include': '#rule-list-innards' } + { + 'include': '$self' + } ] 'rule-list-innards': 'patterns': [ From 0a667f23f997fabe26567a2347cf74c38e275640 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Sun, 1 Jun 2025 11:52:30 +0700 Subject: [PATCH 16/25] Add `&` nesting selector --- grammars/css.cson | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index e659200..aab513b 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -1793,7 +1793,7 @@ [-\\w*]+ \\| (?! - [-\\[:.*\\#a-zA-Z_] # Make sure there's a selector to match + [-\\[:.*&\\#a-zA-Z_] # Make sure there's a selector to match | [^\\x00-\\x7F] ) ) @@ -1811,6 +1811,10 @@ { 'include': '#tag-names' } + { + 'match': '&' + 'name': 'entity.name.tag.nesting.css' + } { 'match': '\\*' 'name': 'entity.name.tag.wildcard.css' @@ -1836,7 +1840,7 @@ # Consists of a hyphen only - # Terminated by either: (?= $ # - End-of-line - | [\\s,.\\#)\\[:{>+~|] # - Followed by another selector + | [\\s,.\\#)\\[:{>+~|&] # - Followed by another selector | /\\* # - Followed by a block comment ) | @@ -1846,7 +1850,7 @@ | \\\\(?:[0-9a-fA-F]{1,6}|.) # - Escape sequence )* (?: # Invalid punctuation - [!"'%&(*;+~|] # - Another selector + | [\\s,.\\#)\\[:{>+~|&] # - Another selector | /\\* # - A block comment ) ''' @@ -1900,7 +1904,7 @@ (?![0-9]) (?:[-a-zA-Z0-9_]|[^\\x00-\\x7F]|\\\\(?:[0-9a-fA-F]{1,6}|.))+ ) - (?=$|[\\s,.\\#)\\[:{>+~|]|/\\*) + (?=$|[\\s,.\\#)\\[:{>+~|&]|/\\*) ''' 'name': 'entity.other.attribute-name.id.css' } @@ -2103,7 +2107,7 @@ | mrow|ms|mscarries|mscarry|msgroup|msline|mspace|msqrt|msrow|mstack|mstyle|msub|msubsup | msup|mtable|mtd|mtext|mtr|munder|munderover|semantics ) - (?=[+~>\\s,.\\#|){:\\[]|/\\*|$) + (?=[+~>\\s,.\\#|&){:\\[]|/\\*|$) ''' 'name': 'entity.name.tag.css' 'unicode-range': From 6d1d839f536958d47eda8a7ad569d11baeae7ddc Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Sun, 1 Jun 2025 11:58:23 +0700 Subject: [PATCH 17/25] Add arithmetic operators to functions --- grammars/css.cson | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index aab513b..3b64a22 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -36,6 +36,9 @@ } ] 'repository': + 'arithmetic-operators': + 'match': '[*/]|(?<=\\s|^)[-+](?=\\s|$)' + 'name': 'keyword.operator.arithmetic.css' 'at-rules': 'patterns': [ { @@ -818,8 +821,7 @@ 'name': 'meta.function.calc.css' 'patterns': [ { - 'match': '[*/]|(?<=\\s|^)[-+](?=\\s|$)' - 'name': 'keyword.operator.arithmetic.css' + 'include': '#arithmetic-operators' } { 'include': '#property-values' @@ -937,6 +939,9 @@ 'match': '(?i)(?<=[,\\s"]|\\*/|^)\\d+x(?=[\\s,"\')]|/\\*|$)' 'name': 'constant.numeric.other.density.css' } + { + 'include': '#arithmetic-operators' + } { 'include': '#property-values' } From fcc2e38e55316ecc873f1751aca7d190749da333 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Sun, 1 Jun 2025 12:00:44 +0700 Subject: [PATCH 18/25] Add `#function-nesting` --- grammars/css.cson | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index 3b64a22..506a89c 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -826,6 +826,9 @@ { 'include': '#property-values' } + { + 'include': '#function-nesting' + } ] } # Colours @@ -1055,6 +1058,26 @@ ] } ] + 'function-nesting': + 'begin': '\\(' + 'beginCaptures': + '0': + 'name': 'punctuation.definition.function.begin.bracket.round.css' + 'end': '\\)' + 'endCaptures': + '0': + 'name': 'punctuation.definition.function.end.bracket.round.css' + 'patterns': [ + { + 'include': '#arithmetic-operators' + } + { + 'include': '#property-values' + }, + { + 'include': '#function-nesting' + } + ] 'functional-pseudo-classes': 'patterns': [ { From 03279adc9a6c6820f44d333d6b079cf309e66ca1 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Sun, 1 Jun 2025 12:03:23 +0700 Subject: [PATCH 19/25] Include `#rule-list-innards` in at-rules --- grammars/css.cson | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index 506a89c..d26e7d1 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -217,6 +217,9 @@ 'name': 'punctuation.section.media.end.bracket.curly.css' 'name': 'meta.at-rule.media.body.css' 'patterns': [ + { + 'include': '#rule-list-innards' + } { 'include': '$self' } @@ -635,6 +638,9 @@ 'name': 'punctuation.section.end.bracket.curly.css' 'name': 'meta.at-rule.body.css' 'patterns': [ + { + 'include': '#rule-list-innards' + } { 'include': '$self' } From 8ef10621cdc2e6f6bdd340d4e9bb6a48868f18ba Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Sun, 1 Jun 2025 12:04:48 +0700 Subject: [PATCH 20/25] Replace spelling of "colour" with "color" for naming consistency --- grammars/css.cson | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index d26e7d1..f9b2bec 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -652,12 +652,12 @@ 'color-keywords': 'patterns': [ { - # CSS 2.1 colours: http://www.w3.org/TR/CSS21/syndata.html#value-def-color + # CSS 2.1 colors: http://www.w3.org/TR/CSS21/syndata.html#value-def-color 'match': '(?i)(? Date: Sun, 1 Jun 2025 12:06:18 +0700 Subject: [PATCH 21/25] Include `#functions` in `media-query` for functions such as `calc()` --- grammars/css.cson | 3 +++ 1 file changed, 3 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index f9b2bec..24d0901 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -1386,6 +1386,9 @@ { 'include': '#comment-block' } + { + 'include': '#functions' + } ] } ] From c6950f07086a9986c1e777b79f90515ca3d95ec9 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Sun, 1 Jun 2025 12:07:49 +0700 Subject: [PATCH 22/25] Update `#selector` rules and include it in the `rule-list-innards` patterns --- grammars/css.cson | 76 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index 24d0901..3fdf0ce 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -1749,6 +1749,9 @@ ''' 'name': 'variable.css' } + { + 'include': '#selector' + } { 'begin': '(?~+] # Selector combinator + | \\| # Selector namespace separator + | \\[ # Attribute selector opening bracket + | [a-zA-Z] # Letter + | [^\\x00-\\x7F] # Non-ASCII symbols + | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence + + # Or one of the following symbols, followed by a word character, hyphen, or escape sequence: + | (?: + \\. # Class selector + | \\# # ID selector + ) + (?: + [\\w-] # Word character or hyphen + | \\\\(?: # Escape sequence + [0-9a-fA-F]{1,6} + | . + ) + ) + + # Or one of the following symbols, followed a letter or hyphen: + | (?: + \\: # Pseudo-class + | \\:\\: # Pseudo-element + ) + [a-zA-Z-] # Letter or hyphen + ) + ) + + # Match must NOT contain any of the following: + (?! + [\\w-]*[\\:]+\\s # One or more colons immediately followed by a whitespace (denotes a property or invalid sequence) + | [^{]*; # Any characters and a semicolon before an opening bracket (denotes the end of a property) + | [^{]*} # A closing bracket before an opening bracket (denotes a property) + | [^\\:]+(\\:\\:):+ # More than two colons (invalid sequence) + ) + ''' + 'end': '''(?x) + # Match must end with: (?= - (?:\\|)? # Possible anonymous namespace prefix + \\s* # Optional whitespace and one of the following: (?: - [-\\[:.*\\#a-zA-Z_] # Valid selector character - | - [^\\x00-\\x7F] # Which can include non-ASCII symbols - | - \\\\ # Or an escape sequence - (?:[0-9a-fA-F]{1,6}|.) + \\/ # Comment + | @ # At-rule + | { # Opening property list brace + | \\) # Closing function brace (for passing test on `some-edgy-new-function(`) + | $ # End of line ) ) - ''' - 'end': '(?=\\s*[/@{)])' + ''' 'name': 'meta.selector.css' 'patterns': [ { From 48d2f20338efef10ae87ff769918d495e2cb6aa6 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Sun, 1 Jun 2025 12:09:14 +0700 Subject: [PATCH 23/25] Add `#combinator-invalid` scope to work with new `#selector` rules --- grammars/css.cson | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index 3fdf0ce..c27f1e7 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -23,7 +23,7 @@ 'include': '#escapes' } { - 'include': '#combinators' + 'include': '#combinator-invalid' } { 'include': '#selector' @@ -698,14 +698,16 @@ 'combinators': 'patterns': [ { - 'match': '/deep/|>>>' - 'name': 'invalid.deprecated.combinator.css' + 'include': '#combinator-invalid' } { 'match': '>>|>|\\+|~' 'name': 'keyword.operator.combinator.css' } ] + 'combinator-invalid': + 'match': '/deep/|>>>' + 'name': 'invalid.deprecated.combinator.css' 'commas': 'match': ',' 'name': 'punctuation.separator.list.comma.css' From f4609732ecf25f2c8c3b1be73ed4fcfc3cb5ce33 Mon Sep 17 00:00:00 2001 From: Jacob Cassidy Date: Sun, 1 Jun 2025 12:11:09 +0700 Subject: [PATCH 24/25] Update scopes for property-names --- grammars/css.cson | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/grammars/css.cson b/grammars/css.cson index c27f1e7..b11e30a 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -1621,11 +1621,11 @@ ) (?![\\w-]) ''' - 'name': 'support.type.property-name.css' + 'name': 'meta.property-name.css support.type.property-name.css' } { 'match': '(? Date: Sun, 1 Jun 2025 12:12:19 +0700 Subject: [PATCH 25/25] Add `#shared-names` for selector and property names --- grammars/css.cson | 132 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/grammars/css.cson b/grammars/css.cson index b11e30a..8e06d41 100644 --- a/grammars/css.cson +++ b/grammars/css.cson @@ -1751,6 +1751,9 @@ ''' 'name': 'variable.css' } + { + 'include': '#shared-names' + } { 'include': '#property-names' } @@ -2112,6 +2115,135 @@ 'name': 'entity.name.tag.custom.css' } ] + 'shared-names': + # Shared names are keywords that are listed in both selector and property name contexts. + 'patterns': [ + # The following are considered selectors by default: + { + 'begin': '''(?xi) + # Selector match must be preceded by one of the following: + (?<= + ^ # Start of line + | (^|[^\\:])\\s # Whitespace, after the start of a line or any character except a colon + | [{}] # Opening or closing brace (condensed property list syntax) + | \\*/ # Comment end + | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence + ) + + (?= + # Selector must match: + (?: + # HTML elements + header|image|label|marquee|mask|nav|ruby|shadow|span|style + # SVG elements + |color-profile|line|text + ) + + # Selector must NOT be followed by any any of the following: + (?! + .*; # Any characters followed by a semicolon (denotes a property) + | [^{]*} # Any characters, except an opening brace, followed by a closing bracket (denotes a property) + | - # A dash (denotes a property name) + | \\:\\s+ # A colon followed by whitespace (denotes a property name) + ) + ) + ''' + 'end': '''(?xi) + # Selector match ends with one of the following: + (?= + \\s # Whitespace + | \\/\\* # Comment + | , # Comma + | { # Opening property list brace + | $ # End of line + ) + ''' + 'patterns': [ + { + 'include': '#selector' + } + ] + } + # The following are considered property names by default when attached to a colon: + { + 'begin': '''(?xi) + # Selector match must be preceded by one of the following: + (?<= + ^ # Start of line + | (^|[^\\:])\\s # Whitespace, after the start of a line or any character except a colon + | [{}] # Opening or closing brace (condensed property list syntax) + | \\*/ # Comment end + | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence + ) + + (?= + # Selector must match: + (?: + # HTML elements + content|font|mark + # SVG elements + |cursor|filter + ) + + # Selector must NOT be followed by any any of the following: + (?! + .*; # Any characters followed by a semicolon (denotes a property) + | [^{]*} # Any characters, except an opening brace, followed by a closing bracket (denotes a property) + | - # A dash (denotes a property name) + | \\: # A colon, unless it's with one of the following: + (?! + # A opening bracket before an closing bracket + [^}]*{ + # A pseudo-class selectors + | active|any-link|checked|disabled|empty|enabled|first + | (?:first|last|only)-(?:child|of-type)|focus|focus-visible|focus-within|fullscreen|host|hover + | in-range|indeterminate|invalid|link|out-of-range + | read-only|read-write|required|root|scope|target|unresolved + | valid|visited + + # A functional pseudo-class selectors + | (?: dir|lang + | not|has|matches|where|is + | nth-(?:last-)?(?:child|of-type) + )\\( + + # A single-colon pseudo-element selectors + | after + | before + | first-letter + | first-line + | (?: + \\- + (?: + ah|apple|atsc|epub|hp|khtml|moz + | ms|o|rim|ro|tc|wap|webkit|xv + ) + | (?: + mso|prince + ) + ) + -[a-z-]+ + ) + ) + ) + ''' + 'end': '''(?xi) + # Selector match ends with one of the following: + (?= + \\s # Whitespace + | \\/\\* # Comment + | , # Comma + | { # Opening property list brace + | $ # End of line + ) + ''' + 'patterns': [ + { + 'include': '#selector' + } + ] + } + ] 'string': 'patterns': [ {