CodeMirror 5.31.0

fixes #225
This commit is contained in:
tophf 2017-11-05 09:12:57 +03:00
parent 72714160bb
commit 93f1bed66c
14 changed files with 1885 additions and 1125 deletions

View File

@ -65,6 +65,8 @@
widget = document.createElement("span"); widget = document.createElement("span");
widget.appendChild(text); widget.appendChild(text);
widget.className = "CodeMirror-foldmarker"; widget.className = "CodeMirror-foldmarker";
} else if (widget) {
widget = widget.cloneNode(true)
} }
return widget; return widget;
} }

View File

@ -302,7 +302,7 @@
setTimeout(function(){cm.focus();}, 20); setTimeout(function(){cm.focus();}, 20);
}); });
CodeMirror.signal(data, "select", completions[0], hints.firstChild); CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
return true; return true;
} }

View File

@ -15,10 +15,15 @@
})(function(CodeMirror) { })(function(CodeMirror) {
"use strict"; "use strict";
CodeMirror.registerHelper("lint", "css", function(text) { CodeMirror.registerHelper("lint", "css", function(text, options) {
var found = []; var found = [];
if (!window.CSSLint) return found; if (!window.CSSLint) {
var results = CSSLint.verify(text), messages = results.messages, message = null; if (window.console) {
window.console.error("Error: window.CSSLint not defined, CodeMirror CSS linting cannot run.");
}
return found;
}
var results = CSSLint.verify(text, options), messages = results.messages, message = null;
for ( var i = 0; i < messages.length; i++) { for ( var i = 0; i < messages.length; i++) {
message = messages[i]; message = messages[i];
var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col; var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col;

View File

@ -112,7 +112,11 @@
if (!severity) severity = "error"; if (!severity) severity = "error";
var tip = document.createElement("div"); var tip = document.createElement("div");
tip.className = "CodeMirror-lint-message-" + severity; tip.className = "CodeMirror-lint-message-" + severity;
tip.appendChild(document.createTextNode(ann.message)); if (typeof ann.messageHTML != 'undefined') {
tip.innerHTML = ann.messageHTML;
} else {
tip.appendChild(document.createTextNode(ann.message));
}
return tip; return tip;
} }
@ -134,7 +138,11 @@
function startLinting(cm) { function startLinting(cm) {
var state = cm.state.lint, options = state.options; var state = cm.state.lint, options = state.options;
var passOptions = options.options || options; // Support deprecated passing of `options` property in options /*
* Passing rules in `options` property prevents JSHint (and other linters) from complaining
* about unrecognized rules like `onUpdateLinting`, `delay`, `lintOnChange`, etc.
*/
var passOptions = options.options || options;
var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint"); var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
if (!getAnnotations) return; if (!getAnnotations) return;
if (options.async || getAnnotations.async) { if (options.async || getAnnotations.async) {

View File

@ -117,6 +117,7 @@
var state = getSearchState(cm); var state = getSearchState(cm);
if (state.query) return findNext(cm, rev); if (state.query) return findNext(cm, rev);
var q = cm.getSelection() || state.lastQuery; var q = cm.getSelection() || state.lastQuery;
if (q instanceof RegExp && q.source == "x^") q = null
if (persistent && cm.openDialog) { if (persistent && cm.openDialog) {
var hiding = null var hiding = null
var searchNext = function(query, event) { var searchNext = function(query, event) {
@ -137,8 +138,7 @@
}; };
persistentDialog(cm, queryDialog, q, searchNext, function(event, query) { persistentDialog(cm, queryDialog, q, searchNext, function(event, query) {
var keyName = CodeMirror.keyName(event) var keyName = CodeMirror.keyName(event)
var cmd = CodeMirror.keyMap[cm.getOption("keyMap")][keyName] var extra = cm.getOption('extraKeys'), cmd = (extra && extra[keyName]) || CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
if (!cmd) cmd = cm.getOption('extraKeys')[keyName]
if (cmd == "findNext" || cmd == "findPrev" || if (cmd == "findNext" || cmd == "findPrev" ||
cmd == "findPersistentNext" || cmd == "findPersistentPrev") { cmd == "findPersistentNext" || cmd == "findPersistentPrev") {
CodeMirror.e_stop(event); CodeMirror.e_stop(event);

View File

@ -128,11 +128,13 @@
// (compensating for codepoints increasing in number during folding) // (compensating for codepoints increasing in number during folding)
function adjustPos(orig, folded, pos, foldFunc) { function adjustPos(orig, folded, pos, foldFunc) {
if (orig.length == folded.length) return pos if (orig.length == folded.length) return pos
for (var pos1 = Math.min(pos, orig.length);;) { for (var min = 0, max = pos + Math.max(0, orig.length - folded.length);;) {
var len1 = foldFunc(orig.slice(0, pos1)).length if (min == max) return min
if (len1 < pos) ++pos1 var mid = (min + max) >> 1
else if (len1 > pos) --pos1 var len = foldFunc(orig.slice(0, mid)).length
else return pos1 if (len == pos) return mid
else if (len > pos) max = mid
else min = mid + 1
} }
} }

View File

@ -369,7 +369,7 @@
"Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"), "Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"),
"Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"), "Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"),
"Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd", "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
"Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace", "Ctrl-S": "findPersistentNext", "Ctrl-R": "findPersistentPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace",
"Alt-/": "autocomplete", "Alt-/": "autocomplete",
"Enter": "newlineAndIndent", "Enter": "newlineAndIndent",
"Ctrl-J": repeated(function(cm) { cm.replaceSelection("\n", "end"); }), "Ctrl-J": repeated(function(cm) { cm.replaceSelection("\n", "end"); }),

View File

@ -14,11 +14,8 @@
})(function(CodeMirror) { })(function(CodeMirror) {
"use strict"; "use strict";
var map = CodeMirror.keyMap.sublime = {fallthrough: "default"};
var cmds = CodeMirror.commands; var cmds = CodeMirror.commands;
var Pos = CodeMirror.Pos; 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. // This is not exactly Sublime's algorithm. I couldn't make heads or tails of that.
function findPosSubword(doc, start, dir) { 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.scrollLineUp = function(cm) {
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) {
var info = cm.getScrollInfo(); var info = cm.getScrollInfo();
if (!cm.somethingSelected()) { if (!cm.somethingSelected()) {
var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local"); var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local");
@ -70,7 +61,7 @@
} }
cm.scrollTo(null, info.top - cm.defaultTextHeight()); cm.scrollTo(null, info.top - cm.defaultTextHeight());
}; };
cmds[map[scrollLineCombo + "Down"] = "scrollLineDown"] = function(cm) { cmds.scrollLineDown = function(cm) {
var info = cm.getScrollInfo(); var info = cm.getScrollInfo();
if (!cm.somethingSelected()) { if (!cm.somethingSelected()) {
var visibleTopLine = cm.lineAtHeight(info.top, "local")+1; var visibleTopLine = cm.lineAtHeight(info.top, "local")+1;
@ -80,7 +71,7 @@
cm.scrollTo(null, info.top + cm.defaultTextHeight()); cm.scrollTo(null, info.top + cm.defaultTextHeight());
}; };
cmds[map["Shift-" + ctrl + "L"] = "splitSelectionByLine"] = function(cm) { cmds.splitSelectionByLine = function(cm) {
var ranges = cm.listSelections(), lineRanges = []; var ranges = cm.listSelections(), lineRanges = [];
for (var i = 0; i < ranges.length; i++) { for (var i = 0; i < ranges.length; i++) {
var from = ranges[i].from(), to = ranges[i].to(); var from = ranges[i].from(), to = ranges[i].to();
@ -92,14 +83,12 @@
cm.setSelections(lineRanges, 0); cm.setSelections(lineRanges, 0);
}; };
map["Shift-Tab"] = "indentLess"; cmds.singleSelectionTop = function(cm) {
cmds[map["Esc"] = "singleSelectionTop"] = function(cm) {
var range = cm.listSelections()[0]; var range = cm.listSelections()[0];
cm.setSelection(range.anchor, range.head, {scroll: false}); cm.setSelection(range.anchor, range.head, {scroll: false});
}; };
cmds[map[ctrl + "L"] = "selectLine"] = function(cm) { cmds.selectLine = function(cm) {
var ranges = cm.listSelections(), extended = []; var ranges = cm.listSelections(), extended = [];
for (var i = 0; i < ranges.length; i++) { for (var i = 0; i < ranges.length; i++) {
var range = ranges[i]; var range = ranges[i];
@ -109,8 +98,6 @@
cm.setSelections(extended); cm.setSelections(extended);
}; };
map["Shift-Ctrl-K"] = "deleteLine";
function insertLine(cm, above) { function insertLine(cm, above) {
if (cm.isReadOnly()) return CodeMirror.Pass if (cm.isReadOnly()) return CodeMirror.Pass
cm.operation(function() { cm.operation(function() {
@ -129,9 +116,9 @@
cm.execCommand("indentAuto"); 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) { function wordAt(cm, pos) {
var start = pos.ch, end = start, line = cm.getLine(pos.line); 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)}; 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 from = cm.getCursor("from"), to = cm.getCursor("to");
var fullWord = cm.state.sublimeFindFullWord == cm.doc.sel; var fullWord = cm.state.sublimeFindFullWord == cm.doc.sel;
if (CodeMirror.cmpPos(from, to) == 0) { if (CodeMirror.cmpPos(from, to) == 0) {
@ -165,6 +152,21 @@
cm.state.sublimeFindFullWord = cm.doc.sel; cm.state.sublimeFindFullWord = cm.doc.sel;
}; };
function addCursorToSelection(cm, dir) {
var ranges = cm.listSelections(), newRanges = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
var newAnchor = cm.findPosV(range.anchor, dir, "line");
var newHead = cm.findPosV(range.head, dir, "line");
var newRange = {anchor: newAnchor, head: newHead};
newRanges.push(range);
newRanges.push(newRange);
}
cm.setSelections(newRanges);
}
cmds.addCursorToPrevLine = function(cm) { addCursorToSelection(cm, -1); };
cmds.addCursorToNextLine = function(cm) { addCursorToSelection(cm, 1); };
function isSelectedRange(ranges, from, to) { function isSelectedRange(ranges, from, to) {
for (var i = 0; i < ranges.length; i++) for (var i = 0; i < ranges.length; i++)
if (ranges[i].from() == from && ranges[i].to() == to) return true if (ranges[i].from() == from && ranges[i].to() == to) return true
@ -192,14 +194,14 @@
return true; return true;
} }
cmds[map["Shift-" + ctrl + "Space"] = "selectScope"] = function(cm) { cmds.selectScope = function(cm) {
selectBetweenBrackets(cm) || cm.execCommand("selectAll"); selectBetweenBrackets(cm) || cm.execCommand("selectAll");
}; };
cmds[map["Shift-" + ctrl + "M"] = "selectBetweenBrackets"] = function(cm) { cmds.selectBetweenBrackets = function(cm) {
if (!selectBetweenBrackets(cm)) return CodeMirror.Pass; if (!selectBetweenBrackets(cm)) return CodeMirror.Pass;
}; };
cmds[map[ctrl + "M"] = "goToBracket"] = function(cm) { cmds.goToBracket = function(cm) {
cm.extendSelectionsBy(function(range) { cm.extendSelectionsBy(function(range) {
var next = cm.scanForBracket(range.head, 1); var next = cm.scanForBracket(range.head, 1);
if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos; if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos;
@ -208,9 +210,7 @@
}); });
}; };
var swapLineCombo = mac ? "Cmd-Ctrl-" : "Shift-Ctrl-"; cmds.swapLineUp = function(cm) {
cmds[map[swapLineCombo + "Up"] = "swapLineUp"] = function(cm) {
if (cm.isReadOnly()) return CodeMirror.Pass if (cm.isReadOnly()) return CodeMirror.Pass
var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = []; var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = [];
for (var i = 0; i < ranges.length; i++) { for (var i = 0; i < ranges.length; i++) {
@ -237,7 +237,7 @@
}); });
}; };
cmds[map[swapLineCombo + "Down"] = "swapLineDown"] = function(cm) { cmds.swapLineDown = function(cm) {
if (cm.isReadOnly()) return CodeMirror.Pass if (cm.isReadOnly()) return CodeMirror.Pass
var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1; var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1;
for (var i = ranges.length - 1; i >= 0; i--) { for (var i = ranges.length - 1; i >= 0; i--) {
@ -261,11 +261,11 @@
}); });
}; };
cmds[map[ctrl + "/"] = "toggleCommentIndented"] = function(cm) { cmds.toggleCommentIndented = function(cm) {
cm.toggleComment({ indent: true }); cm.toggleComment({ indent: true });
} }
cmds[map[ctrl + "J"] = "joinLines"] = function(cm) { cmds.joinLines = function(cm) {
var ranges = cm.listSelections(), joined = []; var ranges = cm.listSelections(), joined = [];
for (var i = 0; i < ranges.length; i++) { for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], from = range.from(); var range = ranges[i], from = range.from();
@ -293,7 +293,7 @@
}); });
}; };
cmds[map["Shift-" + ctrl + "D"] = "duplicateLine"] = function(cm) { cmds.duplicateLine = function(cm) {
cm.operation(function() { cm.operation(function() {
var rangeCount = cm.listSelections().length; var rangeCount = cm.listSelections().length;
for (var i = 0; i < rangeCount; i++) { for (var i = 0; i < rangeCount; i++) {
@ -307,7 +307,6 @@
}); });
}; };
if (!mac) map[ctrl + "T"] = "transposeChars";
function sortLines(cm, caseSensitive) { function sortLines(cm, caseSensitive) {
if (cm.isReadOnly()) return CodeMirror.Pass if (cm.isReadOnly()) return CodeMirror.Pass
@ -345,10 +344,10 @@
}); });
} }
cmds[map["F9"] = "sortLines"] = function(cm) { sortLines(cm, true); }; cmds.sortLines = function(cm) { sortLines(cm, true); };
cmds[map[ctrl + "F9"] = "sortLinesInsensitive"] = function(cm) { sortLines(cm, false); }; cmds.sortLinesInsensitive = function(cm) { sortLines(cm, false); };
cmds[map["F2"] = "nextBookmark"] = function(cm) { cmds.nextBookmark = function(cm) {
var marks = cm.state.sublimeBookmarks; var marks = cm.state.sublimeBookmarks;
if (marks) while (marks.length) { if (marks) while (marks.length) {
var current = marks.shift(); var current = marks.shift();
@ -360,7 +359,7 @@
} }
}; };
cmds[map["Shift-F2"] = "prevBookmark"] = function(cm) { cmds.prevBookmark = function(cm) {
var marks = cm.state.sublimeBookmarks; var marks = cm.state.sublimeBookmarks;
if (marks) while (marks.length) { if (marks) while (marks.length) {
marks.unshift(marks.pop()); marks.unshift(marks.pop());
@ -372,7 +371,7 @@
} }
}; };
cmds[map[ctrl + "F2"] = "toggleBookmark"] = function(cm) { cmds.toggleBookmark = function(cm) {
var ranges = cm.listSelections(); var ranges = cm.listSelections();
var marks = cm.state.sublimeBookmarks || (cm.state.sublimeBookmarks = []); var marks = cm.state.sublimeBookmarks || (cm.state.sublimeBookmarks = []);
for (var i = 0; i < ranges.length; i++) { for (var i = 0; i < ranges.length; i++) {
@ -392,13 +391,13 @@
} }
}; };
cmds[map["Shift-" + ctrl + "F2"] = "clearBookmarks"] = function(cm) { cmds.clearBookmarks = function(cm) {
var marks = cm.state.sublimeBookmarks; var marks = cm.state.sublimeBookmarks;
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear(); if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear();
marks.length = 0; marks.length = 0;
}; };
cmds[map["Alt-F2"] = "selectBookmarks"] = function(cm) { cmds.selectBookmarks = function(cm) {
var marks = cm.state.sublimeBookmarks, ranges = []; var marks = cm.state.sublimeBookmarks, ranges = [];
if (marks) for (var i = 0; i < marks.length; i++) { if (marks) for (var i = 0; i < marks.length; i++) {
var found = marks[i].find(); var found = marks[i].find();
@ -411,10 +410,6 @@
cm.setSelections(ranges, 0); cm.setSelections(ranges, 0);
}; };
map["Alt-Q"] = "wrapLines";
var cK = ctrl + "K ";
function modifyWordOrSelection(cm, mod) { function modifyWordOrSelection(cm, mod) {
cm.operation(function() { cm.operation(function() {
var ranges = cm.listSelections(), indices = [], replacements = []; var ranges = cm.listSelections(), indices = [], replacements = [];
@ -434,9 +429,7 @@
}); });
} }
map[cK + ctrl + "Backspace"] = "delLineLeft"; cmds.smartBackspace = function(cm) {
cmds[map["Backspace"] = "smartBackspace"] = function(cm) {
if (cm.somethingSelected()) return CodeMirror.Pass; if (cm.somethingSelected()) return CodeMirror.Pass;
cm.operation(function() { cm.operation(function() {
@ -464,7 +457,7 @@
}); });
}; };
cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) { cmds.delLineRight = function(cm) {
cm.operation(function() { cm.operation(function() {
var ranges = cm.listSelections(); var ranges = cm.listSelections();
for (var i = ranges.length - 1; i >= 0; i--) for (var i = ranges.length - 1; i >= 0; i--)
@ -473,22 +466,22 @@
}); });
}; };
cmds[map[cK + ctrl + "U"] = "upcaseAtCursor"] = function(cm) { cmds.upcaseAtCursor = function(cm) {
modifyWordOrSelection(cm, function(str) { return str.toUpperCase(); }); 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(); }); 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(); if (cm.state.sublimeMark) cm.state.sublimeMark.clear();
cm.state.sublimeMark = cm.setBookmark(cm.getCursor()); 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(); var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) cm.setSelection(cm.getCursor(), found); 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(); var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) { if (found) {
var from = cm.getCursor(), to = found; var from = cm.getCursor(), to = found;
@ -497,7 +490,7 @@
cm.replaceRange("", from, to); 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(); var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) { if (found) {
cm.state.sublimeMark.clear(); cm.state.sublimeMark.clear();
@ -505,19 +498,17 @@
cm.setCursor(found); cm.setCursor(found);
} }
}; };
cmds[map[cK + ctrl + "Y"] = "sublimeYank"] = function(cm) { cmds.sublimeYank = function(cm) {
if (cm.state.sublimeKilled != null) if (cm.state.sublimeKilled != null)
cm.replaceSelection(cm.state.sublimeKilled, null, "paste"); cm.replaceSelection(cm.state.sublimeKilled, null, "paste");
}; };
map[cK + ctrl + "G"] = "clearBookmarks"; cmds.showInCenter = function(cm) {
cmds[map[cK + ctrl + "C"] = "showInCenter"] = function(cm) {
var pos = cm.cursorCoords(null, "local"); var pos = cm.cursorCoords(null, "local");
cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2); cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2);
}; };
var selectLinesCombo = mac ? "Ctrl-Shift-" : "Ctrl-Alt-"; cmds.selectLinesUpward = function(cm) {
cmds[map[selectLinesCombo + "Up"] = "selectLinesUpward"] = function(cm) {
cm.operation(function() { cm.operation(function() {
var ranges = cm.listSelections(); var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) { for (var i = 0; i < ranges.length; i++) {
@ -527,7 +518,7 @@
} }
}); });
}; };
cmds[map[selectLinesCombo + "Down"] = "selectLinesDownward"] = function(cm) { cmds.selectLinesDownward = function(cm) {
cm.operation(function() { cm.operation(function() {
var ranges = cm.listSelections(); var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) { for (var i = 0; i < ranges.length; i++) {
@ -566,9 +557,9 @@
cm.setSelection(target.from, target.to); cm.setSelection(target.from, target.to);
} }
}; };
cmds[map[ctrl + "F3"] = "findUnder"] = function(cm) { findAndGoTo(cm, true); }; cmds.findUnder = function(cm) { findAndGoTo(cm, true); };
cmds[map["Shift-" + ctrl + "F3"] = "findUnderPrevious"] = function(cm) { findAndGoTo(cm,false); }; cmds.findUnderPrevious = function(cm) { findAndGoTo(cm,false); };
cmds[map["Alt-F3"] = "findAllUnder"] = function(cm) { cmds.findAllUnder = function(cm) {
var target = getTarget(cm); var target = getTarget(cm);
if (!target) return; if (!target) return;
var cur = cm.getSearchCursor(target.query); var cur = cm.getSearchCursor(target.query);
@ -582,15 +573,132 @@
cm.setSelections(matches, primaryIndex); 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"; var keyMap = CodeMirror.keyMap;
map["Shift-" + ctrl + "I"] = "findIncrementalReverse"; keyMap.macSublime = {
map[ctrl + "H"] = "replace"; "Cmd-Left": "goLineStartSmart",
map["F3"] = "findNext"; "Shift-Tab": "indentLess",
map["Shift-F3"] = "findPrev"; "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;
}); });

View File

@ -255,20 +255,67 @@
} }
function detachVimMap(cm, next) { function detachVimMap(cm, next) {
if (this == CodeMirror.keyMap.vim) if (this == CodeMirror.keyMap.vim) {
CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor"); 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) if (!next || next.attach != attachVimMap)
leaveVimMode(cm); leaveVimMode(cm);
} }
function attachVimMap(cm, prev) { function attachVimMap(cm, prev) {
if (this == CodeMirror.keyMap.vim) if (this == CodeMirror.keyMap.vim) {
CodeMirror.addClass(cm.getWrapperElement(), "cm-fat-cursor"); 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) if (!prev || prev.attach != attachVimMap)
enterVimMode(cm); 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. // Deprecated, simply setting the keymap works again.
CodeMirror.defineOption('vimMode', false, function(cm, val, prev) { CodeMirror.defineOption('vimMode', false, function(cm, val, prev) {
if (val && cm.getOption("keyMap") != "vim") if (val && cm.getOption("keyMap") != "vim")
@ -2034,7 +2081,8 @@
vimGlobalState.registerController.pushText( vimGlobalState.registerController.pushText(
args.registerName, 'delete', text, args.registerName, 'delete', text,
args.linewise, vim.visualBlock); args.linewise, vim.visualBlock);
return clipCursorToContent(cm, finalHead); var includeLineBreak = vim.insertMode
return clipCursorToContent(cm, finalHead, includeLineBreak);
}, },
indent: function(cm, args, ranges) { indent: function(cm, args, ranges) {
var vim = cm.state.vim; var vim = cm.state.vim;
@ -3244,7 +3292,7 @@
return cur; return cur;
} }
/** /*
* Returns the boundaries of the next word. If the cursor in the middle of * 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 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 * 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 history = cm.doc.history.done;
var event = history[history.length - 2]; var event = history[history.length - 2];
return event && event.ranges && event.ranges[0].head; 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]; var mark = vim.marks[markName];
@ -4788,7 +4845,8 @@
// so as to update the ". register as expected in real vim. // so as to update the ". register as expected in real vim.
var text = []; var text = [];
if (!isPlaying) { 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 changes = lastChange.changes;
var text = []; var text = [];
var i = 0; var i = 0;

View File

@ -5,6 +5,7 @@
font-family: monospace; font-family: monospace;
height: 300px; height: 300px;
color: black; color: black;
direction: ltr;
} }
/* PADDING */ /* PADDING */
@ -58,7 +59,12 @@
.cm-fat-cursor div.CodeMirror-cursors { .cm-fat-cursor div.CodeMirror-cursors {
z-index: 1; 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 { .cm-animate-fat-cursor {
width: auto; width: auto;
border: 0; border: 0;
@ -319,8 +325,8 @@ div.CodeMirror-dragcursors {
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching { .cm-searching {
background: #ffa; background-color: #ffa;
background: rgba(255, 255, 0, .4); background-color: rgba(255, 255, 0, .4);
} }
/* Used to force a border model for a node */ /* Used to force a border model for a node */

File diff suppressed because it is too large Load Diff

View File

@ -383,7 +383,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
style = style[0]; style = style[0];
} }
override = style; override = style;
state.state = states[state.state](type, stream, state); if (type != "comment")
state.state = states[state.state](type, stream, state);
return override; return override;
}, },
@ -409,6 +410,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
electricChars: "}", electricChars: "}",
blockCommentStart: "/*", blockCommentStart: "/*",
blockCommentEnd: "*/", blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: lineComment, lineComment: lineComment,
fold: "brace" fold: "brace"
}; };

View File

@ -11,11 +11,6 @@
})(function(CodeMirror) { })(function(CodeMirror) {
"use strict"; "use strict";
function expressionAllowed(stream, state, backUp) {
return /^(?:operator|sof|keyword c|case|new|export|default|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
}
CodeMirror.defineMode("javascript", function(config, parserConfig) { CodeMirror.defineMode("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit; var indentUnit = config.indentUnit;
var statementIndent = parserConfig.statementIndent; var statementIndent = parserConfig.statementIndent;
@ -28,13 +23,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var keywords = function(){ var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};} 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 operator = kw("operator"), atom = {type: "atom", style: "atom"};
var jsKeywords = { var jsKeywords = {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, "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, "throw": C, "debugger": C, "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
"var": kw("var"), "const": kw("var"), "let": kw("var"), "debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"), "function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator, "in": operator, "typeof": operator, "instanceof": operator,
@ -60,6 +55,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
"private": kw("modifier"), "private": kw("modifier"),
"protected": kw("modifier"), "protected": kw("modifier"),
"abstract": kw("modifier"), "abstract": kw("modifier"),
"readonly": kw("modifier"),
// types // types
"string": type, "number": type, "boolean": type, "any": type "string": type, "number": type, "boolean": type, "any": type
@ -132,7 +128,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
return ret("regexp", "string-2"); return ret("regexp", "string-2");
} else { } else {
stream.eatWhile(isOperatorChar); stream.eat("=");
return ret("operator", "operator", stream.current()); return ret("operator", "operator", stream.current());
} }
} else if (ch == "`") { } else if (ch == "`") {
@ -142,8 +138,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
stream.skipToEnd(); stream.skipToEnd();
return ret("error", "error"); return ret("error", "error");
} else if (isOperatorChar.test(ch)) { } else if (isOperatorChar.test(ch)) {
if (ch != ">" || !state.lexical || state.lexical.type != ">") if (ch != ">" || !state.lexical || state.lexical.type != ">") {
stream.eatWhile(isOperatorChar); 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()); return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) { } else if (wordRE.test(ch)) {
stream.eatWhile(wordRE); stream.eatWhile(wordRE);
@ -355,6 +357,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); 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 a") return cont(pushlex("form"), parenExpr, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), 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(pushlex("}"), block, poplex);
if (type == ";") return cont(); if (type == ";") return cont();
if (type == "if") { if (type == "if") {
@ -368,6 +372,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (isTS && value == "type") { if (isTS && value == "type") {
cx.marked = "keyword" cx.marked = "keyword"
return cont(typeexpr, expect("operator"), typeexpr, expect(";")); return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
} if (isTS && value == "declare") {
cx.marked = "keyword"
return cont(statement)
} else { } else {
return cont(pushlex("stat"), maybelabel); return cont(pushlex("stat"), maybelabel);
} }
@ -399,7 +406,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function expressionInner(type, noComma) { function expressionInner(type, noComma) {
if (cx.state.fatArrowAt == cx.stream.start) { if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody; var body = noComma ? arrowBodyNoComma : arrowBody;
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
} }
@ -407,7 +414,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, maybeop); if (type == "function") return cont(functiondef, maybeop);
if (type == "class") return cont(pushlex("form"), classExpression, poplex); 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 == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
@ -420,10 +427,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type.match(/[;\}\)\],]/)) return pass(); if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression); return pass(expression);
} }
function maybeexpressionNoComma(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expressionNoComma);
}
function maybeoperatorComma(type, value) { function maybeoperatorComma(type, value) {
if (type == ",") return cont(expression); if (type == ",") return cont(expression);
@ -434,7 +437,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var expr = noComma == false ? expression : expressionNoComma; var expr = noComma == false ? expression : expressionNoComma;
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") { if (type == "operator") {
if (/\+\+|--/.test(value)) return cont(me); if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
if (value == "?") return cont(expression, expect(":"), expr); if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr); return cont(expr);
} }
@ -444,6 +447,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == ".") return cont(property, me); if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) } if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) }
if (type == "regexp") {
cx.state.lastType = cx.marked = "operator"
cx.stream.backUp(cx.stream.pos - cx.stream.start - 1)
return cont(expr)
}
} }
function quasi(type, value) { function quasi(type, value) {
if (type != "quasi") return pass(); if (type != "quasi") return pass();
@ -468,6 +476,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeTarget(noComma) { function maybeTarget(noComma) {
return function(type) { return function(type) {
if (type == ".") return cont(noComma ? targetNoComma : target); if (type == ".") return cont(noComma ? targetNoComma : target);
else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
else return pass(noComma ? expressionNoComma : expression); else return pass(noComma ? expressionNoComma : expression);
}; };
} }
@ -491,6 +500,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} else if (type == "variable" || cx.style == "keyword") { } else if (type == "variable" || cx.style == "keyword") {
cx.marked = "property"; cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter); if (value == "get" || value == "set") return cont(getterSetter);
var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params
if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
cx.state.fatArrowAt = cx.stream.pos + m[0].length
return cont(afterprop); return cont(afterprop);
} else if (type == "number" || type == "string") { } else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (cx.style + " property"); cx.marked = jsonldMode ? "property" : (cx.style + " property");
@ -502,7 +514,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} else if (type == "[") { } else if (type == "[") {
return cont(expression, expect("]"), afterprop); return cont(expression, expect("]"), afterprop);
} else if (type == "spread") { } else if (type == "spread") {
return cont(expression, afterprop); return cont(expressionNoComma, afterprop);
} else if (value == "*") {
cx.marked = "keyword";
return cont(objprop);
} else if (type == ":") { } else if (type == ":") {
return pass(afterprop) return pass(afterprop)
} }
@ -549,9 +564,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (value == "?") return cont(maybetype); if (value == "?") return cont(maybetype);
} }
} }
function typeexpr(type) { function typeexpr(type, value) {
if (type == "variable") {cx.marked = "type"; return cont(afterType);} if (type == "variable" || value == "void") {
if (value == "keyof") {
cx.marked = "keyword"
return cont(typeexpr)
} else {
cx.marked = "type"
return cont(afterType)
}
}
if (type == "string" || type == "number" || type == "atom") return cont(afterType); if (type == "string" || type == "number" || type == "atom") return cont(afterType);
if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType) if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType) if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
} }
@ -580,6 +604,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "[") return cont(expect("]"), afterType) if (type == "[") return cont(expect("]"), afterType)
if (value == "extends") return cont(typeexpr) if (value == "extends") return cont(typeexpr)
} }
function maybeTypeArgs(_, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
}
function vardef() { function vardef() {
return pass(pattern, maybetype, maybeAssign, vardefCont); return pass(pattern, maybetype, maybeAssign, vardefCont);
} }
@ -636,8 +663,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext); if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext);
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, functiondef) if (isTS && value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, functiondef)
} }
function funarg(type) { function funarg(type, value) {
if (type == "spread") return cont(funarg); if (value == "@") cont(expression, funarg)
if (type == "spread" || type == "modifier") return cont(funarg);
return pass(pattern, maybetype, maybeAssign); return pass(pattern, maybetype, maybeAssign);
} }
function classExpression(type, value) { function classExpression(type, value) {
@ -655,13 +683,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "{") return cont(pushlex("}"), classBody, poplex); if (type == "{") return cont(pushlex("}"), classBody, poplex);
} }
function classBody(type, value) { function classBody(type, value) {
if (type == "modifier" || type == "async" ||
(type == "variable" &&
(value == "static" || value == "get" || value == "set") &&
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
cx.marked = "keyword";
return cont(classBody);
}
if (type == "variable" || cx.style == "keyword") { if (type == "variable" || cx.style == "keyword") {
if ((value == "async" || value == "static" || value == "get" || value == "set" ||
(isTS && (value == "public" || value == "private" || value == "protected" || value == "readonly" || value == "abstract"))) &&
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false)) {
cx.marked = "keyword";
return cont(classBody);
}
cx.marked = "property"; cx.marked = "property";
return cont(isTS ? classfield : functiondef, classBody); return cont(isTS ? classfield : functiondef, classBody);
} }
@ -721,6 +750,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
/[,.]/.test(textAfter.charAt(0)); /[,.]/.test(textAfter.charAt(0));
} }
function expressionAllowed(stream, state, backUp) {
return state.tokenize == tokenBase &&
/^(?: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))))
}
// Interface // Interface
return { return {
@ -786,6 +821,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*", blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/", blockCommentEnd: jsonMode ? null : "*/",
blockCommentContinue: jsonMode ? null : " * ",
lineComment: jsonMode ? null : "//", lineComment: jsonMode ? null : "//",
fold: "brace", fold: "brace",
closeBrackets: "()[]{}''\"\"``", closeBrackets: "()[]{}''\"\"``",
@ -795,6 +831,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
jsonMode: jsonMode, jsonMode: jsonMode,
expressionAllowed: expressionAllowed, expressionAllowed: expressionAllowed,
skipExpression: function(state) { skipExpression: function(state) {
var top = state.cc[state.cc.length - 1] var top = state.cc[state.cc.length - 1]
if (top == expression || top == expressionNoComma) state.cc.pop() if (top == expression || top == expressionNoComma) state.cc.pop()

View File

@ -12,8 +12,6 @@
color: #D1EDFF; color: #D1EDFF;
} }
.cm-s-midnight.CodeMirror { border-top: 1px solid black; border-bottom: 1px solid black; }
.cm-s-midnight div.CodeMirror-selected { background: #314D67; } .cm-s-midnight div.CodeMirror-selected { background: #314D67; }
.cm-s-midnight .CodeMirror-line::selection, .cm-s-midnight .CodeMirror-line > span::selection, .cm-s-midnight .CodeMirror-line > span > span::selection { background: rgba(49, 77, 103, .99); } .cm-s-midnight .CodeMirror-line::selection, .cm-s-midnight .CodeMirror-line > span::selection, .cm-s-midnight .CodeMirror-line > span > span::selection { background: rgba(49, 77, 103, .99); }
.cm-s-midnight .CodeMirror-line::-moz-selection, .cm-s-midnight .CodeMirror-line > span::-moz-selection, .cm-s-midnight .CodeMirror-line > span > span::-moz-selection { background: rgba(49, 77, 103, .99); } .cm-s-midnight .CodeMirror-line::-moz-selection, .cm-s-midnight .CodeMirror-line > span::-moz-selection, .cm-s-midnight .CodeMirror-line > span > span::-moz-selection { background: rgba(49, 77, 103, .99); }