Bug 1411006 - Update Codemirror to 5.31.0. r=bgrins

This commit is contained in:
Gabriel Luong 2017-10-30 11:35:22 -04:00
Родитель f816048114
Коммит 794b972d33
15 изменённых файлов: 725 добавлений и 292 удалений

Просмотреть файл

@ -5,7 +5,7 @@ code, and optionally help with indentation.
# Upgrade
Currently used version is 5.30.0. To upgrade: download a new version of
Currently used version is 5.31.0. To upgrade: download a new version of
CodeMirror from the project's page [1] and replace all JavaScript and
CSS files inside the codemirror directory [2].

Просмотреть файл

@ -9,11 +9,6 @@
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var modes = ["clike", "css", "javascript"];
for (var i = 0; i < modes.length; ++i)
CodeMirror.extendMode(modes[i], {blockCommentContinue: " * "});
function continueComment(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), mode, inserts = [];
@ -27,10 +22,10 @@
var insert = null;
if (mode.blockCommentStart && mode.blockCommentContinue) {
var line = cm.getLine(pos.line).slice(0, pos.ch)
var end = line.indexOf(mode.blockCommentEnd), found
var end = line.lastIndexOf(mode.blockCommentEnd), found
if (end != -1 && end == pos.ch - mode.blockCommentEnd.length) {
// Comment ended, don't continue it
} else if ((found = line.indexOf(mode.blockCommentStart)) > -1) {
} else if ((found = line.lastIndexOf(mode.blockCommentStart)) > -1 && found > end) {
insert = line.slice(0, found)
if (/\S/.test(insert)) {
insert = ""

Просмотреть файл

@ -84,7 +84,8 @@
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
cm.replaceSelection("\n\n", null);
var linesep = cm.lineSeparator() || "\n";
cm.replaceSelection(linesep + linesep, null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {

Просмотреть файл

@ -25,7 +25,8 @@
var inQuote = eolState.quote !== 0;
var line = cm.getLine(pos.line), match = listRE.exec(line);
if (!ranges[i].empty() || (!inList && !inQuote) || !match) {
var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch));
if (!ranges[i].empty() || (!inList && !inQuote) || !match || cursorBeforeBullet) {
cm.execCommand("newlineAndIndent");
return;
}

Просмотреть файл

@ -1330,13 +1330,15 @@ var CodeMirror =
if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)) }
}
}
if (order[0].level == 1 && (m = str.match(/^\s+/))) {
order[0].from = m[0].length
order.unshift(new BidiSpan(0, 0, m[0].length))
}
if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
lst(order).to -= m[0].length
order.push(new BidiSpan(0, len - m[0].length, len))
if (direction == "ltr") {
if (order[0].level == 1 && (m = str.match(/^\s+/))) {
order[0].from = m[0].length
order.unshift(new BidiSpan(0, 0, m[0].length))
}
if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
lst(order).to -= m[0].length
order.push(new BidiSpan(0, len - m[0].length, len))
}
}
return direction == "rtl" ? order.reverse() : order
@ -1711,6 +1713,10 @@ var CodeMirror =
var oracle = this.lineOracle
return oracle && oracle.lookAhead(n)
};
StringStream.prototype.baseToken = function () {
var oracle = this.lineOracle
return oracle && oracle.baseToken(this.pos)
};
var SavedContext = function(state, lookAhead) {
this.state = state
@ -1722,6 +1728,8 @@ var CodeMirror =
this.doc = doc
this.line = line
this.maxLookAhead = lookAhead || 0
this.baseTokens = null
this.baseTokenPos = 1
};
Context.prototype.lookAhead = function (n) {
@ -1730,6 +1738,17 @@ var CodeMirror =
return line
};
Context.prototype.baseToken = function (n) {
var this$1 = this;
if (!this.baseTokens) { return null }
while (this.baseTokens[this.baseTokenPos] <= n)
{ this$1.baseTokenPos += 2 }
var type = this.baseTokens[this.baseTokenPos + 1]
return {type: type && type.replace(/( |^)overlay .*/, ""),
size: this.baseTokens[this.baseTokenPos] - n}
};
Context.prototype.nextLine = function () {
this.line++
if (this.maxLookAhead > 0) { this.maxLookAhead-- }
@ -1763,6 +1782,7 @@ var CodeMirror =
// Run overlays, adjust style array.
var loop = function ( o ) {
context.baseTokens = st
var overlay = cm.state.overlays[o], i = 1, at = 0
context.state = true
runMode(cm, line.text, overlay.mode, context, function (end, style) {
@ -1786,10 +1806,12 @@ var CodeMirror =
}
}
}, lineClasses)
context.state = state
context.baseTokens = null
context.baseTokenPos = 1
};
for (var o = 0; o < cm.state.overlays.length; ++o) loop( o );
context.state = state
return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}
}
@ -3129,6 +3151,7 @@ var CodeMirror =
var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y);
var begin = ref.begin;
var end = ref.end;
if (/\s/.test(lineObj.text.charAt(end - 1))) { end-- }
var part = null, closestDist = null
for (var i = 0; i < order.length; i++) {
var p = order[i]
@ -3319,6 +3342,7 @@ var CodeMirror =
var fragment = document.createDocumentFragment()
var padding = paddingH(cm.display), leftSide = padding.left
var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right
var docLTR = doc.direction == "ltr"
function add(left, top, width, bottom) {
if (top < 0) { top = 0 }
@ -3335,42 +3359,43 @@ var CodeMirror =
return charCoords(cm, Pos(line, ch), "div", lineObj, bias)
}
function wrapX(pos, dir, side) {
var extent = wrappedLineExtentChar(cm, lineObj, null, pos)
var prop = (dir == "ltr") == (side == "after") ? "left" : "right"
var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1)
return coords(ch, prop)[prop]
}
var order = getOrder(lineObj, doc.direction)
iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) {
var fromPos = coords(from, dir == "ltr" ? "left" : "right")
var toPos = coords(to - 1, dir == "ltr" ? "right" : "left")
if (dir == "ltr") {
var fromLeft = fromArg == null && from == 0 ? leftSide : fromPos.left
var toRight = toArg == null && to == lineLen ? rightSide : toPos.right
if (toPos.top - fromPos.top <= 3) { // Single line
add(fromLeft, toPos.top, toRight - fromLeft, toPos.bottom)
} else { // Multiple lines
add(fromLeft, fromPos.top, null, fromPos.bottom)
if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top) }
add(leftSide, toPos.top, toPos.right, toPos.bottom)
}
} else if (from < to) { // RTL
var fromRight = fromArg == null && from == 0 ? rightSide : fromPos.right
var toLeft = toArg == null && to == lineLen ? leftSide : toPos.left
if (toPos.top - fromPos.top <= 3) { // Single line
add(toLeft, toPos.top, fromRight - toLeft, toPos.bottom)
} else { // Multiple lines
var topLeft = leftSide
if (i) {
var topEnd = wrappedLineExtentChar(cm, lineObj, null, from).end
// The coordinates returned for an RTL wrapped space tend to
// be complete bogus, so try to skip that here.
topLeft = coords(topEnd - (/\s/.test(lineObj.text.charAt(topEnd - 1)) ? 2 : 1), "left").left
}
add(topLeft, fromPos.top, fromRight - topLeft, fromPos.bottom)
if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top) }
var botWidth = null
if (i < order.length - 1 || true) {
var botStart = wrappedLineExtentChar(cm, lineObj, null, to).begin
botWidth = coords(botStart, "right").right - toLeft
}
add(toLeft, toPos.top, botWidth, toPos.bottom)
var ltr = dir == "ltr"
var fromPos = coords(from, ltr ? "left" : "right")
var toPos = coords(to - 1, ltr ? "right" : "left")
var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen
var first = i == 0, last = !order || i == order.length - 1
if (toPos.top - fromPos.top <= 3) { // Single line
var openLeft = (docLTR ? openStart : openEnd) && first
var openRight = (docLTR ? openEnd : openStart) && last
var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left
var right = openRight ? rightSide : (ltr ? toPos : fromPos).right
add(left, fromPos.top, right - left, fromPos.bottom)
} else { // Multiple lines
var topLeft, topRight, botLeft, botRight
if (ltr) {
topLeft = docLTR && openStart && first ? leftSide : fromPos.left
topRight = docLTR ? rightSide : wrapX(from, dir, "before")
botLeft = docLTR ? leftSide : wrapX(to, dir, "after")
botRight = docLTR && openEnd && last ? rightSide : toPos.right
} else {
topLeft = !docLTR ? leftSide : wrapX(from, dir, "before")
topRight = !docLTR && openStart && first ? rightSide : fromPos.right
botLeft = !docLTR && openEnd && last ? leftSide : toPos.left
botRight = !docLTR ? rightSide : wrapX(to, dir, "after")
}
add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom)
if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top) }
add(botLeft, toPos.top, botRight - botLeft, toPos.bottom)
}
if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos }
@ -6995,7 +7020,7 @@ var CodeMirror =
// Thus, in rtl, we are looking for the first (content-order) character
// in the rtl chunk that is on the last line (that is, the same line
// as the last (content-order) character).
if (part.level > 0) {
if (part.level > 0 || cm.doc.direction == "rtl") {
var prep = prepareMeasureForLine(cm, lineObj)
ch = dir < 0 ? lineObj.text.length - 1 : 0
var targetTop = measureCharPrepared(cm, prep, ch).top
@ -9857,7 +9882,7 @@ var CodeMirror =
addLegacyProps(CodeMirror)
CodeMirror.version = "5.30.0"
CodeMirror.version = "5.31.0"
return CodeMirror;
@ -10667,7 +10692,8 @@ var CodeMirror =
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
cm.replaceSelection("\n\n", null);
var linesep = cm.lineSeparator() || "\n";
cm.replaceSelection(linesep + linesep, null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
@ -11038,13 +11064,13 @@ var CodeMirror =
var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};}
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
var jsKeywords = {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "void": C, "throw": C, "debugger": C,
"var": kw("var"), "const": kw("var"), "let": kw("var"),
"return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
"debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
@ -11143,7 +11169,7 @@ var CodeMirror =
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
return ret("regexp", "string-2");
} else {
stream.eatWhile(isOperatorChar);
stream.eat("=");
return ret("operator", "operator", stream.current());
}
} else if (ch == "`") {
@ -11153,8 +11179,14 @@ var CodeMirror =
stream.skipToEnd();
return ret("error", "error");
} else if (isOperatorChar.test(ch)) {
if (ch != ">" || !state.lexical || state.lexical.type != ">")
stream.eatWhile(isOperatorChar);
if (ch != ">" || !state.lexical || state.lexical.type != ">") {
if (stream.eat("=")) {
if (ch == "!" || ch == "=") stream.eat("=")
} else if (/[<>*+\-]/.test(ch)) {
stream.eat(ch)
if (ch == ">") stream.eat(ch)
}
}
return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) {
stream.eatWhile(wordRE);
@ -11366,6 +11398,8 @@ var CodeMirror =
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
if (type == "debugger") return cont(expect(";"));
if (type == "{") return cont(pushlex("}"), block, poplex);
if (type == ";") return cont();
if (type == "if") {
@ -11421,7 +11455,7 @@ var CodeMirror =
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop);
if (type == "class") return cont(pushlex("form"), classExpression, poplex);
if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
@ -11434,10 +11468,6 @@ var CodeMirror =
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression);
}
function maybeexpressionNoComma(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expressionNoComma);
}
function maybeoperatorComma(type, value) {
if (type == ",") return cont(expression);
@ -11525,7 +11555,10 @@ var CodeMirror =
} else if (type == "[") {
return cont(expression, expect("]"), afterprop);
} else if (type == "spread") {
return cont(expression, afterprop);
return cont(expressionNoComma, afterprop);
} else if (value == "*") {
cx.marked = "keyword";
return cont(objprop);
} else if (type == ":") {
return pass(afterprop)
}
@ -11573,7 +11606,7 @@ var CodeMirror =
}
}
function typeexpr(type, value) {
if (type == "variable") {
if (type == "variable" || value == "void") {
if (value == "keyof") {
cx.marked = "keyword"
return cont(typeexpr)
@ -11760,7 +11793,7 @@ var CodeMirror =
function expressionAllowed(stream, state, backUp) {
return state.tokenize == tokenBase &&
/^(?:operator|sof|keyword [bc]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
}
@ -11829,6 +11862,7 @@ var CodeMirror =
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
blockCommentContinue: jsonMode ? null : " * ",
lineComment: jsonMode ? null : "//",
fold: "brace",
closeBrackets: "()[]{}''\"\"``",
@ -12678,6 +12712,7 @@ var CodeMirror =
electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: lineComment,
fold: "brace"
};
@ -14237,6 +14272,7 @@ var CodeMirror =
electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
blockCommentStart: "/*",
blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: "//",
fold: "brace"
};
@ -14584,7 +14620,7 @@ var CodeMirror =
multiLineStrings: true,
number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
blockKeywords: words("catch class do else finally for if where try while enum"),
defKeywords: words("class val var object package interface fun"),
defKeywords: words("class val var object interface fun"),
atoms: words("true false null this"),
hooks: {
'"': function(stream, state) {
@ -15785,20 +15821,67 @@ var CodeMirror =
}
function detachVimMap(cm, next) {
if (this == CodeMirror.keyMap.vim)
if (this == CodeMirror.keyMap.vim) {
CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor");
if (cm.getOption("inputStyle") == "contenteditable" && document.body.style.caretColor != null) {
disableFatCursorMark(cm);
cm.getInputField().style.caretColor = "";
}
}
if (!next || next.attach != attachVimMap)
leaveVimMode(cm);
}
function attachVimMap(cm, prev) {
if (this == CodeMirror.keyMap.vim)
if (this == CodeMirror.keyMap.vim) {
CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor");
if (cm.getOption("inputStyle") == "contenteditable" && document.body.style.caretColor != null) {
enableFatCursorMark(cm);
cm.getInputField().style.caretColor = "transparent";
}
}
if (!prev || prev.attach != attachVimMap)
enterVimMode(cm);
}
function fatCursorMarks(cm) {
var ranges = cm.listSelections(), result = []
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i]
if (range.empty()) {
if (range.anchor.ch < cm.getLine(range.anchor.line).length) {
result.push(cm.markText(range.anchor, Pos(range.anchor.line, range.anchor.ch + 1),
{className: "cm-fat-cursor-mark"}))
} else {
var widget = document.createElement("span")
widget.textContent = "\u00a0"
widget.className = "cm-fat-cursor-mark"
result.push(cm.setBookmark(range.anchor, {widget: widget}))
}
}
}
return result
}
function updateFatCursorMark(cm) {
var marks = cm.state.fatCursorMarks
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear()
cm.state.fatCursorMarks = fatCursorMarks(cm)
}
function enableFatCursorMark(cm) {
cm.state.fatCursorMarks = fatCursorMarks(cm)
cm.on("cursorActivity", updateFatCursorMark)
}
function disableFatCursorMark(cm) {
var marks = cm.state.fatCursorMarks
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear()
cm.state.fatCursorMarks = null
cm.off("cursorActivity", updateFatCursorMark)
}
// Deprecated, simply setting the keymap works again.
CodeMirror.defineOption('vimMode', false, function(cm, val, prev) {
if (val && cm.getOption("keyMap") != "vim")
@ -17564,7 +17647,8 @@ var CodeMirror =
vimGlobalState.registerController.pushText(
args.registerName, 'delete', text,
args.linewise, vim.visualBlock);
return clipCursorToContent(cm, finalHead);
var includeLineBreak = vim.insertMode
return clipCursorToContent(cm, finalHead, includeLineBreak);
},
indent: function(cm, args, ranges) {
var vim = cm.state.vim;
@ -18774,7 +18858,7 @@ var CodeMirror =
return cur;
}
/**
/*
* Returns the boundaries of the next word. If the cursor in the middle of
* the word, then returns the boundaries of the current word, starting at
* the cursor. If the cursor is at the start/end of a word, and we are going
@ -19508,6 +19592,15 @@ var CodeMirror =
var history = cm.doc.history.done;
var event = history[history.length - 2];
return event && event.ranges && event.ranges[0].head;
} else if (markName == '.') {
if (cm.doc.history.lastModTime == 0) {
return // If no changes, bail out; don't bother to copy or reverse history array.
} else {
var changeHistory = cm.doc.history.done.filter(function(el){ if (el.changes !== undefined) { return el } });
changeHistory.reverse();
var lastEditPos = changeHistory[0].changes[0].to;
}
return lastEditPos;
}
var mark = vim.marks[markName];
@ -20318,7 +20411,8 @@ var CodeMirror =
// so as to update the ". register as expected in real vim.
var text = [];
if (!isPlaying) {
var selLength = lastChange.inVisualBlock ? vim.lastSelection.visualBlock.height : 1;
var selLength = lastChange.inVisualBlock && vim.lastSelection ?
vim.lastSelection.visualBlock.height : 1;
var changes = lastChange.changes;
var text = [];
var i = 0;
@ -20704,11 +20798,8 @@ var CodeMirror =
})(function(CodeMirror) {
"use strict";
var map = CodeMirror.keyMap.sublime = {fallthrough: "default"};
var cmds = CodeMirror.commands;
var Pos = CodeMirror.Pos;
var mac = CodeMirror.keyMap["default"] == CodeMirror.keyMap.macDefault;
var ctrl = mac ? "Cmd-" : "Ctrl-";
// This is not exactly Sublime's algorithm. I couldn't make heads or tails of that.
function findPosSubword(doc, start, dir) {
@ -20742,16 +20833,10 @@ var CodeMirror =
});
}
var goSubwordCombo = mac ? "Ctrl-" : "Alt-";
cmds.goSubwordLeft = function(cm) { moveSubword(cm, -1); };
cmds.goSubwordRight = function(cm) { moveSubword(cm, 1); };
cmds[map[goSubwordCombo + "Left"] = "goSubwordLeft"] = function(cm) { moveSubword(cm, -1); };
cmds[map[goSubwordCombo + "Right"] = "goSubwordRight"] = function(cm) { moveSubword(cm, 1); };
if (mac) map["Cmd-Left"] = "goLineStartSmart";
var scrollLineCombo = mac ? "Ctrl-Alt-" : "Ctrl-";
cmds[map[scrollLineCombo + "Up"] = "scrollLineUp"] = function(cm) {
cmds.scrollLineUp = function(cm) {
var info = cm.getScrollInfo();
if (!cm.somethingSelected()) {
var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local");
@ -20760,7 +20845,7 @@ var CodeMirror =
}
cm.scrollTo(null, info.top - cm.defaultTextHeight());
};
cmds[map[scrollLineCombo + "Down"] = "scrollLineDown"] = function(cm) {
cmds.scrollLineDown = function(cm) {
var info = cm.getScrollInfo();
if (!cm.somethingSelected()) {
var visibleTopLine = cm.lineAtHeight(info.top, "local")+1;
@ -20770,7 +20855,7 @@ var CodeMirror =
cm.scrollTo(null, info.top + cm.defaultTextHeight());
};
cmds[map["Shift-" + ctrl + "L"] = "splitSelectionByLine"] = function(cm) {
cmds.splitSelectionByLine = function(cm) {
var ranges = cm.listSelections(), lineRanges = [];
for (var i = 0; i < ranges.length; i++) {
var from = ranges[i].from(), to = ranges[i].to();
@ -20782,14 +20867,12 @@ var CodeMirror =
cm.setSelections(lineRanges, 0);
};
map["Shift-Tab"] = "indentLess";
cmds[map["Esc"] = "singleSelectionTop"] = function(cm) {
cmds.singleSelectionTop = function(cm) {
var range = cm.listSelections()[0];
cm.setSelection(range.anchor, range.head, {scroll: false});
};
cmds[map[ctrl + "L"] = "selectLine"] = function(cm) {
cmds.selectLine = function(cm) {
var ranges = cm.listSelections(), extended = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
@ -20799,8 +20882,6 @@ var CodeMirror =
cm.setSelections(extended);
};
map["Shift-Ctrl-K"] = "deleteLine";
function insertLine(cm, above) {
if (cm.isReadOnly()) return CodeMirror.Pass
cm.operation(function() {
@ -20819,9 +20900,9 @@ var CodeMirror =
cm.execCommand("indentAuto");
}
cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { return insertLine(cm, false); };
cmds.insertLineAfter = function(cm) { return insertLine(cm, false); };
cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { return insertLine(cm, true); };
cmds.insertLineBefore = function(cm) { return insertLine(cm, true); };
function wordAt(cm, pos) {
var start = pos.ch, end = start, line = cm.getLine(pos.line);
@ -20830,7 +20911,7 @@ var CodeMirror =
return {from: Pos(pos.line, start), to: Pos(pos.line, end), word: line.slice(start, end)};
}
cmds[map[ctrl + "D"] = "selectNextOccurrence"] = function(cm) {
cmds.selectNextOccurrence = function(cm) {
var from = cm.getCursor("from"), to = cm.getCursor("to");
var fullWord = cm.state.sublimeFindFullWord == cm.doc.sel;
if (CodeMirror.cmpPos(from, to) == 0) {
@ -20867,10 +20948,8 @@ var CodeMirror =
}
cm.setSelections(newRanges);
}
var addCursorToLineCombo = mac ? "Shift-Cmd" : 'Alt-Ctrl';
cmds[map[addCursorToLineCombo + "Up"] = "addCursorToPrevLine"] = function(cm) { addCursorToSelection(cm, -1); };
cmds[map[addCursorToLineCombo + "Down"] = "addCursorToNextLine"] = function(cm) { addCursorToSelection(cm, 1); };
cmds.addCursorToPrevLine = function(cm) { addCursorToSelection(cm, -1); };
cmds.addCursorToNextLine = function(cm) { addCursorToSelection(cm, 1); };
function isSelectedRange(ranges, from, to) {
for (var i = 0; i < ranges.length; i++)
@ -20899,14 +20978,14 @@ var CodeMirror =
return true;
}
cmds[map["Shift-" + ctrl + "Space"] = "selectScope"] = function(cm) {
cmds.selectScope = function(cm) {
selectBetweenBrackets(cm) || cm.execCommand("selectAll");
};
cmds[map["Shift-" + ctrl + "M"] = "selectBetweenBrackets"] = function(cm) {
cmds.selectBetweenBrackets = function(cm) {
if (!selectBetweenBrackets(cm)) return CodeMirror.Pass;
};
cmds[map[ctrl + "M"] = "goToBracket"] = function(cm) {
cmds.goToBracket = function(cm) {
cm.extendSelectionsBy(function(range) {
var next = cm.scanForBracket(range.head, 1);
if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos;
@ -20915,9 +20994,7 @@ var CodeMirror =
});
};
var swapLineCombo = mac ? "Cmd-Ctrl-" : "Shift-Ctrl-";
cmds[map[swapLineCombo + "Up"] = "swapLineUp"] = function(cm) {
cmds.swapLineUp = function(cm) {
if (cm.isReadOnly()) return CodeMirror.Pass
var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = [];
for (var i = 0; i < ranges.length; i++) {
@ -20944,7 +21021,7 @@ var CodeMirror =
});
};
cmds[map[swapLineCombo + "Down"] = "swapLineDown"] = function(cm) {
cmds.swapLineDown = function(cm) {
if (cm.isReadOnly()) return CodeMirror.Pass
var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1;
for (var i = ranges.length - 1; i >= 0; i--) {
@ -20968,11 +21045,11 @@ var CodeMirror =
});
};
cmds[map[ctrl + "/"] = "toggleCommentIndented"] = function(cm) {
cmds.toggleCommentIndented = function(cm) {
cm.toggleComment({ indent: true });
}
cmds[map[ctrl + "J"] = "joinLines"] = function(cm) {
cmds.joinLines = function(cm) {
var ranges = cm.listSelections(), joined = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], from = range.from();
@ -21000,7 +21077,7 @@ var CodeMirror =
});
};
cmds[map["Shift-" + ctrl + "D"] = "duplicateLine"] = function(cm) {
cmds.duplicateLine = function(cm) {
cm.operation(function() {
var rangeCount = cm.listSelections().length;
for (var i = 0; i < rangeCount; i++) {
@ -21014,7 +21091,6 @@ var CodeMirror =
});
};
if (!mac) map[ctrl + "T"] = "transposeChars";
function sortLines(cm, caseSensitive) {
if (cm.isReadOnly()) return CodeMirror.Pass
@ -21052,10 +21128,10 @@ var CodeMirror =
});
}
cmds[map["F9"] = "sortLines"] = function(cm) { sortLines(cm, true); };
cmds[map[ctrl + "F9"] = "sortLinesInsensitive"] = function(cm) { sortLines(cm, false); };
cmds.sortLines = function(cm) { sortLines(cm, true); };
cmds.sortLinesInsensitive = function(cm) { sortLines(cm, false); };
cmds[map["F2"] = "nextBookmark"] = function(cm) {
cmds.nextBookmark = function(cm) {
var marks = cm.state.sublimeBookmarks;
if (marks) while (marks.length) {
var current = marks.shift();
@ -21067,7 +21143,7 @@ var CodeMirror =
}
};
cmds[map["Shift-F2"] = "prevBookmark"] = function(cm) {
cmds.prevBookmark = function(cm) {
var marks = cm.state.sublimeBookmarks;
if (marks) while (marks.length) {
marks.unshift(marks.pop());
@ -21079,7 +21155,7 @@ var CodeMirror =
}
};
cmds[map[ctrl + "F2"] = "toggleBookmark"] = function(cm) {
cmds.toggleBookmark = function(cm) {
var ranges = cm.listSelections();
var marks = cm.state.sublimeBookmarks || (cm.state.sublimeBookmarks = []);
for (var i = 0; i < ranges.length; i++) {
@ -21099,13 +21175,13 @@ var CodeMirror =
}
};
cmds[map["Shift-" + ctrl + "F2"] = "clearBookmarks"] = function(cm) {
cmds.clearBookmarks = function(cm) {
var marks = cm.state.sublimeBookmarks;
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear();
marks.length = 0;
};
cmds[map["Alt-F2"] = "selectBookmarks"] = function(cm) {
cmds.selectBookmarks = function(cm) {
var marks = cm.state.sublimeBookmarks, ranges = [];
if (marks) for (var i = 0; i < marks.length; i++) {
var found = marks[i].find();
@ -21118,10 +21194,6 @@ var CodeMirror =
cm.setSelections(ranges, 0);
};
map["Alt-Q"] = "wrapLines";
var cK = ctrl + "K ";
function modifyWordOrSelection(cm, mod) {
cm.operation(function() {
var ranges = cm.listSelections(), indices = [], replacements = [];
@ -21141,9 +21213,7 @@ var CodeMirror =
});
}
map[cK + ctrl + "Backspace"] = "delLineLeft";
cmds[map["Backspace"] = "smartBackspace"] = function(cm) {
cmds.smartBackspace = function(cm) {
if (cm.somethingSelected()) return CodeMirror.Pass;
cm.operation(function() {
@ -21171,7 +21241,7 @@ var CodeMirror =
});
};
cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) {
cmds.delLineRight = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = ranges.length - 1; i >= 0; i--)
@ -21180,22 +21250,22 @@ var CodeMirror =
});
};
cmds[map[cK + ctrl + "U"] = "upcaseAtCursor"] = function(cm) {
cmds.upcaseAtCursor = function(cm) {
modifyWordOrSelection(cm, function(str) { return str.toUpperCase(); });
};
cmds[map[cK + ctrl + "L"] = "downcaseAtCursor"] = function(cm) {
cmds.downcaseAtCursor = function(cm) {
modifyWordOrSelection(cm, function(str) { return str.toLowerCase(); });
};
cmds[map[cK + ctrl + "Space"] = "setSublimeMark"] = function(cm) {
cmds.setSublimeMark = function(cm) {
if (cm.state.sublimeMark) cm.state.sublimeMark.clear();
cm.state.sublimeMark = cm.setBookmark(cm.getCursor());
};
cmds[map[cK + ctrl + "A"] = "selectToSublimeMark"] = function(cm) {
cmds.selectToSublimeMark = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) cm.setSelection(cm.getCursor(), found);
};
cmds[map[cK + ctrl + "W"] = "deleteToSublimeMark"] = function(cm) {
cmds.deleteToSublimeMark = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) {
var from = cm.getCursor(), to = found;
@ -21204,7 +21274,7 @@ var CodeMirror =
cm.replaceRange("", from, to);
}
};
cmds[map[cK + ctrl + "X"] = "swapWithSublimeMark"] = function(cm) {
cmds.swapWithSublimeMark = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) {
cm.state.sublimeMark.clear();
@ -21212,19 +21282,17 @@ var CodeMirror =
cm.setCursor(found);
}
};
cmds[map[cK + ctrl + "Y"] = "sublimeYank"] = function(cm) {
cmds.sublimeYank = function(cm) {
if (cm.state.sublimeKilled != null)
cm.replaceSelection(cm.state.sublimeKilled, null, "paste");
};
map[cK + ctrl + "G"] = "clearBookmarks";
cmds[map[cK + ctrl + "C"] = "showInCenter"] = function(cm) {
cmds.showInCenter = function(cm) {
var pos = cm.cursorCoords(null, "local");
cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2);
};
var selectLinesCombo = mac ? "Ctrl-Shift-" : "Ctrl-Alt-";
cmds[map[selectLinesCombo + "Up"] = "selectLinesUpward"] = function(cm) {
cmds.selectLinesUpward = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
@ -21234,7 +21302,7 @@ var CodeMirror =
}
});
};
cmds[map[selectLinesCombo + "Down"] = "selectLinesDownward"] = function(cm) {
cmds.selectLinesDownward = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
@ -21273,9 +21341,9 @@ var CodeMirror =
cm.setSelection(target.from, target.to);
}
};
cmds[map[ctrl + "F3"] = "findUnder"] = function(cm) { findAndGoTo(cm, true); };
cmds[map["Shift-" + ctrl + "F3"] = "findUnderPrevious"] = function(cm) { findAndGoTo(cm,false); };
cmds[map["Alt-F3"] = "findAllUnder"] = function(cm) {
cmds.findUnder = function(cm) { findAndGoTo(cm, true); };
cmds.findUnderPrevious = function(cm) { findAndGoTo(cm,false); };
cmds.findAllUnder = function(cm) {
var target = getTarget(cm);
if (!target) return;
var cur = cm.getSearchCursor(target.query);
@ -21289,17 +21357,134 @@ var CodeMirror =
cm.setSelections(matches, primaryIndex);
};
map["Shift-" + ctrl + "["] = "fold";
map["Shift-" + ctrl + "]"] = "unfold";
map[cK + ctrl + "0"] = map[cK + ctrl + "J"] = "unfoldAll";
map[ctrl + "I"] = "findIncremental";
map["Shift-" + ctrl + "I"] = "findIncrementalReverse";
map[ctrl + "H"] = "replace";
map["F3"] = "findNext";
map["Shift-F3"] = "findPrev";
var keyMap = CodeMirror.keyMap;
keyMap.macSublime = {
"Cmd-Left": "goLineStartSmart",
"Shift-Tab": "indentLess",
"Shift-Ctrl-K": "deleteLine",
"Alt-Q": "wrapLines",
"Ctrl-Left": "goSubwordLeft",
"Ctrl-Right": "goSubwordRight",
"Ctrl-Alt-Up": "scrollLineUp",
"Ctrl-Alt-Down": "scrollLineDown",
"Cmd-L": "selectLine",
"Shift-Cmd-L": "splitSelectionByLine",
"Esc": "singleSelectionTop",
"Cmd-Enter": "insertLineAfter",
"Shift-Cmd-Enter": "insertLineBefore",
"Cmd-D": "selectNextOccurrence",
"Shift-Cmd-Up": "addCursorToPrevLine",
"Shift-Cmd-Down": "addCursorToNextLine",
"Shift-Cmd-Space": "selectScope",
"Shift-Cmd-M": "selectBetweenBrackets",
"Cmd-M": "goToBracket",
"Cmd-Ctrl-Up": "swapLineUp",
"Cmd-Ctrl-Down": "swapLineDown",
"Cmd-/": "toggleCommentIndented",
"Cmd-J": "joinLines",
"Shift-Cmd-D": "duplicateLine",
"F9": "sortLines",
"Cmd-F9": "sortLinesInsensitive",
"F2": "nextBookmark",
"Shift-F2": "prevBookmark",
"Cmd-F2": "toggleBookmark",
"Shift-Cmd-F2": "clearBookmarks",
"Alt-F2": "selectBookmarks",
"Backspace": "smartBackspace",
"Cmd-K Cmd-K": "delLineRight",
"Cmd-K Cmd-U": "upcaseAtCursor",
"Cmd-K Cmd-L": "downcaseAtCursor",
"Cmd-K Cmd-Space": "setSublimeMark",
"Cmd-K Cmd-A": "selectToSublimeMark",
"Cmd-K Cmd-W": "deleteToSublimeMark",
"Cmd-K Cmd-X": "swapWithSublimeMark",
"Cmd-K Cmd-Y": "sublimeYank",
"Cmd-K Cmd-C": "showInCenter",
"Cmd-K Cmd-G": "clearBookmarks",
"Cmd-K Cmd-Backspace": "delLineLeft",
"Cmd-K Cmd-0": "unfoldAll",
"Cmd-K Cmd-J": "unfoldAll",
"Ctrl-Shift-Up": "selectLinesUpward",
"Ctrl-Shift-Down": "selectLinesDownward",
"Cmd-F3": "findUnder",
"Shift-Cmd-F3": "findUnderPrevious",
"Alt-F3": "findAllUnder",
"Shift-Cmd-[": "fold",
"Shift-Cmd-]": "unfold",
"Cmd-I": "findIncremental",
"Shift-Cmd-I": "findIncrementalReverse",
"Cmd-H": "replace",
"F3": "findNext",
"Shift-F3": "findPrev",
"fallthrough": "macDefault"
};
CodeMirror.normalizeKeyMap(keyMap.macSublime);
CodeMirror.normalizeKeyMap(map);
keyMap.pcSublime = {
"Shift-Tab": "indentLess",
"Shift-Ctrl-K": "deleteLine",
"Alt-Q": "wrapLines",
"Ctrl-T": "transposeChars",
"Alt-Left": "goSubwordLeft",
"Alt-Right": "goSubwordRight",
"Ctrl-Up": "scrollLineUp",
"Ctrl-Down": "scrollLineDown",
"Ctrl-L": "selectLine",
"Shift-Ctrl-L": "splitSelectionByLine",
"Esc": "singleSelectionTop",
"Ctrl-Enter": "insertLineAfter",
"Shift-Ctrl-Enter": "insertLineBefore",
"Ctrl-D": "selectNextOccurrence",
"Alt-CtrlUp": "addCursorToPrevLine",
"Alt-CtrlDown": "addCursorToNextLine",
"Shift-Ctrl-Space": "selectScope",
"Shift-Ctrl-M": "selectBetweenBrackets",
"Ctrl-M": "goToBracket",
"Shift-Ctrl-Up": "swapLineUp",
"Shift-Ctrl-Down": "swapLineDown",
"Ctrl-/": "toggleCommentIndented",
"Ctrl-J": "joinLines",
"Shift-Ctrl-D": "duplicateLine",
"F9": "sortLines",
"Ctrl-F9": "sortLinesInsensitive",
"F2": "nextBookmark",
"Shift-F2": "prevBookmark",
"Ctrl-F2": "toggleBookmark",
"Shift-Ctrl-F2": "clearBookmarks",
"Alt-F2": "selectBookmarks",
"Backspace": "smartBackspace",
"Ctrl-K Ctrl-K": "delLineRight",
"Ctrl-K Ctrl-U": "upcaseAtCursor",
"Ctrl-K Ctrl-L": "downcaseAtCursor",
"Ctrl-K Ctrl-Space": "setSublimeMark",
"Ctrl-K Ctrl-A": "selectToSublimeMark",
"Ctrl-K Ctrl-W": "deleteToSublimeMark",
"Ctrl-K Ctrl-X": "swapWithSublimeMark",
"Ctrl-K Ctrl-Y": "sublimeYank",
"Ctrl-K Ctrl-C": "showInCenter",
"Ctrl-K Ctrl-G": "clearBookmarks",
"Ctrl-K Ctrl-Backspace": "delLineLeft",
"Ctrl-K Ctrl-0": "unfoldAll",
"Ctrl-K Ctrl-J": "unfoldAll",
"Ctrl-Alt-Up": "selectLinesUpward",
"Ctrl-Alt-Down": "selectLinesDownward",
"Ctrl-F3": "findUnder",
"Shift-Ctrl-F3": "findUnderPrevious",
"Alt-F3": "findAllUnder",
"Shift-Ctrl-[": "fold",
"Shift-Ctrl-]": "unfold",
"Ctrl-I": "findIncremental",
"Shift-Ctrl-I": "findIncrementalReverse",
"Ctrl-H": "replace",
"F3": "findNext",
"Shift-F3": "findPrev",
"fallthrough": "pcDefault"
};
CodeMirror.normalizeKeyMap(keyMap.pcSublime);
var mac = keyMap.default == keyMap.macDefault;
keyMap.sublime = mac ? keyMap.macSublime : keyMap.pcSublime;
});

Просмотреть файл

@ -14,11 +14,8 @@
})(function(CodeMirror) {
"use strict";
var map = CodeMirror.keyMap.sublime = {fallthrough: "default"};
var cmds = CodeMirror.commands;
var Pos = CodeMirror.Pos;
var mac = CodeMirror.keyMap["default"] == CodeMirror.keyMap.macDefault;
var ctrl = mac ? "Cmd-" : "Ctrl-";
// This is not exactly Sublime's algorithm. I couldn't make heads or tails of that.
function findPosSubword(doc, start, dir) {
@ -52,16 +49,10 @@
});
}
var goSubwordCombo = mac ? "Ctrl-" : "Alt-";
cmds.goSubwordLeft = function(cm) { moveSubword(cm, -1); };
cmds.goSubwordRight = function(cm) { moveSubword(cm, 1); };
cmds[map[goSubwordCombo + "Left"] = "goSubwordLeft"] = function(cm) { moveSubword(cm, -1); };
cmds[map[goSubwordCombo + "Right"] = "goSubwordRight"] = function(cm) { moveSubword(cm, 1); };
if (mac) map["Cmd-Left"] = "goLineStartSmart";
var scrollLineCombo = mac ? "Ctrl-Alt-" : "Ctrl-";
cmds[map[scrollLineCombo + "Up"] = "scrollLineUp"] = function(cm) {
cmds.scrollLineUp = function(cm) {
var info = cm.getScrollInfo();
if (!cm.somethingSelected()) {
var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local");
@ -70,7 +61,7 @@
}
cm.scrollTo(null, info.top - cm.defaultTextHeight());
};
cmds[map[scrollLineCombo + "Down"] = "scrollLineDown"] = function(cm) {
cmds.scrollLineDown = function(cm) {
var info = cm.getScrollInfo();
if (!cm.somethingSelected()) {
var visibleTopLine = cm.lineAtHeight(info.top, "local")+1;
@ -80,7 +71,7 @@
cm.scrollTo(null, info.top + cm.defaultTextHeight());
};
cmds[map["Shift-" + ctrl + "L"] = "splitSelectionByLine"] = function(cm) {
cmds.splitSelectionByLine = function(cm) {
var ranges = cm.listSelections(), lineRanges = [];
for (var i = 0; i < ranges.length; i++) {
var from = ranges[i].from(), to = ranges[i].to();
@ -92,14 +83,12 @@
cm.setSelections(lineRanges, 0);
};
map["Shift-Tab"] = "indentLess";
cmds[map["Esc"] = "singleSelectionTop"] = function(cm) {
cmds.singleSelectionTop = function(cm) {
var range = cm.listSelections()[0];
cm.setSelection(range.anchor, range.head, {scroll: false});
};
cmds[map[ctrl + "L"] = "selectLine"] = function(cm) {
cmds.selectLine = function(cm) {
var ranges = cm.listSelections(), extended = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
@ -109,8 +98,6 @@
cm.setSelections(extended);
};
map["Shift-Ctrl-K"] = "deleteLine";
function insertLine(cm, above) {
if (cm.isReadOnly()) return CodeMirror.Pass
cm.operation(function() {
@ -129,9 +116,9 @@
cm.execCommand("indentAuto");
}
cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { return insertLine(cm, false); };
cmds.insertLineAfter = function(cm) { return insertLine(cm, false); };
cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { return insertLine(cm, true); };
cmds.insertLineBefore = function(cm) { return insertLine(cm, true); };
function wordAt(cm, pos) {
var start = pos.ch, end = start, line = cm.getLine(pos.line);
@ -140,7 +127,7 @@
return {from: Pos(pos.line, start), to: Pos(pos.line, end), word: line.slice(start, end)};
}
cmds[map[ctrl + "D"] = "selectNextOccurrence"] = function(cm) {
cmds.selectNextOccurrence = function(cm) {
var from = cm.getCursor("from"), to = cm.getCursor("to");
var fullWord = cm.state.sublimeFindFullWord == cm.doc.sel;
if (CodeMirror.cmpPos(from, to) == 0) {
@ -177,10 +164,8 @@
}
cm.setSelections(newRanges);
}
var addCursorToLineCombo = mac ? "Shift-Cmd" : 'Alt-Ctrl';
cmds[map[addCursorToLineCombo + "Up"] = "addCursorToPrevLine"] = function(cm) { addCursorToSelection(cm, -1); };
cmds[map[addCursorToLineCombo + "Down"] = "addCursorToNextLine"] = function(cm) { addCursorToSelection(cm, 1); };
cmds.addCursorToPrevLine = function(cm) { addCursorToSelection(cm, -1); };
cmds.addCursorToNextLine = function(cm) { addCursorToSelection(cm, 1); };
function isSelectedRange(ranges, from, to) {
for (var i = 0; i < ranges.length; i++)
@ -209,14 +194,14 @@
return true;
}
cmds[map["Shift-" + ctrl + "Space"] = "selectScope"] = function(cm) {
cmds.selectScope = function(cm) {
selectBetweenBrackets(cm) || cm.execCommand("selectAll");
};
cmds[map["Shift-" + ctrl + "M"] = "selectBetweenBrackets"] = function(cm) {
cmds.selectBetweenBrackets = function(cm) {
if (!selectBetweenBrackets(cm)) return CodeMirror.Pass;
};
cmds[map[ctrl + "M"] = "goToBracket"] = function(cm) {
cmds.goToBracket = function(cm) {
cm.extendSelectionsBy(function(range) {
var next = cm.scanForBracket(range.head, 1);
if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos;
@ -225,9 +210,7 @@
});
};
var swapLineCombo = mac ? "Cmd-Ctrl-" : "Shift-Ctrl-";
cmds[map[swapLineCombo + "Up"] = "swapLineUp"] = function(cm) {
cmds.swapLineUp = function(cm) {
if (cm.isReadOnly()) return CodeMirror.Pass
var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = [];
for (var i = 0; i < ranges.length; i++) {
@ -254,7 +237,7 @@
});
};
cmds[map[swapLineCombo + "Down"] = "swapLineDown"] = function(cm) {
cmds.swapLineDown = function(cm) {
if (cm.isReadOnly()) return CodeMirror.Pass
var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1;
for (var i = ranges.length - 1; i >= 0; i--) {
@ -278,11 +261,11 @@
});
};
cmds[map[ctrl + "/"] = "toggleCommentIndented"] = function(cm) {
cmds.toggleCommentIndented = function(cm) {
cm.toggleComment({ indent: true });
}
cmds[map[ctrl + "J"] = "joinLines"] = function(cm) {
cmds.joinLines = function(cm) {
var ranges = cm.listSelections(), joined = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], from = range.from();
@ -310,7 +293,7 @@
});
};
cmds[map["Shift-" + ctrl + "D"] = "duplicateLine"] = function(cm) {
cmds.duplicateLine = function(cm) {
cm.operation(function() {
var rangeCount = cm.listSelections().length;
for (var i = 0; i < rangeCount; i++) {
@ -324,7 +307,6 @@
});
};
if (!mac) map[ctrl + "T"] = "transposeChars";
function sortLines(cm, caseSensitive) {
if (cm.isReadOnly()) return CodeMirror.Pass
@ -362,10 +344,10 @@
});
}
cmds[map["F9"] = "sortLines"] = function(cm) { sortLines(cm, true); };
cmds[map[ctrl + "F9"] = "sortLinesInsensitive"] = function(cm) { sortLines(cm, false); };
cmds.sortLines = function(cm) { sortLines(cm, true); };
cmds.sortLinesInsensitive = function(cm) { sortLines(cm, false); };
cmds[map["F2"] = "nextBookmark"] = function(cm) {
cmds.nextBookmark = function(cm) {
var marks = cm.state.sublimeBookmarks;
if (marks) while (marks.length) {
var current = marks.shift();
@ -377,7 +359,7 @@
}
};
cmds[map["Shift-F2"] = "prevBookmark"] = function(cm) {
cmds.prevBookmark = function(cm) {
var marks = cm.state.sublimeBookmarks;
if (marks) while (marks.length) {
marks.unshift(marks.pop());
@ -389,7 +371,7 @@
}
};
cmds[map[ctrl + "F2"] = "toggleBookmark"] = function(cm) {
cmds.toggleBookmark = function(cm) {
var ranges = cm.listSelections();
var marks = cm.state.sublimeBookmarks || (cm.state.sublimeBookmarks = []);
for (var i = 0; i < ranges.length; i++) {
@ -409,13 +391,13 @@
}
};
cmds[map["Shift-" + ctrl + "F2"] = "clearBookmarks"] = function(cm) {
cmds.clearBookmarks = function(cm) {
var marks = cm.state.sublimeBookmarks;
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear();
marks.length = 0;
};
cmds[map["Alt-F2"] = "selectBookmarks"] = function(cm) {
cmds.selectBookmarks = function(cm) {
var marks = cm.state.sublimeBookmarks, ranges = [];
if (marks) for (var i = 0; i < marks.length; i++) {
var found = marks[i].find();
@ -428,10 +410,6 @@
cm.setSelections(ranges, 0);
};
map["Alt-Q"] = "wrapLines";
var cK = ctrl + "K ";
function modifyWordOrSelection(cm, mod) {
cm.operation(function() {
var ranges = cm.listSelections(), indices = [], replacements = [];
@ -451,9 +429,7 @@
});
}
map[cK + ctrl + "Backspace"] = "delLineLeft";
cmds[map["Backspace"] = "smartBackspace"] = function(cm) {
cmds.smartBackspace = function(cm) {
if (cm.somethingSelected()) return CodeMirror.Pass;
cm.operation(function() {
@ -481,7 +457,7 @@
});
};
cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) {
cmds.delLineRight = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = ranges.length - 1; i >= 0; i--)
@ -490,22 +466,22 @@
});
};
cmds[map[cK + ctrl + "U"] = "upcaseAtCursor"] = function(cm) {
cmds.upcaseAtCursor = function(cm) {
modifyWordOrSelection(cm, function(str) { return str.toUpperCase(); });
};
cmds[map[cK + ctrl + "L"] = "downcaseAtCursor"] = function(cm) {
cmds.downcaseAtCursor = function(cm) {
modifyWordOrSelection(cm, function(str) { return str.toLowerCase(); });
};
cmds[map[cK + ctrl + "Space"] = "setSublimeMark"] = function(cm) {
cmds.setSublimeMark = function(cm) {
if (cm.state.sublimeMark) cm.state.sublimeMark.clear();
cm.state.sublimeMark = cm.setBookmark(cm.getCursor());
};
cmds[map[cK + ctrl + "A"] = "selectToSublimeMark"] = function(cm) {
cmds.selectToSublimeMark = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) cm.setSelection(cm.getCursor(), found);
};
cmds[map[cK + ctrl + "W"] = "deleteToSublimeMark"] = function(cm) {
cmds.deleteToSublimeMark = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) {
var from = cm.getCursor(), to = found;
@ -514,7 +490,7 @@
cm.replaceRange("", from, to);
}
};
cmds[map[cK + ctrl + "X"] = "swapWithSublimeMark"] = function(cm) {
cmds.swapWithSublimeMark = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) {
cm.state.sublimeMark.clear();
@ -522,19 +498,17 @@
cm.setCursor(found);
}
};
cmds[map[cK + ctrl + "Y"] = "sublimeYank"] = function(cm) {
cmds.sublimeYank = function(cm) {
if (cm.state.sublimeKilled != null)
cm.replaceSelection(cm.state.sublimeKilled, null, "paste");
};
map[cK + ctrl + "G"] = "clearBookmarks";
cmds[map[cK + ctrl + "C"] = "showInCenter"] = function(cm) {
cmds.showInCenter = function(cm) {
var pos = cm.cursorCoords(null, "local");
cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2);
};
var selectLinesCombo = mac ? "Ctrl-Shift-" : "Ctrl-Alt-";
cmds[map[selectLinesCombo + "Up"] = "selectLinesUpward"] = function(cm) {
cmds.selectLinesUpward = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
@ -544,7 +518,7 @@
}
});
};
cmds[map[selectLinesCombo + "Down"] = "selectLinesDownward"] = function(cm) {
cmds.selectLinesDownward = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
@ -583,9 +557,9 @@
cm.setSelection(target.from, target.to);
}
};
cmds[map[ctrl + "F3"] = "findUnder"] = function(cm) { findAndGoTo(cm, true); };
cmds[map["Shift-" + ctrl + "F3"] = "findUnderPrevious"] = function(cm) { findAndGoTo(cm,false); };
cmds[map["Alt-F3"] = "findAllUnder"] = function(cm) {
cmds.findUnder = function(cm) { findAndGoTo(cm, true); };
cmds.findUnderPrevious = function(cm) { findAndGoTo(cm,false); };
cmds.findAllUnder = function(cm) {
var target = getTarget(cm);
if (!target) return;
var cur = cm.getSearchCursor(target.query);
@ -599,15 +573,132 @@
cm.setSelections(matches, primaryIndex);
};
map["Shift-" + ctrl + "["] = "fold";
map["Shift-" + ctrl + "]"] = "unfold";
map[cK + ctrl + "0"] = map[cK + ctrl + "J"] = "unfoldAll";
map[ctrl + "I"] = "findIncremental";
map["Shift-" + ctrl + "I"] = "findIncrementalReverse";
map[ctrl + "H"] = "replace";
map["F3"] = "findNext";
map["Shift-F3"] = "findPrev";
var keyMap = CodeMirror.keyMap;
keyMap.macSublime = {
"Cmd-Left": "goLineStartSmart",
"Shift-Tab": "indentLess",
"Shift-Ctrl-K": "deleteLine",
"Alt-Q": "wrapLines",
"Ctrl-Left": "goSubwordLeft",
"Ctrl-Right": "goSubwordRight",
"Ctrl-Alt-Up": "scrollLineUp",
"Ctrl-Alt-Down": "scrollLineDown",
"Cmd-L": "selectLine",
"Shift-Cmd-L": "splitSelectionByLine",
"Esc": "singleSelectionTop",
"Cmd-Enter": "insertLineAfter",
"Shift-Cmd-Enter": "insertLineBefore",
"Cmd-D": "selectNextOccurrence",
"Shift-Cmd-Up": "addCursorToPrevLine",
"Shift-Cmd-Down": "addCursorToNextLine",
"Shift-Cmd-Space": "selectScope",
"Shift-Cmd-M": "selectBetweenBrackets",
"Cmd-M": "goToBracket",
"Cmd-Ctrl-Up": "swapLineUp",
"Cmd-Ctrl-Down": "swapLineDown",
"Cmd-/": "toggleCommentIndented",
"Cmd-J": "joinLines",
"Shift-Cmd-D": "duplicateLine",
"F9": "sortLines",
"Cmd-F9": "sortLinesInsensitive",
"F2": "nextBookmark",
"Shift-F2": "prevBookmark",
"Cmd-F2": "toggleBookmark",
"Shift-Cmd-F2": "clearBookmarks",
"Alt-F2": "selectBookmarks",
"Backspace": "smartBackspace",
"Cmd-K Cmd-K": "delLineRight",
"Cmd-K Cmd-U": "upcaseAtCursor",
"Cmd-K Cmd-L": "downcaseAtCursor",
"Cmd-K Cmd-Space": "setSublimeMark",
"Cmd-K Cmd-A": "selectToSublimeMark",
"Cmd-K Cmd-W": "deleteToSublimeMark",
"Cmd-K Cmd-X": "swapWithSublimeMark",
"Cmd-K Cmd-Y": "sublimeYank",
"Cmd-K Cmd-C": "showInCenter",
"Cmd-K Cmd-G": "clearBookmarks",
"Cmd-K Cmd-Backspace": "delLineLeft",
"Cmd-K Cmd-0": "unfoldAll",
"Cmd-K Cmd-J": "unfoldAll",
"Ctrl-Shift-Up": "selectLinesUpward",
"Ctrl-Shift-Down": "selectLinesDownward",
"Cmd-F3": "findUnder",
"Shift-Cmd-F3": "findUnderPrevious",
"Alt-F3": "findAllUnder",
"Shift-Cmd-[": "fold",
"Shift-Cmd-]": "unfold",
"Cmd-I": "findIncremental",
"Shift-Cmd-I": "findIncrementalReverse",
"Cmd-H": "replace",
"F3": "findNext",
"Shift-F3": "findPrev",
"fallthrough": "macDefault"
};
CodeMirror.normalizeKeyMap(keyMap.macSublime);
CodeMirror.normalizeKeyMap(map);
keyMap.pcSublime = {
"Shift-Tab": "indentLess",
"Shift-Ctrl-K": "deleteLine",
"Alt-Q": "wrapLines",
"Ctrl-T": "transposeChars",
"Alt-Left": "goSubwordLeft",
"Alt-Right": "goSubwordRight",
"Ctrl-Up": "scrollLineUp",
"Ctrl-Down": "scrollLineDown",
"Ctrl-L": "selectLine",
"Shift-Ctrl-L": "splitSelectionByLine",
"Esc": "singleSelectionTop",
"Ctrl-Enter": "insertLineAfter",
"Shift-Ctrl-Enter": "insertLineBefore",
"Ctrl-D": "selectNextOccurrence",
"Alt-CtrlUp": "addCursorToPrevLine",
"Alt-CtrlDown": "addCursorToNextLine",
"Shift-Ctrl-Space": "selectScope",
"Shift-Ctrl-M": "selectBetweenBrackets",
"Ctrl-M": "goToBracket",
"Shift-Ctrl-Up": "swapLineUp",
"Shift-Ctrl-Down": "swapLineDown",
"Ctrl-/": "toggleCommentIndented",
"Ctrl-J": "joinLines",
"Shift-Ctrl-D": "duplicateLine",
"F9": "sortLines",
"Ctrl-F9": "sortLinesInsensitive",
"F2": "nextBookmark",
"Shift-F2": "prevBookmark",
"Ctrl-F2": "toggleBookmark",
"Shift-Ctrl-F2": "clearBookmarks",
"Alt-F2": "selectBookmarks",
"Backspace": "smartBackspace",
"Ctrl-K Ctrl-K": "delLineRight",
"Ctrl-K Ctrl-U": "upcaseAtCursor",
"Ctrl-K Ctrl-L": "downcaseAtCursor",
"Ctrl-K Ctrl-Space": "setSublimeMark",
"Ctrl-K Ctrl-A": "selectToSublimeMark",
"Ctrl-K Ctrl-W": "deleteToSublimeMark",
"Ctrl-K Ctrl-X": "swapWithSublimeMark",
"Ctrl-K Ctrl-Y": "sublimeYank",
"Ctrl-K Ctrl-C": "showInCenter",
"Ctrl-K Ctrl-G": "clearBookmarks",
"Ctrl-K Ctrl-Backspace": "delLineLeft",
"Ctrl-K Ctrl-0": "unfoldAll",
"Ctrl-K Ctrl-J": "unfoldAll",
"Ctrl-Alt-Up": "selectLinesUpward",
"Ctrl-Alt-Down": "selectLinesDownward",
"Ctrl-F3": "findUnder",
"Shift-Ctrl-F3": "findUnderPrevious",
"Alt-F3": "findAllUnder",
"Shift-Ctrl-[": "fold",
"Shift-Ctrl-]": "unfold",
"Ctrl-I": "findIncremental",
"Shift-Ctrl-I": "findIncrementalReverse",
"Ctrl-H": "replace",
"F3": "findNext",
"Shift-F3": "findPrev",
"fallthrough": "pcDefault"
};
CodeMirror.normalizeKeyMap(keyMap.pcSublime);
var mac = keyMap.default == keyMap.macDefault;
keyMap.sublime = mac ? keyMap.macSublime : keyMap.pcSublime;
});

Просмотреть файл

@ -255,20 +255,67 @@
}
function detachVimMap(cm, next) {
if (this == CodeMirror.keyMap.vim)
if (this == CodeMirror.keyMap.vim) {
CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor");
if (cm.getOption("inputStyle") == "contenteditable" && document.body.style.caretColor != null) {
disableFatCursorMark(cm);
cm.getInputField().style.caretColor = "";
}
}
if (!next || next.attach != attachVimMap)
leaveVimMode(cm);
}
function attachVimMap(cm, prev) {
if (this == CodeMirror.keyMap.vim)
if (this == CodeMirror.keyMap.vim) {
CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor");
if (cm.getOption("inputStyle") == "contenteditable" && document.body.style.caretColor != null) {
enableFatCursorMark(cm);
cm.getInputField().style.caretColor = "transparent";
}
}
if (!prev || prev.attach != attachVimMap)
enterVimMode(cm);
}
function fatCursorMarks(cm) {
var ranges = cm.listSelections(), result = []
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i]
if (range.empty()) {
if (range.anchor.ch < cm.getLine(range.anchor.line).length) {
result.push(cm.markText(range.anchor, Pos(range.anchor.line, range.anchor.ch + 1),
{className: "cm-fat-cursor-mark"}))
} else {
var widget = document.createElement("span")
widget.textContent = "\u00a0"
widget.className = "cm-fat-cursor-mark"
result.push(cm.setBookmark(range.anchor, {widget: widget}))
}
}
}
return result
}
function updateFatCursorMark(cm) {
var marks = cm.state.fatCursorMarks
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear()
cm.state.fatCursorMarks = fatCursorMarks(cm)
}
function enableFatCursorMark(cm) {
cm.state.fatCursorMarks = fatCursorMarks(cm)
cm.on("cursorActivity", updateFatCursorMark)
}
function disableFatCursorMark(cm) {
var marks = cm.state.fatCursorMarks
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear()
cm.state.fatCursorMarks = null
cm.off("cursorActivity", updateFatCursorMark)
}
// Deprecated, simply setting the keymap works again.
CodeMirror.defineOption('vimMode', false, function(cm, val, prev) {
if (val && cm.getOption("keyMap") != "vim")
@ -2034,7 +2081,8 @@
vimGlobalState.registerController.pushText(
args.registerName, 'delete', text,
args.linewise, vim.visualBlock);
return clipCursorToContent(cm, finalHead);
var includeLineBreak = vim.insertMode
return clipCursorToContent(cm, finalHead, includeLineBreak);
},
indent: function(cm, args, ranges) {
var vim = cm.state.vim;
@ -3244,7 +3292,7 @@
return cur;
}
/**
/*
* Returns the boundaries of the next word. If the cursor in the middle of
* the word, then returns the boundaries of the current word, starting at
* the cursor. If the cursor is at the start/end of a word, and we are going
@ -3978,6 +4026,15 @@
var history = cm.doc.history.done;
var event = history[history.length - 2];
return event && event.ranges && event.ranges[0].head;
} else if (markName == '.') {
if (cm.doc.history.lastModTime == 0) {
return // If no changes, bail out; don't bother to copy or reverse history array.
} else {
var changeHistory = cm.doc.history.done.filter(function(el){ if (el.changes !== undefined) { return el } });
changeHistory.reverse();
var lastEditPos = changeHistory[0].changes[0].to;
}
return lastEditPos;
}
var mark = vim.marks[markName];
@ -4788,7 +4845,8 @@
// so as to update the ". register as expected in real vim.
var text = [];
if (!isPlaying) {
var selLength = lastChange.inVisualBlock ? vim.lastSelection.visualBlock.height : 1;
var selLength = lastChange.inVisualBlock && vim.lastSelection ?
vim.lastSelection.visualBlock.height : 1;
var changes = lastChange.changes;
var text = [];
var i = 0;

Просмотреть файл

@ -59,7 +59,12 @@
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-fat-cursor-mark {
background-color: rgba(20, 255, 20, 0.5);
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;

Просмотреть файл

@ -1088,13 +1088,15 @@ var bidiOrdering = (function() {
if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)) }
}
}
if (order[0].level == 1 && (m = str.match(/^\s+/))) {
order[0].from = m[0].length
order.unshift(new BidiSpan(0, 0, m[0].length))
}
if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
lst(order).to -= m[0].length
order.push(new BidiSpan(0, len - m[0].length, len))
if (direction == "ltr") {
if (order[0].level == 1 && (m = str.match(/^\s+/))) {
order[0].from = m[0].length
order.unshift(new BidiSpan(0, 0, m[0].length))
}
if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
lst(order).to -= m[0].length
order.push(new BidiSpan(0, len - m[0].length, len))
}
}
return direction == "rtl" ? order.reverse() : order
@ -1469,6 +1471,10 @@ StringStream.prototype.lookAhead = function (n) {
var oracle = this.lineOracle
return oracle && oracle.lookAhead(n)
};
StringStream.prototype.baseToken = function () {
var oracle = this.lineOracle
return oracle && oracle.baseToken(this.pos)
};
var SavedContext = function(state, lookAhead) {
this.state = state
@ -1480,6 +1486,8 @@ var Context = function(doc, state, line, lookAhead) {
this.doc = doc
this.line = line
this.maxLookAhead = lookAhead || 0
this.baseTokens = null
this.baseTokenPos = 1
};
Context.prototype.lookAhead = function (n) {
@ -1488,6 +1496,17 @@ Context.prototype.lookAhead = function (n) {
return line
};
Context.prototype.baseToken = function (n) {
var this$1 = this;
if (!this.baseTokens) { return null }
while (this.baseTokens[this.baseTokenPos] <= n)
{ this$1.baseTokenPos += 2 }
var type = this.baseTokens[this.baseTokenPos + 1]
return {type: type && type.replace(/( |^)overlay .*/, ""),
size: this.baseTokens[this.baseTokenPos] - n}
};
Context.prototype.nextLine = function () {
this.line++
if (this.maxLookAhead > 0) { this.maxLookAhead-- }
@ -1521,6 +1540,7 @@ function highlightLine(cm, line, context, forceToEnd) {
// Run overlays, adjust style array.
var loop = function ( o ) {
context.baseTokens = st
var overlay = cm.state.overlays[o], i = 1, at = 0
context.state = true
runMode(cm, line.text, overlay.mode, context, function (end, style) {
@ -1544,10 +1564,12 @@ function highlightLine(cm, line, context, forceToEnd) {
}
}
}, lineClasses)
context.state = state
context.baseTokens = null
context.baseTokenPos = 1
};
for (var o = 0; o < cm.state.overlays.length; ++o) loop( o );
context.state = state
return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}
}
@ -2887,6 +2909,7 @@ function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x,
var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y);
var begin = ref.begin;
var end = ref.end;
if (/\s/.test(lineObj.text.charAt(end - 1))) { end-- }
var part = null, closestDist = null
for (var i = 0; i < order.length; i++) {
var p = order[i]
@ -3077,6 +3100,7 @@ function drawSelectionRange(cm, range, output) {
var fragment = document.createDocumentFragment()
var padding = paddingH(cm.display), leftSide = padding.left
var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right
var docLTR = doc.direction == "ltr"
function add(left, top, width, bottom) {
if (top < 0) { top = 0 }
@ -3093,42 +3117,43 @@ function drawSelectionRange(cm, range, output) {
return charCoords(cm, Pos(line, ch), "div", lineObj, bias)
}
function wrapX(pos, dir, side) {
var extent = wrappedLineExtentChar(cm, lineObj, null, pos)
var prop = (dir == "ltr") == (side == "after") ? "left" : "right"
var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1)
return coords(ch, prop)[prop]
}
var order = getOrder(lineObj, doc.direction)
iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) {
var fromPos = coords(from, dir == "ltr" ? "left" : "right")
var toPos = coords(to - 1, dir == "ltr" ? "right" : "left")
if (dir == "ltr") {
var fromLeft = fromArg == null && from == 0 ? leftSide : fromPos.left
var toRight = toArg == null && to == lineLen ? rightSide : toPos.right
if (toPos.top - fromPos.top <= 3) { // Single line
add(fromLeft, toPos.top, toRight - fromLeft, toPos.bottom)
} else { // Multiple lines
add(fromLeft, fromPos.top, null, fromPos.bottom)
if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top) }
add(leftSide, toPos.top, toPos.right, toPos.bottom)
}
} else if (from < to) { // RTL
var fromRight = fromArg == null && from == 0 ? rightSide : fromPos.right
var toLeft = toArg == null && to == lineLen ? leftSide : toPos.left
if (toPos.top - fromPos.top <= 3) { // Single line
add(toLeft, toPos.top, fromRight - toLeft, toPos.bottom)
} else { // Multiple lines
var topLeft = leftSide
if (i) {
var topEnd = wrappedLineExtentChar(cm, lineObj, null, from).end
// The coordinates returned for an RTL wrapped space tend to
// be complete bogus, so try to skip that here.
topLeft = coords(topEnd - (/\s/.test(lineObj.text.charAt(topEnd - 1)) ? 2 : 1), "left").left
}
add(topLeft, fromPos.top, fromRight - topLeft, fromPos.bottom)
if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top) }
var botWidth = null
if (i < order.length - 1 || true) {
var botStart = wrappedLineExtentChar(cm, lineObj, null, to).begin
botWidth = coords(botStart, "right").right - toLeft
}
add(toLeft, toPos.top, botWidth, toPos.bottom)
var ltr = dir == "ltr"
var fromPos = coords(from, ltr ? "left" : "right")
var toPos = coords(to - 1, ltr ? "right" : "left")
var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen
var first = i == 0, last = !order || i == order.length - 1
if (toPos.top - fromPos.top <= 3) { // Single line
var openLeft = (docLTR ? openStart : openEnd) && first
var openRight = (docLTR ? openEnd : openStart) && last
var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left
var right = openRight ? rightSide : (ltr ? toPos : fromPos).right
add(left, fromPos.top, right - left, fromPos.bottom)
} else { // Multiple lines
var topLeft, topRight, botLeft, botRight
if (ltr) {
topLeft = docLTR && openStart && first ? leftSide : fromPos.left
topRight = docLTR ? rightSide : wrapX(from, dir, "before")
botLeft = docLTR ? leftSide : wrapX(to, dir, "after")
botRight = docLTR && openEnd && last ? rightSide : toPos.right
} else {
topLeft = !docLTR ? leftSide : wrapX(from, dir, "before")
topRight = !docLTR && openStart && first ? rightSide : fromPos.right
botLeft = !docLTR && openEnd && last ? leftSide : toPos.left
botRight = !docLTR ? rightSide : wrapX(to, dir, "after")
}
add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom)
if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top) }
add(botLeft, toPos.top, botRight - botLeft, toPos.bottom)
}
if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos }
@ -6753,7 +6778,7 @@ function endOfLine(visually, cm, lineObj, lineNo, dir) {
// Thus, in rtl, we are looking for the first (content-order) character
// in the rtl chunk that is on the last line (that is, the same line
// as the last (content-order) character).
if (part.level > 0) {
if (part.level > 0 || cm.doc.direction == "rtl") {
var prep = prepareMeasureForLine(cm, lineObj)
ch = dir < 0 ? lineObj.text.length - 1 : 0
var targetTop = measureCharPrepared(cm, prep, ch).top
@ -9615,7 +9640,7 @@ CodeMirror.fromTextArea = fromTextArea
addLegacyProps(CodeMirror)
CodeMirror.version = "5.30.0"
CodeMirror.version = "5.31.0"
return CodeMirror;

Просмотреть файл

@ -244,6 +244,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
blockCommentStart: "/*",
blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: "//",
fold: "brace"
};
@ -591,7 +592,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
multiLineStrings: true,
number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
blockKeywords: words("catch class do else finally for if where try while enum"),
defKeywords: words("class val var object package interface fun"),
defKeywords: words("class val var object interface fun"),
atoms: words("true false null this"),
hooks: {
'"': function(stream, state) {

Просмотреть файл

@ -410,6 +410,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: lineComment,
fold: "brace"
};

Просмотреть файл

@ -23,13 +23,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};}
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
var jsKeywords = {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "void": C, "throw": C, "debugger": C,
"var": kw("var"), "const": kw("var"), "let": kw("var"),
"return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
"debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
@ -128,7 +128,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
return ret("regexp", "string-2");
} else {
stream.eatWhile(isOperatorChar);
stream.eat("=");
return ret("operator", "operator", stream.current());
}
} else if (ch == "`") {
@ -138,8 +138,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
stream.skipToEnd();
return ret("error", "error");
} else if (isOperatorChar.test(ch)) {
if (ch != ">" || !state.lexical || state.lexical.type != ">")
stream.eatWhile(isOperatorChar);
if (ch != ">" || !state.lexical || state.lexical.type != ">") {
if (stream.eat("=")) {
if (ch == "!" || ch == "=") stream.eat("=")
} else if (/[<>*+\-]/.test(ch)) {
stream.eat(ch)
if (ch == ">") stream.eat(ch)
}
}
return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) {
stream.eatWhile(wordRE);
@ -351,6 +357,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
if (type == "debugger") return cont(expect(";"));
if (type == "{") return cont(pushlex("}"), block, poplex);
if (type == ";") return cont();
if (type == "if") {
@ -406,7 +414,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop);
if (type == "class") return cont(pushlex("form"), classExpression, poplex);
if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
@ -419,10 +427,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression);
}
function maybeexpressionNoComma(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expressionNoComma);
}
function maybeoperatorComma(type, value) {
if (type == ",") return cont(expression);
@ -510,7 +514,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} else if (type == "[") {
return cont(expression, expect("]"), afterprop);
} else if (type == "spread") {
return cont(expression, afterprop);
return cont(expressionNoComma, afterprop);
} else if (value == "*") {
cx.marked = "keyword";
return cont(objprop);
} else if (type == ":") {
return pass(afterprop)
}
@ -558,7 +565,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
}
function typeexpr(type, value) {
if (type == "variable") {
if (type == "variable" || value == "void") {
if (value == "keyof") {
cx.marked = "keyword"
return cont(typeexpr)
@ -745,7 +752,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function expressionAllowed(stream, state, backUp) {
return state.tokenize == tokenBase &&
/^(?:operator|sof|keyword [bc]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
}
@ -814,6 +821,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
blockCommentContinue: jsonMode ? null : " * ",
lineComment: jsonMode ? null : "//",
fold: "brace",
closeBrackets: "()[]{}''\"\"``",

Просмотреть файл

@ -236,6 +236,19 @@
" [keyword return] [number 2]",
"}")
MT("regexp_corner_case",
"[operator +]{} [operator /] [atom undefined];",
"[[[meta ...][string-2 /\\//] ]];",
"[keyword void] [string-2 /\\//];",
"[keyword do] [string-2 /\\//]; [keyword while] ([number 0]);",
"[keyword if] ([number 0]) {} [keyword else] [string-2 /\\//];",
"[string-2 `${][variable async][operator ++][string-2 }//`];",
"[string-2 `${]{} [operator /] [string-2 /\\//}`];")
MT("return_eol",
"[keyword return]",
"{} [string-2 /5/]")
var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript")
function TS(name) {
test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1))
@ -352,6 +365,9 @@
" [property constructor]([keyword readonly] [keyword private] [def x]) {}",
"}")
TS("arrow prop",
"({[property a]: [def p] [operator =>] [variable-2 p]})")
var jsonld_mode = CodeMirror.getMode(
{indentUnit: 2},
{name: "javascript", jsonld: true}

Просмотреть файл

@ -2218,6 +2218,21 @@ testCM("getTokenTypeAt", function(cm) {
eq(cm.getTokenTypeAt(Pos(0, 6)), "string");
}, {value: "1 + 'foo'", mode: "javascript"});
testCM("addOverlay", function(cm) {
cm.addOverlay({
token: function(stream) {
var base = stream.baseToken()
if (!/comment/.test(base.type) && stream.match(/\d+/)) return "x"
stream.next()
}
})
var x = byClassName(cm.getWrapperElement(), "cm-x")
is(x.length, 1)
is(x[0].textContent, "233")
cm.replaceRange("", Pos(0, 4), Pos(0, 6))
is(byClassName(cm.getWrapperElement(), "cm-x").length, 2)
}, {value: "foo /* 100 */\nbar + 233;\nbaz", mode: "javascript"})
testCM("resizeLineWidget", function(cm) {
addDoc(cm, 200, 3);
var widget = document.createElement("pre");
@ -2507,6 +2522,14 @@ testCM("delete_wrapped", function(cm) {
eq(cm.getLine(0), "1245");
}, {value: "12345", lineWrapping: true})
testCM("issue_4878", function(cm) {
if (phantom) return
cm.setCursor(Pos(1, 12, "after"));
cm.moveH(-1, "char");
eqCursorPos(cm.getCursor(), Pos(0, 113, "before"));
}, {value: " في تطبيق السمات مرة واحدة https://github.com/codemirror/CodeMirror/issues/4878#issuecomment-330550964على سبيل المثال <code>\"foo bar\"</code>\n" +
" سيتم تعيين", direction: "rtl", lineWrapping: true});
CodeMirror.defineMode("lookahead_mode", function() {
// Colors text as atom if the line two lines down has an x in it
return {

Просмотреть файл

@ -1386,6 +1386,19 @@ testVim('<C-x>/<C-a> search forward', function(cm, vim, helpers) {
helpers.assertCursorAt(0, 11);
});
}, {value: '__jmp1 jmp2 jmp'});
testVim('insert_ctrl_w', function(cm, vim, helpers) {
var curStart = makeCursor(0, 10);
cm.setCursor(curStart);
helpers.doKeys('a');
helpers.doKeys('<C-w>');
eq('word1/', cm.getValue());
var register = helpers.getRegisterController().getRegister();
eq('word2', register.toString());
is(!register.linewise);
var curEnd = makeCursor(0, 6);
eqCursorPos(curEnd, cm.getCursor());
eq('vim-insert', cm.getOption('keyMap'));
}, { value: 'word1/word2' });
testVim('a', function(cm, vim, helpers) {
cm.setCursor(0, 1);
helpers.doKeys('a');
@ -1662,6 +1675,16 @@ testVim('mark\'', function(cm, vim, helpers) {
helpers.doKeys('\'', '\'');
helpers.assertCursorAt(2, 3);
});
testVim('mark.', function(cm, vim, helpers) {
cm.setCursor(0, 0);
helpers.doKeys('O', 'testing', '<Esc>');
cm.setCursor(3, 3);
helpers.doKeys('\'', '.');
helpers.assertCursorAt(0, 0);
cm.setCursor(4, 4);
helpers.doKeys('`', '.');
helpers.assertCursorAt(0, 6);
});
testVim('jumpToMark_next', function(cm, vim, helpers) {
cm.setCursor(2, 2);
helpers.doKeys('m', 't');