Add css/less/scss definitions and grammar

pull/2748/head
Martin Aeschlimann 9 years ago
parent 23b305079f
commit 4be02a4e82

@ -46,6 +46,7 @@ gulp.task('release', ['clean-release','compile'], function() {
return merge( return merge(
bundleOne('src/monaco.contribution'), bundleOne('src/monaco.contribution'),
bundleOne('src/bat'), bundleOne('src/bat'),
bundleOne('src/css'),
bundleOne('src/coffee'), bundleOne('src/coffee'),
bundleOne('src/cpp'), bundleOne('src/cpp'),
bundleOne('src/csharp'), bundleOne('src/csharp'),
@ -55,6 +56,7 @@ gulp.task('release', ['clean-release','compile'], function() {
bundleOne('src/ini'), bundleOne('src/ini'),
bundleOne('src/jade'), bundleOne('src/jade'),
bundleOne('src/java'), bundleOne('src/java'),
bundleOne('src/less'),
bundleOne('src/lua'), bundleOne('src/lua'),
bundleOne('src/markdown'), bundleOne('src/markdown'),
bundleOne('src/objective-c'), bundleOne('src/objective-c'),
@ -62,6 +64,7 @@ gulp.task('release', ['clean-release','compile'], function() {
bundleOne('src/python'), bundleOne('src/python'),
bundleOne('src/r'), bundleOne('src/r'),
bundleOne('src/ruby'), bundleOne('src/ruby'),
bundleOne('src/scss'),
bundleOne('src/sql'), bundleOne('src/sql'),
bundleOne('src/swift'), bundleOne('src/swift'),
bundleOne('src/vb'), bundleOne('src/vb'),

@ -1,6 +1,6 @@
{ {
"name": "monaco-languages", "name": "monaco-languages",
"version": "0.2.0", "version": "0.2.1",
"description": "Bundle of many languages for the Monaco Editor.", "description": "Bundle of many languages for the Monaco Editor.",
"scripts": { "scripts": {
"test": "node_modules/.bin/mocha", "test": "node_modules/.bin/mocha",

@ -0,0 +1,190 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import LanguageConfiguration = monaco.languages.LanguageConfiguration;
import IMonarchLanguage = monaco.languages.IMonarchLanguage;
export var conf:LanguageConfiguration = {
wordPattern: /(#?-?\d*\.\d\w*%?)|((::|[@#.!:])?[\w-?]+%?)|::|[@#.!:]/g,
comments: {
blockComment: ['/*', '*/']
},
brackets: [
['{', '}'],
['[', ']'],
['(', ')']
],
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"', notIn: ['string'] },
{ open: '\'', close: '\'', notIn: ['string'] }
]
};
const TOKEN_SELECTOR = 'entity.name.selector';
const TOKEN_SELECTOR_TAG = 'entity.name.tag';
const TOKEN_PROPERTY = 'support.type.property-name';
const TOKEN_VALUE = 'support.property-value';
const TOKEN_AT_KEYWORD = 'keyword.control.at-rule';
export var language = <IMonarchLanguage> {
defaultToken: '',
tokenPostfix: '.css',
ws: '[ \t\n\r\f]*', // whitespaces (referenced in several rules)
identifier: '-?-?([a-zA-Z]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))([\\w\\-]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))*',
brackets: [
{ open: '{', close: '}', token: 'punctuation.curly' },
{ open: '[', close: ']', token: 'punctuation.bracket' },
{ open: '(', close: ')', token: 'punctuation.parenthesis' },
{ open: '<', close: '>', token: 'punctuation.angle' }
],
tokenizer: {
root: [
{ include: '@selector' },
],
selector: [
{ include: '@comments' },
{ include: '@import' },
['[@](keyframes|-webkit-keyframes|-moz-keyframes|-o-keyframes)', { token: TOKEN_AT_KEYWORD, next: '@keyframedeclaration' }],
['[@](page|content|font-face|-moz-document)', { token: TOKEN_AT_KEYWORD }],
['[@](charset|namespace)', { token: TOKEN_AT_KEYWORD, next: '@declarationbody' }],
['url(\\-prefix)?\\(', { token: 'support.function.name', bracket: '@open', next: '@urldeclaration' }],
{ include: '@selectorname' },
['[\\*]', TOKEN_SELECTOR_TAG], // selector symbols
['[>\\+,]', 'punctuation'], // selector operators
['\\[', { token: 'punctuation.bracket', bracket: '@open', next: '@selectorattribute' }],
['{', { token: 'punctuation.curly', bracket: '@open', next: '@selectorbody' }]
],
selectorbody: [
['[*_]?@identifier@ws:(?=(\\s|\\d|[^{;}]*[;}]))', TOKEN_PROPERTY, '@rulevalue'], // rule definition: to distinguish from a nested selector check for whitespace, number or a semicolon
['}', { token: 'punctuation.curly', bracket: '@close', next: '@pop' }]
],
selectorname: [
['(\\.|#(?=[^{])|%|(@identifier)|:)+', TOKEN_SELECTOR], // selector (.foo, div, ...)
],
selectorattribute: [
{ include: '@term' },
[']', { token: 'punctuation.bracket', bracket: '@close', next: '@pop' }],
],
term: [
{ include: '@comments' },
['url(\\-prefix)?\\(', { token: 'support.function.name', bracket: '@open', next: '@urldeclaration' }],
{ include: '@functioninvocation' },
{ include: '@numbers' },
{ include: '@name' },
['([<>=\\+\\-\\*\\/\\^\\|\\~,])', 'keyword.operator'],
[',', 'punctuation']
],
rulevalue: [
{ include: '@term' },
['!important', 'literal'],
[';', 'punctuation', '@pop'],
['(?=})', { token: '', next: '@pop' }] // missing semicolon
],
warndebug: [
['[@](warn|debug)', { token: TOKEN_AT_KEYWORD, next: '@declarationbody' }]
],
import: [
['[@](import)', { token: TOKEN_AT_KEYWORD, next: '@declarationbody' }]
],
urldeclaration: [
{ include: '@strings' },
['[^)\r\n]+', 'string'],
['\\)', { token: 'support.function.name', bracket: '@close', next: '@pop' }]
],
parenthizedterm: [
{ include: '@term' },
['\\)', { token: 'punctuation.parenthesis', bracket: '@close', next: '@pop' }]
],
declarationbody: [
{ include: '@term' },
[';', 'punctuation', '@pop'],
['(?=})', { token: '', next: '@pop' }] // missing semicolon
],
comments: [
['\\/\\*', 'comment', '@comment'],
['\\/\\/+.*', 'comment']
],
comment: [
['\\*\\/', 'comment', '@pop'],
['.', 'comment']
],
name: [
['@identifier', TOKEN_VALUE]
],
numbers: [
['(\\d*\\.)?\\d+([eE][\\-+]?\\d+)?', { token: 'constant.numeric', next: '@units' }],
['#[0-9a-fA-F_]+(?!\\w)', 'constant.rgb-value']
],
units: [
['(em|ex|ch|rem|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?', 'constant.numeric', '@pop']
],
keyframedeclaration: [
['@identifier', 'support.function.name'],
['{', { token: 'punctuation.curly', bracket: '@open', switchTo: '@keyframebody' }],
],
keyframebody: [
{ include: '@term' },
['{', { token: 'punctuation.curly', bracket: '@open', next: '@selectorbody' }],
['}', { token: 'punctuation.curly', bracket: '@close', next: '@pop' }],
],
functioninvocation: [
['@identifier\\(', { token: 'support.function.name', bracket: '@open', next: '@functionarguments' }],
],
functionarguments: [
['\\$@identifier@ws:', TOKEN_PROPERTY],
['[,]', 'punctuation'],
{ include: '@term' },
['\\)', { token: 'support.function.name', bracket: '@close', next: '@pop' }],
],
strings: [
['~?"', { token: 'string.punctuation', bracket: '@open', next: '@stringenddoublequote' }],
['~?\'', { token: 'string.punctuation', bracket: '@open', next: '@stringendquote' }]
],
stringenddoublequote: [
['\\\\.', 'string'],
['"', { token: 'string.punctuation', next: '@pop', bracket: '@close' }],
['.', 'string']
],
stringendquote: [
['\\\\.', 'string'],
['\'', { token: 'string.punctuation', next: '@pop', bracket: '@close' }],
['.', 'string']
]
}
};

@ -0,0 +1,175 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import IRichLanguageConfiguration = monaco.languages.LanguageConfiguration;
import ILanguage = monaco.languages.IMonarchLanguage;
export var lessLanguageConfiguration: IRichLanguageConfiguration = {
wordPattern: /(#?-?\d*\.\d\w*%?)|([@#!.:]?[\w-?]+%?)|[@#!.]/g,
comments: {
blockComment: ['/*', '*/'],
lineComment: '//'
},
brackets: [['{','}'], ['[',']'], ['(',')'], ['<','>']],
autoClosingPairs: [
{ open: '"', close: '"', notIn: ['string', 'comment'] },
{ open: '\'', close: '\'', notIn: ['string', 'comment'] },
{ open: '{', close: '}', notIn: ['string', 'comment'] },
{ open: '[', close: ']', notIn: ['string', 'comment'] },
{ open: '(', close: ')', notIn: ['string', 'comment'] },
{ open: '<', close: '>', notIn: ['string', 'comment'] },
]
};
const TOKEN_SELECTOR = 'entity.name.selector';
const TOKEN_SELECTOR_TAG = 'entity.name.tag';
const TOKEN_PROPERTY = 'support.type.property-name';
const TOKEN_VALUE = 'support.property-value';
const TOKEN_AT_KEYWORD = 'keyword.control.at-rule';
export var language = <ILanguage> {
defaultToken: '',
tokenPostfix: '.less',
identifier: '-?-?([a-zA-Z]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))([\\w\\-]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))*',
identifierPlus: '-?-?([a-zA-Z:.]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))([\\w\\-:.]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))*',
brackets: [
{ open: '{', close: '}', token: 'punctuation.curly' },
{ open: '[', close: ']', token: 'punctuation.bracket' },
{ open: '(', close: ')', token: 'punctuation.parenthesis' },
{ open: '<', close: '>', token: 'punctuation.angle' }
],
tokenizer: {
root: <any[]>[
{ include: '@nestedJSBegin' },
['[ \\t\\r\\n]+', ''],
{ include: '@comments' },
{ include: '@keyword' },
{ include: '@strings' },
{ include: '@numbers' },
['[*_]?[a-zA-Z\\-\\s]+(?=:.*(;|(\\\\$)))', TOKEN_PROPERTY, '@attribute'],
['url(\\-prefix)?\\(', { token: 'function', bracket: '@open', next: '@urldeclaration'}],
['[{}()\\[\\]]', '@brackets'],
['[,:;]', 'punctuation'],
['#@identifierPlus', TOKEN_SELECTOR + '.id'],
['&', TOKEN_SELECTOR_TAG],
['\\.@identifierPlus(?=\\()', TOKEN_SELECTOR + '.class', '@attribute'],
['\\.@identifierPlus', TOKEN_SELECTOR + '.class'],
['@identifierPlus', TOKEN_SELECTOR_TAG],
{ include: '@operators' },
['@(@identifier(?=[:,\\)]))', 'variable', '@attribute'],
['@(@identifier)', 'variable'],
['@', 'key', '@atRules']
],
nestedJSBegin: [
['``', 'punctuation.backtick'],
<any[]>['`', { token: 'punctuation.backtick', bracket: '@open', next: '@nestedJSEnd', nextEmbedded: 'text/javascript' }],
],
nestedJSEnd: [
<any[]>['`', { token: 'punctuation.backtick', bracket: '@close', next: '@pop' }],
<any[]>['.', { token: '@rematch', next: '@javascript_block' }],
],
javascript_block: [
<any[]>['`', { token: '@rematch', next: '@pop', nextEmbedded: '@pop' }],
],
operators: [
['[<>=\\+\\-\\*\\/\\^\\|\\~]', 'operator']
],
keyword: [
['(@[\\s]*import|![\\s]*important|true|false|when|iscolor|isnumber|isstring|iskeyword|isurl|ispixel|ispercentage|isem|hue|saturation|lightness|alpha|lighten|darken|saturate|desaturate|fadein|fadeout|fade|spin|mix|round|ceil|floor|percentage)\\b', 'keyword']
],
urldeclaration: [
{ include: '@strings'},
[ '[^)\r\n]+', 'string' ],
['\\)', { token: 'tag', bracket: '@close', next: '@pop'}],
],
attribute: <any[]>[
{ include: '@nestedJSBegin' },
{ include: '@comments' },
{ include: '@strings' },
{ include: '@numbers' },
{ include: '@keyword' },
['[a-zA-Z\\-]+(?=\\()', TOKEN_VALUE, '@attribute'],
['>', 'operator', '@pop'],
['@identifier', TOKEN_VALUE],
{ include: '@operators' },
['@(@identifier)', 'variable'],
['[)\\}]', '@brackets', '@pop'],
['[{}()\\[\\]>]', '@brackets'],
['[;]', 'punctuation', '@pop'],
['[,=:]', 'punctuation'],
['\\s', ''],
['.', TOKEN_VALUE]
],
comments: [
['\\/\\*', 'comment', '@comment'],
['\\/\\/+.*', 'comment'],
],
comment: [
['\\*\\/', 'comment', '@pop'],
['.', 'comment'],
],
numbers: [
<any[]>['(\\d*\\.)?\\d+([eE][\\-+]?\\d+)?', { token: TOKEN_VALUE + '.numeric', next: '@units' }],
['#[0-9a-fA-F_]+(?!\\w)', TOKEN_VALUE + '.rgb-value']
],
units: [
['((em|ex|ch|rem|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)\\b)?', TOKEN_VALUE + '.unit', '@pop']
],
strings: [
<any[]>['~?"', { token: 'string.punctuation', bracket: '@open', next: '@stringsEndDoubleQuote' }],
<any[]>['~?\'', { token: 'string.punctuation', bracket: '@open', next: '@stringsEndQuote' }]
],
stringsEndDoubleQuote: [
['\\\\"', 'string'],
<any[]>['"', { token: 'string.punctuation', next: '@popall', bracket: '@close' }],
['.', 'string']
],
stringsEndQuote: [
['\\\\\'', 'string'],
<any[]>['\'', { token: 'string.punctuation', next: '@popall', bracket: '@close' }],
['.', 'string']
],
atRules: <any[]>[
{ include: '@comments' },
{ include: '@strings' },
['[()]', 'punctuation'],
['[\\{;]', 'punctuation', '@pop'],
['.', 'key']
]
}
};

@ -183,3 +183,24 @@ registerLanguage({
mimetypes: ['text/xml', 'application/xml', 'application/xaml+xml', 'application/xml-dtd'], mimetypes: ['text/xml', 'application/xml', 'application/xaml+xml', 'application/xml-dtd'],
module: './xml' module: './xml'
}); });
registerLanguage({
id: 'less',
extensions: ['.less'],
aliases: ['Less', 'less'],
mimetypes: ['text/x-less', 'text/less'],
module: './less'
});
registerLanguage({
id: 'scss',
extensions: ['.scss'],
aliases: ['Sass', 'sass', 'scss'],
mimetypes: ['text/x-scss', 'text/scss'],
module: './scss'
});
registerLanguage({
id: 'css',
extensions: ['.css'],
aliases: ['CSS', 'css'],
mimetypes: ['text/css'],
module: './css'
});

@ -0,0 +1,277 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import LanguageConfiguration = monaco.languages.LanguageConfiguration;
import IMonarchLanguage = monaco.languages.IMonarchLanguage;
export var conf: LanguageConfiguration = {
wordPattern: /(#?-?\d*\.\d\w*%?)|([@#!.:]?[\w-?]+%?)|[@#!.]/g,
comments: {
blockComment: ['/*', '*/'],
lineComment: '//'
},
brackets: [['{', '}'], ['[', ']'], ['(', ')'], ['<', '>']],
autoClosingPairs: [
{ open: '"', close: '"', notIn: ['string', 'comment'] },
{ open: '\'', close: '\'', notIn: ['string', 'comment'] },
{ open: '{', close: '}', notIn: ['string', 'comment'] },
{ open: '[', close: ']', notIn: ['string', 'comment'] },
{ open: '(', close: ')', notIn: ['string', 'comment'] },
{ open: '<', close: '>', notIn: ['string', 'comment'] },
]
};
const TOKEN_SELECTOR = 'entity.name.selector';
const TOKEN_SELECTOR_TAG = 'entity.name.tag';
const TOKEN_PROPERTY = 'support.type.property-name';
const TOKEN_VALUE = 'support.property-value';
const TOKEN_AT_KEYWORD = 'keyword.control.at-rule';
export var language = <IMonarchLanguage> {
defaultToken: '',
tokenPostfix: '.scss',
ws: '[ \t\n\r\f]*', // whitespaces (referenced in several rules)
identifier: '-?-?([a-zA-Z]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))([\\w\\-]|(\\\\(([0-9a-fA-F]{1,6}\\s?)|[^[0-9a-fA-F])))*',
brackets: [
{ open: '{', close: '}', token: 'punctuation.curly' },
{ open: '[', close: ']', token: 'punctuation.bracket' },
{ open: '(', close: ')', token: 'punctuation.parenthesis' },
{ open: '<', close: '>', token: 'punctuation.angle' }
],
tokenizer: {
root: [
{ include: '@selector' },
],
selector: [
{ include: '@comments' },
{ include: '@import' },
{ include: '@variabledeclaration' },
{ include: '@warndebug' }, // sass: log statements
['[@](include)', { token: TOKEN_AT_KEYWORD, next: '@includedeclaration' }], // sass: include statement
['[@](keyframes|-webkit-keyframes|-moz-keyframes|-o-keyframes)', { token: TOKEN_AT_KEYWORD, next: '@keyframedeclaration' }],
['[@](page|content|font-face|-moz-document)', { token: TOKEN_AT_KEYWORD }], // sass: placeholder for includes
['[@](charset|namespace)', { token: TOKEN_AT_KEYWORD, next: '@declarationbody' }],
['[@](function)', { token: TOKEN_AT_KEYWORD, next: '@functiondeclaration' }],
['[@](mixin)', { token: TOKEN_AT_KEYWORD, next: '@mixindeclaration' }],
['url(\\-prefix)?\\(', { token: 'support.function.name', bracket: '@open', next: '@urldeclaration' }],
{ include: '@controlstatement' }, // sass control statements
{ include: '@selectorname' },
['[&\\*]', TOKEN_SELECTOR_TAG], // selector symbols
['[>\\+,]', 'punctuation'], // selector operators
['\\[', { token: 'punctuation.bracket', bracket: '@open', next: '@selectorattribute' }],
['{', { token: 'punctuation.curly', bracket: '@open', next: '@selectorbody' }],
],
selectorbody: [
['[*_]?@identifier@ws:(?=(\\s|\\d|[^{;}]*[;}]))', TOKEN_PROPERTY, '@rulevalue'], // rule definition: to distinguish from a nested selector check for whitespace, number or a semicolon
{ include: '@selector' }, // sass: nested selectors
['[@](extend)', { token: TOKEN_AT_KEYWORD, next: '@extendbody' }], // sass: extend other selectors
['[@](return)', { token: TOKEN_AT_KEYWORD, next: '@declarationbody' }],
['}', { token: 'punctuation.curly', bracket: '@close', next: '@pop' }],
],
selectorname: [
['#{', { token: 'support.function.interpolation', bracket: '@open', next: '@variableinterpolation' }], // sass: interpolation
['(\\.|#(?=[^{])|%|(@identifier)|:)+', TOKEN_SELECTOR], // selector (.foo, div, ...)
],
selectorattribute: [
{ include: '@term' },
[']', { token: 'punctuation.bracket', bracket: '@close', next: '@pop' }],
],
term: [
{ include: '@comments' },
['url(\\-prefix)?\\(', { token: 'support.function.name', bracket: '@open', next: '@urldeclaration' }],
{ include: '@functioninvocation' },
{ include: '@numbers' },
{ include: '@strings' },
{ include: '@variablereference' },
['(and\\b|or\\b|not\\b)', 'keyword.operator'],
{ include: '@name' },
['([<>=\\+\\-\\*\\/\\^\\|\\~,])', 'keyword.operator'],
[',', 'punctuation'],
['!default', 'literal'],
['\\(', { token: 'punctuation.parenthesis', bracket: '@open', next: '@parenthizedterm' }],
],
rulevalue: [
{ include: '@term' },
['!important', 'literal'],
[';', 'punctuation', '@pop'],
['{', { token: 'punctuation.curly', bracket: '@open', switchTo: '@nestedproperty' }], // sass: nested properties
['(?=})', { token: '', next: '@pop' }], // missing semicolon
],
nestedproperty: [
['[*_]?@identifier@ws:', TOKEN_PROPERTY, '@rulevalue'],
{ include: '@comments' },
['}', { token: 'punctuation.curly', bracket: '@close', next: '@pop' }],
],
warndebug: [
['[@](warn|debug)', { token: TOKEN_AT_KEYWORD, next: '@declarationbody' }],
],
import: [
['[@](import)', { token: TOKEN_AT_KEYWORD, next: '@declarationbody' }],
],
variabledeclaration: [ // sass variables
['\\$@identifier@ws:', 'variable.decl', '@declarationbody'],
],
urldeclaration: [
{ include: '@strings' },
['[^)\r\n]+', 'string'],
['\\)', { token: 'support.function.name', bracket: '@close', next: '@pop' }],
],
parenthizedterm: [
{ include: '@term' },
['\\)', { token: 'punctuation.parenthesis', bracket: '@close', next: '@pop' }],
],
declarationbody: [
{ include: '@term' },
[';', 'punctuation', '@pop'],
['(?=})', { token: '', next: '@pop' }], // missing semicolon
],
extendbody: [
{ include: '@selectorname' },
['!optional', 'literal'],
[';', 'punctuation', '@pop'],
['(?=})', { token: '', next: '@pop' }], // missing semicolon
],
variablereference: [ // sass variable reference
['\\$@identifier', 'variable.ref'],
['\\.\\.\\.', 'keyword.operator'], // var args in reference
['#{', { token: 'support.function.interpolation', bracket: '@open', next: '@variableinterpolation' }], // sass var resolve
],
variableinterpolation: [
{ include: '@variablereference' },
['}', { token: 'support.function.interpolation', bracket: '@close', next: '@pop' }],
],
comments: [
['\\/\\*', 'comment', '@comment'],
['\\/\\/+.*', 'comment'],
],
comment: [
['\\*\\/', 'comment', '@pop'],
['.', 'comment'],
],
name: [
['@identifier', TOKEN_VALUE],
],
numbers: [
['(\\d*\\.)?\\d+([eE][\\-+]?\\d+)?', { token: 'constant.numeric', next: '@units' }],
['#[0-9a-fA-F_]+(?!\\w)', 'constant.rgb-value'],
],
units: [
['(em|ex|ch|rem|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?', 'constant.numeric', '@pop']
],
functiondeclaration: [
['@identifier@ws\\(', { token: 'support.function.name', bracket: '@open', next: '@parameterdeclaration' }],
['{', { token: 'punctuation.curly', bracket: '@open', switchTo: '@functionbody' }],
],
mixindeclaration: [
// mixin with parameters
['@identifier@ws\\(', { token: 'support.function.name', bracket: '@open', next: '@parameterdeclaration' }],
// mixin without parameters
['@identifier', 'support.function.name'],
['{', { token: 'punctuation.curly', bracket: '@open', switchTo: '@selectorbody' }],
],
parameterdeclaration: [
['\\$@identifier@ws:', 'variable'],
['\\.\\.\\.', 'keyword.operator'], // var args in declaration
[',', 'punctuation'],
{ include: '@term' },
['\\)', { token: 'support.function.name', bracket: '@close', next: '@pop' }],
],
includedeclaration: [
{ include: '@functioninvocation' },
['@identifier', 'support.function.name'],
[';', 'punctuation', '@pop'],
['(?=})', { token: '', next: '@pop' }], // missing semicolon
['{', { token: 'punctuation.curly', bracket: '@open', switchTo: '@selectorbody' }],
],
keyframedeclaration: [
['@identifier', 'support.function.name'],
['{', { token: 'punctuation.curly', bracket: '@open', switchTo: '@keyframebody' }],
],
keyframebody: [
{ include: '@term' },
['{', { token: 'punctuation.curly', bracket: '@open', next: '@selectorbody' }],
['}', { token: 'punctuation.curly', bracket: '@close', next: '@pop' }],
],
controlstatement: [
['[@](if|else|for|while|each|media)', { token: 'keyword.flow.control.at-rule', next: '@controlstatementdeclaration' }],
],
controlstatementdeclaration: [
['(in|from|through|if|to)\\b', { token: 'keyword.flow.control.at-rule' }],
{ include: '@term' },
['{', { token: 'punctuation.curly', bracket: '@open', switchTo: '@selectorbody' }],
],
functionbody: [
['[@](return)', { token: TOKEN_AT_KEYWORD }],
{ include: '@variabledeclaration' },
{ include: '@term' },
{ include: '@controlstatement' },
[';', 'punctuation'],
['}', { token: 'punctuation.curly', bracket: '@close', next: '@pop' }],
],
functioninvocation: [
['@identifier\\(', { token: 'support.function.name', bracket: '@open', next: '@functionarguments' }],
],
functionarguments: [
['\\$@identifier@ws:', TOKEN_PROPERTY],
['[,]', 'punctuation'],
{ include: '@term' },
['\\)', { token: 'support.function.name', bracket: '@close', next: '@pop' }],
],
strings: [
['~?"', { token: 'string.punctuation', bracket: '@open', next: '@stringenddoublequote' }],
['~?\'', { token: 'string.punctuation', bracket: '@open', next: '@stringendquote' }]
],
stringenddoublequote: [
['\\\\.', 'string'],
['"', { token: 'string.punctuation', next: '@pop', bracket: '@close' }],
['.', 'string']
],
stringendquote: [
['\\\\.', 'string'],
['\'', { token: 'string.punctuation', next: '@pop', bracket: '@close' }],
['.', 'string']
]
}
};
Loading…
Cancel
Save