1082 lines
33 KiB
XML
1082 lines
33 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
|
|
This file is part of GtkSourceView
|
|
|
|
Author: Jeffery To <jeffery.to@gmail.com>
|
|
Copyright (C) 2018-2020 Jeffery To <jeffery.to@gmail.com>
|
|
|
|
GtkSourceView is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
GtkSourceView is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
-->
|
|
<language id="scss" name="SCSS" version="2.0" _section="Other">
|
|
<metadata>
|
|
<property name="mimetypes">text/x-scss</property>
|
|
<property name="globs">*.scss</property>
|
|
<property name="line-comment-start">//</property>
|
|
<property name="block-comment-start">/*</property>
|
|
<property name="block-comment-end">*/</property>
|
|
</metadata>
|
|
|
|
<styles>
|
|
|
|
<!-- interpolations -->
|
|
<style id="interpolation" name="Interpolation" map-to="def:preprocessor"/>
|
|
|
|
<!-- variables -->
|
|
<style id="variable" name="Variable" map-to="def:identifier"/>
|
|
|
|
<!-- operators -->
|
|
<style id="operator-symbol" name="Operator Symbol" map-to="css:symbol"/>
|
|
<style id="logical-operator" name="Logical Operator" map-to="def:preprocessor"/>
|
|
|
|
<!-- Sass data types -->
|
|
<style id="boolean" name="Boolean Value" map-to="def:boolean"/>
|
|
<style id="null" name="Null Value" map-to="def:special-constant"/>
|
|
<style id="list-delimiter" name="List Delimiter" map-to="css:delimiter"/>
|
|
<style id="group-delimiter" name="Group Delimiter" map-to="css:delimiter"/>
|
|
|
|
<!-- Sass selectors -->
|
|
<style id="placeholder-selector" name="Placeholder Selector" map-to="def:identifier"/>
|
|
<style id="selector-fragment" name="Selector Fragment"/>
|
|
|
|
<!-- Sass at-rules -->
|
|
<style id="mixin-name" name="Mixin Name" map-to="def:keyword"/>
|
|
|
|
</styles>
|
|
|
|
<default-regex-options case-sensitive="false"/>
|
|
|
|
<!-- from css:keyword-code-point -->
|
|
<keyword-char-class>[^\x{0}-\x{2C}\x{2E}\x{2F}\x{3A}-\x{40}\x{5B}\x{5D}\x{5E}\x{60}\x{7B}-\x{7F}]</keyword-char-class>
|
|
|
|
<definitions>
|
|
|
|
<!-- global -->
|
|
|
|
<context id="embedded-lang-hook"/>
|
|
|
|
<context id="scss-embedded-lang-hook">
|
|
<include>
|
|
<context ref="embedded-lang-hook"/>
|
|
<context ref="css:embedded-lang-hook" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-multiline-comment" style-ref="css:comment" class-disabled="no-spell-check" class="comment">
|
|
<start>/\*</start>
|
|
<end>\*/</end>
|
|
<include>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="interpolation"/>
|
|
<context ref="def:in-comment"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="single-line-comment" style-ref="css:comment" end-at-line-end="true" class-disabled="no-spell-check" class="comment">
|
|
<start>//</start>
|
|
<include>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<!-- line continuations not allowed -->
|
|
<context ref="def:in-comment"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-comment">
|
|
<include>
|
|
<context ref="single-line-comment"/>
|
|
<context ref="css:comment" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:embedded-lang-hook" ref="scss-embedded-lang-hook"/>
|
|
<replace id="css:multiline-comment" ref="scss-multiline-comment"/>
|
|
<replace id="css:comment" ref="scss-comment"/>
|
|
|
|
|
|
<!-- interpolations -->
|
|
|
|
<context id="interpolation">
|
|
<start>#{</start>
|
|
<end>}</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="interpolation"/>
|
|
<context sub-pattern="0" where="end" style-ref="interpolation"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:any-value"/>
|
|
</include>
|
|
</context>
|
|
|
|
|
|
<!-- variables -->
|
|
|
|
<context id="variable" style-ref="variable">
|
|
<match>\$\%{css:identifier}</match>
|
|
</context>
|
|
|
|
|
|
<!-- operators -->
|
|
|
|
<!-- leave out the division operator (/)
|
|
as we cannot reliably distinguish between a literal slash and
|
|
a division operation -->
|
|
<context id="arithmetic-operator" style-ref="operator-symbol">
|
|
<match extended="true">
|
|
[+*%] |
|
|
(?<! \%{css:keyword-code-point} )
|
|
-
|
|
(?! \%{css:keyword-code-point} )
|
|
</match>
|
|
</context>
|
|
|
|
<context id="string-operator" style-ref="operator-symbol">
|
|
<match>\+</match>
|
|
</context>
|
|
|
|
<context id="comparison-operator" style-ref="operator-symbol">
|
|
<match><=?|>=?|[=!]=</match>
|
|
</context>
|
|
|
|
<context id="logical-operator" style-ref="logical-operator">
|
|
<prefix>\%{css:keyword-start}</prefix>
|
|
<suffix>\%{css:keyword-end}</suffix>
|
|
<keyword>and</keyword>
|
|
<keyword>not</keyword>
|
|
<keyword>or</keyword>
|
|
</context>
|
|
|
|
|
|
<!-- Sass data types -->
|
|
|
|
<context id="boolean" style-ref="boolean">
|
|
<prefix>\%{css:keyword-start}</prefix>
|
|
<suffix>\%{css:keyword-end}</suffix>
|
|
<keyword>false</keyword>
|
|
<keyword>true</keyword>
|
|
</context>
|
|
|
|
<context id="null" style-ref="null">
|
|
<prefix>\%{css:keyword-start}</prefix>
|
|
<suffix>\%{css:keyword-end}</suffix>
|
|
<keyword>null</keyword>
|
|
</context>
|
|
|
|
<context id="parent-selector-list" style-ref="css:combinator">
|
|
<match>&</match>
|
|
</context>
|
|
|
|
<context id="bracketed-list">
|
|
<start>\[</start>
|
|
<end>]</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="list-delimiter"/>
|
|
<context sub-pattern="0" where="end" style-ref="list-delimiter"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:any-value"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!-- not sure why one would use a string group but it appears to be syntactically valid -->
|
|
<context id="string-group">
|
|
<start>\(</start>
|
|
<end>\)</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="group-delimiter"/>
|
|
<context sub-pattern="0" where="end" style-ref="group-delimiter"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:string-value"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="data-group">
|
|
<start>\(</start>
|
|
<end>\)</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="group-delimiter"/>
|
|
<context sub-pattern="0" where="end" style-ref="group-delimiter"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:data-value"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
this could be a list, a map, or an order of operations grouping
|
|
not sure how to differentiate between these
|
|
-->
|
|
<context id="any-group">
|
|
<start>\(</start>
|
|
<end>\)</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="group-delimiter"/>
|
|
<context sub-pattern="0" where="end" style-ref="group-delimiter"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:any-value"/>
|
|
<context ref="css:colon"/> <!-- for maps -->
|
|
</include>
|
|
</context>
|
|
|
|
|
|
<!-- data types -->
|
|
|
|
<context id="scss-string-content">
|
|
<include>
|
|
<context ref="interpolation"/>
|
|
<context ref="css:string-content" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:string-content" ref="scss-string-content"/>
|
|
|
|
|
|
<!-- functions -->
|
|
|
|
<context id="variable-arguments" style-ref="operator-symbol">
|
|
<match>\.\.\.</match>
|
|
</context>
|
|
|
|
<context id="scss-url">
|
|
<start extended="true">
|
|
\%{css:keyword-start} url \(
|
|
</start>
|
|
<end>\)</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:function"/>
|
|
<context sub-pattern="0" where="end" style-ref="css:function"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<!-- only accept multi-line comments because // is part of urls -->
|
|
<context ref="css:comment" original="true"/>
|
|
<context ref="interpolation"/>
|
|
<context ref="css:escape" ignore-style="true"/>
|
|
<context ref="css:string-value"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-function-content">
|
|
<include>
|
|
<context ref="css:function-content" original="true"/>
|
|
<context ref="variable-arguments"/>
|
|
<context ref="css:colon"/> <!-- for named arguments -->
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:url" ref="scss-url"/>
|
|
<replace id="css:function-content" ref="scss-function-content"/>
|
|
|
|
|
|
<!-- data values -->
|
|
|
|
<context id="scss-name-value">
|
|
<include>
|
|
<context ref="css:function-call"/>
|
|
<context ref="interpolation"/> <!-- outputs unquoted strings -->
|
|
<context ref="variable"/>
|
|
<context ref="css:name-value" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-string-value">
|
|
<include>
|
|
<context ref="css:function-call"/>
|
|
<context ref="string-group"/>
|
|
<context ref="variable"/>
|
|
<context ref="css:string-value" original="true"/>
|
|
<context ref="string-operator"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-data-value">
|
|
<include>
|
|
<context ref="css:function-call"/>
|
|
<context ref="data-group"/>
|
|
<context ref="interpolation"/>
|
|
<context ref="variable"/>
|
|
<context ref="css:string-value" original="true"/>
|
|
<context ref="css:color-value"/>
|
|
<context ref="css:number-value"/>
|
|
<context ref="css:unicode-range"/>
|
|
<context ref="arithmetic-operator"/>
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:name-value" ref="scss-name-value"/>
|
|
<replace id="css:string-value" ref="scss-string-value"/>
|
|
<replace id="css:data-value" ref="scss-data-value"/>
|
|
|
|
|
|
<!-- any assignable value -->
|
|
|
|
<context id="scss-any-value">
|
|
<include>
|
|
<context ref="css:function-call"/>
|
|
<context ref="any-group"/>
|
|
<context ref="parent-selector-list"/>
|
|
<context ref="bracketed-list"/>
|
|
<context ref="interpolation"/>
|
|
<context ref="variable"/>
|
|
<context ref="boolean"/>
|
|
<context ref="null"/>
|
|
<context ref="css:property-value-keyword"/>
|
|
<context ref="css:string-value" original="true"/>
|
|
<context ref="css:color-value"/>
|
|
<context ref="css:number-value"/>
|
|
<context ref="css:unicode-range"/>
|
|
<context ref="logical-operator"/>
|
|
<context ref="comparison-operator"/>
|
|
<context ref="arithmetic-operator"/>
|
|
<context ref="css:name-value" original="true"/>
|
|
<context ref="css:slash"/>
|
|
<context ref="css:comma"/>
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:any-value" ref="scss-any-value"/>
|
|
|
|
|
|
<!-- Sass modifiers -->
|
|
|
|
<context id="variable-assignment-modifiers" style-ref="css:modifier">
|
|
<prefix>\%{css:keyword-start}</prefix>
|
|
<suffix>\%{css:keyword-end}</suffix>
|
|
<keyword>default</keyword>
|
|
<keyword>global</keyword>
|
|
</context>
|
|
|
|
<context id="at-extend-modifiers" style-ref="css:modifier">
|
|
<prefix>\%{css:keyword-start}</prefix>
|
|
<suffix>\%{css:keyword-end}</suffix>
|
|
<keyword>optional</keyword>
|
|
</context>
|
|
|
|
|
|
<!-- modifiers -->
|
|
|
|
<context id="scss-modifier-content">
|
|
<include>
|
|
<context ref="variable-assignment-modifiers"/>
|
|
<context ref="at-extend-modifiers"/>
|
|
<context ref="css:modifier-content" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:modifier-content" ref="scss-modifier-content"/>
|
|
|
|
|
|
<!-- style properties -->
|
|
|
|
<context id="scss-property-name">
|
|
<include>
|
|
<context ref="interpolation"/>
|
|
<context ref="css:property-name" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:property-name" ref="scss-property-name"/>
|
|
|
|
|
|
<!-- style block -->
|
|
|
|
<context id="nested-properties" end-parent="true">
|
|
<start>{</start>
|
|
<end>}</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:block-delimiter"/>
|
|
<context sub-pattern="0" where="end" style-ref="css:block-delimiter"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:declaration"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-declaration-property">
|
|
<include>
|
|
<context ref="variable"/> <!-- variable assignment -->
|
|
<context ref="css:declaration-property" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-declaration-value-content">
|
|
<include>
|
|
<context ref="nested-properties"/>
|
|
<context ref="css:declaration-value-content" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-declaration-value">
|
|
<start extended="true">
|
|
(?(DEFINE)
|
|
(?<escape_interpolation_start> (?: \\ \#{ )+ )
|
|
(?<escape_comment_start> (?: \\ /[/*] )+ )
|
|
(?<escape> (?: \\ . )+ )
|
|
|
|
(?<interpolation_start_chars>
|
|
(?: (?: \# (?! { ) )+ | (?: (?<! \# ) { )+ )
|
|
)
|
|
(?<comment_start_chars>
|
|
(?: (?: (?<! / ) / (?! [/*] ) )+ | (?: (?<! / ) \* )+ )
|
|
)
|
|
(?<comment_end_chars>
|
|
(?: (?: \* (?! / ) )+ | (?: (?<! \* ) / )+ )
|
|
)
|
|
|
|
(?<single_line_comment> // .* )
|
|
|
|
(?<interpolation> # recursive subpattern to find matching braces
|
|
\#{
|
|
(?:
|
|
(?>
|
|
(?:
|
|
[^\\}#{(/*"']+ |
|
|
(?&escape_interpolation_start) |
|
|
(?&escape_comment_start) |
|
|
(?&escape) |
|
|
(?&interpolation_start_chars) |
|
|
(?&comment_start_chars)
|
|
)+
|
|
) |
|
|
(?&interpolation) |
|
|
(?&parentheses) |
|
|
(?&single_line_comment) |
|
|
(?&multiline_comment) |
|
|
(?&double_quote_string) |
|
|
(?&single_quote_string)
|
|
)*
|
|
}
|
|
)
|
|
|
|
(?<parentheses> # recursive subpattern to find matching parentheses
|
|
\(
|
|
(?:
|
|
(?>
|
|
(?:
|
|
[^\\)(#{/*"']+ |
|
|
(?&escape_interpolation_start) |
|
|
(?&escape_comment_start) |
|
|
(?&escape) |
|
|
(?&interpolation_start_chars) |
|
|
(?&comment_start_chars)
|
|
)+
|
|
) |
|
|
(?&interpolation) |
|
|
(?&parentheses) |
|
|
(?&single_line_comment) |
|
|
(?&multiline_comment) |
|
|
(?&double_quote_string) |
|
|
(?&single_quote_string)
|
|
)*
|
|
\)
|
|
)
|
|
|
|
(?<multiline_comment> # subpattern to find matching comment delimiters
|
|
/\*
|
|
(?:
|
|
(?>
|
|
(?:
|
|
[^*/#{]+ |
|
|
# no escapes
|
|
(?&comment_end_chars) |
|
|
(?&interpolation_start_chars)
|
|
)+
|
|
) |
|
|
(?&interpolation)
|
|
)*
|
|
\*/
|
|
)
|
|
|
|
(?<double_quote_string> # subpattern to find matching double quotes
|
|
"
|
|
(?:
|
|
(?>
|
|
(?:
|
|
[^\\"#{]+ |
|
|
(?&escape_interpolation_start) |
|
|
(?&escape) |
|
|
(?&interpolation_start_chars)
|
|
)+
|
|
) |
|
|
(?&interpolation)
|
|
)*
|
|
"
|
|
)
|
|
|
|
(?<single_quote_string> # subpattern to find matching single quotes
|
|
'
|
|
(?:
|
|
(?>
|
|
(?:
|
|
[^\\'#{]+ |
|
|
(?&escape_interpolation_start) |
|
|
(?&escape) |
|
|
(?&interpolation_start_chars)
|
|
)+
|
|
) |
|
|
(?&interpolation)
|
|
)*
|
|
'
|
|
)
|
|
)
|
|
|
|
:
|
|
(?:
|
|
(?! # not the start of a
|
|
\%{css:keyword-code-point} | # pseudo-class
|
|
[:\\] | # pseudo-element, escape
|
|
\#{ | # interpolation
|
|
/\* # comment
|
|
) | # or
|
|
(?= # ends like a normal declaration
|
|
(?>
|
|
(?:
|
|
(?>
|
|
(?:
|
|
[^\\;}{#(/*"']+ |
|
|
(?&escape_interpolation_start) |
|
|
(?&escape_comment_start) |
|
|
(?&escape) |
|
|
(?: \# (?! { ) )+ | # interpolation_start_chars allows {
|
|
(?&comment_start_chars)
|
|
)+
|
|
) |
|
|
(?&interpolation) |
|
|
(?&parentheses) |
|
|
(?&single_line_comment) |
|
|
(?&multiline_comment) |
|
|
(?&double_quote_string) |
|
|
(?&single_quote_string)
|
|
)*
|
|
)
|
|
\%{css:declaration-value-end} # with a semicolon or at the end of a block
|
|
)
|
|
)
|
|
</start>
|
|
<end>\%{css:declaration-value-end}</end> <!-- nested-properties has end-parent="true" -->
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:delimiter"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:declaration-value-content"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-style-block-content">
|
|
<include>
|
|
<context ref="css:style-block-content" original="true"/>
|
|
<context ref="css:at-rule"/>
|
|
<context ref="css:selector"/>
|
|
<context ref="css:style-block"/>
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:declaration-property" ref="scss-declaration-property"/>
|
|
<replace id="css:declaration-value-content" ref="scss-declaration-value-content"/>
|
|
<replace id="css:declaration-value" ref="scss-declaration-value"/>
|
|
<replace id="css:style-block-content" ref="scss-style-block-content"/>
|
|
|
|
|
|
<!-- media queries -->
|
|
|
|
<context id="scss-media-type-value">
|
|
<include>
|
|
<context ref="interpolation"/>
|
|
<context ref="css:media-type-value" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-media-feature-test-name">
|
|
<include>
|
|
<context ref="interpolation"/>
|
|
<context ref="variable"/>
|
|
<context ref="css:media-feature-test-name" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-media-feature-test-value-content">
|
|
<include>
|
|
<context ref="interpolation"/>
|
|
<context ref="variable"/>
|
|
<context ref="css:media-feature-test-value-content" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:media-type-value" ref="scss-media-type-value"/>
|
|
<replace id="css:media-feature-test-name" ref="scss-media-feature-test-name"/>
|
|
<replace id="css:media-feature-test-value-content" ref="scss-media-feature-test-value-content"/>
|
|
|
|
|
|
<!-- Sass at-rules -->
|
|
|
|
<!--
|
|
@extend <selector> <optional modifier>?;
|
|
-->
|
|
|
|
<context id="at-extend">
|
|
<start extended="true">
|
|
@extend \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:selector"/>
|
|
<context ref="css:modifier"/>
|
|
<context ref="css:at-rule-delimiter"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@at-root (<selector>|<query>)? <css-block>
|
|
-->
|
|
|
|
<context id="at-at-root-query-type" style-ref="css:property-name">
|
|
<prefix>\%{css:keyword-start}</prefix>
|
|
<suffix>\%{css:keyword-end}</suffix>
|
|
<keyword>without</keyword>
|
|
<keyword>with</keyword>
|
|
</context>
|
|
|
|
<context id="at-at-root-query-directive" style-ref="css:keyword">
|
|
<prefix>\%{css:keyword-start}</prefix>
|
|
<suffix>\%{css:keyword-end}</suffix>
|
|
<keyword>all</keyword>
|
|
<keyword>media</keyword>
|
|
<keyword>rule</keyword>
|
|
<keyword>supports</keyword>
|
|
</context>
|
|
|
|
<context id="at-at-root-query-value">
|
|
<start>:</start>
|
|
<end>\%{css:test-value-end}</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:delimiter"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="interpolation"/>
|
|
<context ref="variable"/>
|
|
<context ref="at-at-root-query-directive"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="at-at-root-query">
|
|
<start>\(</start>
|
|
<end>\)</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:test-delimiter"/>
|
|
<context sub-pattern="0" where="end" style-ref="css:test-delimiter"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="interpolation"/>
|
|
<context ref="variable"/>
|
|
<context ref="at-at-root-query-type"/>
|
|
<context ref="at-at-root-query-value"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="at-at-root">
|
|
<start extended="true">
|
|
@at-root \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:selector"/>
|
|
<context ref="at-at-root-query"/>
|
|
<context ref="css:at-rule-css-block"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@debug <any-value>;
|
|
@warn <any-value>;
|
|
@error <any-value>;
|
|
-->
|
|
|
|
<context id="at-debug-warn-error">
|
|
<start extended="true">
|
|
@ (?: debug | warn | error ) \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:any-value"/>
|
|
<context ref="css:at-rule-delimiter"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@if <any-value> <css-block>
|
|
@else if <any-value> <css-block>
|
|
@else <css-block>
|
|
-->
|
|
|
|
<context id="at-if-else-if">
|
|
<start extended="true">
|
|
@ (?: if | else \s+ if ) \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:any-value"/>
|
|
<context ref="css:at-rule-css-block"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="at-else">
|
|
<start extended="true">
|
|
@else \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:at-rule-css-block"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@for <variable> from <any-value> (through|to) <any-value> <css-block>
|
|
-->
|
|
|
|
<context id="at-for-keyword" style-ref="css:at-rule-operator">
|
|
<prefix>\%{css:keyword-start}</prefix>
|
|
<suffix>\%{css:keyword-end}</suffix>
|
|
<keyword>from</keyword>
|
|
<keyword>through</keyword>
|
|
<keyword>to</keyword>
|
|
</context>
|
|
|
|
<context id="at-for">
|
|
<start extended="true">
|
|
@for \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="at-for-keyword"/>
|
|
<context ref="variable"/>
|
|
<context ref="css:any-value"/>
|
|
<context ref="css:at-rule-css-block"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@each <variable> in <list> <css-block>
|
|
-->
|
|
|
|
<context id="at-each-keyword" style-ref="css:at-rule-operator">
|
|
<prefix>\%{css:keyword-start}</prefix>
|
|
<suffix>\%{css:keyword-end}</suffix>
|
|
<keyword>in</keyword>
|
|
</context>
|
|
|
|
<context id="at-each">
|
|
<start extended="true">
|
|
@each \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="at-each-keyword"/>
|
|
<context ref="variable"/>
|
|
<context ref="css:any-value"/>
|
|
<context ref="css:comma"/>
|
|
<context ref="css:at-rule-css-block"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@while <expression> <css-block>
|
|
-->
|
|
|
|
<context id="at-while">
|
|
<start extended="true">
|
|
@while \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:any-value"/>
|
|
<context ref="css:at-rule-css-block"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@mixin <mixin name> <mixin-parameters>? <css-block>
|
|
-->
|
|
|
|
<context id="mixin-parameters">
|
|
<start>\(</start>
|
|
<end>\)</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="mixin-name"/>
|
|
<context sub-pattern="0" where="end" style-ref="mixin-name"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:function-content"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="at-mixin">
|
|
<start extended="true">
|
|
@mixin \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:name" style-ref="mixin-name"/>
|
|
<context ref="mixin-parameters"/>
|
|
<context ref="css:at-rule-css-block"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@include <mixin name> <mixin-parameters>? (;|<css-block>)
|
|
-->
|
|
|
|
<context id="at-include">
|
|
<start extended="true">
|
|
@include \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:name" style-ref="mixin-name"/>
|
|
<context ref="mixin-parameters"/>
|
|
<context ref="css:at-rule-delimiter"/>
|
|
<context ref="css:at-rule-css-block"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@content;
|
|
-->
|
|
|
|
<context id="at-content">
|
|
<start extended="true">
|
|
@content \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:at-rule-delimiter"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@function <function name> <function-parameters> <css-block>
|
|
-->
|
|
|
|
<context id="function-parameters">
|
|
<start>\(</start>
|
|
<end>\)</end>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:function"/>
|
|
<context sub-pattern="0" where="end" style-ref="css:function"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:function-content"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="at-function">
|
|
<start extended="true">
|
|
@function \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<!-- we define it this way because there can be whitespace
|
|
between the function name and the parentheses -->
|
|
<context ref="css:name" style-ref="css:function"/>
|
|
<context ref="function-parameters"/>
|
|
<context ref="css:at-rule-css-block"/>
|
|
</include>
|
|
</context>
|
|
|
|
<!--
|
|
@return <any-value>;
|
|
-->
|
|
|
|
<context id="at-return">
|
|
<start extended="true">
|
|
@return \%{css:keyword-end}
|
|
</start>
|
|
<include>
|
|
<context sub-pattern="0" where="start" style-ref="css:at-rule"/>
|
|
<context ref="css:embedded-lang-hook"/>
|
|
<context ref="css:comment"/>
|
|
<context ref="css:any-value"/>
|
|
<context ref="css:at-rule-delimiter"/>
|
|
</include>
|
|
</context>
|
|
|
|
|
|
<!-- at-rules -->
|
|
|
|
<context id="scss-font-feature-value-declaration-value-content">
|
|
<include>
|
|
<context ref="interpolation"/>
|
|
<context ref="variable"/>
|
|
<context ref="css:font-feature-value-declaration-value-content" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-keyframe-selector-value">
|
|
<include>
|
|
<context ref="interpolation"/>
|
|
<context ref="css:keyframe-selector-value" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-namespace-value">
|
|
<include>
|
|
<context ref="interpolation"/>
|
|
<context ref="css:namespace-value" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-at-rule">
|
|
<include>
|
|
|
|
<context ref="at-extend"/>
|
|
<context ref="at-at-root"/>
|
|
|
|
<context ref="at-debug-warn-error"/>
|
|
|
|
<context ref="at-if-else-if"/>
|
|
<context ref="at-else"/>
|
|
|
|
<context ref="at-for"/>
|
|
<context ref="at-each"/>
|
|
<context ref="at-while"/>
|
|
|
|
<context ref="at-mixin"/>
|
|
<context ref="at-include"/>
|
|
<context ref="at-content"/>
|
|
|
|
<context ref="at-function"/>
|
|
<context ref="at-return"/>
|
|
|
|
<context ref="css:at-rule" original="true"/>
|
|
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:at-rule-style-block-content" ref="scss-style-block-content"/>
|
|
<replace id="css:at-rule-css-block-content" ref="scss-style-block-content"/>
|
|
<replace id="css:font-feature-value-declaration-value-content" ref="scss-font-feature-value-declaration-value-content"/>
|
|
<replace id="css:keyframe-selector-value" ref="scss-keyframe-selector-value"/>
|
|
<replace id="css:namespace-value" ref="scss-namespace-value"/>
|
|
<replace id="css:at-rule" ref="scss-at-rule"/>
|
|
|
|
|
|
<!-- Sass selectors -->
|
|
|
|
<context id="parent-combinator">
|
|
<match>(&)(\%{css:identifier-chars}?)</match>
|
|
<include>
|
|
<context sub-pattern="1" style-ref="css:combinator"/>
|
|
<context sub-pattern="2" style-ref="selector-fragment"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="placeholder-selector" style-ref="placeholder-selector">
|
|
<match>%\%{css:identifier}</match>
|
|
</context>
|
|
|
|
<context id="interpolation-fragment" style-ref="selector-fragment">
|
|
<match>(?<=})\%{css:identifier-chars}</match>
|
|
</context>
|
|
|
|
|
|
<!-- selectors -->
|
|
|
|
<context id="scss-simple-selector">
|
|
<include>
|
|
<context ref="interpolation"/> <!-- include in simple selector to be included in :not() -->
|
|
<context ref="interpolation-fragment"/>
|
|
<context ref="css:simple-selector" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-combinator">
|
|
<include>
|
|
<context ref="parent-combinator"/>
|
|
<context ref="css:combinator" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-nth-pseudo-class-content">
|
|
<include>
|
|
<context ref="interpolation"/>
|
|
<context ref="css:nth-pseudo-class-content" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="scss-selector">
|
|
<include>
|
|
<context ref="placeholder-selector"/>
|
|
<context ref="css:selector" original="true"/>
|
|
</include>
|
|
</context>
|
|
|
|
<replace id="css:simple-selector" ref="scss-simple-selector"/>
|
|
<replace id="css:combinator" ref="scss-combinator"/>
|
|
<replace id="css:nth-pseudo-class-content" ref="scss-nth-pseudo-class-content"/>
|
|
<replace id="css:selector" ref="scss-selector"/>
|
|
|
|
|
|
<!-- top level declarations -->
|
|
|
|
<context id="top-level-declaration-property">
|
|
<include>
|
|
<context ref="variable"/>
|
|
</include>
|
|
</context>
|
|
|
|
<context id="top-level-declaration">
|
|
<include>
|
|
<context ref="top-level-declaration-property"/>
|
|
<context ref="css:declaration-value"/>
|
|
<context ref="css:modifier"/>
|
|
<context ref="css:semicolon"/>
|
|
</include>
|
|
</context>
|
|
|
|
|
|
<!-- main context -->
|
|
|
|
<context id="scss" class="no-spell-check">
|
|
<include>
|
|
<context ref="top-level-declaration"/>
|
|
<context ref="css:css"/>
|
|
</include>
|
|
</context>
|
|
|
|
</definitions>
|
|
</language>
|