CodeMirror 5.24
Notable change for css mode: Expose lineComment property for LESS and SCSS dialects. Recognize vendor prefixes on pseudo-elements.
This commit is contained in:
parent
df570dab9e
commit
b2e8bf02a9
|
@ -1,3 +1,5 @@
|
|||
MIT License
|
||||
|
||||
Copyright (C) 2017 by Marijn Haverbeke <marijnh@gmail.com> and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
|
19
codemirror/addon/comment/comment.js
vendored
19
codemirror/addon/comment/comment.js
vendored
|
@ -46,12 +46,17 @@
|
|||
|
||||
// Rough heuristic to try and detect lines that are part of multi-line string
|
||||
function probablyInsideString(cm, pos, line) {
|
||||
return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"`]/.test(line)
|
||||
return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"\`]/.test(line)
|
||||
}
|
||||
|
||||
function getMode(cm, pos) {
|
||||
var mode = cm.getMode()
|
||||
return mode.useInnerComments === false || !mode.innerMode ? mode : cm.getModeAt(pos)
|
||||
}
|
||||
|
||||
CodeMirror.defineExtension("lineComment", function(from, to, options) {
|
||||
if (!options) options = noOptions;
|
||||
var self = this, mode = self.getModeAt(from);
|
||||
var self = this, mode = getMode(self, from);
|
||||
var firstLine = self.getLine(from.line);
|
||||
if (firstLine == null || probablyInsideString(self, from, firstLine)) return;
|
||||
|
||||
|
@ -95,7 +100,7 @@
|
|||
|
||||
CodeMirror.defineExtension("blockComment", function(from, to, options) {
|
||||
if (!options) options = noOptions;
|
||||
var self = this, mode = self.getModeAt(from);
|
||||
var self = this, mode = getMode(self, from);
|
||||
var startString = options.blockCommentStart || mode.blockCommentStart;
|
||||
var endString = options.blockCommentEnd || mode.blockCommentEnd;
|
||||
if (!startString || !endString) {
|
||||
|
@ -129,7 +134,7 @@
|
|||
|
||||
CodeMirror.defineExtension("uncomment", function(from, to, options) {
|
||||
if (!options) options = noOptions;
|
||||
var self = this, mode = self.getModeAt(from);
|
||||
var self = this, mode = getMode(self, from);
|
||||
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
|
||||
|
||||
// Try finding line comments
|
||||
|
@ -171,9 +176,11 @@
|
|||
endLine = self.getLine(--end);
|
||||
close = endLine.indexOf(endString);
|
||||
}
|
||||
var insideStart = Pos(start, open + 1), insideEnd = Pos(end, close + 1)
|
||||
if (close == -1 ||
|
||||
!/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) ||
|
||||
!/comment/.test(self.getTokenTypeAt(Pos(end, close + 1))))
|
||||
!/comment/.test(self.getTokenTypeAt(insideStart)) ||
|
||||
!/comment/.test(self.getTokenTypeAt(insideEnd)) ||
|
||||
self.getRange(insideStart, insideEnd, "\n").indexOf(endString) > -1)
|
||||
return false;
|
||||
|
||||
// Avoid killing block comments completely outside the selection.
|
||||
|
|
6
codemirror/addon/lint/lint.js
vendored
6
codemirror/addon/lint/lint.js
vendored
|
@ -140,7 +140,11 @@
|
|||
if (options.async || getAnnotations.async) {
|
||||
lintAsync(cm, getAnnotations, passOptions)
|
||||
} else {
|
||||
updateLinting(cm, getAnnotations(cm.getValue(), passOptions, cm));
|
||||
var annotations = getAnnotations(cm.getValue(), passOptions, cm);
|
||||
if (annotations.then) annotations.then(function(issues) {
|
||||
updateLinting(cm, issues);
|
||||
});
|
||||
else updateLinting(cm, annotations);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
6
codemirror/addon/scroll/annotatescrollbar.js
vendored
6
codemirror/addon/scroll/annotatescrollbar.js
vendored
|
@ -77,17 +77,21 @@
|
|||
curLine = pos.line;
|
||||
curLineObj = cm.getLineHandle(curLine);
|
||||
}
|
||||
if (wrapping && curLineObj.height > singleLineH)
|
||||
if ((curLineObj.widgets && curLineObj.widgets.length) ||
|
||||
(wrapping && curLineObj.height > singleLineH))
|
||||
return cm.charCoords(pos, "local")[top ? "top" : "bottom"];
|
||||
var topY = cm.heightAtLine(curLineObj, "local");
|
||||
return topY + (top ? 0 : curLineObj.height);
|
||||
}
|
||||
|
||||
var lastLine = cm.lastLine()
|
||||
if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) {
|
||||
var ann = anns[i];
|
||||
if (ann.to.line > lastLine) continue;
|
||||
var top = nextTop || getY(ann.from, true) * hScale;
|
||||
var bottom = getY(ann.to, false) * hScale;
|
||||
while (i < anns.length - 1) {
|
||||
if (anns[i + 1].to.line > lastLine) break;
|
||||
nextTop = getY(anns[i + 1].from, true) * hScale;
|
||||
if (nextTop > bottom + .9) break;
|
||||
ann = anns[++i];
|
||||
|
|
4
codemirror/keymap/emacs.js
vendored
4
codemirror/keymap/emacs.js
vendored
|
@ -371,7 +371,9 @@
|
|||
"Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
|
||||
"Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace",
|
||||
"Alt-/": "autocomplete",
|
||||
"Ctrl-J": "newlineAndIndent", "Enter": false, "Tab": "indentAuto",
|
||||
"Enter": "newlineAndIndent",
|
||||
"Ctrl-J": repeated(function(cm) { cm.replaceSelection("\n", "end"); }),
|
||||
"Tab": "indentAuto",
|
||||
|
||||
"Alt-G G": function(cm) {
|
||||
var prefix = getPrefix(cm, true);
|
||||
|
|
17
codemirror/keymap/sublime.js
vendored
17
codemirror/keymap/sublime.js
vendored
|
@ -152,18 +152,25 @@
|
|||
var text = cm.getRange(from, to);
|
||||
var query = fullWord ? new RegExp("\\b" + text + "\\b") : text;
|
||||
var cur = cm.getSearchCursor(query, to);
|
||||
if (cur.findNext()) {
|
||||
cm.addSelection(cur.from(), cur.to());
|
||||
} else {
|
||||
var found = cur.findNext();
|
||||
if (!found) {
|
||||
cur = cm.getSearchCursor(query, Pos(cm.firstLine(), 0));
|
||||
if (cur.findNext())
|
||||
cm.addSelection(cur.from(), cur.to());
|
||||
found = cur.findNext();
|
||||
}
|
||||
if (!found || isSelectedRange(cm.listSelections(), cur.from(), cur.to()))
|
||||
return CodeMirror.Pass
|
||||
cm.addSelection(cur.from(), cur.to());
|
||||
}
|
||||
if (fullWord)
|
||||
cm.state.sublimeFindFullWord = cm.doc.sel;
|
||||
};
|
||||
|
||||
function isSelectedRange(ranges, from, to) {
|
||||
for (var i = 0; i < ranges.length; i++)
|
||||
if (ranges[i].from() == from && ranges[i].to() == to) return true
|
||||
return false
|
||||
}
|
||||
|
||||
var mirror = "(){}[]";
|
||||
function selectBetweenBrackets(cm) {
|
||||
var ranges = cm.listSelections(), newRanges = []
|
||||
|
|
93
codemirror/keymap/vim.js
vendored
93
codemirror/keymap/vim.js
vendored
|
@ -142,7 +142,7 @@
|
|||
{ keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }},
|
||||
{ keys: 'D', type: 'operatorMotion', operator: 'delete', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'},
|
||||
{ keys: 'D', type: 'operator', operator: 'delete', operatorArgs: { linewise: true }, context: 'visual'},
|
||||
{ keys: 'Y', type: 'operatorMotion', operator: 'yank', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'},
|
||||
{ keys: 'Y', type: 'operatorMotion', operator: 'yank', motion: 'expandToLine', motionArgs: { linewise: true }, context: 'normal'},
|
||||
{ keys: 'Y', type: 'operator', operator: 'yank', operatorArgs: { linewise: true }, context: 'visual'},
|
||||
{ keys: 'C', type: 'operatorMotion', operator: 'change', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'},
|
||||
{ keys: 'C', type: 'operator', operator: 'change', operatorArgs: { linewise: true }, context: 'visual'},
|
||||
|
@ -1245,11 +1245,13 @@
|
|||
}
|
||||
}
|
||||
function onPromptKeyUp(e, query, close) {
|
||||
var keyName = CodeMirror.keyName(e), up;
|
||||
var keyName = CodeMirror.keyName(e), up, offset;
|
||||
if (keyName == 'Up' || keyName == 'Down') {
|
||||
up = keyName == 'Up' ? true : false;
|
||||
offset = e.target ? e.target.selectionEnd : 0;
|
||||
query = vimGlobalState.searchHistoryController.nextMatch(query, up) || '';
|
||||
close(query);
|
||||
if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length);
|
||||
} else {
|
||||
if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift')
|
||||
vimGlobalState.searchHistoryController.reset();
|
||||
|
@ -1281,6 +1283,8 @@
|
|||
clearInputState(cm);
|
||||
close();
|
||||
cm.focus();
|
||||
} else if (keyName == 'Up' || keyName == 'Down') {
|
||||
CodeMirror.e_stop(e);
|
||||
} else if (keyName == 'Ctrl-U') {
|
||||
// Ctrl-U clears input.
|
||||
CodeMirror.e_stop(e);
|
||||
|
@ -1344,7 +1348,7 @@
|
|||
exCommandDispatcher.processCommand(cm, input);
|
||||
}
|
||||
function onPromptKeyDown(e, input, close) {
|
||||
var keyName = CodeMirror.keyName(e), up;
|
||||
var keyName = CodeMirror.keyName(e), up, offset;
|
||||
if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' ||
|
||||
(keyName == 'Backspace' && input == '')) {
|
||||
vimGlobalState.exCommandHistoryController.pushInput(input);
|
||||
|
@ -1355,9 +1359,12 @@
|
|||
cm.focus();
|
||||
}
|
||||
if (keyName == 'Up' || keyName == 'Down') {
|
||||
CodeMirror.e_stop(e);
|
||||
up = keyName == 'Up' ? true : false;
|
||||
offset = e.target ? e.target.selectionEnd : 0;
|
||||
input = vimGlobalState.exCommandHistoryController.nextMatch(input, up) || '';
|
||||
close(input);
|
||||
if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length);
|
||||
} else if (keyName == 'Ctrl-U') {
|
||||
// Ctrl-U clears input.
|
||||
CodeMirror.e_stop(e);
|
||||
|
@ -1620,9 +1627,8 @@
|
|||
return findNext(cm, prev/** prev */, query, motionArgs.repeat);
|
||||
},
|
||||
goToMark: function(cm, _head, motionArgs, vim) {
|
||||
var mark = vim.marks[motionArgs.selectedCharacter];
|
||||
if (mark) {
|
||||
var pos = mark.find();
|
||||
var pos = getMarkPos(cm, vim, motionArgs.selectedCharacter);
|
||||
if (pos) {
|
||||
return motionArgs.linewise ? { line: pos.line, ch: findFirstNonWhiteSpaceCharacter(cm.getLine(pos.line)) } : pos;
|
||||
}
|
||||
return null;
|
||||
|
@ -3966,6 +3972,17 @@
|
|||
return {top: from.line, bottom: to.line};
|
||||
}
|
||||
|
||||
function getMarkPos(cm, vim, markName) {
|
||||
if (markName == '\'') {
|
||||
var history = cm.doc.history.done;
|
||||
var event = history[history.length - 2];
|
||||
return event && event.ranges && event.ranges[0].head;
|
||||
}
|
||||
|
||||
var mark = vim.marks[markName];
|
||||
return mark && mark.find();
|
||||
}
|
||||
|
||||
var ExCommandDispatcher = function() {
|
||||
this.buildCommandMap_();
|
||||
};
|
||||
|
@ -4074,11 +4091,10 @@
|
|||
case '$':
|
||||
return cm.lastLine();
|
||||
case '\'':
|
||||
var mark = cm.state.vim.marks[inputStream.next()];
|
||||
if (mark && mark.find()) {
|
||||
return mark.find().line;
|
||||
}
|
||||
throw new Error('Mark not set');
|
||||
var markName = inputStream.next();
|
||||
var markPos = getMarkPos(cm, cm.state.vim, markName);
|
||||
if (!markPos) throw new Error('Mark not set');
|
||||
return markPos.line;
|
||||
default:
|
||||
inputStream.backUp(1);
|
||||
return undefined;
|
||||
|
@ -4147,8 +4163,8 @@
|
|||
var mapping = {
|
||||
keys: lhs,
|
||||
type: 'keyToEx',
|
||||
exArgs: { input: rhs.substring(1) },
|
||||
user: true};
|
||||
exArgs: { input: rhs.substring(1) }
|
||||
};
|
||||
if (ctx) { mapping.context = ctx; }
|
||||
defaultKeymap.unshift(mapping);
|
||||
} else {
|
||||
|
@ -4156,8 +4172,7 @@
|
|||
var mapping = {
|
||||
keys: lhs,
|
||||
type: 'keyToKey',
|
||||
toKeys: rhs,
|
||||
user: true
|
||||
toKeys: rhs
|
||||
};
|
||||
if (ctx) { mapping.context = ctx; }
|
||||
defaultKeymap.unshift(mapping);
|
||||
|
@ -4178,8 +4193,7 @@
|
|||
var keys = lhs;
|
||||
for (var i = 0; i < defaultKeymap.length; i++) {
|
||||
if (keys == defaultKeymap[i].keys
|
||||
&& defaultKeymap[i].context === ctx
|
||||
&& defaultKeymap[i].user) {
|
||||
&& defaultKeymap[i].context === ctx) {
|
||||
defaultKeymap.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
|
@ -4310,25 +4324,27 @@
|
|||
showConfirm(cm, regInfo);
|
||||
},
|
||||
sort: function(cm, params) {
|
||||
var reverse, ignoreCase, unique, number;
|
||||
var reverse, ignoreCase, unique, number, pattern;
|
||||
function parseArgs() {
|
||||
if (params.argString) {
|
||||
var args = new CodeMirror.StringStream(params.argString);
|
||||
if (args.eat('!')) { reverse = true; }
|
||||
if (args.eol()) { return; }
|
||||
if (!args.eatSpace()) { return 'Invalid arguments'; }
|
||||
var opts = args.match(/[a-z]+/);
|
||||
if (opts) {
|
||||
opts = opts[0];
|
||||
ignoreCase = opts.indexOf('i') != -1;
|
||||
unique = opts.indexOf('u') != -1;
|
||||
var decimal = opts.indexOf('d') != -1 && 1;
|
||||
var hex = opts.indexOf('x') != -1 && 1;
|
||||
var octal = opts.indexOf('o') != -1 && 1;
|
||||
var opts = args.match(/([dinuox]+)?\s*(\/.+\/)?\s*/);
|
||||
if (!opts && !args.eol()) { return 'Invalid arguments'; }
|
||||
if (opts[1]) {
|
||||
ignoreCase = opts[1].indexOf('i') != -1;
|
||||
unique = opts[1].indexOf('u') != -1;
|
||||
var decimal = opts[1].indexOf('d') != -1 || opts[1].indexOf('n') != -1 && 1;
|
||||
var hex = opts[1].indexOf('x') != -1 && 1;
|
||||
var octal = opts[1].indexOf('o') != -1 && 1;
|
||||
if (decimal + hex + octal > 1) { return 'Invalid arguments'; }
|
||||
number = decimal && 'decimal' || hex && 'hex' || octal && 'octal';
|
||||
}
|
||||
if (args.match(/\/.*\//)) { return 'patterns not supported'; }
|
||||
if (opts[2]) {
|
||||
pattern = new RegExp(opts[2].substr(1, opts[2].length - 2), ignoreCase ? 'i' : '');
|
||||
}
|
||||
}
|
||||
}
|
||||
var err = parseArgs();
|
||||
|
@ -4342,14 +4358,18 @@
|
|||
var curStart = Pos(lineStart, 0);
|
||||
var curEnd = Pos(lineEnd, lineLength(cm, lineEnd));
|
||||
var text = cm.getRange(curStart, curEnd).split('\n');
|
||||
var numberRegex = (number == 'decimal') ? /(-?)([\d]+)/ :
|
||||
var numberRegex = pattern ? pattern :
|
||||
(number == 'decimal') ? /(-?)([\d]+)/ :
|
||||
(number == 'hex') ? /(-?)(?:0x)?([0-9a-f]+)/i :
|
||||
(number == 'octal') ? /([0-7]+)/ : null;
|
||||
var radix = (number == 'decimal') ? 10 : (number == 'hex') ? 16 : (number == 'octal') ? 8 : null;
|
||||
var numPart = [], textPart = [];
|
||||
if (number) {
|
||||
if (number || pattern) {
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
if (numberRegex.exec(text[i])) {
|
||||
var matchPart = pattern ? text[i].match(pattern) : null;
|
||||
if (matchPart && matchPart[0] != '') {
|
||||
numPart.push(matchPart);
|
||||
} else if (!pattern && numberRegex.exec(text[i])) {
|
||||
numPart.push(text[i]);
|
||||
} else {
|
||||
textPart.push(text[i]);
|
||||
|
@ -4368,8 +4388,17 @@
|
|||
bnum = parseInt((bnum[1] + bnum[2]).toLowerCase(), radix);
|
||||
return anum - bnum;
|
||||
}
|
||||
numPart.sort(compareFn);
|
||||
textPart.sort(compareFn);
|
||||
function comparePatternFn(a, b) {
|
||||
if (reverse) { var tmp; tmp = a; a = b; b = tmp; }
|
||||
if (ignoreCase) { a[0] = a[0].toLowerCase(); b[0] = b[0].toLowerCase(); }
|
||||
return (a[0] < b[0]) ? -1 : 1;
|
||||
}
|
||||
numPart.sort(pattern ? comparePatternFn : compareFn);
|
||||
if (pattern) {
|
||||
for (var i = 0; i < numPart.length; i++) {
|
||||
numPart[i] = numPart[i].input;
|
||||
}
|
||||
} else if (!number) { textPart.sort(compareFn); }
|
||||
text = (!reverse) ? textPart.concat(numPart) : numPart.concat(textPart);
|
||||
if (unique) { // Remove duplicate lines
|
||||
var textOld = text;
|
||||
|
|
9
codemirror/lib/codemirror.css
vendored
9
codemirror/lib/codemirror.css
vendored
|
@ -223,11 +223,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
|||
cursor: default;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
|
||||
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
|
||||
|
||||
.CodeMirror-lines {
|
||||
cursor: text;
|
||||
|
@ -272,6 +269,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
|||
|
||||
.CodeMirror-widget {}
|
||||
|
||||
.CodeMirror-rtl pre { direction: rtl; }
|
||||
|
||||
.CodeMirror-code {
|
||||
outline: none;
|
||||
}
|
||||
|
|
8
codemirror/mode/css/css.js
vendored
8
codemirror/mode/css/css.js
vendored
|
@ -28,6 +28,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
colorKeywords = parserConfig.colorKeywords || {},
|
||||
valueKeywords = parserConfig.valueKeywords || {},
|
||||
allowNested = parserConfig.allowNested,
|
||||
lineComment = parserConfig.lineComment,
|
||||
supportsAtComponent = parserConfig.supportsAtComponent === true;
|
||||
|
||||
var type, override;
|
||||
|
@ -253,6 +254,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
};
|
||||
|
||||
states.pseudo = function(type, stream, state) {
|
||||
if (type == "meta") return "pseudo";
|
||||
|
||||
if (type == "word") {
|
||||
override = "variable-3";
|
||||
return state.context.type;
|
||||
|
@ -407,6 +410,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
electricChars: "}",
|
||||
blockCommentStart: "/*",
|
||||
blockCommentEnd: "*/",
|
||||
lineComment: lineComment,
|
||||
fold: "brace"
|
||||
};
|
||||
});
|
||||
|
@ -663,7 +667,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
|
||||
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
|
||||
"square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
|
||||
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
|
||||
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
|
||||
"table-caption", "table-cell", "table-column", "table-column-group",
|
||||
"table-footer-group", "table-header-group", "table-row", "table-row-group",
|
||||
"tamil",
|
||||
|
@ -730,6 +734,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
valueKeywords: valueKeywords,
|
||||
fontProperties: fontProperties,
|
||||
allowNested: true,
|
||||
lineComment: "//",
|
||||
tokenHooks: {
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("/")) {
|
||||
|
@ -772,6 +777,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
valueKeywords: valueKeywords,
|
||||
fontProperties: fontProperties,
|
||||
allowNested: true,
|
||||
lineComment: "//",
|
||||
tokenHooks: {
|
||||
"/": function(stream, state) {
|
||||
if (stream.eat("/")) {
|
||||
|
|
2
codemirror/mode/css/index.html
vendored
2
codemirror/mode/css/index.html
vendored
|
@ -64,7 +64,7 @@ code {
|
|||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"},
|
||||
extraKeys: {"Ctrl-Space": "autocomplete"}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user