Blame | Letzte Änderung | Log anzeigen | RSS feed
// CodeMirror, copyright (c) by Marijn Haverbeke and others// Distributed under an MIT license: http://codemirror.net/LICENSE(function(mod) {if (typeof exports == "object" && typeof module == "object") // CommonJSmod(require("../../lib/codemirror"));else if (typeof define == "function" && define.amd) // AMDdefine(["../../lib/codemirror"], mod);else // Plain browser envmod(CodeMirror);})(function(CodeMirror) {var defaults = {pairs: "()[]{}''\"\"",triples: "",explode: "[]{}"};var Pos = CodeMirror.Pos;CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {if (old && old != CodeMirror.Init) {cm.removeKeyMap(keyMap);cm.state.closeBrackets = null;}if (val) {cm.state.closeBrackets = val;cm.addKeyMap(keyMap);}});function getOption(conf, name) {if (name == "pairs" && typeof conf == "string") return conf;if (typeof conf == "object" && conf[name] != null) return conf[name];return defaults[name];}var bind = defaults.pairs + "`";var keyMap = {Backspace: handleBackspace, Enter: handleEnter};for (var i = 0; i < bind.length; i++)keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i));function handler(ch) {return function(cm) { return handleChar(cm, ch); };}function getConfig(cm) {var deflt = cm.state.closeBrackets;if (!deflt) return null;var mode = cm.getModeAt(cm.getCursor());return mode.closeBrackets || deflt;}function handleBackspace(cm) {var conf = getConfig(cm);if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;var pairs = getOption(conf, "pairs");var ranges = cm.listSelections();for (var i = 0; i < ranges.length; i++) {if (!ranges[i].empty()) return CodeMirror.Pass;var around = charsAround(cm, ranges[i].head);if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;}for (var i = ranges.length - 1; i >= 0; i--) {var cur = ranges[i].head;cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));}}function handleEnter(cm) {var conf = getConfig(cm);var explode = conf && getOption(conf, "explode");if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;var ranges = cm.listSelections();for (var i = 0; i < ranges.length; i++) {if (!ranges[i].empty()) return CodeMirror.Pass;var around = charsAround(cm, ranges[i].head);if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;}cm.operation(function() {cm.replaceSelection("\n\n", null);cm.execCommand("goCharLeft");ranges = cm.listSelections();for (var i = 0; i < ranges.length; i++) {var line = ranges[i].head.line;cm.indentLine(line, null, true);cm.indentLine(line + 1, null, true);}});}function handleChar(cm, ch) {var conf = getConfig(cm);if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;var pairs = getOption(conf, "pairs");var pos = pairs.indexOf(ch);if (pos == -1) return CodeMirror.Pass;var triples = getOption(conf, "triples");var identical = pairs.charAt(pos + 1) == ch;var ranges = cm.listSelections();var opening = pos % 2 == 0;var type, next;for (var i = 0; i < ranges.length; i++) {var range = ranges[i], cur = range.head, curType;var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));if (opening && !range.empty()) {curType = "surround";} else if ((identical || !opening) && next == ch) {if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)curType = "skipThree";elsecurType = "skip";} else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch &&(cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) {curType = "addFour";} else if (identical) {if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both";else return CodeMirror.Pass;} else if (opening && (cm.getLine(cur.line).length == cur.ch ||isClosingBracket(next, pairs) ||/\s/.test(next))) {curType = "both";} else {return CodeMirror.Pass;}if (!type) type = curType;else if (type != curType) return CodeMirror.Pass;}var left = pos % 2 ? pairs.charAt(pos - 1) : ch;var right = pos % 2 ? ch : pairs.charAt(pos + 1);cm.operation(function() {if (type == "skip") {cm.execCommand("goCharRight");} else if (type == "skipThree") {for (var i = 0; i < 3; i++)cm.execCommand("goCharRight");} else if (type == "surround") {var sels = cm.getSelections();for (var i = 0; i < sels.length; i++)sels[i] = left + sels[i] + right;cm.replaceSelections(sels, "around");} else if (type == "both") {cm.replaceSelection(left + right, null);cm.triggerElectric(left + right);cm.execCommand("goCharLeft");} else if (type == "addFour") {cm.replaceSelection(left + left + left + left, "before");cm.execCommand("goCharRight");}});}function isClosingBracket(ch, pairs) {var pos = pairs.lastIndexOf(ch);return pos > -1 && pos % 2 == 1;}function charsAround(cm, pos) {var str = cm.getRange(Pos(pos.line, pos.ch - 1),Pos(pos.line, pos.ch + 1));return str.length == 2 ? str : null;}// Project the token type that will exists after the given char is// typed, and use it to determine whether it would cause the start// of a string token.function enteringString(cm, pos, ch) {var line = cm.getLine(pos.line);var token = cm.getTokenAt(pos);if (/\bstring2?\b/.test(token.type)) return false;var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4);stream.pos = stream.start = token.start;for (;;) {var type1 = cm.getMode().token(stream, token.state);if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1);stream.start = stream.pos;}}});