/*global ace*/ ace.define("ace/mode/mp_highlight_rules", ["require", "exports", "module", "ace/lib/oop"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; var MpHighlightRules = function() { this.$rules = { // identifier: [a-zA-Z0-9]\w* // variable: \$\w+ start: [ // line comment { token: "comment.line.double-slash", regex: /\/\/.*/, }, // multi-line comment { token: "comment.block", regex: /\/\*/, next: "comment", }, // schema { token: [ "keyword.operator", "text", "entity.name.section", "text", "punctuation.operator", ], regex: /(\bSCHEMA\b)(\s+)([a-zA-Z0-9]\w*)(\s*)(;?)/, }, // includes { token: [ "keyword.operator", "text", "entity.name.section", "text", "punctuation.operator", ], regex: /(\bINCLUDE\b)(\s+)([a-zA-Z0-9]\w*)(\s*)(;)/, }, // roots { token: [ "keyword", "text", "variable.other", "text", "punctuation.operator", ], regex: /(\bROOT\b)(\s+)([a-zA-Z0-9]\w*)(\s*)(:)/, push: "eventPatternList", }, // events { token: [ "variable.other", "text", "punctuation.operator", ], regex: /([a-zA-Z0-9]\w*)(\s*)(:)/, push: "eventPatternList", }, // push: shareAll { token: "entity.name.tag", regex: /([a-zA-Z0-9$]\w*)(?=[$\w\s,]+\bSHARE\s+ALL\b)/, push: "shareAll", }, // push: coordinate { token: "keyword.control", regex: /(\bCOORDINATE\b)/, push: "coordinate", }, // whitespace { token: "text", regex: /\s+/, }, // default: invalid { defaultToken: "invalid" }, ], eventPatternList: [ // opening bracket { token: [ "paren.lparen.type", "paren.lparen.quantifier", ], regex: /([\[({])([*+]?)/, }, // closing bracket { token: [ "paren.rparen.quantifier", "paren.rparen.type", ], regex: /([*+]?)([\])}])/, }, // scope { token: [ "comment", "comment", "comment", "comment", ], regex: /(<)(\d)(\.\.\d)?(>)/, }, // seperators { token: "keyword.operator", regex: /[,|]/, }, // identifiers { token: "text", regex: /\$\w[\w\d_]*/, }, { token: "punctuation.operator", regex: /;/, next: "pop", }, ], shareAll: [ // share all { token: "support.function", regex: /(\bSHARE\s+ALL\b)/, }, // id list { token: "entity.name.tag", regex: /([a-zA-Z0-9]\w*)/, }, // list seperator { token: "text", regex: /[, ]/, }, // pop: semicolon { token: "punctuation.operator", regex: /(;)/, next: "pop", }, ], coordinate: [ // async flag { token: "support.function", regex: /()/, }, // coordination source list { token: [ "variable", "punctuation.operator", "text", "text", "text", ], regex: /(\$\w+)(\s*:\s*)([a-zA-Z0-9]\w*|[(](([a-zA-Z0-9]\w*\s*\|?)+)[)])/, }, // coordination source from { token:[ "keyword.control", "text", "variable", "text", ], regex: /(\bFROM\b)(\s+)(?:(\$\w+)|([a-zA-Z0-9]\w*))/, }, // push: doBlock { token: "support.constant", regex: /(\bDO\b)/, push: "doBlock", }, // pop: semi { token: "punctuation.operator", regex: /;/, next: "pop", }, // seperator { token: "punctuation.operator", regex: /,/, }, // whitespace { token: "text", regex: /\s+/, }, ], addRelation: [ // relationship list { token: [ "variable", "text", "support.function", "text", "variable", ], regex: /(\$\w+)(\s+)(IN|PRECEDES|CONTAINS|FOLLOWS)(\s+)(\$\w+)/, }, // seperator { token: "text", regex: /[, ]/, }, // pop: semicolon { token: "punctuation.operator", regex: /;/, next: "pop", }, ], doBlock: [ // push: addRelation { token: "support.function", regex: /(\bADD\b)/, push: "addRelation", }, // push: share all { token: "text", regex: /([a-zA-Z0-9]\w*)(?=[\w\s,]+\bSHARE\s+ALL\b)/, push: "shareAll", }, // push: coordinate { token: "keyword.control", regex: /(\bCOORDINATE\b)/, push: "coordinate", }, // pop: od { token: "support.constant", regex: /(\bOD\b)/, next: "pop", }, ], comment: [ // multi-line comment terminator { token: "comment.block", regex: /.*?\*\//, next: "start", }, // stuff { regex: /.*/, token: "comment.block", }, ], meta: { dontIndentStates: ["comment"], lineComment: "//", }, }; this.normalizeRules(); }; oop.inherits(MpHighlightRules, TextHighlightRules); exports.MpHighlightRules = MpHighlightRules; }); ace.define("ace/mode/mp", ["require", "exports", "module", "ace/lib/oop", "ace/mode/text", "ace/mode/mp_highlight_rules"], function(require, exports, module) { "use strict"; var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; var CstyleFoldMode = require("./folding/cstyle").FoldMode; var MpHighlightRules = require("./mp_highlight_rules").MpHighlightRules; var Mode = function() { this.HighlightRules = MpHighlightRules; this.$behaviour = new CstyleBehaviour(); this.foldingRules = new CstyleFoldMode(); }; oop.inherits(Mode, TextMode); (function() { this.lineCommentStart = "//"; this.blockComment = {start:"/*", end:"*/"}; this.$id = "ace/mode/mp"; this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); var tokenizedLine = this.getTokenizer().getLineTokens(line, state); var tokens = tokenizedLine.tokens; if (tokens.length && tokens[tokens.length - 1].type === "comment") { return indent; } var match; if (state === "eventPatternList") { match = line.match(/^.*(?:[:]).*$/); if (match) { indent += tab; } } else if (state[0] === "coordinate" || state[0] === "doBlock") { match = line.match(/^.*(?:\bDO)\s*$/); if (match) { indent += tab; } } return indent; }; }).call(Mode.prototype); exports.Mode = Mode; }); ace.define("ace/mode/behaviour/cstyle", ["require", "exports", "module", "ace/lib/oop", "ace/mode/behaviour", "ace/token_iterator", "ace/lib/lang"], function(require, exports, module) { "use strict"; var oop = require("../../lib/oop"); var Behaviour = require("../behaviour").Behaviour; var TokenIterator = require("../../token_iterator").TokenIterator; var lang = require("../../lib/lang"); var SAFE_INSERT_IN_TOKENS = ["text", "paren.rparen", "punctuation.operator"]; var SAFE_INSERT_BEFORE_TOKENS = ["text", "paren.rparen", "punctuation.operator", "comment"]; var context; var contextCache = {}; var initContext = function(editor) { var id = -1; if (editor.multiSelect) { id = editor.selection.index; if (contextCache.rangeCount !== editor.multiSelect.rangeCount) contextCache = {rangeCount: editor.multiSelect.rangeCount}; } if (contextCache[id]) return context = contextCache[id]; context = contextCache[id] = { autoInsertedBrackets: 0, autoInsertedRow: -1, autoInsertedLineEnd: "", maybeInsertedBrackets: 0, maybeInsertedRow: -1, maybeInsertedLineStart: "", maybeInsertedLineEnd: "", }; }; var getWrapped = function(selection, selected, opening, closing) { var rowDiff = selection.end.row - selection.start.row; return { text: opening + selected + closing, selection: [ 0, selection.start.column + 1, rowDiff, selection.end.column + (rowDiff ? 0 : 1), ], }; }; var CstyleBehaviour = function() { this.add("braces", "insertion", function(state, action, editor, session, text) { var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); if (text === "{") { initContext(editor); var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) { return getWrapped(selection, selected, "{", "}"); } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode) { CstyleBehaviour.recordAutoInsert(editor, session, "}"); return { text: "{}", selection: [1, 1], }; } else { CstyleBehaviour.recordMaybeInsert(editor, session, "{"); return { text: "{", selection: [1, 1], }; } } } else if (text === "}") { initContext(editor); var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar === "}") { var matching = session.$findOpeningBracket("}", {column: cursor.column + 1, row: cursor.row}); if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { CstyleBehaviour.popAutoInsertedClosing(); return { text: "", selection: [1, 1], }; } } } else if (text === "\n" || text === "\r\n") { initContext(editor); var closing = ""; if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) { closing = lang.stringRepeat("}", context.maybeInsertedBrackets); CstyleBehaviour.clearMaybeInsertedClosing(); } var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar === "}") { var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column + 1}, "}"); if (!openBracePos) return null; var next_indent = this.$getIndent(session.getLine(openBracePos.row)); } else if (closing) { var next_indent = this.$getIndent(line); } else { CstyleBehaviour.clearMaybeInsertedClosing(); return; } var indent = next_indent + session.getTabString(); return { text: "\n" + indent + "\n" + next_indent + closing, selection: [1, indent.length, 1, indent.length], }; } else { CstyleBehaviour.clearMaybeInsertedClosing(); } }); this.add("braces", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && selected === "{") { initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.end.column, range.end.column + 1); if (rightChar === "}") { range.end.column++; return range; } else { context.maybeInsertedBrackets--; } } }); this.add("parens", "insertion", function(state, action, editor, session, text) { if (text === "(") { initContext(editor); var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && editor.getWrapBehavioursEnabled()) { return getWrapped(selection, selected, "(", ")"); } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { CstyleBehaviour.recordAutoInsert(editor, session, ")"); return { text: "()", selection: [1, 1], }; } } else if (text === ")") { initContext(editor); var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar === ")") { var matching = session.$findOpeningBracket(")", {column: cursor.column + 1, row: cursor.row}); if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { CstyleBehaviour.popAutoInsertedClosing(); return { text: "", selection: [1, 1], }; } } } }); this.add("parens", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && selected === "(") { initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.start.column + 1, range.start.column + 2); if (rightChar === ")") { range.end.column++; return range; } } }); this.add("brackets", "insertion", function(state, action, editor, session, text) { if (text == "[") { initContext(editor); var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && editor.getWrapBehavioursEnabled()) { return getWrapped(selection, selected, "[", "]"); } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { CstyleBehaviour.recordAutoInsert(editor, session, "]"); return { text: "[]", selection: [1, 1], }; } } else if (text == "]") { initContext(editor); var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); var rightChar = line.substring(cursor.column, cursor.column + 1); if (rightChar == "]") { var matching = session.$findOpeningBracket("]", {column: cursor.column + 1, row: cursor.row}); if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { CstyleBehaviour.popAutoInsertedClosing(); return { text: "", selection: [1, 1], }; } } } }); this.add("brackets", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && selected == "[") { initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.start.column + 1, range.start.column + 2); if (rightChar == "]") { range.end.column++; return range; } } }); this.add("string_dquotes", "insertion", function(state, action, editor, session, text) { if (text === '"' || text === "'") { initContext(editor); var quote = text; var selection = editor.getSelectionRange(); var selected = session.doc.getTextRange(selection); if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { return getWrapped(selection, selected, quote, quote); } else if (!selected) { var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); var leftChar = line.substring(cursor.column - 1, cursor.column); var rightChar = line.substring(cursor.column, cursor.column + 1); var token = session.getTokenAt(cursor.row, cursor.column); var rightToken = session.getTokenAt(cursor.row, cursor.column + 1); if (leftChar === "\\" && token && /escape/.test(token.type)) return null; var stringBefore = token && /string/.test(token.type); var stringAfter = !rightToken || /string/.test(rightToken.type); var pair; if (rightChar === quote) { pair = stringBefore !== stringAfter; } else { if (stringBefore && !stringAfter) return null; // wrap string with different quote if (stringBefore && stringAfter) return null; // do not pair quotes inside strings var wordRe = session.$mode.tokenRe; wordRe.lastIndex = 0; var isWordBefore = wordRe.test(leftChar); wordRe.lastIndex = 0; var isWordAfter = wordRe.test(leftChar); if (isWordBefore || isWordAfter) return null; // before or after alphanumeric if (rightChar && !/[\s;,.})\]\\]/.test(rightChar)) return null; // there is rightChar and it isn't closing pair = true; } return { text: pair ? quote + quote : "", selection: [1, 1], }; } } }); this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { var selected = session.doc.getTextRange(range); if (!range.isMultiLine() && (selected === '"' || selected === "'")) { initContext(editor); var line = session.doc.getLine(range.start.row); var rightChar = line.substring(range.start.column + 1, range.start.column + 2); if (rightChar === selected) { range.end.column++; return range; } } }); }; CstyleBehaviour.isSaneInsertion = function(editor, session) { var cursor = editor.getCursorPosition(); var iterator = new TokenIterator(session, cursor.row, cursor.column); if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) { var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1); if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) return false; } iterator.stepForward(); return iterator.getCurrentTokenRow() !== cursor.row || this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS); }; CstyleBehaviour.$matchTokenType = function(token, types) { return types.indexOf(token.type || token) > -1; }; CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) { var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0])) context.autoInsertedBrackets = 0; context.autoInsertedRow = cursor.row; context.autoInsertedLineEnd = bracket + line.substr(cursor.column); context.autoInsertedBrackets++; }; CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) { var cursor = editor.getCursorPosition(); var line = session.doc.getLine(cursor.row); if (!this.isMaybeInsertedClosing(cursor, line)) context.maybeInsertedBrackets = 0; context.maybeInsertedRow = cursor.row; context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket; context.maybeInsertedLineEnd = line.substr(cursor.column); context.maybeInsertedBrackets++; }; CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) { return context.autoInsertedBrackets > 0 && cursor.row === context.autoInsertedRow && bracket === context.autoInsertedLineEnd[0] && line.substr(cursor.column) === context.autoInsertedLineEnd; }; CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) { return context.maybeInsertedBrackets > 0 && cursor.row === context.maybeInsertedRow && line.substr(cursor.column) === context.maybeInsertedLineEnd && line.substr(0, cursor.column) === context.maybeInsertedLineStart; }; CstyleBehaviour.popAutoInsertedClosing = function() { context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1); context.autoInsertedBrackets--; }; CstyleBehaviour.clearMaybeInsertedClosing = function() { if (context) { context.maybeInsertedBrackets = 0; context.maybeInsertedRow = -1; } }; oop.inherits(CstyleBehaviour, Behaviour); exports.CstyleBehaviour = CstyleBehaviour; }); ace.define("ace/mode/folding/cstyle", ["require", "exports", "module", "ace/lib/oop", "ace/range", "ace/mode/folding/fold_mode"], function(require, exports, module) { "use strict"; var oop = require("../../lib/oop"); var Range = require("../../range").Range; var BaseFoldMode = require("./fold_mode").FoldMode; var FoldMode = exports.FoldMode = function(commentRegex) { if (commentRegex) { this.foldingStartMarker = new RegExp( this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) ); this.foldingStopMarker = new RegExp( this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) ); } }; oop.inherits(FoldMode, BaseFoldMode); (function() { this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/; this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/; this.singleLineBlockCommentRe = /^\s*(\/\*).*\*\/\s*$/; this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; this.startRegionRe = /^\s*(\/\*|\/\/)#region\b/; this._getFoldWidgetBase = this.getFoldWidget; this.getFoldWidget = function(session, foldStyle, row) { var line = session.getLine(row); if (this.singleLineBlockCommentRe.test(line)) { if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) return ""; } var fw = this._getFoldWidgetBase(session, foldStyle, row); if (!fw && this.startRegionRe.test(line)) return "start"; // lineCommentRegionStart return fw; }; this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { var line = session.getLine(row); if (this.startRegionRe.test(line)) return this.getCommentRegionBlock(session, line, row); var match = line.match(this.foldingStartMarker); if (match) { var i = match.index; if (match[1]) return this.openingBracketBlock(session, match[1], row, i); var range = session.getCommentFoldRange(row, i + match[0].length, 1); if (range && !range.isMultiLine()) { if (forceMultiline) { range = this.getSectionRange(session, row); } else if (foldStyle !== "all") range = null; } return range; } if (foldStyle === "markbegin") return; match = line.match(this.foldingStopMarker); if (match) { var i = match.index + match[0].length; if (match[1]) return this.closingBracketBlock(session, match[1], row, i); return session.getCommentFoldRange(row, i, -1); } }; this.getSectionRange = function(session, row) { var line = session.getLine(row); var startIndent = line.search(/\S/); var startRow = row; var startColumn = line.length; row = row + 1; var endRow = row; var maxRow = session.getLength(); while (++row < maxRow) { line = session.getLine(row); var indent = line.search(/\S/); if (indent === -1) continue; if (startIndent > indent) break; var subRange = this.getFoldWidgetRange(session, "all", row); if (subRange) { if (subRange.start.row <= startRow) { break; } else if (subRange.isMultiLine()) { row = subRange.end.row; } else if (startIndent === indent) { break; } } endRow = row; } return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); }; this.getCommentRegionBlock = function(session, line, row) { var startColumn = line.search(/\s*$/); var maxRow = session.getLength(); var startRow = row; var re = /^\s*(?:\/\*|\/\/)#(end)?region\b/; var depth = 1; while (++row < maxRow) { line = session.getLine(row); var m = re.exec(line); if (!m) continue; if (m[1]) depth--; else depth++; if (!depth) break; } var endRow = row; if (endRow > startRow) { return new Range(startRow, startColumn, endRow, line.length); } }; }).call(FoldMode.prototype); });