Rainbow.extend('html', [
{
'name': 'source.php.embedded',
'matches': {
2: {
'language': 'php'
}
},
'pattern': /<\?=?(?!xml)(php)?([\s\S]*?)(\?>)/gm
},
{
'name': 'source.css.embedded',
'matches': {
1: {
'matches': {
1: 'support.tag.style',
2: [
{
'name': 'entity.tag.style',
'pattern': /^style/g
},
{
'name': 'string',
'pattern': /('|")(.*?)(\1)/g
},
{
'name': 'entity.tag.style.attribute',
'pattern': /(\w+)/g
}
],
3: 'support.tag.style'
},
'pattern': /(<\/?)(style.*?)(>)/g
},
2: {
'language': 'css'
},
3: 'support.tag.style',
4: 'entity.tag.style',
5: 'support.tag.style'
},
'pattern': /(<style.*?>)([\s\S]*?)(<\/)(style)(>)/gm
},
{
'name': 'source.js.embedded',
'matches': {
1: {
'matches': {
1: 'support.tag.script',
2: [
{
'name': 'entity.tag.script',
'pattern': /^script/g
},
{
'name': 'string',
'pattern': /('|")(.*?)(\1)/g
},
{
'name': 'entity.tag.script.attribute',
'pattern': /(\w+)/g
}
],
3: 'support.tag.script'
},
'pattern': /(<\/?)(script.*?)(>)/g
},
2: {
'language': 'javascript'
},
3: 'support.tag.script',
4: 'entity.tag.script',
5: 'support.tag.script'
},
'pattern': /(<script(?! src).*?>)([\s\S]*?)(<\/)(script)(>)/gm
},
{
'name': 'comment.html',
'pattern': /<\!--[\S\s]*?-->/g
},
{
'matches': {
1: 'support.tag.open',
2: 'support.tag.close'
},
'pattern': /(<)|(\/?\??>)/g
},
{
'name': 'support.tag',
'matches': {
1: 'support.tag',
2: 'support.tag.special',
3: 'support.tag-name'
},
'pattern': /(<\??)(\/|\!?)(\w+)/g
},
{
'matches': {
1: 'support.attribute'
},
'pattern': /([a-z-]+)(?=\=)/gi
},
{
'matches': {
1: 'support.operator',
2: 'string.quote',
3: 'string.value',
4: 'string.quote'
},
'pattern': /(=)('|")(.*?)(\2)/g
},
{
'matches': {
1: 'support.operator',
2: 'support.value'
},
'pattern': /(=)([a-zA-Z\-0-9]*)\b/g
},
{
'matches': {
1: 'support.attribute'
},
'pattern': /\s(\w+)(?=\s|>)(?![\s\S]*<)/g
}
], true);
Rainbow.extend('css', [
{
'name': 'comment',
'pattern': /\/\*[\s\S]*?\*\//gm
},
{
'name': 'constant.hex-color',
'pattern': /#([a-f0-9]{3}|[a-f0-9]{6})(?=;|\s|,|\))/gi
},
{
'matches': {
1: 'constant.numeric',
2: 'keyword.unit'
},
'pattern': /(\d+)(px|em|cm|s|%)?/g
},
{
'name': 'string',
'pattern': /('|")(.*?)\1/g
},
{
'name': 'support.css-property',
'matches': {
1: 'support.vendor-prefix'
},
'pattern': /(-o-|-moz-|-webkit-|-ms-)?[\w-]+(?=\s?:)(?!.*\{)/g
},
{
'matches': {
1: [
{
'name': 'entity.name.sass',
'pattern': /&/g
},
{
'name': 'direct-descendant',
'pattern': />/g
},
{
'name': 'entity.name.class',
'pattern': /\.[\w\-_]+/g
},
{
'name': 'entity.name.id',
'pattern': /\#[\w\-_]+/g
},
{
'name': 'entity.name.pseudo',
'pattern': /:[\w\-_]+/g
},
{
'name': 'entity.name.tag',
'pattern': /\w+/g
}
]
},
'pattern': /([\w\ ,\n:\.\#\&\;\-_]+)(?=.*\{)/g
},
{
'matches': {
2: 'support.vendor-prefix',
3: 'support.css-value'
},
'pattern': /(:|,)\s*(-o-|-moz-|-webkit-|-ms-)?([a-zA-Z-]*)(?=\b)(?!.*\{)/g
}
], true);
Rainbow.extend('javascript', [
/**
* matches $. or $(
*/
{
'name': 'selector',
'pattern': /(\s|^)\$(?=\.|\()/g
},
{
'name': 'support',
'pattern': /\b(window|document)\b/g
},
{
'matches': {
1: 'support.property'
},
'pattern': /\.(length|node(Name|Value))\b/g
},
{
'matches': {
1: 'support.function'
},
'pattern': /(setTimeout|setInterval)(?=\()/g
},
{
'matches': {
1: 'support.method'
},
'pattern': /\.(getAttribute|push|getElementById|getElementsByClassName|log|setTimeout|setInterval)(?=\()/g
},
/**
* matches any escaped characters inside of a js regex pattern
*
* @see https://github.com/ccampbell/rainbow/issues/22
*
* this was causing single line comments to fail so it now makes sure
* the opening / is not directly followed by a *
*
* @todo check that there is valid regex in match group 1
*/
{
'name': 'string.regexp',
'matches': {
1: 'string.regexp.open',
2: {
'name': 'constant.regexp.escape',
'pattern': /\\(.){1}/g
},
3: 'string.regexp.close',
4: 'string.regexp.modifier'
},
'pattern': /(\/)(?!\*)(.+)(\/)([igm]{0,3})/g
},
/**
* matches runtime function declarations
*/
{
'matches': {
1: 'storage',
3: 'entity.function'
},
'pattern': /(var)?(\s|^)(\S*)(?=\s?=\s?function\()/g
},
/**
* matches constructor call
*/
{
'matches': {
1: 'keyword',
2: 'entity.function'
},
'pattern': /(new)\s+(.*)(?=\()/g
},
/**
* matches any function call in the style functionName: function()
*/
{
'name': 'entity.function',
'pattern': /(\w+)(?=:\s{0,}function)/g
}
]);
Rainbow.extend('coffeescript', [
{
'name': 'comment.block',
'pattern': /(\#{3})[\s\S]*\1/gm
},
{
'name': 'string.block',
'pattern': /('{3}|"{3})[\s\S]*\1/gm
},
/**
* multiline regex with comments
*/
{
'name': 'string.regex',
'matches': {
2: {
'name': 'comment',
'pattern': /\#(.*?)\n/g
}
},
'pattern': /(\/{3})([\s\S]*)\1/gm
},
{
'matches': {
1: 'keyword'
},
'pattern': /\b(in|when|is|isnt|of|not|unless|until|super)(?=\b)/gi
},
{
'name': 'keyword.operator',
'pattern': /\?/g
},
{
'name': 'constant.language',
'pattern': /\b(undefined|yes|on|no|off)\b/g
},
{
'name': 'keyword.variable.coffee',
'pattern': /@(\w+)/gi
},
/**
* reset global keywards from generic
*/
{
'name': 'reset',
'pattern': /object|class|print/gi
},
/**
* named function
*/
{
'matches' : {
1: 'entity.name.function',
2: 'keyword.operator',
3: {
'name': 'function.argument.coffee',
'pattern': /([\@\w]+)/g
},
4: 'keyword.function'
},
'pattern': /(\w+)\s{0,}(=|:)\s{0,}\((.*?)((-|=)>)/gi
},
/**
* anonymous function
*/
{
'matches': {
1: {
'name': 'function.argument.coffee',
'pattern': /([\@\w]+)/g
},
2: 'keyword.function'
},
'pattern': /\s\((.*?)\)\s{0,}((-|=)>)/gi
},
/**
* direct function no arguments
*/
{
'matches' : {
1: 'entity.name.function',
2: 'keyword.operator',
3: 'keyword.function'
},
'pattern': /(\w+)\s{0,}(=|:)\s{0,}((-|=)>)/gi
},
/**
* class definitions
*/
{
'matches': {
1: 'storage.class',
2: 'entity.name.class',
3: 'storage.modifier.extends',
4: 'entity.other.inherited-class'
},
'pattern': /\b(class)\s(\w+)(\sextends\s)?([\w\\]*)?\b/g
},
/**
* object instantiation
*/
{
'matches': {
1: 'keyword.new',
2: {
'name': 'support.class',
'pattern': /\w+/g
}
},
'pattern': /\b(new)\s(.*?)(?=\s)/g
}
]);
Rainbow.extend('php', [
{
'name': 'support',
'pattern': /\becho\b/g
},
{
'matches': {
1: 'variable.dollar-sign',
2: 'variable'
},
'pattern': /(\$)(\w+)\b/g
},
{
'name': 'constant.language',
'pattern': /true|false|null/ig
},
{
'name': 'constant',
'pattern': /\b[A-Z0-9_]{2,}\b/g
},
{
'name': 'keyword.dot',
'pattern': /\./g
},
{
'name': 'keyword',
'pattern': /\b(die|end(for(each)?|switch|if)|case|require(_once)?|include(_once)?)(?=\(|\b)/g
},
{
'matches': {
1: 'keyword',
2: {
'name': 'support.class',
'pattern': /\w+/g
}
},
'pattern': /(instanceof)\s([^\$].*?)(\)|;)/g
},
/**
* these are the top 50 most used PHP functions
* found from running a script and checking the frequency of each function
* over a bunch of popular PHP frameworks then combining the results
*/
{
'matches': {
1: 'support.function'
},
'pattern': /\b(array(_key_exists|_merge|_keys|_shift)?|isset|count|empty|unset|printf|is_(array|string|numeric|object)|sprintf|each|date|time|substr|pos|str(len|pos|tolower|_replace|totime)?|ord|trim|in_array|implode|end|preg_match|explode|fmod|define|link|list|get_class|serialize|file|sort|mail|dir|idate|log|intval|header|chr|function_exists|dirname|preg_replace|file_exists)(?=\()/g
},
{
'name': 'variable.language.php-tag',
'pattern': /(<\?(php)?|\?>)/g
},
{
'matches': {
1: 'keyword.namespace',
2: {
'name': 'support.namespace',
'pattern': /\w+/g
}
},
'pattern': /\b(namespace|use)\s(.*?);/g
},
{
'matches': {
1: 'storage.modifier',
2: 'storage.class',
3: 'entity.name.class',
4: 'storage.modifier.extends',
5: 'entity.other.inherited-class',
6: 'storage.modifier.extends',
7: 'entity.other.inherited-class'
},
'pattern': /\b(abstract|final)?\s?(class|interface|trait)\s(\w+)(\sextends\s)?([\w\\]*)?(\simplements\s)?([\w\\]*)?\s?\{?(\n|\})/g
},
{
'name': 'keyword.static',
'pattern': /self::|static::/g
},
{
'matches': {
1: 'storage.function',
2: 'support.magic'
},
'pattern': /(function)\s(__.*?)(?=\()/g
},
{
'matches': {
1: 'keyword.new',
2: {
'name': 'support.class',
'pattern': /\w+/g
}
},
'pattern': /\b(new)\s([^\$].*?)(?=\)|\(|;)/g
},
{
'matches': {
1: {
'name': 'support.class',
'pattern': /\w+/g
},
2: 'keyword.static'
},
'pattern': /([\w\\]*?)(::)(?=\b|\$)/g
},
{
'matches': {
2: {
'name': 'support.class',
'pattern': /\w+/g
}
},
'pattern': /(\(|,\s?)([\w\\]*?)(?=\s\$)/g
}
]);
Rainbow.extend('ruby', [
/**
* __END__ DATA
*/
{
'matches': {
1: 'variable.language',
2: {
'language': null
}
},
//find __END__ and consume remaining text
'pattern': /^(__END__)\n((?:.*\n)*)/gm
},
/**
* Strings
* 1. No support for multi-line strings
*/
{
'name': 'string',
'matches': {
1: 'string.open',
2: [{
'name': 'string.interpolation',
'matches': {
1: 'string.open',
2: {
'language': 'ruby'
},
3: 'string.close'
},
'pattern': /(\#\{)(.*?)(\})/g
}],
3: 'string.close'
},
'pattern': /("|`)(.*?[^\\\1])?(\1)/g
},
{
'name': 'string',
'pattern': /('|"|`)([^\\\1\n]|\\.)*?\1/g
},
{
'name': 'string',
'pattern': /%[qQ](?=(\(|\[|\{|<|.)(.*?)(?:'|\)|\]|\}|>|\1))(?:\(\2\)|\[\2\]|\{\2\}|\<\2>|\1\2\1)/g
},
/**
* Heredocs
* Heredocs of the form `<<'HTML' ... HTML` are unsupported.
*/
{
'matches': {
1: 'string',
2: 'string',
3: 'string'
},
'pattern': /(<<)(\w+).*?$([\s\S]*?^\2)/gm
},
{
'matches': {
1: 'string',
2: 'string',
3: 'string'
},
'pattern': /(<<\-)(\w+).*?$([\s\S]*?\2)/gm
},
/**
* Regular expressions
* Escaped delimiter (`/\//`) is unsupported.
*/
{
'name': 'string.regexp',
'matches': {
1: 'string.regexp',
2: {
'name': 'string.regexp',
'pattern': /\\(.){1}/g
},
3: 'string.regexp',
4: 'string.regexp'
},
'pattern': /(\/)(.*?)(\/)([a-z]*)/g
},
{
'name': 'string.regexp',
'matches': {
1: 'string.regexp',
2: {
'name': 'string.regexp',
'pattern': /\\(.){1}/g
},
3: 'string.regexp',
4: 'string.regexp'
},
'pattern': /%r(?=(\(|\[|\{|<|.)(.*?)('|\)|\]|\}|>|\1))(?:\(\2\)|\[\2\]|\{\2\}|\<\2>|\1\2\1)([a-z]*)/g
},
/**
* Comments
*/
{
'name': 'comment',
'pattern': /#.*$/gm
},
{
'name': 'comment',
'pattern': /^\=begin[\s\S]*?\=end$/gm
},
/**
* Symbols
*/
{
'matches': {
1: 'constant'
},
'pattern': /(\w+:)[^:]/g
},
{
'matches': {
1: 'constant.symbol'
},
'pattern': /[^:](:(?:\w+|(?=['"](.*?)['"])(?:"\2"|'\2')))/g
},
{
'name': 'constant.numeric',
'pattern': /\b(0x[\da-f]+|\d+)\b/g
},
{
'name': 'support.class',
'pattern': /\b[A-Z]\w*(?=((\.|::)[A-Za-z]|\[))/g
},
{
'name': 'constant',
'pattern': /\b[A-Z]\w*\b/g
},
/**
* Keywords, variables, constants, and operators
* In Ruby some keywords are valid method names, e.g., MyClass#yield
* Don't mark those instances as "keywords"
*/
{
'matches': {
1: 'storage.class',
2: 'entity.name.class',
3: 'entity.other.inherited-class'
},
'pattern': /\s*(class)\s+((?:(?:::)?[A-Z]\w*)+)(?:\s+<\s+((?:(?:::)?[A-Z]\w*)+))?/g
},
{
'matches': {
1: 'storage.module',
2: 'entity.name.class'
},
'pattern': /\s*(module)\s+((?:(?:::)?[A-Z]\w*)+)/g
},
{
'name': 'variable.global',
'pattern': /\$([a-zA-Z_]\w*)\b/g
},
{
'name': 'variable.class',
'pattern': /@@([a-zA-Z_]\w*)\b/g
},
{
'name': 'variable.instance',
'pattern': /@([a-zA-Z_]\w*)\b/g
},
{
'matches': {
1: 'keyword.control'
},
'pattern': /[^\.]\b(BEGIN|begin|case|class|do|else|elsif|END|end|ensure|for|if|in|module|rescue|then|unless|until|when|while)\b(?![?!])/g
},
{
'matches': {
1: 'keyword.control.pseudo-method'
},
'pattern': /[^\.]\b(alias|alias_method|break|next|redo|retry|return|super|undef|yield)\b(?![?!])|\bdefined\?|\bblock_given\?/g
},
{
'matches': {
1: 'constant.language'
},
'pattern': /\b(nil|true|false)\b(?![?!])/g
},
{
'matches': {
1: 'variable.language'
},
'pattern': /\b(__(FILE|LINE)__|self)\b(?![?!])/g
},
{
'matches': {
1: 'keyword.special-method'
},
'pattern': /\b(require|gem|initialize|new|loop|include|extend|raise|attr_reader|attr_writer|attr_accessor|attr|catch|throw|private|module_function|public|protected)\b(?![?!])/g
},
{
'name': 'keyword.operator',
'pattern': /\s\?\s|=|<<|<<=|%=|&=|\*=|\*\*=|\+=|\-=|\^=|\|{1,2}=|<<|<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|%|&|\*\*|\*|\+|\-|\/|\||~|>>/g
},
{
'matches': {
1: 'keyword.operator.logical'
},
'pattern': /[^\.]\b(and|not|or)\b/g
},
/**
* Functions
* 1. No support for marking function parameters
*/
{
'matches': {
1: 'storage.function',
2: 'entity.name.function'
},
'pattern': /(def)\s(.*?)(?=(\s|\())/g
}
], true);
Rainbow.extend('go', [
{
'matches': {
1: {
'name': 'keyword.operator',
'pattern': /\=/g
},
2: {
'name': 'string',
'matches': {
'name': 'constant.character.escape',
'pattern': /\\(`|"){1}/g
}
}
},
'pattern': /(\(|\s|\[|\=|:)((`|")([^\\\1]|\\.)*?(\3))/gm
},
{
'name': 'comment',
'pattern': /\/\*[\s\S]*?\*\/|(\/\/)[\s\S]*?$/gm
},
{
'name': 'constant.numeric',
'pattern': /\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi
},
{
'matches': {
1: 'keyword'
},
'pattern': /\b(break|c(ase|onst|ontinue)|d(efault|efer)|else|fallthrough|for|go(to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)(?=\(|\b)/gi
},
{
'name': 'constant.language',
'pattern': /true|false|null|string|byte|rune|u?int(8|16|32|64)?|float(32|64)|complex(64|128)/g
},
{
'name': 'keyword.operator',
'pattern': /\+|\!|\-|&(gt|lt|amp);|\||\*|\:?=/g
},
{
'matches': {
1: 'function.call'
},
'pattern': /(\w+?)(?=\()/g
},
{
'matches': {
1: 'storage.function',
2: 'entity.name.function'
},
'pattern': /(func)\s(.*?)(?=\()/g
}
]);