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 } ]);