Created
June 19, 2015 11:30
Revisions
-
espadrine created this gist
Jun 19, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,1201 @@ // Parts from Ace; see <https://raw.githubusercontent.com/ajaxorg/ace/master/LICENSE> CodeMirror.defineMode("perl6", function(cmCfg, modeCfg) { // Fake define() function. var moduleHolder = Object.create(null); // Given a module path as a string, create the canonical version // (no leading ./, no ending .js). var canonicalPath = function(path) { return path.replace(/\.\//, '').replace(/\.js$/, ''); }; // We intentionally add the `path` argument to `define()`. var define = function(path, init) { var exports = Object.create(null); init(require, exports); // module (3rd parameter) isn't supported. moduleHolder[canonicalPath(path)] = exports; }; // path: string of the location of the JS file. var require = function(path) { return moduleHolder[canonicalPath(path)]; }; // All dependencies here. define("../lib/oop.js", function(require, exports, module) { "use strict"; exports.inherits = function(ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; exports.mixin = function(obj, mixin) { for (var key in mixin) { obj[key] = mixin[key]; } return obj; }; exports.implement = function(proto, mixin) { exports.mixin(proto, mixin); }; }); define("../lib/lang.js", function(require, exports, module) { "use strict"; exports.last = function(a) { return a[a.length - 1]; }; exports.stringReverse = function(string) { return string.split("").reverse().join(""); }; exports.stringRepeat = function (string, count) { var result = ''; while (count > 0) { if (count & 1) result += string; if (count >>= 1) string += string; } return result; }; var trimBeginRegexp = /^\s\s*/; var trimEndRegexp = /\s\s*$/; exports.stringTrimLeft = function (string) { return string.replace(trimBeginRegexp, ''); }; exports.stringTrimRight = function (string) { return string.replace(trimEndRegexp, ''); }; exports.copyObject = function(obj) { var copy = {}; for (var key in obj) { copy[key] = obj[key]; } return copy; }; exports.copyArray = function(array){ var copy = []; for (var i=0, l=array.length; i<l; i++) { if (array[i] && typeof array[i] == "object") copy[i] = this.copyObject( array[i] ); else copy[i] = array[i]; } return copy; }; exports.deepCopy = function deepCopy(obj) { if (typeof obj !== "object" || !obj) return obj; var copy; if (Array.isArray(obj)) { copy = []; for (var key = 0; key < obj.length; key++) { copy[key] = deepCopy(obj[key]); } return copy; } var cons = obj.constructor; if (cons === RegExp) return obj; copy = cons(); for (var key in obj) { copy[key] = deepCopy(obj[key]); } return copy; }; exports.arrayToMap = function(arr) { var map = {}; for (var i=0; i<arr.length; i++) { map[arr[i]] = 1; } return map; }; exports.createMap = function(props) { var map = Object.create(null); for (var i in props) { map[i] = props[i]; } return map; }; /* * splice out of 'array' anything that === 'value' */ exports.arrayRemove = function(array, value) { for (var i = 0; i <= array.length; i++) { if (value === array[i]) { array.splice(i, 1); } } }; exports.escapeRegExp = function(str) { return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); }; exports.escapeHTML = function(str) { return str.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<"); }; exports.getMatchOffsets = function(string, regExp) { var matches = []; string.replace(regExp, function(str) { matches.push({ offset: arguments[arguments.length-2], length: str.length }); }); return matches; }; /* deprecated */ exports.deferredCall = function(fcn) { var timer = null; var callback = function() { timer = null; fcn(); }; var deferred = function(timeout) { deferred.cancel(); timer = setTimeout(callback, timeout || 0); return deferred; }; deferred.schedule = deferred; deferred.call = function() { this.cancel(); fcn(); return deferred; }; deferred.cancel = function() { clearTimeout(timer); timer = null; return deferred; }; deferred.isPending = function() { return timer; }; return deferred; }; exports.delayedCall = function(fcn, defaultTimeout) { var timer = null; var callback = function() { timer = null; fcn(); }; var _self = function(timeout) { if (timer == null) timer = setTimeout(callback, timeout || defaultTimeout); }; _self.delay = function(timeout) { timer && clearTimeout(timer); timer = setTimeout(callback, timeout || defaultTimeout); }; _self.schedule = _self; _self.call = function() { this.cancel(); fcn(); }; _self.cancel = function() { timer && clearTimeout(timer); timer = null; }; _self.isPending = function() { return timer; }; return _self; }; }); define("./text_highlight_rules.js", function(require, exports, module) { "use strict"; var lang = require("../lib/lang"); var TextHighlightRules = function() { // regexp must not have capturing parentheses // regexps are ordered -> the first match is used this.$rules = { "start" : [{ token : "empty_line", regex : '^$' }, { defaultToken : "text" }] }; }; (function() { this.addRules = function(rules, prefix) { if (!prefix) { for (var key in rules) this.$rules[key] = rules[key]; return; } for (var key in rules) { var state = rules[key]; for (var i = 0; i < state.length; i++) { var rule = state[i]; if (rule.next || rule.onMatch) { if (typeof rule.next != "string") { if (rule.nextState && rule.nextState.indexOf(prefix) !== 0) rule.nextState = prefix + rule.nextState; } else { if (rule.next.indexOf(prefix) !== 0) rule.next = prefix + rule.next; } } } this.$rules[prefix + key] = state; } }; this.getRules = function() { return this.$rules; }; this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) { var embedRules = typeof HighlightRules == "function" ? new HighlightRules().getRules() : HighlightRules; if (states) { for (var i = 0; i < states.length; i++) states[i] = prefix + states[i]; } else { states = []; for (var key in embedRules) states.push(prefix + key); } this.addRules(embedRules, prefix); if (escapeRules) { var addRules = Array.prototype[append ? "push" : "unshift"]; for (var i = 0; i < states.length; i++) addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules)); } if (!this.$embeds) this.$embeds = []; this.$embeds.push(prefix); }; this.getEmbeds = function() { return this.$embeds; }; var pushState = function(currentState, stack) { if (currentState != "start" || stack.length) stack.unshift(this.nextState, currentState); return this.nextState; }; var popState = function(currentState, stack) { // if (stack[0] === currentState) stack.shift(); return stack.shift() || "start"; }; this.normalizeRules = function() { var id = 0; var rules = this.$rules; function processState(key) { var state = rules[key]; state.processed = true; for (var i = 0; i < state.length; i++) { var rule = state[i]; if (!rule.regex && rule.start) { rule.regex = rule.start; if (!rule.next) rule.next = []; rule.next.push({ defaultToken: rule.token }, { token: rule.token + ".end", regex: rule.end || rule.start, next: "pop" }); rule.token = rule.token + ".start"; rule.push = true; } var next = rule.next || rule.push; if (next && Array.isArray(next)) { var stateName = rule.stateName; if (!stateName) { stateName = rule.token; if (typeof stateName != "string") stateName = stateName[0] || ""; if (rules[stateName]) stateName += id++; } rules[stateName] = next; rule.next = stateName; processState(stateName); } else if (next == "pop") { rule.next = popState; } if (rule.push) { rule.nextState = rule.next || rule.push; rule.next = pushState; delete rule.push; } if (rule.rules) { for (var r in rule.rules) { if (rules[r]) { if (rules[r].push) rules[r].push.apply(rules[r], rule.rules[r]); } else { rules[r] = rule.rules[r]; } } } if (rule.include || typeof rule == "string") { var includeName = rule.include || rule; var toInsert = rules[includeName]; } else if (Array.isArray(rule)) toInsert = rule; if (toInsert) { var args = [i, 1].concat(toInsert); if (rule.noEscape) args = args.filter(function(x) {return !x.next;}); state.splice.apply(state, args); // skip included rules since they are already processed //i += args.length - 3; i--; toInsert = null; } if (rule.keywordMap) { rule.token = this.createKeywordMapper( rule.keywordMap, rule.defaultToken || "text", rule.caseInsensitive ); delete rule.defaultToken; } } } Object.keys(rules).forEach(processState, this); }; this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) { var keywords = Object.create(null); Object.keys(map).forEach(function(className) { var a = map[className]; if (ignoreCase) a = a.toLowerCase(); var list = a.split(splitChar || "|"); for (var i = list.length; i--; ) keywords[list[i]] = className; }); // in old versions of opera keywords["__proto__"] sets prototype // even on objects with __proto__=null if (Object.getPrototypeOf(keywords)) { keywords.__proto__ = null; } this.$keywordList = Object.keys(keywords); map = null; return ignoreCase ? function(value) {return keywords[value.toLowerCase()] || defaultToken } : function(value) {return keywords[value] || defaultToken }; }; this.getKeywords = function() { return this.$keywords; }; }).call(TextHighlightRules.prototype); exports.TextHighlightRules = TextHighlightRules; }); define("perl_6_highlight_rules", function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var Perl6HighlightRules = function() { // regexp must not have capturing parentheses. Use (?:) instead. // regexps are ordered -> the first match is used this.$rules = { start: [{ token: "comment.block.perl", regex: /^=begin/, push: [{ token: "comment.block.perl", regex: /^=end/, next: "pop" }, { defaultToken: "comment.block.perl" }] }, { token: "punctuation.definition.comment.perl", regex: /#/, push: [{ token: "comment.line.number-sign.perl", regex: /$/, next: "pop" }, { defaultToken: "comment.line.number-sign.perl" }] }, { token: "punctuation.definition.string.begin.perl", regex: /'/, push: [{ token: "punctuation.definition.string.end.perl", regex: /'/, next: "pop" }, { token: "constant.character.escape.perl", regex: /\\['\\]/ }, { defaultToken: "string.quoted.single.perl" }] }, { token: "punctuation.definition.string.begin.perl", regex: /"/, push: [{ token: "punctuation.definition.string.end.perl", regex: /"/, next: "pop" }, { token: "constant.character.escape.perl", regex: /\\[abtnfre"\\]/ }, { defaultToken: "string.quoted.double.perl" }] }, { token: "string.quoted.single.heredoc.perl", regex: /q(?:q|to|heredoc)*\s*:?(?:q|to|heredoc)*\s*\/.+\//, push: [{ token: "string.quoted.single.heredoc.perl", regex: /.+/, next: "pop" }, { defaultToken: "string.quoted.single.heredoc.perl" }] }, { token: "string.quoted.double.heredoc.brace.perl", regex: /(?:q|Q)(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*:?(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*{{/, push: [{ token: "string.quoted.double.heredoc.brace.perl", regex: /}}/, next: "pop" }, { include: "#qq_brace_string_content" }, { defaultToken: "string.quoted.double.heredoc.brace.perl" }] }, { token: "string.quoted.double.heredoc.paren.perl", regex: /(?:q|Q)(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*:?(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*\(\(/, push: [{ token: "string.quoted.double.heredoc.paren.perl", regex: /\)\)/, next: "pop" }, { include: "#qq_paren_string_content" }, { defaultToken: "string.quoted.double.heredoc.paren.perl" }] }, { token: "string.quoted.double.heredoc.bracket.perl", regex: /(?:q|Q)(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*:?(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*\[\[/, push: [{ token: "string.quoted.double.heredoc.bracket.perl", regex: /\]\]/, next: "pop" }, { include: "#qq_bracket_string_content" }, { defaultToken: "string.quoted.double.heredoc.bracket.perl" }] }, { token: "string.quoted.single.heredoc.brace.perl", regex: /(?:q|Q)(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*:?(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*{/, push: [{ token: "string.quoted.single.heredoc.brace.perl", regex: /}/, next: "pop" }, { include: "#qq_brace_string_content" }, { defaultToken: "string.quoted.single.heredoc.brace.perl" }] }, { token: "string.quoted.single.heredoc.slash.perl", regex: /(?:q|Q)(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*:?(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*\//, push: [{ token: "string.quoted.single.heredoc.slash.perl", regex: /\//, next: "pop" }, { include: "#qq_slash_string_content" }, { defaultToken: "string.quoted.single.heredoc.slash.perl" }] }, { token: "string.quoted.single.heredoc.paren.perl", regex: /(?:q|Q)(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*:?(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*\(/, push: [{ token: "string.quoted.single.heredoc.paren.perl", regex: /\)/, next: "pop" }, { include: "#qq_paren_string_content" }, { defaultToken: "string.quoted.single.heredoc.paren.perl" }] }, { token: "string.quoted.single.heredoc.bracket.perl", regex: /(?:q|Q)(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*:?(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*\[/, push: [{ token: "string.quoted.single.heredoc.bracket.perl", regex: /\]/, next: "pop" }, { include: "#qq_bracket_string_content" }, { defaultToken: "string.quoted.single.heredoc.bracket.perl" }] }, { token: "string.quoted.single.heredoc.single.perl", regex: /(?:q|Q)(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*:?(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*'/, push: [{ token: "string.quoted.single.heredoc.single.perl", regex: /'/, next: "pop" }, { include: "#qq_single_string_content" }, { defaultToken: "string.quoted.single.heredoc.single.perl" }] }, { token: "string.quoted.single.heredoc.double.perl", regex: /(?:q|Q)(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*:?(?:x|exec|w|words|ww|quotewords|v|val|q|single|qq|double|s|scalar|a|array|h|hash|f|function|c|closure|b|blackslash|regexp|substr|trans|codes|p|path)*\s*"/, push: [{ token: "string.quoted.single.heredoc.double.perl", regex: /"/, next: "pop" }, { include: "#qq_double_string_content" }, { defaultToken: "string.quoted.single.heredoc.double.perl" }] }, { token: "variable.other.perl", regex: /\b\$\w+\b/ }, { token: "storage.type.declare.routine.perl", regex: /\b(?:macro|sub|submethod|method|multi|proto|only|rule|token|regex|category)\b/ }, { token: "keyword.other.module.perl", regex: /\b(?:module|class|role|package|enum|grammar|slang|subset)\b/ }, { token: "variable.language.perl", regex: /\bself\b/ }, { token: "keyword.other.include.perl", regex: /\b(?:use|require)\b/ }, { token: "keyword.control.conditional.perl", regex: /\b(?:if|else|elsif|unless)\b/ }, { token: "storage.type.variable.perl", regex: /\b(?:let|my|our|state|temp|has|constant)\b/ }, { token: "keyword.control.repeat.perl", regex: /\b(?:for|loop|repeat|while|until|gather|given)\b/ }, { token: "keyword.control.flowcontrol.perl", regex: /\b(?:take|do|when|next|last|redo|return|contend|maybe|defer|default|exit|make|continue|break|goto|leave|async|lift)\b/ }, { token: "storage.modifier.type.constraints.perl", regex: /\b(?:is|as|but|trusts|of|returns|handles|where|augment|supersede)\b/ }, { token: "meta.function.perl", regex: /\b(?:BEGIN|CHECK|INIT|START|FIRST|ENTER|LEAVE|KEEP|UNDO|NEXT|LAST|PRE|POST|END|CATCH|CONTROL|TEMP)\b/ }, { token: "keyword.control.control-handlers.perl", regex: /\b(?:die|fail|try|warn)\b/ }, { token: "storage.modifier.perl", regex: /\b(?:prec|irs|ofs|ors|export|deep|binary|unary|reparsed|rw|parsed|cached|readonly|defequiv|will|ref|copy|inline|tighter|looser|equiv|assoc|required)\b/ }, { token: "constant.numeric.perl", regex: /\b(?:NaN|Inf)\b/ }, { token: "keyword.other.pragma.perl", regex: /\b(?:oo|fatal)\b/ }, { token: "support.type.perl", regex: /\b(?:Object|Any|Junction|Whatever|Capture|MatchSignature|Proxy|Matcher|Package|Module|ClassGrammar|Scalar|Array|Hash|KeyHash|KeySet|KeyBagPair|List|Seq|Range|Set|Bag|Mapping|Void|UndefFailure|Exception|Code|Block|Routine|Sub|MacroMethod|Submethod|Regex|Str|str|Blob|Char|ByteCodepoint|Grapheme|StrPos|StrLen|Version|NumComplex|num|complex|Bit|bit|bool|True|FalseIncreasing|Decreasing|Ordered|Callable|AnyCharPositional|Associative|Ordering|KeyExtractorComparator|OrderingPair|IO|KitchenSink|RoleInt|int|int1|int2|int4|int8|int16|int32|int64Rat|rat|rat1|rat2|rat4|rat8|rat16|rat32|rat64Buf|buf|buf1|buf2|buf4|buf8|buf16|buf32|buf64UInt|uint|uint1|uint2|uint4|uint8|uint16|uint32uint64|Abstraction|utf8|utf16|utf32)\b/ }, { token: "keyword.operator.perl", regex: /\b(?:div|x|xx|mod|also|leg|cmp|before|after|eq|ne|le|lt|gt|ge|eqv|ff|fff|and|andthen|Z|X|or|xor|orelse|extra|m|mm|rx|s|tr)\b/ }, { token: "variable.other.basic.perl", regex: /(?:\$|@|%|&)(?:\*|:|!|\^|~|=|\?|<(?=.+>))?[A-Za-z_](?:[A-Za-z0-9_]|[\-'][A-Za-z0-9_])*/ }, { token: "support.function.perl", regex: /\b(?:eager|hyper|substr|index|rindex|grep|map|sort|join|lines|hints|chmod|split|reduce|min|max|reverse|truncate|zip|cat|roundrobin|classify|first|sum|keys|values|pairs|defined|delete|exists|elems|end|kv|any|all|one|wrap|shape|key|value|name|pop|push|shift|splice|unshift|floor|ceiling|abs|exp|log|log10|rand|sign|sqrt|sin|cos|tan|round|strand|roots|cis|unpolar|polar|atan2|pick|chop|p5chop|chomp|p5chomp|lc|lcfirst|uc|ucfirst|capitalize|normalize|pack|unpack|quotemeta|comb|samecase|sameaccent|chars|nfd|nfc|nfkd|nfkc|printf|sprintf|caller|evalfile|run|runinstead|nothing|want|bless|chr|ord|gmtime|time|eof|localtime|gethost|getpw|chroot|getlogin|getpeername|kill|fork|wait|perl|graphs|codes|bytes|clone|print|open|read|write|readline|say|seek|close|opendir|readdir|slurp|spurt|shell|run|pos|fmt|vec|link|unlink|symlink|uniq|pair|asin|atan|sec|cosec|cotan|asec|acosec|acotan|sinh|cosh|tanh|asinh|done|acos|acosh|atanh|sech|cosech|cotanh|sech|acosech|acotanh|asech|ok|nok|plan_ok|dies_ok|lives_ok|skip|todo|pass|flunk|force_todo|use_ok|isa_ok|diag|is_deeply|isnt|like|skip_rest|unlike|cmp_ok|eval_dies_ok|nok_error|eval_lives_ok|approx|is_approx|throws_ok|version_lt|plan|EVAL|succ|pred|times|nonce|once|signature|new|connect|operator|undef|undefine|sleep|from|to|infix|postfix|prefix|circumfix|postcircumfix|minmax|lazy|count|unwrap|getc|pi|e|context|void|quasi|body|each|contains|rewinddir|subst|can|isa|flush|arity|assuming|rewind|callwith|callsame|nextwith|nextsame|attr|eval_elsewhere|none|srand|trim|trim_start|trim_end|lastcall|WHAT|WHERE|HOW|WHICH|VAR|WHO|WHENCE|ACCEPTS|REJECTS|not|true|iterator|by|re|im|invert|flip|gist|flat|tree|is-prime|throws_like|trans)\b/ }], "#qq_brace_string_content": [{ token: "text", regex: /{/, push: [{ token: "text", regex: /}/, next: "pop" }, { include: "#qq_brace_string_content" }] }], "#qq_bracket_string_content": [{ token: "text", regex: /\[/, push: [{ token: "text", regex: /\]/, next: "pop" }, { include: "#qq_bracket_string_content" }] }], "#qq_double_string_content": [{ token: "text", regex: /"/, push: [{ token: "text", regex: /"/, next: "pop" }, { include: "#qq_double_string_content" }] }], "#qq_paren_string_content": [{ token: "text", regex: /\(/, push: [{ token: "text", regex: /\)/, next: "pop" }, { include: "#qq_paren_string_content" }] }], "#qq_single_string_content": [{ token: "text", regex: /'/, push: [{ token: "text", regex: /'/, next: "pop" }, { include: "#qq_single_string_content" }] }], "#qq_slash_string_content": [{ token: "text", regex: /\\\//, push: [{ token: "text", regex: /\\\//, next: "pop" }, { include: "#qq_slash_string_content" }] }] } this.normalizeRules(); }; Perl6HighlightRules.metaData = { fileTypes: ["p6", "pl6", "pm6", "nqp"], firstLineMatch: "(^#!.*\\bperl6\\b)|use\\s+v6", keyEquivalent: "^~P", name: "Perl 6", scopeName: "source.perl.6" } oop.inherits(Perl6HighlightRules, TextHighlightRules); exports.Perl6HighlightRules = Perl6HighlightRules; }); // Ace highlight rules function imported below. var HighlightRules = require("perl_6_highlight_rules").Perl6HighlightRules; // Ace's Syntax Tokenizer. // tokenizing lines longer than this makes editor very slow var MAX_TOKEN_COUNT = 1000; var Tokenizer = function(rules) { this.states = rules; this.regExps = {}; this.matchMappings = {}; for (var key in this.states) { var state = this.states[key]; var ruleRegExps = []; var matchTotal = 0; var mapping = this.matchMappings[key] = {defaultToken: "text"}; var flag = "g"; var splitterRurles = []; for (var i = 0; i < state.length; i++) { var rule = state[i]; if (rule.defaultToken) mapping.defaultToken = rule.defaultToken; if (rule.caseInsensitive) flag = "gi"; if (rule.regex == null) continue; if (rule.regex instanceof RegExp) rule.regex = rule.regex.toString().slice(1, -1); // Count number of matching groups. 2 extra groups from the full match // And the catch-all on the end (used to force a match); var adjustedregex = rule.regex; var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2; if (Array.isArray(rule.token)) { if (rule.token.length == 1 || matchcount == 1) { rule.token = rule.token[0]; } else if (matchcount - 1 != rule.token.length) { throw new Error("number of classes and regexp groups in '" + rule.token + "'\n'" + rule.regex + "' doesn't match\n" + (matchcount - 1) + "!=" + rule.token.length); } else { rule.tokenArray = rule.token; rule.token = null; rule.onMatch = this.$arrayTokens; } } else if (typeof rule.token == "function" && !rule.onMatch) { if (matchcount > 1) rule.onMatch = this.$applyToken; else rule.onMatch = rule.token; } if (matchcount > 1) { if (/\\\d/.test(rule.regex)) { // Replace any backreferences and offset appropriately. adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function(match, digit) { return "\\" + (parseInt(digit, 10) + matchTotal + 1); }); } else { matchcount = 1; adjustedregex = this.removeCapturingGroups(rule.regex); } if (!rule.splitRegex && typeof rule.token != "string") splitterRurles.push(rule); // flag will be known only at the very end } mapping[matchTotal] = i; matchTotal += matchcount; ruleRegExps.push(adjustedregex); // makes property access faster if (!rule.onMatch) rule.onMatch = null; } splitterRurles.forEach(function(rule) { rule.splitRegex = this.createSplitterRegexp(rule.regex, flag); }, this); this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag); } }; (function() { this.$setMaxTokenCount = function(m) { MAX_TOKEN_COUNT = m | 0; }; this.$applyToken = function(str) { var values = this.splitRegex.exec(str).slice(1); var types = this.token.apply(this, values); // required for compatibility with old modes if (typeof types === "string") return [{type: types, value: str}]; var tokens = []; for (var i = 0, l = types.length; i < l; i++) { if (values[i]) tokens[tokens.length] = { type: types[i], value: values[i] }; } return tokens; }, this.$arrayTokens = function(str) { if (!str) return []; var values = this.splitRegex.exec(str); if (!values) return "text"; var tokens = []; var types = this.tokenArray; for (var i = 0, l = types.length; i < l; i++) { if (values[i + 1]) tokens[tokens.length] = { type: types[i], value: values[i + 1] }; } return tokens; }; this.removeCapturingGroups = function(src) { var r = src.replace( /\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g, function(x, y) {return y ? "(?:" : x;} ); return r; }; this.createSplitterRegexp = function(src, flag) { if (src.indexOf("(?=") != -1) { var stack = 0; var inChClass = false; var lastCapture = {}; src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g, function( m, esc, parenOpen, parenClose, square, index ) { if (inChClass) { inChClass = square != "]"; } else if (square) { inChClass = true; } else if (parenClose) { if (stack == lastCapture.stack) { lastCapture.end = index+1; lastCapture.stack = -1; } stack--; } else if (parenOpen) { stack++; if (parenOpen.length != 1) { lastCapture.stack = stack lastCapture.start = index; } } return m; }); if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end))) src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end); } return new RegExp(src, (flag||"").replace("g", "")); }; /** * Returns an object containing two properties: `tokens`, which contains all the tokens; and `state`, the current state. * @returns {Object} **/ this.getLineTokens = function(line, startState) { if (startState && typeof startState != "string") { var stack = startState.slice(0); startState = stack[0]; } else var stack = []; var currentState = startState || "start"; var state = this.states[currentState]; if (!state) { currentState = "start"; state = this.states[currentState]; } var mapping = this.matchMappings[currentState]; var re = this.regExps[currentState]; re.lastIndex = 0; var match, tokens = []; var lastIndex = 0; var token = {type: null, value: ""}; while (match = re.exec(line)) { var type = mapping.defaultToken; var rule = null; var value = match[0]; var index = re.lastIndex; if (index - value.length > lastIndex) { var skipped = line.substring(lastIndex, index - value.length); if (token.type == type) { token.value += skipped; } else { if (token.type) tokens.push(token); token = {type: type, value: skipped}; } } for (var i = 0; i < match.length-2; i++) { if (match[i + 1] === undefined) continue; rule = state[mapping[i]]; if (rule.onMatch) type = rule.onMatch(value, currentState, stack); else type = rule.token; if (rule.next) { if (typeof rule.next == "string") currentState = rule.next; else currentState = rule.next(currentState, stack); state = this.states[currentState]; if (!state) { window.console && console.error && console.error(currentState, "doesn't exist"); currentState = "start"; state = this.states[currentState]; } mapping = this.matchMappings[currentState]; lastIndex = index; re = this.regExps[currentState]; re.lastIndex = index; } break; } if (value) { if (typeof type == "string") { if ((!rule || rule.merge !== false) && token.type === type) { token.value += value; } else { if (token.type) tokens.push(token); token = {type: type, value: value}; } } else if (type) { if (token.type) tokens.push(token); token = {type: null, value: ""}; for (var i = 0; i < type.length; i++) tokens.push(type[i]); } } if (lastIndex == line.length) break; lastIndex = index; if (tokens.length > MAX_TOKEN_COUNT) { // chrome doens't show contents of text nodes with very long text while (lastIndex < line.length) { if (token.type) tokens.push(token); token = { value: line.substring(lastIndex, lastIndex += 2000), type: "overflow" }; } currentState = "start"; stack = []; break; } } if (token.type) tokens.push(token); if (stack.length > 1) { if (stack[0] !== currentState) stack.unshift(currentState); } return { tokens : tokens, state : stack.length ? stack : currentState }; }; }).call(Tokenizer.prototype); // Token conversion. // See <https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode#common-tokens> // This is not an exact match nor the best match that can be made. var tokenFromAceToken = { empty: null, text: null, // Keyword keyword: 'keyword', control: 'keyword', operator: 'operator', // Constants constant: 'atom', numeric: 'number', character: 'atom', escape: 'atom', // Variables variable: 'variable', parameter: 'variable-3', language: 'variable-2', // Python's `self` uses that. // Comments comment: 'comment', line: 'comment', 'double-slash': 'comment', 'double-dash': 'comment', 'number-sign': 'comment', percentage: 'comment', block: 'comment', documentation: 'comment', // String string: 'string', quoted: 'string', single: 'string', double: 'string', triple: 'string', unquoted: 'string', interpolated: 'string', regexp: 'string-2', meta: 'meta', literal: 'qualifier', support: 'builtin', // Markup markup: 'tag', underline: 'link', link: 'link', bold: 'strong', heading: 'header', italic: 'em', list: 'variable-2', numbered: 'variable-2', unnumbered: 'variable-2', quote: 'quote', raw: 'variable-2', // Markdown's raw block uses that. // Invalid invalid: 'error', illegal: 'invalidchar', deprecated: 'error' }; // Takes a list of Ace tokens, returns a (string) CodeMirror token. var cmTokenFromAceTokens = function(tokens) { var token = null; for (var i = 0; i < tokens.length; i++) { // Find the most specific token. if (tokenFromAceToken[tokens[i]] !== undefined) { token = tokenFromAceToken[tokens[i]]; } } return token; }; // Consume a token from plannedTokens. var consumeToken = function(stream, state) { var plannedToken = state.plannedTokens.shift(); if (plannedToken === undefined) { return null; } stream.match(plannedToken.value); var tokens = plannedToken.type.split('.'); return cmTokenFromAceTokens(tokens); }; var matchToken = function(stream, state) { // Anormal start: we already have planned tokens to consume. if (state.plannedTokens.length > 0) { return consumeToken(stream, state); } // Normal start. var currentState = state.current; var currentLine = stream.match(/.*$/, false)[0]; var tokenized = tokenizer.getLineTokens(currentLine, currentState); // We got a {tokens, state} object. // Each token is a {value, type} object. state.plannedTokens = tokenized.tokens; state.current = tokenized.state; // Consume a token. return consumeToken(stream, state); } // Initialize all state. var aceHighlightRules = new HighlightRules(); var tokenizer = new Tokenizer(aceHighlightRules.$rules); return { startState: function() { return { current: 'start', // List of {value, type}, with type being an Ace token string. plannedTokens: [] }; }, blankLine: function(state) { matchToken('', state); }, token: matchToken }; }); CodeMirror.defineMIME("text/x-perl6", "perl6");