commit 594ae653a3dcad9e8a6dc1ca56600531608af501 Author: Buddy Sandidge Date: Wed Feb 19 22:11:48 2014 -0800 Squashed 'vim/bundle/scss-syntax/' content from commit ea4d26944 git-subtree-dir: vim/bundle/scss-syntax git-subtree-split: ea4d26944b5f8c3aa2e24c9ba791097d099a6667 diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..5f811e6 --- /dev/null +++ b/Readme.md @@ -0,0 +1,20 @@ +# Vim Syntax File for SCSS (Sassy CSS) + +## Installation + +I recommend to use a plugin manager like [Vundle](https://github.com/gmarik/vundle) for the installation. + +### Vundle + +Open your `~/.vimrc` file and add the following line: + +``` +Bundle 'cakebaker/scss-syntax.vim' +``` + +Afterwards, run `:BundleInstall` in Vim. + +### Manual + +* [Download](https://github.com/cakebaker/scss-syntax.vim/archive/master.zip) the files +* Copy the content of the folders to the respective folders in `~/.vim/` diff --git a/autoload/scss_indent.vim b/autoload/scss_indent.vim new file mode 100644 index 0000000..2e57ab2 --- /dev/null +++ b/autoload/scss_indent.vim @@ -0,0 +1,37 @@ +" usage: +" set indentexpr=scss_indent#GetIndent(v:lnum) +fun! scss_indent#GetIndent(lnum) + " { -> increase indent + " } -> decrease indent + if a:lnum == 1 + " start at 0 indentation + return 0 + endif + + " try to find last line ending with { or } + " ignoring // comments + let regex = '\([{}]\)\%(\/\/.*\)\?$' + let nr = search(regex, 'bnW') + if nr > 0 + let last = indent(nr) + let m = matchlist(getline(nr), regex) + let m_curr = matchlist(getline(a:lnum), regex) + echoe string(m).string(m_curr) + if !empty(m_curr) && m_curr[1] == '}' && m[1] == '{' + " last was open, current is close, use same indent + return last + elseif !empty(m_curr) && m_curr[1] == '}' && m[1] == '}' + " } line and last line was }: decrease + return last - &sw + endif + if m[1] == '{' + " line after {: increase indent + return last + &sw + else + " line after } or { - same indent + return last + endif + else + return 0 + endif +endfun diff --git a/example.scss b/example.scss new file mode 100644 index 0000000..5b08ded --- /dev/null +++ b/example.scss @@ -0,0 +1,720 @@ +// Nested Rules + +#main p { + color: #00ff00; + width: 97%; + + #hello { + background-color: blue; + } + + .redbox { + background-color: #ff0000; + color: #000000; + } +} + +#main { + width: 97%; + + p, div { + font-size: 2em; + a { font-weight: bold; } + } + + pre { font-size: 3em; } +} + +// Referencing Parent Selectors: & + +a { + font-weight: bold; + text-decoration: none; + &:hover { text-decoration: underline; } + body.firefox & { font-weight: normal; } +} + +#main { + color: black; + a { + font-weight: bold; + &:hover { color: red; } + } +} + +// Nested Properties + +.funky { + font: { + family: fantasy; + size: 30em; + weight: bold; + } +} + +.funky { + font: 2px/3px { + family: fantasy; + size: 30em; + weight: bold; + } +} + +// Comments: /* */ and // + +/* This comment is + * several lines long. + * since it uses the CSS comment syntax, + * it will appear in the CSS output */ +body { color: black; } + +// These comments are only one line long each. +// They won't appear in the CSS output, +// since they use the single-line comment syntax. +a { color: green; } + +a { + color: green; // a comment after an assignment +} + +.foo { + color: green; // issue #3: a comment ending with {} +} + +// Variables: $ + +$width: 5em; // another comment + +#main { + width: $width; +} + +// Data Types: Strings + +@mixin firefox-message($selector) { + body.firefox #{$selector}:before { + content: "Hi, Firefox users!"; + } +} + +@include firefox-message(".header"); + +// Number Operations + +p { + width: 1in + 8pt; +} + +p { + font: 10px/8px; + $width: 1000px; + width: $width/2; + height: (500px/2); + margin-left: 5px + 8px/2px; +} + +p { + $font-size: 12px; + $line-height: 30px; + font: #{$font-size}/#{$line-height}; +} + +// Color Operations + +p { + color: #010203 + #040506; +} + +p { + color: #010203 * 2; +} + +p { + color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75); +} + +$translucent-red: rgba(255, 0, 0, 0.5); +p { + color: opacify($translucent-red, 0.3); + background-color: transparentize($translucent-red, 0.25); +} + +// String Operations + +p { + cursor: e + -resize; +} + +p:before { + content: "Foo " + Bar; + font-family: sans- + "serif"; +} + +p { + margin: 3px + 4px auto; +} + +p:before { + content: "I ate #{5 + 10} pies!"; +} + +$value: null; +p:before { + content: "I ate #{$value} pies!"; +} + +// Parentheses + +p { + width: 1em + (2em * 3); +} + +// Functions + +p { + color: hsl(0, 100%, 50%); +} + +// Keyword Arguments + +p { + color: hsl($hue: 0, $saturation: 100%, $lightness: 50%); +} + +// Interpolation: #{} + +$name: foo; +$attr: border; +p.#{$name} { + #{$attr}-color: blue; +} + +p { + $font-size: 12px; + $line-height: 30px; + font: #{$font-size}/#{$line-height}; +} + +// Variable Defaults: !default + +$content: "First content"; +$content: "Second content?" !default; +$new_content: "First time reference" !default; + +#main { + content: $content; + new-content: $new_content; +} + +$content: null; +$content: "Non-null content" !default; + +#main { + content: $content; +} + +// @import + +@import "foo.scss"; +@import "foo"; + +@import "foo.css"; +@import "foo" screen; +@import "http://foo.com/bar"; +@import url(foo); + +@import "rounded-corners", "text-shadow"; + +$family: unquote("Droid+Sans"); +@import url("http://fonts.googleapis.com/css?family=#{$family}"); + +// Partials + +@import "colors"; + +// Nested @import + +.example { + color: red; +} + +#main { + @import "example"; +} + +// @media + +.sidebar { + width: 300px; + @media screen and (orientation: landscape) { + width: 500px; + } +} + +@media screen { + .sidebar { + @media (orientation: landscape) { + width: 500px; + } + } +} + +$media: screen; +$feature: -webkit-min-device-pixel-ratio; +$value: 1.5; + +@media #{$media} and ($feature: $value) { + .sidebar { + width: 500px; + } +} + +// @extend + +.error { + border: 1px #f00; + background-color: #fdd; +} +.seriousError { + @extend .error; + border-width: 3px; +} + +.error { + border: 1px #f00; + background-color: #fdd; +} +.error.intrusion { + background-image: url("/image/hacked.png"); +} +.seriousError { + @extend .error; + border-width: 3px; +} + +// Extending Complex Selectors + +.hoverlink { + @extend a:hover; +} +a:hover { + text-decoration: underline; +} + +.hoverlink { + @extend a:hover; +} +.comment a.user:hover { + font-weight: bold; +} + +// Multiple Extends + +.error { + border: 1px #f00; + background-color: #fdd; +} +.attention { + font-size: 3em; + background-color: #ff0; +} +.seriousError { + @extend .error; + @extend .attention; + border-width: 3px; +} + +// Chaining Extends + +.error { + border: 1px #f00; + background-color: #fdd; +} +.seriousError { + @extend .error; + border-width: 3px; +} +.criticalError { + @extend .seriousError; + position: fixed; + top: 10%; + bottom: 10%; + left: 10%; + right: 10%; +} + +// Selector Sequences + +#fake-links .link { + @extend a; +} + +a { + color: blue; + &:hover { + text-decoration: underline; + } +} + +// Merging Selector Sequences + +#admin .tabbar a { + font-weight: bold; +} +#demo .overview .fakelink { + @extend a; +} + +#admin .tabbar a { + font-weight: bold; +} +#admin .overview .fakelink { + @extend a; +} + +// @extend-Only Selectors + +#context a%extreme { + color: blue; + font-weight: bold; + font-size: 2em; +} + +.notice { + @extend %extreme; +} + +// The !optional Flag + +a.important { + @extend .notice !optional; +} + +// @extend in Directives + +@media print { + .error { + border: 1px #f00; + background-color: #fdd; + } + .seriousError { + @extend .error; + border-width: 3px; + } +} + +// @debug + +@debug 10em + 12em; + +// @warn + +@mixin adjust-location($x, $y) { + @if unitless($x) { + @warn "Assuming #{$x} to be in pixels"; + $x: 1px * $x; + } + @if unitless($y) { + @warn "Assuming #{$y} to be in pixels"; + $y: 1px * $y; + } + position: relative; left: $x; top: $y; +} + +// @if + +p { + @if 1 + 1 == 2 { border: 1px solid; } + @if 5 < 3 { border: 2px dotted; } + @if null { border: 3px double; } +} + +$type: monster; +p { + @if $type == ocean { + color: blue; + } @else if $type == matador { + color: red; + } @else if $type == monster { + color: green; + } @else { + color: black; + } +} + +// @for + +@for $i from 1 through 3 { + .item-#{$1} { width: 2em * $i; } +} + +@for $i from 1 to 3 { + .item-#{$1} { width: 2em * $i; } +} + +// @each + +@each $animal in puma, sea-slug, egret, salamander { + .#{$animal}-icon { + background-image: url('/images/#{$animal}.png'); + } +} + +// @while + +$i: 6; +@while $1 > 0 { + .item-#{$i} { width: 2em * $i; } + $i: $1 - 2; +} + +// Defining a Mixin: @mixin + +@mixin large-text { + font: { + family: Arial; + size: 20px; + weight: bold; + } + color: #ff0000; +} + +@mixin clearfix { + display: inline-block; + &:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; + } + * html & { height: 1px } +} + +// Including a Mixin: @include + +.page-title { + @include large-text; + padding: 4px; + margin-top: 10px; +} + +@mixin silly-links { + a { + color: blue; + background-color: red; + } +} + +@include silly-links; + +@mixin compound { + @include highlighted-background; + @include header-text; +} + +@mixin highlighted-background { background-color: #fc0; } +@mixin header-text { font-size: 20px; } + +// Arguments + +@mixin sexy-border($color, $width) { + border: { + color: $color; + width: $width; + style: dashed; + } +} + +p { @include sexy-border(blue, 1in); } + +@mixin sexy-border($color, $width: 1in) { + border: { + color: $color; + width: $width; + style: dashed; + } +} +p { @include sexy-border(blue); } +h1 { @include sexy-border(blue, 2in); } + +// Keyword Arguments + +p { @include sexy-border($color: blue); } +h1 { @include sexy-border($color: blue, $width: 2in); } + +// Variable Arguments + +@mixin box-shadows($shadows...) { + -moz-box-shadow: $shadows; + -webkit-box-shadow: $shadows; + box-shadow: $shadows; +} + +.shadows { + @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999); +} + +@mixin colors($text, $background, $border) { + color: $text; + background-color: $background; + border-color: $border; +} + +$values: #ff0000, #00ff00, #0000ff; +.primary { + @include colors($values...); +} + +@mixin wrapped-stylish-mixin($args...) { + font-weight: bold; + @include stylish-mixin($args...); +} + +.stylish { + // The $width argument will get passed on to "stylish-mixin" as a keyword + @include wrapped-stylish-mixin(#00ff00, $width: 100px); +} + +// Passing Content Blocks to a Mixin + +@mixin apply-to-ie6-only { + * html { + @content; + } +} +@include apply-to-ie6-only { + #logo { + background-image: url(/logo.gif); + } +} + +// Variable Scope and Content Blocks + +$color: white; +@mixin colors($color: blue) { + background-color: $color; + @content; + border-color: $color; +} +.colors { + @include colors { color: $color; } +} + +#sidebar { + $sidebar-width: 300px; + width: $sidebar-width; + @include smartphone { + width: $sidebar-width / 3; + } +} + +// Function Directives + +$grid-width: 40px; +$gutter-width: 10px; + +@function grid-width($n) { + @return $n * $grid-width + ($n - 1) * $gutter-width; +} + +#sidebar { width: grid-width(5); } +#sidebar { width: grid-width($n: 5); } + +// TODO: todo should be highlighted, ticket #21 +/* TODO: same here */ + +@import url(http://fonts.googleapis.com/css?family=Vollkorn); // the // in the url shouldn't be highlighted as comment, ticket #24 + +// Styles which were not highlighted correctly in the past + +// Attribute selectors should get highlighted for parent references. +input { + &[type="text"] { } // <-- This should look the same as... +} +input[type="text"] { } // <-- this. + +$a: $b + $c; // issue #4: variables should be displayed with the same color + +@include text-shadow; // issue #23, @include content block + +@include breakpoint( $bp-default ) { + display: inline-block; +} + +.app-header { // issue #31, functions with hyphens not properly highlighted + @include linear-gradient(gray-with-lightness(0.94), #FFF 90%); + border-bottom: 1px solid gray-with-lightness(0.95); +} + +.breadcrumb:before { // issue #20, string escaping rendering incorrectly for "\\" + content: "\\"; +} + +@import "icons/*.png"; // issue #14, don't treat "/*" as the start of a comment + +.foo { // issue #5, lines without {} colored incorrectly + label.due input[type=text] + { + padding-right: 25px; + } +} + +.funky { // comments after nested properties should be recognized + font: { + family: fantasy; // a comment + size: 30em; /* another comment */ + weight: bold; + } +} + +.container { // issue #33, multiline comments are not recognized as comments + /*height: auto !important; + min-height: 100%;*/ + background: #fff; +} + +.button { // issue #34, functions as params should be recognized as functions + background-image: -webkit-linear-gradient(top, bottom, from(#933), to(#944)); +} + +.class { // issue #35 a) media block is not recognized + @media screen and (min-width: em(480)) { + a { + @extend .clearfix; + } + } +} + +.class { + div { + a { + @extend .clearfix; + } + } +} + +@media screen and (min-width: em(480)) { + a { + @extend .clearfix; + } +} + +.class { // issue #35 b) @extend & @include are not recognized inside media block + @media screen and (min-width: em(480)) { + @extend .clearfix; + @include header-text; + } +} + +div { + height: 10px; +} + +div { + a: 10px; +} + +div { + foo: 10px; +} diff --git a/ftdetect/scss.vim b/ftdetect/scss.vim new file mode 100644 index 0000000..67afaaa --- /dev/null +++ b/ftdetect/scss.vim @@ -0,0 +1,2 @@ +au BufRead,BufNewFile *.scss set filetype=scss.css +au BufEnter *.scss :syntax sync fromstart diff --git a/ftplugin/scss.vim b/ftplugin/scss.vim new file mode 100644 index 0000000..8e72e90 --- /dev/null +++ b/ftplugin/scss.vim @@ -0,0 +1,10 @@ +if exists('b:did_indent') && b:did_indent + " be kind. allow users to override this. Does it work? + finish +endif + +setlocal indentexpr=scss_indent#GetIndent(v:lnum) + +" Automatically insert the current comment leader after hitting +" in Insert mode respectively after hitting 'o' or 'O' in Normal mode +setlocal formatoptions+=ro diff --git a/plugin-info.txt b/plugin-info.txt new file mode 100644 index 0000000..4162181 --- /dev/null +++ b/plugin-info.txt @@ -0,0 +1,8 @@ +{ + "name" : "scss-syntax.vim", + "version" : "dev", + "author" : "Daniel Hofstetter ", + "repository" : {"type": "git", "url": "git://github.com/cakebaker/scss-syntax.vim.git"}, + "dependencies" : {}, + "description" : "Vim syntax file for scss (Sassy CSS)" +} diff --git a/syntax/scss.vim b/syntax/scss.vim new file mode 100644 index 0000000..48f91bb --- /dev/null +++ b/syntax/scss.vim @@ -0,0 +1,182 @@ +" Vim syntax file +" Language: SCSS (Sassy CSS) +" Author: Daniel Hofstetter (daniel.hofstetter@42dh.com) +" URL: https://github.com/cakebaker/scss-syntax.vim +" Last Change: 2013-12-26 +" Inspired by the syntax files for sass and css. Thanks to the authors of +" those files! + +if !exists("main_syntax") + if exists("b:current_syntax") + finish + endif + let main_syntax = 'scss' +endif + +runtime! syntax/css.vim +runtime! syntax/css/*.vim + +syn case ignore + +" XXX fix for #20, can be removed once the patch is in vim's css.vim +syn match cssSpecialCharQQ +\\\\\|\\"+ contained +syn match cssSpecialCharQ +\\\\\|\\'+ contained + +syn region scssDefinition matchgroup=cssBraces start='{' end='}' contains=cssComment,cssInclude,scssComment,scssDefinition,scssProperty,scssSelector,scssVariable,scssImport,scssExtend,scssInclude,@scssControl,scssWarn containedin=cssMediaBlock + +syn match scssSelector "^\s*\zs\([^:@]\|:[^ ]\)\+{\@=" contained contains=@scssSelectors +syn match scssSelector "^\s*\zs\([^:@{]\|:[^ ]\)\+\_$" contained contains=@scssSelectors +syn cluster scssSelectors contains=cssTagName,cssPseudoClass,cssAttributeSelector,scssSelectorChar,scssAmpersand,scssInterpolation + +syn match scssProperty "\([[:alnum:]-]\)\+\s*\(: \)\@=" contained contains=css.*Prop,cssVendor containedin=cssMediaBlock nextgroup=scssAttribute,scssAttributeWithNestedDefinition +syn match scssAttribute ":[^;]*;" contained contains=css.*Attr,cssValue.*,cssColor,cssFunction,cssString.*,cssURL,scssFunction,scssInterpolation,scssVariable + +syn match scssAttributeWithNestedDefinition ": [^#]*{\@=" nextgroup=scssNestedDefinition contained contains=cssValue.*,scssVariable +syn region scssNestedDefinition matchgroup=cssBraces start="{" end="}" contained contains=cssComment,scssComment,scssProperty,scssNestedProperty + +" CSS properties from https://developer.mozilla.org/en-US/docs/Web/CSS/Reference +" align +syn keyword scssNestedProperty contained content items self nextgroup=scssAttribute +" animation +syn keyword scssNestedProperty contained delay direction duration fill-mode iteration-count name play-state timing-function nextgroup=scssAttribute +" background +syn keyword scssNestedProperty contained attachment clip color image origin position repeat size nextgroup=scssAttribute +" border +syn keyword scssNestedProperty contained bottom bottom-color bottom-left-radius bottom-right-radius bottom-style bottom-width nextgroup=scssAttribute +syn keyword scssNestedProperty contained collapse color nextgroup=scssAttribute +syn keyword scssNestedProperty contained image image-outset image-repeat image-slice image-source image-width nextgroup=scssAttribute +syn keyword scssNestedProperty contained left left-color left-style left-width nextgroup=scssAttribute +syn keyword scssNestedProperty contained radius nextgroup=scssAttribute +syn keyword scssNestedProperty contained right right-color right-style right-width nextgroup=scssAttribute +syn keyword scssNestedProperty contained spacing style nextgroup=scssAttribute +syn keyword scssNestedProperty contained top top-color top-left-radius top-right-radius top-style top-width nextgroup=scssAttribute +syn keyword scssNestedProperty contained width nextgroup=scssAttribute +" box +syn keyword scssNestedProperty contained decoration-break shadow sizing nextgroup=scssAttribute +" break +syn keyword scssNestedProperty contained after before inside nextgroup=scssAttribute +" column +syn keyword scssNestedProperty contained count fill gap rule rule-color rule-style rule-width span width nextgroup=scssAttribute +" counter +syn keyword scssNestedProperty contained increment reset nextgroup=scssAttribute +" flex +syn keyword scssNestedProperty contained basis direction flow grow shrink wrap nextgroup=scssAttribute +" font +syn keyword scssNestedProperty contained family feature-settings kerning language-override size size-adjust stretch style synthesis nextgroup=scssAttribute +syn keyword scssNestedProperty contained variant variant-alternates variant-caps variant-east-asian variant-ligatures variant-numeric variant-position nextgroup=scssAttribute +syn keyword scssNestedProperty contained weight nextgroup=scssAttribute +" image +syn keyword scssNestedProperty contained rendering resolution orientation nextgroup=scssAttribute +" list +syn keyword scssNestedProperty contained style style-image style-position style-type nextgroup=scssAttribute +" margin/padding +syn keyword scssNestedProperty contained bottom left right top nextgroup=scssAttribute +" max/min +syn keyword scssNestedProperty contained height width nextgroup=scssAttribute +" nav +syn keyword scssNestedProperty contained down index left right up nextgroup=scssAttribute +" object +syn keyword scssNestedProperty contained fit position nextgroup=scssAttribute +" outline +syn keyword scssNestedProperty contained color offset style width nextgroup=scssAttribute +" overflow +syn keyword scssNestedProperty contained wrap x y nextgroup=scssAttribute +" page +syn keyword scssNestedProperty contained break-after break-before break-inside nextgroup=scssAttribute +" text +syn keyword scssNestedProperty contained align align-last combine-horizontal nextgroup=scssAttribute +syn keyword scssNestedProperty contained decoration decoration-color decoration-line decoration-style nextgroup=scssAttribute +syn keyword scssNestedProperty contained indent orientation overflow rendering shadow transform underline-position nextgroup=scssAttribute +" transform +syn keyword scssNestedProperty contained origin style nextgroup=scssAttribute +" transition +syn keyword scssNestedProperty contained delay duration property timing-function nextgroup=scssAttribute +" unicode +syn keyword scssNestedProperty contained bidi range nextgroup=scssAttribute +" word +syn keyword scssNestedProperty contained break spacing wrap nextgroup=scssAttribute + +syn region scssInterpolation matchgroup=scssInterpolationDelimiter start="#{" end="}" contains=cssValue.*,cssColor,cssString.*,scssFunction,scssVariable containedin=cssString.*,cssURL,scssFunction + +" ignores the url() function so it can be handled by css.vim +syn region scssFunction contained matchgroup=scssFunctionName start="\<\(url(\)\@!\([[:alnum:]-]\)\+\s*(" end=")" oneline keepend extend containedin=cssMediaType +syn match scssParameterList ".*" contained containedin=cssFunction,scssFunction contains=css.*Attr,cssColor,cssString.*,cssValue.*,scssFunction,scssVariable + +syn match scssVariable "$[[:alnum:]_-]\+" containedin=cssFunction,scssFunction,cssMediaType nextgroup=scssVariableAssignment skipwhite +syn match scssVariableAssignment ":" contained nextgroup=scssVariableValue skipwhite +syn match scssVariableValue "[^;)]\+[;)]\@=" contained contains=css.*Attr,cssValue.*,cssColor,cssFunction,cssString.*,cssURL,scssDefault,scssFunction,scssInterpolation,scssNull,scssVariable +syn keyword scssNull null contained; + +syn match scssMixin "^@mixin" nextgroup=scssMixinName skipwhite +syn match scssMixinName "[[:alnum:]_-]\+" contained nextgroup=scssDefinition,scssMixinParams +syn region scssMixinParams contained contains=cssColor,cssValue.*,cssString.*,scssVariable,scssFunction start="(" end=")" oneline extend +syn match scssInclude "@include" nextgroup=scssMixinName skipwhite containedin=cssMediaBlock +syn match scssContent "@content" contained containedin=scssDefinition + +syn match scssFunctionDefinition "^@function" nextgroup=scssFunctionName skipwhite +syn match scssFunctionName "[[:alnum:]_-]\+" contained nextgroup=scssFunctionParams +syn region scssFunctionParams contained start="(" end=")" nextgroup=scssFunctionBody contains=scssVariable skipwhite +syn region scssFunctionBody contained matchgroup=cssBraces start="{" end="}" contains=cssString.*,cssValue.*,scssVariable,scssReturn,scssFunction +syn match scssReturn "@return" contained +syn match scssExtend "@extend" nextgroup=scssExtendedSelector skipwhite containedin=cssMediaBlock +syn match scssExtendedSelector "[^ ;]\+" contained contains=cssTagName,cssPseudoClass,scssSelectorChar nextgroup=scssOptional skipwhite +syn match scssOptional "!optional" contained +syn match scssImport "@import" nextgroup=scssImportList +syn match scssImportList "[^;]\+" contained contains=cssString.*,cssMediaType,cssURL + +syn match scssSelectorChar "\(#\|\.\|%\)\([[:alnum:]_-]\|#{.*}\)\@=" nextgroup=scssSelectorName containedin=cssMediaBlock +syn match scssSelectorName "\([[:alnum:]_-]\|#{[^}]*}\)\+" contained contains=scssInterpolation + +syn match scssAmpersand "&" nextgroup=cssPseudoClass + +syn match scssDebug "@debug" nextgroup=scssOutput +syn match scssWarn "@warn" nextgroup=scssOutput +syn match scssOutput "[^;]\+" contained contains=cssValue.*,cssString.*,scssFunction,scssVariable +syn match scssDefault "!default" contained + +syn match scssIf "@\=if" nextgroup=scssCondition +syn match scssCondition "[^{]\+" contained contains=cssValue.*,cssString.*,scssFunction,scssNull,scssVariable +syn match scssElse "@else" nextgroup=scssIf +syn match scssElse "@else\(\s*\({\|$\)\)\@=" +syn match scssWhile "@while" nextgroup=scssCondition +syn match scssFor "@for\s\+.*from\s\+.*\(to\|through\)\s\+[^{ ]\+" contains=cssValueNumber,scssFunction,scssVariable,scssForKeyword +syn match scssForKeyword "@for\|from\|to\|through" contained +syn region scssEach matchgroup=scssEachKeyword start="@each" end="in" contains=scssVariable nextgroup=scssList +syn match scssList "[^{]\+" contained contains=scssFunction,scssVariable +syn cluster scssControl contains=scssIf,scssElse,scssWhile,scssFor,scssEach + +syn match scssComment "//.*$" contains=@Spell +syn keyword scssTodo TODO FIXME NOTE OPTIMIZE XXX contained containedin=cssComment,scssComment + +hi def link scssNestedProperty cssProp +hi def link scssVariable Identifier +hi def link scssNull Constant +hi def link scssMixin PreProc +hi def link scssMixinName Function +hi def link scssContent PreProc +hi def link scssFunctionDefinition PreProc +hi def link scssFunctionName Function +hi def link scssReturn Statement +hi def link scssInclude PreProc +hi def link scssExtend PreProc +hi def link scssOptional Special +hi def link scssComment Comment +hi def link scssSelectorChar Special +hi def link scssSelectorName Identifier +hi def link scssAmpersand Character +hi def link scssDebug Debug +hi def link scssWarn Debug +hi def link scssDefault Special +hi def link scssIf Conditional +hi def link scssElse Conditional +hi def link scssWhile Repeat +hi def link scssForKeyword Repeat +hi def link scssEachKeyword Repeat +hi def link scssInterpolationDelimiter Delimiter +hi def link scssImport Include +hi def link scssTodo Todo + +let b:current_syntax = "scss" +if main_syntax == 'scss' + unlet main_syntax +endif