mirror of https://github.com/status-im/codimd.git
Upgrade CodeMirror to 5.10.1 and now support fullscreen, jump-to-line in editor
This commit is contained in:
parent
ce65e58096
commit
eaa8ccaccb
|
@ -6,6 +6,12 @@ var version = '0.3.3';
|
|||
var defaultTextHeight = 20;
|
||||
var viewportMargin = 20;
|
||||
var defaultExtraKeys = {
|
||||
"F11": function(cm) {
|
||||
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||
},
|
||||
"Esc": function(cm) {
|
||||
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
|
||||
},
|
||||
"Cmd-S": function () {
|
||||
return CodeMirror.PASS
|
||||
},
|
||||
|
@ -237,6 +243,7 @@ var editor = CodeMirror.fromTextArea(textit, {
|
|||
flattenSpans: true,
|
||||
addModeClass: true,
|
||||
readOnly: true,
|
||||
autoRefresh: true,
|
||||
placeholder: "← Start by enter title here\n===\nVisit /features if you don't know what to do.\nHappy hacking :)"
|
||||
});
|
||||
var inlineAttach = inlineAttachment.editors.codemirror4.attach(editor);
|
||||
|
|
|
@ -21,22 +21,28 @@
|
|||
}
|
||||
|
||||
CodeMirror.commands.toggleComment = function(cm) {
|
||||
var minLine = Infinity, ranges = cm.listSelections(), mode = null;
|
||||
cm.toggleComment();
|
||||
};
|
||||
|
||||
CodeMirror.defineExtension("toggleComment", function(options) {
|
||||
if (!options) options = noOptions;
|
||||
var cm = this;
|
||||
var minLine = Infinity, ranges = this.listSelections(), mode = null;
|
||||
for (var i = ranges.length - 1; i >= 0; i--) {
|
||||
var from = ranges[i].from(), to = ranges[i].to();
|
||||
if (from.line >= minLine) continue;
|
||||
if (to.line >= minLine) to = Pos(minLine, 0);
|
||||
minLine = from.line;
|
||||
if (mode == null) {
|
||||
if (cm.uncomment(from, to)) mode = "un";
|
||||
else { cm.lineComment(from, to); mode = "line"; }
|
||||
if (cm.uncomment(from, to, options)) mode = "un";
|
||||
else { cm.lineComment(from, to, options); mode = "line"; }
|
||||
} else if (mode == "un") {
|
||||
cm.uncomment(from, to);
|
||||
cm.uncomment(from, to, options);
|
||||
} else {
|
||||
cm.lineComment(from, to);
|
||||
cm.lineComment(from, to, options);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineExtension("lineComment", function(from, to, options) {
|
||||
if (!options) options = noOptions;
|
||||
|
@ -57,7 +63,14 @@
|
|||
|
||||
self.operation(function() {
|
||||
if (options.indent) {
|
||||
var baseString = firstLine.slice(0, firstNonWS(firstLine));
|
||||
var baseString = null;
|
||||
for (var i = from.line; i < end; ++i) {
|
||||
var line = self.getLine(i);
|
||||
var whitespace = line.slice(0, firstNonWS(line));
|
||||
if (baseString == null || baseString.length > whitespace.length) {
|
||||
baseString = whitespace;
|
||||
}
|
||||
}
|
||||
for (var i = from.line; i < end; ++i) {
|
||||
var line = self.getLine(i), cut = baseString.length;
|
||||
if (!blankLines && !nonWS.test(line)) continue;
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"))
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod)
|
||||
else // Plain browser env
|
||||
mod(CodeMirror)
|
||||
})(function(CodeMirror) {
|
||||
"use strict"
|
||||
|
||||
CodeMirror.defineOption("autoRefresh", false, function(cm, val) {
|
||||
if (cm.state.autoRefresh) {
|
||||
stopListening(cm, cm.state.autoRefresh)
|
||||
cm.state.autoRefresh = null
|
||||
}
|
||||
if (val && cm.display.wrapper.offsetHeight == 0)
|
||||
startListening(cm, cm.state.autoRefresh = {delay: val.delay || 250})
|
||||
})
|
||||
|
||||
function startListening(cm, state) {
|
||||
function check() {
|
||||
if (cm.display.wrapper.offsetHeight) {
|
||||
stopListening(cm, state)
|
||||
if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight)
|
||||
cm.refresh()
|
||||
} else {
|
||||
state.timeout = setTimeout(check, state.delay)
|
||||
}
|
||||
}
|
||||
state.timeout = setTimeout(check, state.delay)
|
||||
state.hurry = function() {
|
||||
clearTimeout(state.timeout)
|
||||
state.timeout = setTimeout(check, 50)
|
||||
}
|
||||
CodeMirror.on(window, "mouseup", state.hurry)
|
||||
CodeMirror.on(window, "keyup", state.hurry)
|
||||
}
|
||||
|
||||
function stopListening(_cm, state) {
|
||||
clearTimeout(state.timeout)
|
||||
CodeMirror.off(window, "mouseup", state.hurry)
|
||||
CodeMirror.off(window, "keyup", state.hurry)
|
||||
}
|
||||
});
|
|
@ -2,5 +2,5 @@
|
|||
position: fixed;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
height: auto;
|
||||
z-index: 9;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,9 @@
|
|||
var elt = cm.state.placeholder = document.createElement("pre");
|
||||
elt.style.cssText = "height: 0; overflow: visible";
|
||||
elt.className = "CodeMirror-placeholder";
|
||||
elt.appendChild(document.createTextNode(cm.getOption("placeholder")));
|
||||
var placeHolder = cm.getOption("placeholder")
|
||||
if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder)
|
||||
elt.appendChild(placeHolder)
|
||||
cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
|
||||
}
|
||||
cm.operation(function() {
|
||||
cm.replaceSelection("\n\n", null, "+input");
|
||||
cm.replaceSelection("\n\n", null);
|
||||
cm.execCommand("goCharLeft");
|
||||
ranges = cm.listSelections();
|
||||
for (var i = 0; i < ranges.length; i++) {
|
||||
|
@ -90,6 +90,12 @@
|
|||
});
|
||||
}
|
||||
|
||||
function contractSelection(sel) {
|
||||
var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
|
||||
return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
|
||||
head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
|
||||
}
|
||||
|
||||
function handleChar(cm, ch) {
|
||||
var conf = getConfig(cm);
|
||||
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||
|
@ -144,13 +150,17 @@
|
|||
var sels = cm.getSelections();
|
||||
for (var i = 0; i < sels.length; i++)
|
||||
sels[i] = left + sels[i] + right;
|
||||
cm.replaceSelections(sels, "around", "+input");
|
||||
cm.replaceSelections(sels, "around");
|
||||
sels = cm.listSelections().slice();
|
||||
for (var i = 0; i < sels.length; i++)
|
||||
sels[i] = contractSelection(sels[i]);
|
||||
cm.setSelections(sels);
|
||||
} else if (type == "both") {
|
||||
cm.replaceSelection(left + right, null, "+input");
|
||||
cm.replaceSelection(left + right, null);
|
||||
cm.triggerElectric(left + right);
|
||||
cm.execCommand("goCharLeft");
|
||||
} else if (type == "addFour") {
|
||||
cm.replaceSelection(left + left + left + left, "before", "+input");
|
||||
cm.replaceSelection(left + left + left + left, "before");
|
||||
cm.execCommand("goCharRight");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -108,21 +108,24 @@
|
|||
// when completing in JS/CSS snippet in htmlmixed mode. Does not
|
||||
// work for other XML embedded languages (there is no general
|
||||
// way to go from a mixed mode to its current XML state).
|
||||
var replacement;
|
||||
if (inner.mode.name != "xml") {
|
||||
if (cm.getMode().name == "htmlmixed" && inner.mode.name == "javascript")
|
||||
replacements[i] = head + "script>";
|
||||
replacement = head + "script";
|
||||
else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css")
|
||||
replacements[i] = head + "style>";
|
||||
replacement = head + "style";
|
||||
else
|
||||
return CodeMirror.Pass;
|
||||
} else {
|
||||
if (!state.context || !state.context.tagName ||
|
||||
closingTagExists(cm, state.context.tagName, pos, state))
|
||||
return CodeMirror.Pass;
|
||||
replacements[i] = head + state.context.tagName + ">";
|
||||
replacement = head + state.context.tagName;
|
||||
}
|
||||
if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
|
||||
replacements[i] = replacement;
|
||||
}
|
||||
cm.replaceSelections(replacements, null, '+input');
|
||||
cm.replaceSelections(replacements);
|
||||
ranges = cm.listSelections();
|
||||
for (var i = 0; i < ranges.length; i++)
|
||||
if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line)
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
var listRE = /^(\s*)(>[> ]*|[*+-]\s|(\d+)([.)]))(\[\s\]\s|\[x\]\s|\s*)/,
|
||||
emptyListRE = /^(\s*)(>[> ]*|[*+-]\s|(\d+)[.)])(\[\s\]\s*|\[x\]\s|\s*)$/,
|
||||
var listRE = /^(\s*)(>[> ]*|[*+-]\s|(\d+)([.)]))(\s*)/,
|
||||
emptyListRE = /^(\s*)(>[> ]*|[*+-]|(\d+)[.)])(\s*)$/,
|
||||
unorderedListRE = /[*+-]\s/;
|
||||
|
||||
CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
|
||||
|
@ -34,7 +34,7 @@
|
|||
line: pos.line, ch: 0
|
||||
}, {
|
||||
line: pos.line, ch: pos.ch + 1
|
||||
}, "+delete");
|
||||
});
|
||||
replacements[i] = "\n";
|
||||
} else {
|
||||
var indent = match[1], after = match[5];
|
||||
|
@ -46,6 +46,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
cm.replaceSelections(replacements, null, "+input");
|
||||
cm.replaceSelections(replacements);
|
||||
};
|
||||
});
|
||||
|
|
|
@ -28,7 +28,9 @@ CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
|
|||
continue;
|
||||
}
|
||||
if (pass == 1 && found < start.ch) return;
|
||||
if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)))) {
|
||||
if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) &&
|
||||
(lineText.slice(found - endToken.length, found) == endToken ||
|
||||
!/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) {
|
||||
startCh = found + startToken.length;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
cm.off("viewportChange", onViewportChange);
|
||||
cm.off("fold", onFold);
|
||||
cm.off("unfold", onFold);
|
||||
cm.off("swapDoc", updateInViewport);
|
||||
cm.off("swapDoc", onChange);
|
||||
}
|
||||
if (val) {
|
||||
cm.state.foldGutter = new State(parseOptions(val));
|
||||
|
@ -30,7 +30,7 @@
|
|||
cm.on("viewportChange", onViewportChange);
|
||||
cm.on("fold", onFold);
|
||||
cm.on("unfold", onFold);
|
||||
cm.on("swapDoc", updateInViewport);
|
||||
cm.on("swapDoc", onChange);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
while (start && word.test(curLine.charAt(start - 1))) --start;
|
||||
var curWord = start != end && curLine.slice(start, end);
|
||||
|
||||
var list = [], seen = {};
|
||||
var list = options && options.list || [], seen = {};
|
||||
var re = new RegExp(word.source, "g");
|
||||
for (var dir = -1; dir <= 1; dir += 2) {
|
||||
var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
|
||||
|
|
|
@ -25,8 +25,18 @@
|
|||
};
|
||||
|
||||
CodeMirror.defineExtension("showHint", function(options) {
|
||||
// We want a single cursor position.
|
||||
if (this.listSelections().length > 1 || this.somethingSelected()) return;
|
||||
options = parseOptions(this, this.getCursor("start"), options);
|
||||
var selections = this.listSelections()
|
||||
if (selections.length > 1) return;
|
||||
// By default, don't allow completion when something is selected.
|
||||
// A hint function can have a `supportsSelection` property to
|
||||
// indicate that it can handle selections.
|
||||
if (this.somethingSelected()) {
|
||||
if (!options.hint.supportsSelection) return;
|
||||
// Don't try with cross-line selections
|
||||
for (var i = 0; i < selections.length; i++)
|
||||
if (selections[i].head.line != selections[i].anchor.line) return;
|
||||
}
|
||||
|
||||
if (this.state.completionActive) this.state.completionActive.close();
|
||||
var completion = this.state.completionActive = new Completion(this, options);
|
||||
|
@ -38,12 +48,12 @@
|
|||
|
||||
function Completion(cm, options) {
|
||||
this.cm = cm;
|
||||
this.options = this.buildOptions(options);
|
||||
this.options = options;
|
||||
this.widget = null;
|
||||
this.debounce = 0;
|
||||
this.tick = 0;
|
||||
this.startPos = this.cm.getCursor();
|
||||
this.startLen = this.cm.getLine(this.startPos.line).length;
|
||||
this.startPos = this.cm.getCursor("start");
|
||||
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
|
||||
|
||||
var self = this;
|
||||
cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
|
||||
|
@ -99,7 +109,6 @@
|
|||
|
||||
update: function(first) {
|
||||
if (this.tick == null) return;
|
||||
if (this.data) CodeMirror.signal(this.data, "update");
|
||||
if (!this.options.hint.async) {
|
||||
this.finishUpdate(this.options.hint(this.cm, this.options), first);
|
||||
} else {
|
||||
|
@ -111,6 +120,8 @@
|
|||
},
|
||||
|
||||
finishUpdate: function(data, first) {
|
||||
if (this.data) CodeMirror.signal(this.data, "update");
|
||||
if (data && this.data && CodeMirror.cmpPos(data.from, this.data.from)) data = null;
|
||||
this.data = data;
|
||||
|
||||
var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
|
||||
|
@ -123,20 +134,21 @@
|
|||
CodeMirror.signal(data, "shown");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
buildOptions: function(options) {
|
||||
var editor = this.cm.options.hintOptions;
|
||||
var out = {};
|
||||
for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
|
||||
if (editor) for (var prop in editor)
|
||||
if (editor[prop] !== undefined) out[prop] = editor[prop];
|
||||
if (options) for (var prop in options)
|
||||
if (options[prop] !== undefined) out[prop] = options[prop];
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
function parseOptions(cm, pos, options) {
|
||||
var editor = cm.options.hintOptions;
|
||||
var out = {};
|
||||
for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
|
||||
if (editor) for (var prop in editor)
|
||||
if (editor[prop] !== undefined) out[prop] = editor[prop];
|
||||
if (options) for (var prop in options)
|
||||
if (options[prop] !== undefined) out[prop] = options[prop];
|
||||
if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
|
||||
return out;
|
||||
}
|
||||
|
||||
function getText(completion) {
|
||||
if (typeof completion == "string") return completion;
|
||||
else return completion.text;
|
||||
|
@ -335,34 +347,79 @@
|
|||
}
|
||||
};
|
||||
|
||||
CodeMirror.registerHelper("hint", "auto", function(cm, options) {
|
||||
var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
|
||||
function applicableHelpers(cm, helpers) {
|
||||
if (!cm.somethingSelected()) return helpers
|
||||
var result = []
|
||||
for (var i = 0; i < helpers.length; i++)
|
||||
if (helpers[i].supportsSelection) result.push(helpers[i])
|
||||
return result
|
||||
}
|
||||
|
||||
function resolveAutoHints(cm, pos) {
|
||||
var helpers = cm.getHelpers(pos, "hint"), words
|
||||
if (helpers.length) {
|
||||
for (var i = 0; i < helpers.length; i++) {
|
||||
var cur = helpers[i](cm, options);
|
||||
if (cur && cur.list.length) return cur;
|
||||
var async = false, resolved
|
||||
for (var i = 0; i < helpers.length; i++) if (helpers[i].async) async = true
|
||||
if (async) {
|
||||
resolved = function(cm, callback, options) {
|
||||
var app = applicableHelpers(cm, helpers)
|
||||
function run(i, result) {
|
||||
if (i == app.length) return callback(null)
|
||||
var helper = app[i]
|
||||
if (helper.async) {
|
||||
helper(cm, function(result) {
|
||||
if (result) callback(result)
|
||||
else run(i + 1)
|
||||
}, options)
|
||||
} else {
|
||||
var result = helper(cm, options)
|
||||
if (result) callback(result)
|
||||
else run(i + 1)
|
||||
}
|
||||
}
|
||||
run(0)
|
||||
}
|
||||
resolved.async = true
|
||||
} else {
|
||||
resolved = function(cm, options) {
|
||||
var app = applicableHelpers(cm, helpers)
|
||||
for (var i = 0; i < app.length; i++) {
|
||||
var cur = app[i](cm, options)
|
||||
if (cur && cur.list.length) return cur
|
||||
}
|
||||
}
|
||||
}
|
||||
resolved.supportsSelection = true
|
||||
return resolved
|
||||
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
|
||||
if (words) return CodeMirror.hint.fromList(cm, {words: words});
|
||||
return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
|
||||
} else if (CodeMirror.hint.anyword) {
|
||||
return CodeMirror.hint.anyword(cm, options);
|
||||
return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
|
||||
} else {
|
||||
return function() {}
|
||||
}
|
||||
}
|
||||
|
||||
CodeMirror.registerHelper("hint", "auto", {
|
||||
resolve: resolveAutoHints
|
||||
});
|
||||
|
||||
CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
|
||||
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
|
||||
var to = CodeMirror.Pos(cur.line, token.end);
|
||||
if (token.string && /\w/.test(token.string[token.string.length - 1])) {
|
||||
var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
|
||||
} else {
|
||||
var term = "", from = to;
|
||||
}
|
||||
var found = [];
|
||||
for (var i = 0; i < options.words.length; i++) {
|
||||
var word = options.words[i];
|
||||
if (word.slice(0, token.string.length) == token.string)
|
||||
if (word.slice(0, term.length) == term)
|
||||
found.push(word);
|
||||
}
|
||||
|
||||
if (found.length) return {
|
||||
list: found,
|
||||
from: CodeMirror.Pos(cur.line, token.start),
|
||||
to: CodeMirror.Pos(cur.line, token.end)
|
||||
};
|
||||
if (found.length) return {list: found, from: from, to: to};
|
||||
});
|
||||
|
||||
CodeMirror.commands.autocomplete = CodeMirror.showHint;
|
||||
|
@ -373,7 +430,7 @@
|
|||
alignWithWord: true,
|
||||
closeCharacters: /[\s()\[\]{};:>,]/,
|
||||
closeOnUnfocus: true,
|
||||
completeOnSingleClick: false,
|
||||
completeOnSingleClick: true,
|
||||
container: null,
|
||||
customKeys: null,
|
||||
extraKeys: null
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
// Depends on htmlhint.js from http://htmlhint.com/js/htmlhint.js
|
||||
|
||||
// declare global: HTMLHint
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"), require("htmlhint"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror", "htmlhint"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
var defaultRules = {
|
||||
"tagname-lowercase": true,
|
||||
"attr-lowercase": true,
|
||||
"attr-value-double-quotes": true,
|
||||
"doctype-first": false,
|
||||
"tag-pair": true,
|
||||
"spec-char-escape": true,
|
||||
"id-unique": true,
|
||||
"src-not-empty": true,
|
||||
"attr-no-duplication": true
|
||||
};
|
||||
|
||||
CodeMirror.registerHelper("lint", "html", function(text, options) {
|
||||
var found = [];
|
||||
if (!window.HTMLHint) return found;
|
||||
var messages = HTMLHint.verify(text, options && options.rules || defaultRules);
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
var message = messages[i];
|
||||
var startLine = message.line - 1, endLine = message.line - 1, startCol = message.col - 1, endCol = message.col;
|
||||
found.push({
|
||||
from: CodeMirror.Pos(startLine, startCol),
|
||||
to: CodeMirror.Pos(endLine, endCol),
|
||||
message: message.message,
|
||||
severity : message.type
|
||||
});
|
||||
}
|
||||
return found;
|
||||
});
|
||||
});
|
|
@ -61,6 +61,7 @@
|
|||
this.timeout = null;
|
||||
this.hasGutter = hasGutter;
|
||||
this.onMouseOver = function(e) { onMouseOver(cm, e); };
|
||||
this.waitingFor = 0
|
||||
}
|
||||
|
||||
function parseOptions(_cm, options) {
|
||||
|
@ -115,15 +116,32 @@
|
|||
return tip;
|
||||
}
|
||||
|
||||
function lintAsync(cm, getAnnotations, passOptions) {
|
||||
var state = cm.state.lint
|
||||
var id = ++state.waitingFor
|
||||
function abort() {
|
||||
id = -1
|
||||
cm.off("change", abort)
|
||||
}
|
||||
cm.on("change", abort)
|
||||
getAnnotations(cm.getValue(), function(annotations, arg2) {
|
||||
cm.off("change", abort)
|
||||
if (state.waitingFor != id) return
|
||||
if (arg2 && annotations instanceof CodeMirror) annotations = arg2
|
||||
updateLinting(cm, annotations)
|
||||
}, passOptions, cm);
|
||||
}
|
||||
|
||||
function startLinting(cm) {
|
||||
var state = cm.state.lint, options = state.options;
|
||||
var passOptions = options.options || options; // Support deprecated passing of `options` property in options
|
||||
var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
|
||||
if (!getAnnotations) return;
|
||||
if (options.async || getAnnotations.async)
|
||||
getAnnotations(cm.getValue(), updateLinting, passOptions, cm);
|
||||
else
|
||||
if (options.async || getAnnotations.async) {
|
||||
lintAsync(cm, getAnnotations, passOptions)
|
||||
} else {
|
||||
updateLinting(cm, getAnnotations(cm.getValue(), passOptions, cm));
|
||||
}
|
||||
}
|
||||
|
||||
function updateLinting(cm, annotationsNotSorted) {
|
||||
|
@ -187,7 +205,8 @@
|
|||
CodeMirror.defineOption("lint", false, function(cm, val, old) {
|
||||
if (old && old != CodeMirror.Init) {
|
||||
clearMarks(cm);
|
||||
cm.off("change", onChange);
|
||||
if (cm.state.lint.options.lintOnChange !== false)
|
||||
cm.off("change", onChange);
|
||||
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
|
||||
clearTimeout(cm.state.lint.timeout);
|
||||
delete cm.state.lint;
|
||||
|
@ -197,11 +216,16 @@
|
|||
var gutters = cm.getOption("gutters"), hasLintGutter = false;
|
||||
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
|
||||
var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
|
||||
cm.on("change", onChange);
|
||||
if (state.options.lintOnChange !== false)
|
||||
cm.on("change", onChange);
|
||||
if (state.options.tooltips != false)
|
||||
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
|
||||
|
||||
startLinting(cm);
|
||||
}
|
||||
});
|
||||
|
||||
CodeMirror.defineExtension("performLint", function() {
|
||||
if (this.state.lint) startLinting(this);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"), require("diff_match_patch"));
|
||||
mod(require("../../lib/codemirror")); // Note non-packaged dependency diff_match_patch
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror", "diff_match_patch"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror, diff_match_patch);
|
||||
})(function(CodeMirror, diff_match_patch) {
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
var Pos = CodeMirror.Pos;
|
||||
var svgNS = "http://www.w3.org/2000/svg";
|
||||
|
@ -471,13 +471,10 @@
|
|||
if (left) left.init(leftPane, origLeft, options);
|
||||
if (right) right.init(rightPane, origRight, options);
|
||||
|
||||
if (options.collapseIdentical) {
|
||||
updating = true;
|
||||
if (options.collapseIdentical)
|
||||
this.editor().operation(function() {
|
||||
collapseIdenticalStretches(self, options.collapseIdentical);
|
||||
});
|
||||
updating = false;
|
||||
}
|
||||
if (options.connect == "align") {
|
||||
this.aligners = [];
|
||||
alignChunks(this.left || this.right, true);
|
||||
|
@ -640,7 +637,7 @@
|
|||
mark.clear();
|
||||
cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
|
||||
}
|
||||
widget.addEventListener("click", clear);
|
||||
CodeMirror.on(widget, "click", clear);
|
||||
return {mark: mark, clear: clear};
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
|
|||
if (!other.parseDelimiters) stream.match(other.open);
|
||||
state.innerActive = other;
|
||||
state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
|
||||
return other.delimStyle;
|
||||
return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open");
|
||||
} else if (found != -1 && found < cutOff) {
|
||||
cutOff = found;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
|
|||
if (found == stream.pos && !curInner.parseDelimiters) {
|
||||
stream.match(curInner.close);
|
||||
state.innerActive = state.inner = null;
|
||||
return curInner.delimStyle;
|
||||
return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close");
|
||||
}
|
||||
if (found > -1) stream.string = oldContent.slice(0, found);
|
||||
var innerToken = curInner.mode.token(stream, state.inner);
|
||||
|
@ -80,7 +80,7 @@ CodeMirror.multiplexingMode = function(outer /*, others */) {
|
|||
state.innerActive = state.inner = null;
|
||||
|
||||
if (curInner.innerStyle) {
|
||||
if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle;
|
||||
if (innerToken) innerToken = innerToken + " " + curInner.innerStyle;
|
||||
else innerToken = curInner.innerStyle;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,5 +29,5 @@
|
|||
|
||||
MT(
|
||||
"stexInsideMarkdown",
|
||||
"[strong **Equation:**] [delim $][inner&tag \\pi][delim $]");
|
||||
"[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]");
|
||||
})();
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
|
||||
function ensureState(states, name) {
|
||||
if (!states.hasOwnProperty(name))
|
||||
throw new Error("Undefined state " + name + "in simple mode");
|
||||
throw new Error("Undefined state " + name + " in simple mode");
|
||||
}
|
||||
|
||||
function toRegex(val, caret) {
|
||||
|
|
0
public/vendor/codemirror/addon/runmode/runmode-standalone.js
vendored
Executable file → Normal file
0
public/vendor/codemirror/addon/runmode/runmode-standalone.js
vendored
Executable file → Normal file
|
@ -16,7 +16,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
|
|||
var ie = /MSIE \d/.test(navigator.userAgent);
|
||||
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
|
||||
|
||||
if (callback.nodeType == 1) {
|
||||
if (callback.appendChild) {
|
||||
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
|
||||
var node = callback, col = 0;
|
||||
node.innerHTML = "";
|
||||
|
|
|
@ -176,3 +176,4 @@ exports.runMode = function(string, modespec, callback, options) {
|
|||
};
|
||||
|
||||
require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")];
|
||||
require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")];
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
Annotation.prototype.computeScale = function() {
|
||||
var cm = this.cm;
|
||||
var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) /
|
||||
cm.heightAtLine(cm.lastLine() + 1, "local");
|
||||
cm.getScrollerElement().scrollHeight
|
||||
if (hScale != this.hScale) {
|
||||
this.hScale = hScale;
|
||||
return true;
|
||||
|
@ -100,6 +100,9 @@
|
|||
elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth * 1.5, 2) + "px; top: "
|
||||
+ (top + this.buttonHeight) + "px; height: " + height + "px";
|
||||
elt.className = this.options.className;
|
||||
if (ann.id) {
|
||||
elt.setAttribute("annotation-id", ann.id);
|
||||
}
|
||||
}
|
||||
this.div.textContent = "";
|
||||
this.div.appendChild(frag);
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
// Defines jumpToLine command. Uses dialog.js if present.
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"), require("../dialog/dialog"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror", "../dialog/dialog"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
function dialog(cm, text, shortText, deflt, f) {
|
||||
if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
|
||||
else f(prompt(shortText, deflt));
|
||||
}
|
||||
|
||||
var jumpDialog =
|
||||
'Jump to line: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use line:column or scroll% syntax)</span>';
|
||||
|
||||
function interpretLine(cm, string) {
|
||||
var num = Number(string)
|
||||
if (/^[-+]/.test(string)) return cm.getCursor().line + num
|
||||
else return num - 1
|
||||
}
|
||||
|
||||
CodeMirror.commands.jumpToLine = function(cm) {
|
||||
var cur = cm.getCursor();
|
||||
dialog(cm, jumpDialog, "Jump to line:", (cur.line + 1) + ":" + cur.ch, function(posStr) {
|
||||
if (!posStr) return;
|
||||
|
||||
var match;
|
||||
if (match = /^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(posStr)) {
|
||||
cm.setCursor(interpretLine(cm, match[1]), Number(match[2]))
|
||||
} else if (match = /^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(posStr)) {
|
||||
var line = Math.round(cm.lineCount() * Number(match[1]) / 100);
|
||||
if (/^[-+]/.test(match[1])) line = cur.line + line + 1;
|
||||
cm.setCursor(line - 1, cur.ch);
|
||||
} else if (match = /^\s*\:?\s*([\+\-]?\d+)\s*/.exec(posStr)) {
|
||||
cm.setCursor(interpretLine(cm, match[1]), cur.ch);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
CodeMirror.keyMap["default"]["Alt-G"] = "jumpToLine";
|
||||
});
|
43
public/vendor/codemirror/addon/search/match-highlighter.js
vendored
Executable file → Normal file
43
public/vendor/codemirror/addon/search/match-highlighter.js
vendored
Executable file → Normal file
|
@ -16,13 +16,14 @@
|
|||
// highlighted only if the selected text is a word. showToken, when enabled,
|
||||
// will cause the current token to be highlighted when nothing is selected.
|
||||
// delay is used to specify how much time to wait, in milliseconds, before
|
||||
// highlighting the matches.
|
||||
// highlighting the matches. If annotateScrollbar is enabled, the occurances
|
||||
// will be highlighted on the scrollbar via the matchesonscrollbar addon.
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
mod(require("../../lib/codemirror"), require("./matchesonscrollbar"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod);
|
||||
define(["../../lib/codemirror", "./matchesonscrollbar"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
|
@ -40,18 +41,19 @@
|
|||
this.showToken = options.showToken;
|
||||
this.delay = options.delay;
|
||||
this.wordsOnly = options.wordsOnly;
|
||||
this.annotateScrollbar = options.annotateScrollbar;
|
||||
}
|
||||
if (this.style == null) this.style = DEFAULT_TOKEN_STYLE;
|
||||
if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS;
|
||||
if (this.delay == null) this.delay = DEFAULT_DELAY;
|
||||
if (this.wordsOnly == null) this.wordsOnly = DEFAULT_WORDS_ONLY;
|
||||
this.overlay = this.timeout = null;
|
||||
this.matchesonscroll = null;
|
||||
}
|
||||
|
||||
CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
|
||||
if (old && old != CodeMirror.Init) {
|
||||
var over = cm.state.matchHighlighter.overlay;
|
||||
if (over) cm.removeOverlay(over);
|
||||
removeOverlay(cm);
|
||||
clearTimeout(cm.state.matchHighlighter.timeout);
|
||||
cm.state.matchHighlighter = null;
|
||||
cm.off("cursorActivity", cursorActivity);
|
||||
|
@ -69,20 +71,39 @@
|
|||
state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay);
|
||||
}
|
||||
|
||||
function addOverlay(cm, query, hasBoundary, style) {
|
||||
var state = cm.state.matchHighlighter;
|
||||
cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
|
||||
if (state.annotateScrollbar) {
|
||||
var searchFor = hasBoundary ? new RegExp("\\b" + query + "\\b") : query;
|
||||
state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, true,
|
||||
{className: "CodeMirror-selection-highlight-scrollbar"});
|
||||
}
|
||||
}
|
||||
|
||||
function removeOverlay(cm) {
|
||||
var state = cm.state.matchHighlighter;
|
||||
if (state.overlay) {
|
||||
cm.removeOverlay(state.overlay);
|
||||
state.overlay = null;
|
||||
if (state.annotateScrollbar) {
|
||||
state.matchesonscroll.clear();
|
||||
state.matchesonscroll = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function highlightMatches(cm) {
|
||||
cm.operation(function() {
|
||||
var state = cm.state.matchHighlighter;
|
||||
if (state.overlay) {
|
||||
cm.removeOverlay(state.overlay);
|
||||
state.overlay = null;
|
||||
}
|
||||
removeOverlay(cm);
|
||||
if (!cm.somethingSelected() && state.showToken) {
|
||||
var re = state.showToken === true ? /[\w$]/ : state.showToken;
|
||||
var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
|
||||
while (start && re.test(line.charAt(start - 1))) --start;
|
||||
while (end < line.length && re.test(line.charAt(end))) ++end;
|
||||
if (start < end)
|
||||
cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style));
|
||||
addOverlay(cm, line.slice(start, end), re, state.style);
|
||||
return;
|
||||
}
|
||||
var from = cm.getCursor("from"), to = cm.getCursor("to");
|
||||
|
@ -90,7 +111,7 @@
|
|||
if (state.wordsOnly && !isWord(cm, from, to)) return;
|
||||
var selection = cm.getRange(from, to).replace(/^\s+|\s+$/g, "");
|
||||
if (selection.length >= state.minChars)
|
||||
cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style));
|
||||
addOverlay(cm, selection, false, state.style);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
0
public/vendor/codemirror/addon/search/matchesonscrollbar.js
vendored
Executable file → Normal file
0
public/vendor/codemirror/addon/search/matchesonscrollbar.js
vendored
Executable file → Normal file
|
@ -18,6 +18,7 @@
|
|||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
function searchOverlay(query, caseInsensitive) {
|
||||
if (typeof query == "string")
|
||||
query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
|
||||
|
@ -28,7 +29,7 @@
|
|||
query.lastIndex = stream.pos;
|
||||
var match = query.exec(stream.string);
|
||||
if (match && match.index == stream.pos) {
|
||||
stream.pos += match[0].length;
|
||||
stream.pos += match[0].length || 1;
|
||||
return "searching";
|
||||
} else if (match) {
|
||||
stream.pos = match.index;
|
||||
|
@ -42,57 +43,106 @@
|
|||
this.posFrom = this.posTo = this.lastQuery = this.query = null;
|
||||
this.overlay = null;
|
||||
}
|
||||
|
||||
function getSearchState(cm) {
|
||||
return cm.state.search || (cm.state.search = new SearchState());
|
||||
}
|
||||
|
||||
function queryCaseInsensitive(query) {
|
||||
return typeof query == "string" && query == query.toLowerCase();
|
||||
}
|
||||
|
||||
function getSearchCursor(cm, query, pos) {
|
||||
// Heuristic: if the query string is all lowercase, do a case insensitive search.
|
||||
return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
|
||||
}
|
||||
|
||||
function persistentDialog(cm, text, deflt, f) {
|
||||
cm.openDialog(text, f, {
|
||||
value: deflt,
|
||||
selectValueOnOpen: true,
|
||||
closeOnEnter: false,
|
||||
onClose: function() { clearSearch(cm); }
|
||||
});
|
||||
}
|
||||
|
||||
function dialog(cm, text, shortText, deflt, f) {
|
||||
if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
|
||||
else f(prompt(shortText, deflt));
|
||||
}
|
||||
|
||||
function confirmDialog(cm, text, shortText, fs) {
|
||||
if (cm.openConfirm) cm.openConfirm(text, fs);
|
||||
else if (confirm(shortText)) fs[0]();
|
||||
}
|
||||
|
||||
function parseString(string) {
|
||||
return string.replace(/\\(.)/g, function(_, ch) {
|
||||
if (ch == "n") return "\n"
|
||||
if (ch == "r") return "\r"
|
||||
return ch
|
||||
})
|
||||
}
|
||||
|
||||
function parseQuery(query) {
|
||||
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
|
||||
if (isRE) {
|
||||
try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
|
||||
catch(e) {} // Not a regular expression after all, do a string search
|
||||
} else {
|
||||
query = parseString(query)
|
||||
}
|
||||
if (typeof query == "string" ? query == "" : query.test(""))
|
||||
query = /x^/;
|
||||
return query;
|
||||
}
|
||||
|
||||
var queryDialog =
|
||||
'Search: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
|
||||
function doSearch(cm, rev) {
|
||||
|
||||
function startSearch(cm, state, query) {
|
||||
state.queryText = query;
|
||||
state.query = parseQuery(query);
|
||||
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
|
||||
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
|
||||
cm.addOverlay(state.overlay);
|
||||
if (cm.showMatchesOnScrollbar) {
|
||||
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
|
||||
state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
|
||||
}
|
||||
}
|
||||
|
||||
function doSearch(cm, rev, persistent) {
|
||||
var state = getSearchState(cm);
|
||||
if (state.query) return findNext(cm, rev);
|
||||
var q = cm.getSelection() || state.lastQuery;
|
||||
dialog(cm, queryDialog, "Search for:", q, function(query) {
|
||||
cm.operation(function() {
|
||||
if (!query || state.query) return;
|
||||
state.query = parseQuery(query);
|
||||
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
|
||||
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
|
||||
cm.addOverlay(state.overlay);
|
||||
if (cm.showMatchesOnScrollbar) {
|
||||
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
|
||||
state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
|
||||
}
|
||||
state.posFrom = state.posTo = cm.getCursor();
|
||||
findNext(cm, rev);
|
||||
if (persistent && cm.openDialog) {
|
||||
var hiding = null
|
||||
persistentDialog(cm, queryDialog, q, function(query, event) {
|
||||
CodeMirror.e_stop(event);
|
||||
if (!query) return;
|
||||
if (query != state.queryText) startSearch(cm, state, query);
|
||||
if (hiding) hiding.style.opacity = 1
|
||||
findNext(cm, event.shiftKey, function(_, to) {
|
||||
var dialog
|
||||
if (to.line < 3 && document.querySelector &&
|
||||
(dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) &&
|
||||
dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top)
|
||||
(hiding = dialog).style.opacity = .4
|
||||
})
|
||||
});
|
||||
});
|
||||
} else {
|
||||
dialog(cm, queryDialog, "Search for:", q, function(query) {
|
||||
if (query && !state.query) cm.operation(function() {
|
||||
startSearch(cm, state, query);
|
||||
state.posFrom = state.posTo = cm.getCursor();
|
||||
findNext(cm, rev);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
function findNext(cm, rev) {cm.operation(function() {
|
||||
|
||||
function findNext(cm, rev, callback) {cm.operation(function() {
|
||||
var state = getSearchState(cm);
|
||||
var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
|
||||
if (!cursor.find(rev)) {
|
||||
|
@ -100,38 +150,47 @@
|
|||
if (!cursor.find(rev)) return;
|
||||
}
|
||||
cm.setSelection(cursor.from(), cursor.to());
|
||||
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
|
||||
cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
|
||||
state.posFrom = cursor.from(); state.posTo = cursor.to();
|
||||
if (callback) callback(cursor.from(), cursor.to())
|
||||
});}
|
||||
|
||||
function clearSearch(cm) {cm.operation(function() {
|
||||
var state = getSearchState(cm);
|
||||
state.lastQuery = state.query;
|
||||
if (!state.query) return;
|
||||
state.query = null;
|
||||
state.query = state.queryText = null;
|
||||
cm.removeOverlay(state.overlay);
|
||||
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
|
||||
});}
|
||||
|
||||
var replaceQueryDialog =
|
||||
'Replace: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
|
||||
' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
|
||||
var replacementQueryDialog = 'With: <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
|
||||
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
|
||||
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>All</button> <button>Stop</button>";
|
||||
|
||||
function replaceAll(cm, query, text) {
|
||||
cm.operation(function() {
|
||||
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
|
||||
if (typeof query != "string") {
|
||||
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
|
||||
cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
|
||||
} else cursor.replace(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function replace(cm, all) {
|
||||
if (cm.getOption("readOnly")) return;
|
||||
var query = cm.getSelection() || getSearchState(cm).lastQuery;
|
||||
dialog(cm, replaceQueryDialog, "Replace:", query, function(query) {
|
||||
var dialogText = all ? "Replace all:" : "Replace:"
|
||||
dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) {
|
||||
if (!query) return;
|
||||
query = parseQuery(query);
|
||||
dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
|
||||
text = parseString(text)
|
||||
if (all) {
|
||||
cm.operation(function() {
|
||||
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
|
||||
if (typeof query != "string") {
|
||||
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
|
||||
cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}), "+input");
|
||||
} else cursor.replace(text, "+input");
|
||||
}
|
||||
});
|
||||
replaceAll(cm, query, text)
|
||||
} else {
|
||||
clearSearch(cm);
|
||||
var cursor = getSearchCursor(cm, query, cm.getCursor());
|
||||
|
@ -145,11 +204,12 @@
|
|||
cm.setSelection(cursor.from(), cursor.to());
|
||||
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
|
||||
confirmDialog(cm, doReplaceConfirm, "Replace?",
|
||||
[function() {doReplace(match);}, advance]);
|
||||
[function() {doReplace(match);}, advance,
|
||||
function() {replaceAll(cm, query, text)}]);
|
||||
};
|
||||
var doReplace = function(match) {
|
||||
cursor.replace(typeof query == "string" ? text :
|
||||
text.replace(/\$(\d)/g, function(_, i) {return match[i];}), "+input");
|
||||
text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
|
||||
advance();
|
||||
};
|
||||
advance();
|
||||
|
@ -159,6 +219,7 @@
|
|||
}
|
||||
|
||||
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
|
||||
CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
|
||||
CodeMirror.commands.findNext = doSearch;
|
||||
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
|
||||
CodeMirror.commands.clearSearch = clearSearch;
|
||||
|
|
0
public/vendor/codemirror/addon/selection/selection-pointer.js
vendored
Executable file → Normal file
0
public/vendor/codemirror/addon/selection/selection-pointer.js
vendored
Executable file → Normal file
|
@ -1,6 +1,7 @@
|
|||
.CodeMirror-Tern-completion {
|
||||
padding-left: 22px;
|
||||
position: relative;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.CodeMirror-Tern-completion:before {
|
||||
position: absolute;
|
||||
|
|
|
@ -135,6 +135,7 @@
|
|||
},
|
||||
|
||||
destroy: function () {
|
||||
closeArgHints(this)
|
||||
if (this.worker) {
|
||||
this.worker.terminate();
|
||||
this.worker = null;
|
||||
|
@ -216,7 +217,7 @@
|
|||
var completion = data.completions[i], className = typeToIcon(completion.type);
|
||||
if (data.guess) className += " " + cls + "guess";
|
||||
completions.push({text: completion.name + after,
|
||||
displayText: completion.name,
|
||||
displayText: completion.displayName || completion.name,
|
||||
className: className,
|
||||
data: completion});
|
||||
}
|
||||
|
@ -266,7 +267,7 @@
|
|||
child.target = "_blank";
|
||||
}
|
||||
}
|
||||
tempTooltip(cm, tip);
|
||||
tempTooltip(cm, tip, ts);
|
||||
if (c) c();
|
||||
}, pos);
|
||||
}
|
||||
|
@ -466,11 +467,12 @@
|
|||
ts.request(cm, {type: "refs"}, function(error, data) {
|
||||
if (error) return showError(ts, cm, error);
|
||||
var ranges = [], cur = 0;
|
||||
var curPos = cm.getCursor();
|
||||
for (var i = 0; i < data.refs.length; i++) {
|
||||
var ref = data.refs[i];
|
||||
if (ref.file == name) {
|
||||
ranges.push({anchor: ref.start, head: ref.end});
|
||||
if (cmpPos(cur, ref.start) >= 0 && cmpPos(cur, ref.end) <= 0)
|
||||
if (cmpPos(curPos, ref.start) >= 0 && cmpPos(curPos, ref.end) <= 0)
|
||||
cur = ranges.length - 1;
|
||||
}
|
||||
}
|
||||
|
@ -592,7 +594,7 @@
|
|||
|
||||
// Tooltips
|
||||
|
||||
function tempTooltip(cm, content) {
|
||||
function tempTooltip(cm, content, ts) {
|
||||
if (cm.state.ternTooltip) remove(cm.state.ternTooltip);
|
||||
var where = cm.cursorCoords();
|
||||
var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content);
|
||||
|
@ -616,7 +618,7 @@
|
|||
else mouseOnTip = false;
|
||||
}
|
||||
});
|
||||
setTimeout(maybeClear, 1700);
|
||||
setTimeout(maybeClear, ts.options.hintDelay ? ts.options.hintDelay : 1700);
|
||||
cm.on("cursorActivity", clear);
|
||||
cm.on('blur', clear);
|
||||
cm.on('scroll', clear);
|
||||
|
@ -644,7 +646,7 @@
|
|||
if (ts.options.showError)
|
||||
ts.options.showError(cm, msg);
|
||||
else
|
||||
tempTooltip(cm, String(msg));
|
||||
tempTooltip(cm, String(msg), ts);
|
||||
}
|
||||
|
||||
function closeArgHints(ts) {
|
||||
|
|
|
@ -32,11 +32,13 @@
|
|||
function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
|
||||
for (var at = column; at > 0; --at)
|
||||
if (wrapOn.test(text.slice(at - 1, at + 1))) break;
|
||||
if (at == 0) at = column;
|
||||
var endOfText = at;
|
||||
if (killTrailingSpace)
|
||||
while (text.charAt(endOfText - 1) == " ") --endOfText;
|
||||
return {from: endOfText, to: at};
|
||||
for (var first = true;; first = false) {
|
||||
var endOfText = at;
|
||||
if (killTrailingSpace)
|
||||
while (text.charAt(endOfText - 1) == " ") --endOfText;
|
||||
if (endOfText == 0 && first) at = column;
|
||||
else return {from: endOfText, to: at};
|
||||
}
|
||||
}
|
||||
|
||||
function wrapRange(cm, from, to, options) {
|
||||
|
@ -86,7 +88,8 @@
|
|||
if (changes.length) cm.operation(function() {
|
||||
for (var i = 0; i < changes.length; ++i) {
|
||||
var change = changes[i];
|
||||
cm.replaceRange(change.text, change.from, change.to);
|
||||
if (change.text || CodeMirror.cmpPos(change.from, change.to))
|
||||
cm.replaceRange(change.text, change.from, change.to);
|
||||
}
|
||||
});
|
||||
return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -6,12 +6,15 @@ addon/mode/multiplex.js \
|
|||
addon/selection/active-line.js \
|
||||
addon/search/searchcursor.js \
|
||||
addon/search/search.js \
|
||||
addon/search/jump-to-line.js \
|
||||
addon/search/matchesonscrollbar.js \
|
||||
addon/search/match-highlighter.js \
|
||||
addon/scroll/simplescrollbars.js \
|
||||
addon/scroll/annotatescrollbar.js \
|
||||
addon/display/panel.js \
|
||||
addon/display/placeholder.js \
|
||||
addon/display/fullscreen.js \
|
||||
addon/display/autorefresh.js \
|
||||
addon/dialog/dialog.js \
|
||||
addon/edit/matchbrackets.js \
|
||||
addon/edit/closebrackets.js \
|
||||
|
|
|
@ -377,7 +377,7 @@
|
|||
|
||||
getInput(cm, "Goto line", function(str) {
|
||||
var num;
|
||||
if (str && !isNaN(num = Number(str)) && num == num|0 && num > 0)
|
||||
if (str && !isNaN(num = Number(str)) && num == (num|0) && num > 0)
|
||||
cm.setCursor(num - 1);
|
||||
});
|
||||
},
|
||||
|
|
|
@ -55,7 +55,9 @@
|
|||
cmds[map["Alt-Left"] = "goSubwordLeft"] = function(cm) { moveSubword(cm, -1); };
|
||||
cmds[map["Alt-Right"] = "goSubwordRight"] = function(cm) { moveSubword(cm, 1); };
|
||||
|
||||
cmds[map[ctrl + "Up"] = "scrollLineUp"] = function(cm) {
|
||||
var scrollLineCombo = mac ? "Ctrl-Alt-" : "Ctrl-";
|
||||
|
||||
cmds[map[scrollLineCombo + "Up"] = "scrollLineUp"] = function(cm) {
|
||||
var info = cm.getScrollInfo();
|
||||
if (!cm.somethingSelected()) {
|
||||
var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local");
|
||||
|
@ -64,7 +66,7 @@
|
|||
}
|
||||
cm.scrollTo(null, info.top - cm.defaultTextHeight());
|
||||
};
|
||||
cmds[map[ctrl + "Down"] = "scrollLineDown"] = function(cm) {
|
||||
cmds[map[scrollLineCombo + "Down"] = "scrollLineDown"] = function(cm) {
|
||||
var info = cm.getScrollInfo();
|
||||
if (!cm.somethingSelected()) {
|
||||
var visibleTopLine = cm.lineAtHeight(info.top, "local")+1;
|
||||
|
@ -106,6 +108,7 @@
|
|||
map["Shift-" + ctrl + "K"] = "deleteLine";
|
||||
|
||||
function insertLine(cm, above) {
|
||||
if (cm.isReadOnly()) return CodeMirror.Pass
|
||||
cm.operation(function() {
|
||||
var len = cm.listSelections().length, newSelection = [], last = -1;
|
||||
for (var i = 0; i < len; i++) {
|
||||
|
@ -121,9 +124,9 @@
|
|||
});
|
||||
}
|
||||
|
||||
cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { insertLine(cm, false); };
|
||||
cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { return insertLine(cm, false); };
|
||||
|
||||
cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { insertLine(cm, true); };
|
||||
cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { return insertLine(cm, true); };
|
||||
|
||||
function wordAt(cm, pos) {
|
||||
var start = pos.ch, end = start, line = cm.getLine(pos.line);
|
||||
|
@ -190,6 +193,7 @@
|
|||
var swapLineCombo = mac ? "Cmd-Ctrl-" : "Shift-Ctrl-";
|
||||
|
||||
cmds[map[swapLineCombo + "Up"] = "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++) {
|
||||
var range = ranges[i], from = range.from().line - 1, to = range.to().line;
|
||||
|
@ -216,6 +220,7 @@
|
|||
};
|
||||
|
||||
cmds[map[swapLineCombo + "Down"] = "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--) {
|
||||
var range = ranges[i], from = range.to().line + 1, to = range.from().line;
|
||||
|
@ -238,7 +243,9 @@
|
|||
});
|
||||
};
|
||||
|
||||
map[ctrl + "/"] = "toggleComment";
|
||||
cmds[map[ctrl + "/"] = "toggleCommentIndented"] = function(cm) {
|
||||
cm.toggleComment({ indent: true });
|
||||
}
|
||||
|
||||
cmds[map[ctrl + "J"] = "joinLines"] = function(cm) {
|
||||
var ranges = cm.listSelections(), joined = [];
|
||||
|
@ -258,7 +265,7 @@
|
|||
var actual = line - offset;
|
||||
if (line == obj.end) head = Pos(actual, cm.getLine(actual).length + 1);
|
||||
if (actual < cm.lastLine()) {
|
||||
cm.replaceRange(" ", Pos(actual), Pos(actual + 1, /^\s*/.exec(cm.getLine(actual + 1))[0].length), "+joinLines");
|
||||
cm.replaceRange(" ", Pos(actual), Pos(actual + 1, /^\s*/.exec(cm.getLine(actual + 1))[0].length));
|
||||
++offset;
|
||||
}
|
||||
}
|
||||
|
@ -274,9 +281,9 @@
|
|||
for (var i = 0; i < rangeCount; i++) {
|
||||
var range = cm.listSelections()[i];
|
||||
if (range.empty())
|
||||
cm.replaceRange(cm.getLine(range.head.line) + "\n", Pos(range.head.line, 0), null, "+duplicateLine");
|
||||
cm.replaceRange(cm.getLine(range.head.line) + "\n", Pos(range.head.line, 0));
|
||||
else
|
||||
cm.replaceRange(cm.getRange(range.from(), range.to()), range.from(), null, "+duplicateLine");
|
||||
cm.replaceRange(cm.getRange(range.from(), range.to()), range.from());
|
||||
}
|
||||
cm.scrollIntoView();
|
||||
});
|
||||
|
@ -285,6 +292,7 @@
|
|||
map[ctrl + "T"] = "transposeChars";
|
||||
|
||||
function sortLines(cm, caseSensitive) {
|
||||
if (cm.isReadOnly()) return CodeMirror.Pass
|
||||
var ranges = cm.listSelections(), toSort = [], selected;
|
||||
for (var i = 0; i < ranges.length; i++) {
|
||||
var range = ranges[i];
|
||||
|
@ -311,7 +319,7 @@
|
|||
if (au != bu) { a = au; b = bu; }
|
||||
return a < b ? -1 : a == b ? 0 : 1;
|
||||
});
|
||||
cm.replaceRange(lines, start, end, "+sortLines");
|
||||
cm.replaceRange(lines, start, end);
|
||||
if (selected) ranges.push({anchor: start, head: end});
|
||||
}
|
||||
if (selected) cm.setSelections(ranges, 0);
|
||||
|
@ -402,7 +410,7 @@
|
|||
if (at && CodeMirror.cmpPos(range.head, at) > 0) continue;
|
||||
var word = wordAt(cm, range.head);
|
||||
at = word.from;
|
||||
cm.replaceRange(mod(word.word), word.from, word.to, "case");
|
||||
cm.replaceRange(mod(word.word), word.from, word.to);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -415,11 +423,19 @@
|
|||
var cursor = cm.getCursor();
|
||||
var toStartOfLine = cm.getRange({line: cursor.line, ch: 0}, cursor);
|
||||
var column = CodeMirror.countColumn(toStartOfLine, null, cm.getOption("tabSize"));
|
||||
var indentUnit = cm.getOption("indentUnit");
|
||||
|
||||
if (toStartOfLine && !/\S/.test(toStartOfLine) && column % cm.getOption("indentUnit") == 0)
|
||||
return cm.indentSelection("subtract");
|
||||
else
|
||||
if (toStartOfLine && !/\S/.test(toStartOfLine) && column % indentUnit == 0) {
|
||||
var prevIndent = new Pos(cursor.line,
|
||||
CodeMirror.findColumn(toStartOfLine, column - indentUnit, indentUnit));
|
||||
|
||||
// If no smart delete is happening (due to tab sizing) just do a regular delete
|
||||
if (prevIndent.ch == cursor.ch) return CodeMirror.Pass;
|
||||
|
||||
return cm.replaceRange("", prevIndent, cursor, "+delete");
|
||||
} else {
|
||||
return CodeMirror.Pass;
|
||||
}
|
||||
};
|
||||
|
||||
cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) {
|
||||
|
@ -452,7 +468,7 @@
|
|||
var from = cm.getCursor(), to = found;
|
||||
if (CodeMirror.cmpPos(from, to) > 0) { var tmp = to; to = from; from = tmp; }
|
||||
cm.state.sublimeKilled = cm.getRange(from, to);
|
||||
cm.replaceRange("", from, to, "+delete");
|
||||
cm.replaceRange("", from, to);
|
||||
}
|
||||
};
|
||||
cmds[map[cK + ctrl + "X"] = "swapWithSublimeMark"] = function(cm) {
|
||||
|
|
|
@ -292,12 +292,7 @@
|
|||
// Keypress character binding of format "'a'"
|
||||
return key.charAt(1);
|
||||
}
|
||||
var pieces = key.split('-');
|
||||
if (/-$/.test(key)) {
|
||||
// If the - key was typed, split will result in 2 extra empty strings
|
||||
// in the array. Replace them with 1 '-'.
|
||||
pieces.splice(-2, 2, '-');
|
||||
}
|
||||
var pieces = key.split(/-(?!$)/);
|
||||
var lastPiece = pieces[pieces.length - 1];
|
||||
if (pieces.length == 1 && pieces[0].length == 1) {
|
||||
// No-modifier bindings use literal character bindings above. Skip.
|
||||
|
@ -1959,13 +1954,21 @@
|
|||
text = text.slice(0, - match[0].length);
|
||||
}
|
||||
}
|
||||
var wasLastLine = head.line - 1 == cm.lastLine();
|
||||
cm.replaceRange('', anchor, head);
|
||||
if (args.linewise && !wasLastLine) {
|
||||
var prevLineEnd = new Pos(anchor.line - 1, Number.MAX_VALUE);
|
||||
var wasLastLine = cm.firstLine() == cm.lastLine();
|
||||
if (head.line > cm.lastLine() && args.linewise && !wasLastLine) {
|
||||
cm.replaceRange('', prevLineEnd, head);
|
||||
} else {
|
||||
cm.replaceRange('', anchor, head);
|
||||
}
|
||||
if (args.linewise) {
|
||||
// Push the next line back down, if there is a next line.
|
||||
CodeMirror.commands.newlineAndIndent(cm);
|
||||
// null ch so setCursor moves to end of line.
|
||||
anchor.ch = null;
|
||||
if (!wasLastLine) {
|
||||
cm.setCursor(prevLineEnd);
|
||||
CodeMirror.commands.newlineAndIndent(cm);
|
||||
}
|
||||
// make sure cursor ends up at the end of the line.
|
||||
anchor.ch = Number.MAX_VALUE;
|
||||
}
|
||||
finalHead = anchor;
|
||||
} else {
|
||||
|
@ -2144,9 +2147,7 @@
|
|||
switch (actionArgs.position) {
|
||||
case 'center': y = y - (height / 2) + lineHeight;
|
||||
break;
|
||||
case 'bottom': y = y - height + lineHeight*1.4;
|
||||
break;
|
||||
case 'top': y = y + lineHeight*0.4;
|
||||
case 'bottom': y = y - height + lineHeight;
|
||||
break;
|
||||
}
|
||||
cm.scrollTo(null, y);
|
||||
|
@ -3208,7 +3209,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
|
||||
|
@ -4308,7 +4309,7 @@
|
|||
if (decimal + hex + octal > 1) { return 'Invalid arguments'; }
|
||||
number = decimal && 'decimal' || hex && 'hex' || octal && 'octal';
|
||||
}
|
||||
if (args.eatSpace() && args.match(/\/.*\//)) { 'patterns not supported'; }
|
||||
if (args.match(/\/.*\//)) { return 'patterns not supported'; }
|
||||
}
|
||||
}
|
||||
var err = parseArgs();
|
||||
|
|
|
@ -41,19 +41,21 @@
|
|||
|
||||
/* CURSOR */
|
||||
|
||||
.CodeMirror div.CodeMirror-cursor {
|
||||
.CodeMirror-cursor {
|
||||
border-left: 1px solid black;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
/* Shown when moving in bi-directional text */
|
||||
.CodeMirror div.CodeMirror-secondarycursor {
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
.CodeMirror.cm-fat-cursor div.CodeMirror-cursor {
|
||||
.cm-fat-cursor .CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0;
|
||||
background: #7e7;
|
||||
}
|
||||
.CodeMirror.cm-fat-cursor div.CodeMirror-cursors {
|
||||
.cm-fat-cursor div.CodeMirror-cursors {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
@ -63,25 +65,26 @@
|
|||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
background-color: #7e7;
|
||||
}
|
||||
@-moz-keyframes blink {
|
||||
0% { background: #7e7; }
|
||||
50% { background: none; }
|
||||
100% { background: #7e7; }
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@-webkit-keyframes blink {
|
||||
0% { background: #7e7; }
|
||||
50% { background: none; }
|
||||
100% { background: #7e7; }
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@keyframes blink {
|
||||
0% { background: #7e7; }
|
||||
50% { background: none; }
|
||||
100% { background: #7e7; }
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
|
||||
/* Can style cursor different in overwrite (non-insert) mode */
|
||||
div.CodeMirror-overwrite div.CodeMirror-cursor {}
|
||||
.CodeMirror-overwrite .CodeMirror-cursor {}
|
||||
|
||||
.cm-tab { display: inline-block; text-decoration: inherit; }
|
||||
|
||||
|
@ -162,7 +165,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
|||
}
|
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||
before actuall scrolling happens, thus preventing shaking and
|
||||
before actual scrolling happens, thus preventing shaking and
|
||||
flickering artifacts. */
|
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
position: absolute;
|
||||
|
@ -202,7 +205,13 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
|||
.CodeMirror-gutter-wrapper {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
height: 100%;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
.CodeMirror-gutter-background {
|
||||
position: absolute;
|
||||
top: 0; bottom: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-elt {
|
||||
position: absolute;
|
||||
|
@ -277,19 +286,19 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
|||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
.CodeMirror div.CodeMirror-cursor {
|
||||
position: absolute;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
.CodeMirror-cursor { position: absolute; }
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
div.CodeMirror-dragcursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-focused div.CodeMirror-cursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
@ -297,8 +306,8 @@ div.CodeMirror-cursors {
|
|||
.CodeMirror-selected { background: #d9d9d9; }
|
||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
|
||||
.CodeMirror-crosshair { cursor: crosshair; }
|
||||
.CodeMirror ::selection { background: #d7d4f0; }
|
||||
.CodeMirror ::-moz-selection { background: #d7d4f0; }
|
||||
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
|
||||
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
|
||||
|
||||
.cm-searching {
|
||||
background: #ffa;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
<!doctype html>
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: ASN.1 mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
|
@ -73,6 +73,5 @@
|
|||
<p>The development of this mode has been sponsored by <a href="http://www.ericsson.com/">Ericsson
|
||||
</a>.</p>
|
||||
<p>Coded by Asmelash Tsegay Gebretsadkan </p>
|
||||
</article>
|
||||
</article>
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
// Brainfuck mode created by Michael Kaminsky https://github.com/mkaminsky11
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object")
|
||||
mod(require("../../lib/codemirror"))
|
||||
else if (typeof define == "function" && define.amd)
|
||||
define(["../../lib/codemirror"], mod)
|
||||
else
|
||||
mod(CodeMirror)
|
||||
})(function(CodeMirror) {
|
||||
"use strict"
|
||||
var reserve = "><+-.,[]".split("");
|
||||
/*
|
||||
comments can be either:
|
||||
placed behind lines
|
||||
|
||||
+++ this is a comment
|
||||
|
||||
where reserved characters cannot be used
|
||||
or in a loop
|
||||
[
|
||||
this is ok to use [ ] and stuff
|
||||
]
|
||||
or preceded by #
|
||||
*/
|
||||
CodeMirror.defineMode("brainfuck", function() {
|
||||
return {
|
||||
startState: function() {
|
||||
return {
|
||||
commentLine: false,
|
||||
left: 0,
|
||||
right: 0,
|
||||
commentLoop: false
|
||||
}
|
||||
},
|
||||
token: function(stream, state) {
|
||||
if (stream.eatSpace()) return null
|
||||
if(stream.sol()){
|
||||
state.commentLine = false;
|
||||
}
|
||||
var ch = stream.next().toString();
|
||||
if(reserve.indexOf(ch) !== -1){
|
||||
if(state.commentLine === true){
|
||||
if(stream.eol()){
|
||||
state.commentLine = false;
|
||||
}
|
||||
return "comment";
|
||||
}
|
||||
if(ch === "]" || ch === "["){
|
||||
if(ch === "["){
|
||||
state.left++;
|
||||
}
|
||||
else{
|
||||
state.right++;
|
||||
}
|
||||
return "bracket";
|
||||
}
|
||||
else if(ch === "+" || ch === "-"){
|
||||
return "keyword";
|
||||
}
|
||||
else if(ch === "<" || ch === ">"){
|
||||
return "atom";
|
||||
}
|
||||
else if(ch === "." || ch === ","){
|
||||
return "def";
|
||||
}
|
||||
}
|
||||
else{
|
||||
state.commentLine = true;
|
||||
if(stream.eol()){
|
||||
state.commentLine = false;
|
||||
}
|
||||
return "comment";
|
||||
}
|
||||
if(stream.eol()){
|
||||
state.commentLine = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
CodeMirror.defineMIME("text/x-brainfuck","brainfuck")
|
||||
});
|
|
@ -0,0 +1,85 @@
|
|||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Brainfuck mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="./brainfuck.js"></script>
|
||||
<style>
|
||||
.CodeMirror { border: 2px inset #dee; }
|
||||
</style>
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#"></a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Brainfuck mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
[ This program prints "Hello World!" and a newline to the screen, its
|
||||
length is 106 active command characters [it is not the shortest.]
|
||||
|
||||
This loop is a "comment loop", it's a simple way of adding a comment
|
||||
to a BF program such that you don't have to worry about any command
|
||||
characters. Any ".", ",", "+", "-", "<" and ">" characters are simply
|
||||
ignored, the "[" and "]" characters just have to be balanced.
|
||||
]
|
||||
+++++ +++ Set Cell #0 to 8
|
||||
[
|
||||
>++++ Add 4 to Cell #1; this will always set Cell #1 to 4
|
||||
[ as the cell will be cleared by the loop
|
||||
>++ Add 2 to Cell #2
|
||||
>+++ Add 3 to Cell #3
|
||||
>+++ Add 3 to Cell #4
|
||||
>+ Add 1 to Cell #5
|
||||
<<<<- Decrement the loop counter in Cell #1
|
||||
] Loop till Cell #1 is zero; number of iterations is 4
|
||||
>+ Add 1 to Cell #2
|
||||
>+ Add 1 to Cell #3
|
||||
>- Subtract 1 from Cell #4
|
||||
>>+ Add 1 to Cell #6
|
||||
[<] Move back to the first zero cell you find; this will
|
||||
be Cell #1 which was cleared by the previous loop
|
||||
<- Decrement the loop Counter in Cell #0
|
||||
] Loop till Cell #0 is zero; number of iterations is 8
|
||||
|
||||
The result of this is:
|
||||
Cell No : 0 1 2 3 4 5 6
|
||||
Contents: 0 0 72 104 88 32 8
|
||||
Pointer : ^
|
||||
|
||||
>>. Cell #2 has value 72 which is 'H'
|
||||
>---. Subtract 3 from Cell #3 to get 101 which is 'e'
|
||||
+++++++..+++. Likewise for 'llo' from Cell #3
|
||||
>>. Cell #5 is 32 for the space
|
||||
<-. Subtract 1 from Cell #4 for 87 to give a 'W'
|
||||
<. Cell #3 was set to 'o' from the end of 'Hello'
|
||||
+++.------.--------. Cell #3 for 'rl' and 'd'
|
||||
>>+. Add 1 to Cell #5 gives us an exclamation point
|
||||
>++. And finally a newline from Cell #6
|
||||
</textarea></form>
|
||||
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-brainfuck"
|
||||
});
|
||||
</script>
|
||||
|
||||
<p>A mode for Brainfuck</p>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-brainfuck</code></p>
|
||||
</article>
|
|
@ -25,8 +25,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
multiLineStrings = parserConfig.multiLineStrings,
|
||||
indentStatements = parserConfig.indentStatements !== false,
|
||||
indentSwitch = parserConfig.indentSwitch !== false,
|
||||
namespaceSeparator = parserConfig.namespaceSeparator;
|
||||
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
|
||||
namespaceSeparator = parserConfig.namespaceSeparator,
|
||||
isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/,
|
||||
numberStart = parserConfig.numberStart || /[\d\.]/,
|
||||
number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
|
||||
isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
|
||||
endStatement = parserConfig.endStatement || /^[;:,]$/;
|
||||
|
||||
var curPunc, isDefKeyword;
|
||||
|
||||
|
@ -40,13 +44,14 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
state.tokenize = tokenString(ch);
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
|
||||
if (isPunctuationChar.test(ch)) {
|
||||
curPunc = ch;
|
||||
return null;
|
||||
}
|
||||
if (/\d/.test(ch)) {
|
||||
stream.eatWhile(/[\w\.]/);
|
||||
return "number";
|
||||
if (numberStart.test(ch)) {
|
||||
stream.backUp(1)
|
||||
if (stream.match(number)) return "number"
|
||||
stream.next()
|
||||
}
|
||||
if (ch == "/") {
|
||||
if (stream.eat("*")) {
|
||||
|
@ -67,17 +72,17 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
|
||||
|
||||
var cur = stream.current();
|
||||
if (keywords.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
if (defKeywords.propertyIsEnumerable(cur)) isDefKeyword = true;
|
||||
if (contains(keywords, cur)) {
|
||||
if (contains(blockKeywords, cur)) curPunc = "newstatement";
|
||||
if (contains(defKeywords, cur)) isDefKeyword = true;
|
||||
return "keyword";
|
||||
}
|
||||
if (types.propertyIsEnumerable(cur)) return "variable-3";
|
||||
if (builtin.propertyIsEnumerable(cur)) {
|
||||
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
|
||||
if (contains(types, cur)) return "variable-3";
|
||||
if (contains(builtin, cur)) {
|
||||
if (contains(blockKeywords, cur)) curPunc = "newstatement";
|
||||
return "builtin";
|
||||
}
|
||||
if (atoms.propertyIsEnumerable(cur)) return "atom";
|
||||
if (contains(atoms, cur)) return "atom";
|
||||
return "variable";
|
||||
}
|
||||
|
||||
|
@ -168,8 +173,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
if (style == "comment" || style == "meta") return style;
|
||||
if (ctx.align == null) ctx.align = true;
|
||||
|
||||
if ((curPunc == ";" || curPunc == ":" || curPunc == ","))
|
||||
while (isStatement(state.context.type)) popContext(state);
|
||||
if (endStatement.test(curPunc)) while (isStatement(state.context.type)) popContext(state);
|
||||
else if (curPunc == "{") pushContext(state, stream.column(), "}");
|
||||
else if (curPunc == "[") pushContext(state, stream.column(), "]");
|
||||
else if (curPunc == "(") pushContext(state, stream.column(), ")");
|
||||
|
@ -212,8 +216,16 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
|
||||
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
|
||||
if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev;
|
||||
if (hooks.indent) {
|
||||
var hook = hooks.indent(state, ctx, textAfter);
|
||||
if (typeof hook == "number") return hook
|
||||
}
|
||||
var closing = firstChar == ctx.type;
|
||||
var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
|
||||
if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
|
||||
while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
|
||||
return ctx.indented
|
||||
}
|
||||
if (isStatement(ctx.type))
|
||||
return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
|
||||
if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
|
||||
|
@ -238,27 +250,30 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
|
||||
return obj;
|
||||
}
|
||||
function contains(words, word) {
|
||||
if (typeof words === "function") {
|
||||
return words(word);
|
||||
} else {
|
||||
return words.propertyIsEnumerable(word);
|
||||
}
|
||||
}
|
||||
var cKeywords = "auto if break case register continue return default do sizeof " +
|
||||
"static else struct switch extern typedef float union for " +
|
||||
"goto while enum const volatile";
|
||||
"static else struct switch extern typedef union for goto while enum const volatile";
|
||||
var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
|
||||
|
||||
function cppHook(stream, state) {
|
||||
if (!state.startOfLine) return false;
|
||||
for (;;) {
|
||||
if (stream.skipTo("\\")) {
|
||||
stream.next();
|
||||
if (stream.eol()) {
|
||||
state.tokenize = cppHook;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
stream.skipToEnd();
|
||||
state.tokenize = null;
|
||||
break;
|
||||
if (!state.startOfLine) return false
|
||||
for (var ch, next = null; ch = stream.peek();) {
|
||||
if (ch == "\\" && stream.match(/^.$/)) {
|
||||
next = cppHook
|
||||
break
|
||||
} else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
|
||||
break
|
||||
}
|
||||
stream.next()
|
||||
}
|
||||
return "meta";
|
||||
state.tokenize = next
|
||||
return "meta"
|
||||
}
|
||||
|
||||
function pointerHook(_stream, state) {
|
||||
|
@ -266,6 +281,11 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
return false;
|
||||
}
|
||||
|
||||
function cpp14Literal(stream) {
|
||||
stream.eatWhile(/[\w\.']/);
|
||||
return "number";
|
||||
}
|
||||
|
||||
function cpp11StringHook(stream, state) {
|
||||
stream.backUp(1);
|
||||
// Raw strings.
|
||||
|
@ -373,6 +393,16 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
"U": cpp11StringHook,
|
||||
"L": cpp11StringHook,
|
||||
"R": cpp11StringHook,
|
||||
"0": cpp14Literal,
|
||||
"1": cpp14Literal,
|
||||
"2": cpp14Literal,
|
||||
"3": cpp14Literal,
|
||||
"4": cpp14Literal,
|
||||
"5": cpp14Literal,
|
||||
"6": cpp14Literal,
|
||||
"7": cpp14Literal,
|
||||
"8": cpp14Literal,
|
||||
"9": cpp14Literal,
|
||||
token: function(stream, state, style) {
|
||||
if (style == "variable" && stream.peek() == "(" &&
|
||||
(state.prevToken == ";" || state.prevToken == null ||
|
||||
|
@ -398,6 +428,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
defKeywords: words("class interface package enum"),
|
||||
typeFirstDefinitions: true,
|
||||
atoms: words("true false null"),
|
||||
endStatement: /^[;:]$/,
|
||||
hooks: {
|
||||
"@": function(stream) {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
|
@ -453,7 +484,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
keywords: words(
|
||||
|
||||
/* scala */
|
||||
"abstract case catch class def do else extends false final finally for forSome if " +
|
||||
"abstract case catch class def do else extends final finally for forSome if " +
|
||||
"implicit import lazy match new null object override package private protected return " +
|
||||
"sealed super this throw trait try type val var while with yield _ : = => <- <: " +
|
||||
"<% >: # @ " +
|
||||
|
@ -501,6 +532,59 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
modeProps: {closeBrackets: {triples: '"'}}
|
||||
});
|
||||
|
||||
function tokenKotlinString(tripleString){
|
||||
return function (stream, state) {
|
||||
var escaped = false, next, end = false;
|
||||
while (!stream.eol()) {
|
||||
if (!tripleString && !escaped && stream.match('"') ) {end = true; break;}
|
||||
if (tripleString && stream.match('"""')) {end = true; break;}
|
||||
next = stream.next();
|
||||
if(!escaped && next == "$" && stream.match('{'))
|
||||
stream.skipTo("}");
|
||||
escaped = !escaped && next == "\\" && !tripleString;
|
||||
}
|
||||
if (end || !tripleString)
|
||||
state.tokenize = null;
|
||||
return "string";
|
||||
}
|
||||
}
|
||||
|
||||
def("text/x-kotlin", {
|
||||
name: "clike",
|
||||
keywords: words(
|
||||
/*keywords*/
|
||||
"package as typealias class interface this super val " +
|
||||
"var fun for is in This throw return " +
|
||||
"break continue object if else while do try when !in !is as? " +
|
||||
|
||||
/*soft keywords*/
|
||||
"file import where by get set abstract enum open inner override private public internal " +
|
||||
"protected catch finally out final vararg reified dynamic companion constructor init " +
|
||||
"sealed field property receiver param sparam lateinit data inline noinline tailrec " +
|
||||
"external annotation crossinline const operator infix"
|
||||
),
|
||||
types: words(
|
||||
/* package java.lang */
|
||||
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
|
||||
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
|
||||
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
|
||||
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
|
||||
),
|
||||
intendSwitch: false,
|
||||
indentStatements: false,
|
||||
multiLineStrings: true,
|
||||
blockKeywords: words("catch class do else finally for if where try while enum"),
|
||||
defKeywords: words("class val var object package interface fun"),
|
||||
atoms: words("true false null this"),
|
||||
hooks: {
|
||||
'"': function(stream, state) {
|
||||
state.tokenize = tokenKotlinString(stream.match('""'));
|
||||
return state.tokenize(stream, state);
|
||||
}
|
||||
},
|
||||
modeProps: {closeBrackets: {triples: '"'}}
|
||||
});
|
||||
|
||||
def(["x-shader/x-vertex", "x-shader/x-fragment"], {
|
||||
name: "clike",
|
||||
keywords: words("sampler1D sampler2D sampler3D samplerCube " +
|
||||
|
@ -583,9 +667,106 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
|||
stream.eatWhile(/[\w\$]/);
|
||||
return "keyword";
|
||||
},
|
||||
"#": cppHook
|
||||
"#": cppHook,
|
||||
indent: function(_state, ctx, textAfter) {
|
||||
if (ctx.type == "statement" && /^@\w/.test(textAfter)) return ctx.indented
|
||||
}
|
||||
},
|
||||
modeProps: {fold: "brace"}
|
||||
});
|
||||
|
||||
def("text/x-squirrel", {
|
||||
name: "clike",
|
||||
keywords: words("base break clone continue const default delete enum extends function in class" +
|
||||
" foreach local resume return this throw typeof yield constructor instanceof static"),
|
||||
types: words(cTypes),
|
||||
blockKeywords: words("case catch class else for foreach if switch try while"),
|
||||
defKeywords: words("function local class"),
|
||||
typeFirstDefinitions: true,
|
||||
atoms: words("true false null"),
|
||||
hooks: {"#": cppHook},
|
||||
modeProps: {fold: ["brace", "include"]}
|
||||
});
|
||||
|
||||
// Ceylon Strings need to deal with interpolation
|
||||
var stringTokenizer = null;
|
||||
function tokenCeylonString(type) {
|
||||
return function(stream, state) {
|
||||
var escaped = false, next, end = false;
|
||||
while (!stream.eol()) {
|
||||
if (!escaped && stream.match('"') &&
|
||||
(type == "single" || stream.match('""'))) {
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
if (!escaped && stream.match('``')) {
|
||||
stringTokenizer = tokenCeylonString(type);
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
next = stream.next();
|
||||
escaped = type == "single" && !escaped && next == "\\";
|
||||
}
|
||||
if (end)
|
||||
state.tokenize = null;
|
||||
return "string";
|
||||
}
|
||||
}
|
||||
|
||||
def("text/x-ceylon", {
|
||||
name: "clike",
|
||||
keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" +
|
||||
" exists extends finally for function given if import in interface is let module new" +
|
||||
" nonempty object of out outer package return satisfies super switch then this throw" +
|
||||
" try value void while"),
|
||||
types: function(word) {
|
||||
// In Ceylon all identifiers that start with an uppercase are types
|
||||
var first = word.charAt(0);
|
||||
return (first === first.toUpperCase() && first !== first.toLowerCase());
|
||||
},
|
||||
blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"),
|
||||
defKeywords: words("class dynamic function interface module object package value"),
|
||||
builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" +
|
||||
" native optional sealed see serializable shared suppressWarnings tagged throws variable"),
|
||||
isPunctuationChar: /[\[\]{}\(\),;\:\.`]/,
|
||||
isOperatorChar: /[+\-*&%=<>!?|^~:\/]/,
|
||||
numberStart: /[\d#$]/,
|
||||
number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,
|
||||
multiLineStrings: true,
|
||||
typeFirstDefinitions: true,
|
||||
atoms: words("true false null larger smaller equal empty finished"),
|
||||
indentSwitch: false,
|
||||
styleDefs: false,
|
||||
hooks: {
|
||||
"@": function(stream) {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
return "meta";
|
||||
},
|
||||
'"': function(stream, state) {
|
||||
state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single");
|
||||
return state.tokenize(stream, state);
|
||||
},
|
||||
'`': function(stream, state) {
|
||||
if (!stringTokenizer || !stream.match('`')) return false;
|
||||
state.tokenize = stringTokenizer;
|
||||
stringTokenizer = null;
|
||||
return state.tokenize(stream, state);
|
||||
},
|
||||
"'": function(stream) {
|
||||
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
|
||||
return "atom";
|
||||
},
|
||||
token: function(_stream, state, style) {
|
||||
if ((style == "variable" || style == "variable-3") &&
|
||||
state.prevToken == ".") {
|
||||
return "variable-2";
|
||||
}
|
||||
}
|
||||
},
|
||||
modeProps: {
|
||||
fold: ["brace", "import"],
|
||||
closeBrackets: {triples: '"'}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -206,6 +206,103 @@ object FilterTest extends App {
|
|||
}
|
||||
</textarea></div>
|
||||
|
||||
<h2>Kotlin mode</h2>
|
||||
|
||||
<div><textarea id="kotlin-code">
|
||||
package org.wasabi.http
|
||||
|
||||
import java.util.concurrent.Executors
|
||||
import java.net.InetSocketAddress
|
||||
import org.wasabi.app.AppConfiguration
|
||||
import io.netty.bootstrap.ServerBootstrap
|
||||
import io.netty.channel.nio.NioEventLoopGroup
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel
|
||||
import org.wasabi.app.AppServer
|
||||
|
||||
public class HttpServer(private val appServer: AppServer) {
|
||||
|
||||
val bootstrap: ServerBootstrap
|
||||
val primaryGroup: NioEventLoopGroup
|
||||
val workerGroup: NioEventLoopGroup
|
||||
|
||||
init {
|
||||
// Define worker groups
|
||||
primaryGroup = NioEventLoopGroup()
|
||||
workerGroup = NioEventLoopGroup()
|
||||
|
||||
// Initialize bootstrap of server
|
||||
bootstrap = ServerBootstrap()
|
||||
|
||||
bootstrap.group(primaryGroup, workerGroup)
|
||||
bootstrap.channel(javaClass<NioServerSocketChannel>())
|
||||
bootstrap.childHandler(NettyPipelineInitializer(appServer))
|
||||
}
|
||||
|
||||
public fun start(wait: Boolean = true) {
|
||||
val channel = bootstrap.bind(appServer.configuration.port)?.sync()?.channel()
|
||||
|
||||
if (wait) {
|
||||
channel?.closeFuture()?.sync()
|
||||
}
|
||||
}
|
||||
|
||||
public fun stop() {
|
||||
// Shutdown all event loops
|
||||
primaryGroup.shutdownGracefully()
|
||||
workerGroup.shutdownGracefully()
|
||||
|
||||
// Wait till all threads are terminated
|
||||
primaryGroup.terminationFuture().sync()
|
||||
workerGroup.terminationFuture().sync()
|
||||
}
|
||||
}
|
||||
</textarea></div>
|
||||
|
||||
<h2>Ceylon mode</h2>
|
||||
|
||||
<div><textarea id="ceylon-code">
|
||||
"Produces the [[stream|Iterable]] that results from repeated
|
||||
application of the given [[function|next]] to the given
|
||||
[[first]] element of the stream, until the function first
|
||||
returns [[finished]]. If the given function never returns
|
||||
`finished`, the resulting stream is infinite.
|
||||
|
||||
For example:
|
||||
|
||||
loop(0)(2.plus).takeWhile(10.largerThan)
|
||||
|
||||
produces the stream `{ 0, 2, 4, 6, 8 }`."
|
||||
tagged("Streams")
|
||||
shared {Element+} loop<Element>(
|
||||
"The first element of the resulting stream."
|
||||
Element first)(
|
||||
"The function that produces the next element of the
|
||||
stream, given the current element. The function may
|
||||
return [[finished]] to indicate the end of the
|
||||
stream."
|
||||
Element|Finished next(Element element))
|
||||
=> let (start = first)
|
||||
object satisfies {Element+} {
|
||||
first => start;
|
||||
empty => false;
|
||||
function nextElement(Element element)
|
||||
=> next(element);
|
||||
iterator()
|
||||
=> object satisfies Iterator<Element> {
|
||||
variable Element|Finished current = start;
|
||||
shared actual Element|Finished next() {
|
||||
if (!is Finished result = current) {
|
||||
current = nextElement(result);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return finished;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
</textarea></div>
|
||||
|
||||
<script>
|
||||
var cEditor = CodeMirror.fromTextArea(document.getElementById("c-code"), {
|
||||
lineNumbers: true,
|
||||
|
@ -232,6 +329,16 @@ object FilterTest extends App {
|
|||
matchBrackets: true,
|
||||
mode: "text/x-scala"
|
||||
});
|
||||
var kotlinEditor = CodeMirror.fromTextArea(document.getElementById("kotlin-code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-kotlin"
|
||||
});
|
||||
var ceylonEditor = CodeMirror.fromTextArea(document.getElementById("ceylon-code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
mode: "text/x-ceylon"
|
||||
});
|
||||
var mac = CodeMirror.keyMap.default == CodeMirror.keyMap.macDefault;
|
||||
CodeMirror.keyMap.default[(mac ? "Cmd" : "Ctrl") + "-Space"] = "autocomplete";
|
||||
</script>
|
||||
|
@ -247,5 +354,7 @@ object FilterTest extends App {
|
|||
(Java), <code>text/x-csharp</code> (C#),
|
||||
<code>text/x-objectivec</code> (Objective-C),
|
||||
<code>text/x-scala</code> (Scala), <code>text/x-vertex</code>
|
||||
and <code>x-shader/x-fragment</code> (shader programs).</p>
|
||||
<code>x-shader/x-fragment</code> (shader programs),
|
||||
<code>text/x-squirrel</code> (Squirrel) and
|
||||
<code>text/x-ceylon</code> (Ceylon)</p>
|
||||
</article>
|
||||
|
|
|
@ -30,4 +30,22 @@
|
|||
" [keyword for] (;;)",
|
||||
" [variable x][operator ++];",
|
||||
"[keyword return];");
|
||||
|
||||
MT("preprocessor",
|
||||
"[meta #define FOO 3]",
|
||||
"[variable-3 int] [variable foo];",
|
||||
"[meta #define BAR\\]",
|
||||
"[meta 4]",
|
||||
"[variable-3 unsigned] [variable-3 int] [variable bar] [operator =] [number 8];",
|
||||
"[meta #include <baz> ][comment // comment]")
|
||||
|
||||
|
||||
var mode_cpp = CodeMirror.getMode({indentUnit: 2}, "text/x-c++src");
|
||||
function MTCPP(name) { test.mode(name, mode_cpp, Array.prototype.slice.call(arguments, 1)); }
|
||||
|
||||
MTCPP("cpp14_literal",
|
||||
"[number 10'000];",
|
||||
"[number 0b10'000];",
|
||||
"[number 0x10'000];",
|
||||
"[string '100000'];");
|
||||
})();
|
||||
|
|
|
@ -96,6 +96,9 @@ CodeMirror.defineMode("clojure", function (options) {
|
|||
if ( '.' == stream.peek() ) {
|
||||
stream.eat('.');
|
||||
stream.eatWhile(tests.digit);
|
||||
} else if ('/' == stream.peek() ) {
|
||||
stream.eat('/');
|
||||
stream.eatWhile(tests.digit);
|
||||
}
|
||||
|
||||
if ( stream.eat(tests.exponent) ) {
|
||||
|
|
|
@ -78,6 +78,9 @@
|
|||
\tab \return \backspace
|
||||
\u1000 \uAaAa \u9F9F)
|
||||
|
||||
;; Let's play with numbers
|
||||
(+ 1 -1 1/2 -1/2 -0.5 0.5)
|
||||
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
|
|
40
public/vendor/codemirror/mode/coffeescript/coffeescript.js
vendored
Executable file → Normal file
40
public/vendor/codemirror/mode/coffeescript/coffeescript.js
vendored
Executable file → Normal file
|
@ -25,7 +25,7 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
|
|||
var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
|
||||
var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
|
||||
var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
|
||||
var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
|
||||
var atProp = /^@[_A-Za-z$][_A-Za-z$0-9]*/;
|
||||
|
||||
var wordOperators = wordRegexp(["and", "or", "not",
|
||||
"is", "isnt", "in",
|
||||
|
@ -145,6 +145,8 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Handle operators and delimiters
|
||||
if (stream.match(operators) || stream.match(wordOperators)) {
|
||||
return "operator";
|
||||
|
@ -157,6 +159,10 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
|
|||
return "atom";
|
||||
}
|
||||
|
||||
if (stream.match(atProp) || state.prop && stream.match(identifiers)) {
|
||||
return "property";
|
||||
}
|
||||
|
||||
if (stream.match(keywords)) {
|
||||
return "keyword";
|
||||
}
|
||||
|
@ -165,10 +171,6 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
|
|||
return "variable";
|
||||
}
|
||||
|
||||
if (stream.match(properties)) {
|
||||
return "property";
|
||||
}
|
||||
|
||||
// Handle non-detected items
|
||||
stream.next();
|
||||
return ERRORCLASS;
|
||||
|
@ -265,24 +267,11 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
|
|||
var style = state.tokenize(stream, state);
|
||||
var current = stream.current();
|
||||
|
||||
// Handle "." connected identifiers
|
||||
if (current === ".") {
|
||||
style = state.tokenize(stream, state);
|
||||
current = stream.current();
|
||||
if (/^\.[\w$]+$/.test(current)) {
|
||||
return "variable";
|
||||
} else {
|
||||
return ERRORCLASS;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle scope changes.
|
||||
if (current === "return") {
|
||||
state.dedent = true;
|
||||
}
|
||||
if (((current === "->" || current === "=>") &&
|
||||
!state.lambda &&
|
||||
!stream.peek())
|
||||
if (((current === "->" || current === "=>") && stream.eol())
|
||||
|| style === "indent") {
|
||||
indent(stream, state);
|
||||
}
|
||||
|
@ -324,8 +313,7 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
|
|||
return {
|
||||
tokenize: tokenBase,
|
||||
scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
|
||||
lastToken: null,
|
||||
lambda: false,
|
||||
prop: false,
|
||||
dedent: 0
|
||||
};
|
||||
},
|
||||
|
@ -335,12 +323,9 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
|
|||
if (fillAlign && stream.sol()) fillAlign.align = false;
|
||||
|
||||
var style = tokenLexer(stream, state);
|
||||
if (fillAlign && style && style != "comment") fillAlign.align = true;
|
||||
|
||||
state.lastToken = {style:style, content: stream.current()};
|
||||
|
||||
if (stream.eol() && stream.lambda) {
|
||||
state.lambda = false;
|
||||
if (style && style != "comment") {
|
||||
if (fillAlign) fillAlign.align = true;
|
||||
state.prop = style == "punctuation" && stream.current() == "."
|
||||
}
|
||||
|
||||
return style;
|
||||
|
@ -365,5 +350,6 @@ CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
|
|||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
|
||||
CodeMirror.defineMIME("text/coffeescript", "coffeescript");
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1,391 @@
|
|||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
CodeMirror.defineMode("crystal", function(config) {
|
||||
function wordRegExp(words, end) {
|
||||
return new RegExp((end ? "" : "^") + "(?:" + words.join("|") + ")" + (end ? "$" : "\\b"));
|
||||
}
|
||||
|
||||
function chain(tokenize, stream, state) {
|
||||
state.tokenize.push(tokenize);
|
||||
return tokenize(stream, state);
|
||||
}
|
||||
|
||||
var operators = /^(?:[-+/%|&^]|\*\*?|[<>]{2})/;
|
||||
var conditionalOperators = /^(?:[=!]~|===|<=>|[<>=!]=?|[|&]{2}|~)/;
|
||||
var indexingOperators = /^(?:\[\][?=]?)/;
|
||||
var anotherOperators = /^(?:\.(?:\.{2})?|->|[?:])/;
|
||||
var idents = /^[a-z_\u009F-\uFFFF][a-zA-Z0-9_\u009F-\uFFFF]*/;
|
||||
var types = /^[A-Z_\u009F-\uFFFF][a-zA-Z0-9_\u009F-\uFFFF]*/;
|
||||
var keywords = wordRegExp([
|
||||
"abstract", "alias", "as", "asm", "begin", "break", "case", "class", "def", "do",
|
||||
"else", "elsif", "end", "ensure", "enum", "extend", "for", "fun", "if", "ifdef",
|
||||
"include", "instance_sizeof", "lib", "macro", "module", "next", "of", "out", "pointerof",
|
||||
"private", "protected", "rescue", "return", "require", "sizeof", "struct",
|
||||
"super", "then", "type", "typeof", "union", "unless", "until", "when", "while", "with",
|
||||
"yield", "__DIR__", "__FILE__", "__LINE__"
|
||||
]);
|
||||
var atomWords = wordRegExp(["true", "false", "nil", "self"]);
|
||||
var indentKeywordsArray = [
|
||||
"def", "fun", "macro",
|
||||
"class", "module", "struct", "lib", "enum", "union",
|
||||
"if", "unless", "case", "while", "until", "begin", "then",
|
||||
"do",
|
||||
"for", "ifdef"
|
||||
];
|
||||
var indentKeywords = wordRegExp(indentKeywordsArray);
|
||||
var dedentKeywordsArray = [
|
||||
"end",
|
||||
"else", "elsif",
|
||||
"rescue", "ensure"
|
||||
];
|
||||
var dedentKeywords = wordRegExp(dedentKeywordsArray);
|
||||
var dedentPunctualsArray = ["\\)", "\\}", "\\]"];
|
||||
var dedentPunctuals = new RegExp("^(?:" + dedentPunctualsArray.join("|") + ")$");
|
||||
var nextTokenizer = {
|
||||
"def": tokenFollowIdent, "fun": tokenFollowIdent, "macro": tokenMacroDef,
|
||||
"class": tokenFollowType, "module": tokenFollowType, "struct": tokenFollowType,
|
||||
"lib": tokenFollowType, "enum": tokenFollowType, "union": tokenFollowType
|
||||
};
|
||||
var matching = {"[": "]", "{": "}", "(": ")", "<": ">"};
|
||||
|
||||
function tokenBase(stream, state) {
|
||||
if (stream.eatSpace()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Macros
|
||||
if (state.lastToken != "\\" && stream.match("{%", false)) {
|
||||
return chain(tokenMacro("%", "%"), stream, state);
|
||||
}
|
||||
|
||||
if (state.lastToken != "\\" && stream.match("{{", false)) {
|
||||
return chain(tokenMacro("{", "}"), stream, state);
|
||||
}
|
||||
|
||||
// Comments
|
||||
if (stream.peek() == "#") {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
|
||||
// Variables and keywords
|
||||
var matched;
|
||||
if (stream.match(idents)) {
|
||||
stream.eat(/[?!]/);
|
||||
|
||||
matched = stream.current();
|
||||
if (stream.eat(":")) {
|
||||
return "atom";
|
||||
} else if (state.lastToken == ".") {
|
||||
return "property";
|
||||
} else if (keywords.test(matched)) {
|
||||
if (state.lastToken != "abstract" && indentKeywords.test(matched)) {
|
||||
if (!(matched == "fun" && state.blocks.indexOf("lib") >= 0)) {
|
||||
state.blocks.push(matched);
|
||||
state.currentIndent += 1;
|
||||
}
|
||||
} else if (dedentKeywords.test(matched)) {
|
||||
state.blocks.pop();
|
||||
state.currentIndent -= 1;
|
||||
}
|
||||
|
||||
if (nextTokenizer.hasOwnProperty(matched)) {
|
||||
state.tokenize.push(nextTokenizer[matched]);
|
||||
}
|
||||
|
||||
return "keyword";
|
||||
} else if (atomWords.test(matched)) {
|
||||
return "atom";
|
||||
}
|
||||
|
||||
return "variable";
|
||||
}
|
||||
|
||||
// Class variables and instance variables
|
||||
// or attributes
|
||||
if (stream.eat("@")) {
|
||||
if (stream.peek() == "[") {
|
||||
return chain(tokenNest("[", "]", "meta"), stream, state);
|
||||
}
|
||||
|
||||
stream.eat("@");
|
||||
stream.match(idents) || stream.match(types);
|
||||
return "variable-2";
|
||||
}
|
||||
|
||||
// Global variables
|
||||
if (stream.eat("$")) {
|
||||
stream.eat(/[0-9]+|\?/) || stream.match(idents) || stream.match(types);
|
||||
return "variable-3";
|
||||
}
|
||||
|
||||
// Constants and types
|
||||
if (stream.match(types)) {
|
||||
return "tag";
|
||||
}
|
||||
|
||||
// Symbols or ':' operator
|
||||
if (stream.eat(":")) {
|
||||
if (stream.eat("\"")) {
|
||||
return chain(tokenQuote("\"", "atom", false), stream, state);
|
||||
} else if (stream.match(idents) || stream.match(types) ||
|
||||
stream.match(operators) || stream.match(conditionalOperators) || stream.match(indexingOperators)) {
|
||||
return "atom";
|
||||
}
|
||||
stream.eat(":");
|
||||
return "operator";
|
||||
}
|
||||
|
||||
// Strings
|
||||
if (stream.eat("\"")) {
|
||||
return chain(tokenQuote("\"", "string", true), stream, state);
|
||||
}
|
||||
|
||||
// Strings or regexps or macro variables or '%' operator
|
||||
if (stream.peek() == "%") {
|
||||
var style = "string";
|
||||
var embed = true;
|
||||
var delim;
|
||||
|
||||
if (stream.match("%r")) {
|
||||
// Regexps
|
||||
style = "string-2";
|
||||
delim = stream.next();
|
||||
} else if (stream.match("%w")) {
|
||||
embed = false;
|
||||
delim = stream.next();
|
||||
} else {
|
||||
if(delim = stream.match(/^%([^\w\s=])/)) {
|
||||
delim = delim[1];
|
||||
} else if (stream.match(/^%[a-zA-Z0-9_\u009F-\uFFFF]*/)) {
|
||||
// Macro variables
|
||||
return "meta";
|
||||
} else {
|
||||
// '%' operator
|
||||
return "operator";
|
||||
}
|
||||
}
|
||||
|
||||
if (matching.hasOwnProperty(delim)) {
|
||||
delim = matching[delim];
|
||||
}
|
||||
return chain(tokenQuote(delim, style, embed), stream, state);
|
||||
}
|
||||
|
||||
// Characters
|
||||
if (stream.eat("'")) {
|
||||
stream.match(/^(?:[^']|\\(?:[befnrtv0'"]|[0-7]{3}|u(?:[0-9a-fA-F]{4}|\{[0-9a-fA-F]{1,6}\})))/);
|
||||
stream.eat("'");
|
||||
return "atom";
|
||||
}
|
||||
|
||||
// Numbers
|
||||
if (stream.eat("0")) {
|
||||
if (stream.eat("x")) {
|
||||
stream.match(/^[0-9a-fA-F]+/);
|
||||
} else if (stream.eat("o")) {
|
||||
stream.match(/^[0-7]+/);
|
||||
} else if (stream.eat("b")) {
|
||||
stream.match(/^[01]+/);
|
||||
}
|
||||
return "number";
|
||||
}
|
||||
|
||||
if (stream.eat(/\d/)) {
|
||||
stream.match(/^\d*(?:\.\d+)?(?:[eE][+-]?\d+)?/);
|
||||
return "number";
|
||||
}
|
||||
|
||||
// Operators
|
||||
if (stream.match(operators)) {
|
||||
stream.eat("="); // Operators can follow assigin symbol.
|
||||
return "operator";
|
||||
}
|
||||
|
||||
if (stream.match(conditionalOperators) || stream.match(anotherOperators)) {
|
||||
return "operator";
|
||||
}
|
||||
|
||||
// Parens and braces
|
||||
if (matched = stream.match(/[({[]/, false)) {
|
||||
matched = matched[0];
|
||||
return chain(tokenNest(matched, matching[matched], null), stream, state);
|
||||
}
|
||||
|
||||
// Escapes
|
||||
if (stream.eat("\\")) {
|
||||
stream.next();
|
||||
return "meta";
|
||||
}
|
||||
|
||||
stream.next();
|
||||
return null;
|
||||
}
|
||||
|
||||
function tokenNest(begin, end, style, started) {
|
||||
return function (stream, state) {
|
||||
if (!started && stream.match(begin)) {
|
||||
state.tokenize[state.tokenize.length - 1] = tokenNest(begin, end, style, true);
|
||||
state.currentIndent += 1;
|
||||
return style;
|
||||
}
|
||||
|
||||
var nextStyle = tokenBase(stream, state);
|
||||
if (stream.current() === end) {
|
||||
state.tokenize.pop();
|
||||
state.currentIndent -= 1;
|
||||
nextStyle = style;
|
||||
}
|
||||
|
||||
return nextStyle;
|
||||
};
|
||||
}
|
||||
|
||||
function tokenMacro(begin, end, started) {
|
||||
return function (stream, state) {
|
||||
if (!started && stream.match("{" + begin)) {
|
||||
state.currentIndent += 1;
|
||||
state.tokenize[state.tokenize.length - 1] = tokenMacro(begin, end, true);
|
||||
return "meta";
|
||||
}
|
||||
|
||||
if (stream.match(end + "}")) {
|
||||
state.currentIndent -= 1;
|
||||
state.tokenize.pop();
|
||||
return "meta";
|
||||
}
|
||||
|
||||
return tokenBase(stream, state);
|
||||
};
|
||||
}
|
||||
|
||||
function tokenMacroDef(stream, state) {
|
||||
if (stream.eatSpace()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var matched;
|
||||
if (matched = stream.match(idents)) {
|
||||
if (matched == "def") {
|
||||
return "keyword";
|
||||
}
|
||||
stream.eat(/[?!]/);
|
||||
}
|
||||
|
||||
state.tokenize.pop();
|
||||
return "def";
|
||||
}
|
||||
|
||||
function tokenFollowIdent(stream, state) {
|
||||
if (stream.eatSpace()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (stream.match(idents)) {
|
||||
stream.eat(/[!?]/);
|
||||
} else {
|
||||
stream.match(operators) || stream.match(conditionalOperators) || stream.match(indexingOperators);
|
||||
}
|
||||
state.tokenize.pop();
|
||||
return "def";
|
||||
}
|
||||
|
||||
function tokenFollowType(stream, state) {
|
||||
if (stream.eatSpace()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
stream.match(types);
|
||||
state.tokenize.pop();
|
||||
return "def";
|
||||
}
|
||||
|
||||
function tokenQuote(end, style, embed) {
|
||||
return function (stream, state) {
|
||||
var escaped = false;
|
||||
|
||||
while (stream.peek()) {
|
||||
if (!escaped) {
|
||||
if (stream.match("{%", false)) {
|
||||
state.tokenize.push(tokenMacro("%", "%"));
|
||||
return style;
|
||||
}
|
||||
|
||||
if (stream.match("{{", false)) {
|
||||
state.tokenize.push(tokenMacro("{", "}"));
|
||||
return style;
|
||||
}
|
||||
|
||||
if (embed && stream.match("#{", false)) {
|
||||
state.tokenize.push(tokenNest("#{", "}", "meta"));
|
||||
return style;
|
||||
}
|
||||
|
||||
var ch = stream.next();
|
||||
|
||||
if (ch == end) {
|
||||
state.tokenize.pop();
|
||||
return style;
|
||||
}
|
||||
|
||||
escaped = ch == "\\";
|
||||
} else {
|
||||
stream.next();
|
||||
escaped = false;
|
||||
}
|
||||
}
|
||||
|
||||
return style;
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function () {
|
||||
return {
|
||||
tokenize: [tokenBase],
|
||||
currentIndent: 0,
|
||||
lastToken: null,
|
||||
blocks: []
|
||||
};
|
||||
},
|
||||
|
||||
token: function (stream, state) {
|
||||
var style = state.tokenize[state.tokenize.length - 1](stream, state);
|
||||
var token = stream.current();
|
||||
|
||||
if (style && style != "comment") {
|
||||
state.lastToken = token;
|
||||
}
|
||||
|
||||
return style;
|
||||
},
|
||||
|
||||
indent: function (state, textAfter) {
|
||||
textAfter = textAfter.replace(/^\s*(?:\{%)?\s*|\s*(?:%\})?\s*$/g, "");
|
||||
|
||||
if (dedentKeywords.test(textAfter) || dedentPunctuals.test(textAfter)) {
|
||||
return config.indentUnit * (state.currentIndent - 1);
|
||||
}
|
||||
|
||||
return config.indentUnit * state.currentIndent;
|
||||
},
|
||||
|
||||
fold: "indent",
|
||||
electricInput: wordRegExp(dedentPunctualsArray.concat(dedentKeywordsArray), true),
|
||||
lineComment: '#'
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-crystal", "crystal");
|
||||
});
|
|
@ -0,0 +1,119 @@
|
|||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Crystal mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="../../addon/edit/matchbrackets.js"></script>
|
||||
<script src="crystal.js"></script>
|
||||
<style>
|
||||
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
|
||||
.cm-s-default span.cm-arrow { color: red; }
|
||||
</style>
|
||||
|
||||
<div id=nav>
|
||||
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Crystal</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Crystal mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
# Features of Crystal
|
||||
# - Ruby-inspired syntax.
|
||||
# - Statically type-checked but without having to specify the type of variables or method arguments.
|
||||
# - Be able to call C code by writing bindings to it in Crystal.
|
||||
# - Have compile-time evaluation and generation of code, to avoid boilerplate code.
|
||||
# - Compile to efficient native code.
|
||||
|
||||
# A very basic HTTP server
|
||||
require "http/server"
|
||||
|
||||
server = HTTP::Server.new(8080) do |request|
|
||||
HTTP::Response.ok "text/plain", "Hello world, got #{request.path}!"
|
||||
end
|
||||
|
||||
puts "Listening on http://0.0.0.0:8080"
|
||||
server.listen
|
||||
|
||||
module Foo
|
||||
def initialize(@foo); end
|
||||
|
||||
abstract def abstract_method : String
|
||||
|
||||
@[AlwaysInline]
|
||||
def with_foofoo
|
||||
with Foo.new(self) yield
|
||||
end
|
||||
|
||||
struct Foo
|
||||
def initialize(@foo); end
|
||||
|
||||
def hello_world
|
||||
@foo.abstract_method
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Bar
|
||||
include Foo
|
||||
|
||||
@@foobar = 12345
|
||||
|
||||
def initialize(@bar)
|
||||
super(@bar.not_nil! + 100)
|
||||
end
|
||||
|
||||
macro alias_method(name, method)
|
||||
def {{ name }}(*args)
|
||||
{{ method }}(*args)
|
||||
end
|
||||
end
|
||||
|
||||
def a_method
|
||||
"Hello, World"
|
||||
end
|
||||
|
||||
alias_method abstract_method, a_method
|
||||
|
||||
macro def show_instance_vars : Nil
|
||||
{% for var in @type.instance_vars %}
|
||||
puts "@{{ var }} = #{ @{{ var }} }"
|
||||
{% end %}
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
class Baz < Bar; end
|
||||
|
||||
lib LibC
|
||||
fun c_puts = "puts"(str : Char*) : Int
|
||||
end
|
||||
|
||||
$baz = Baz.new(100)
|
||||
$baz.show_instance_vars
|
||||
$baz.with_foofoo do
|
||||
LibC.c_puts hello_world
|
||||
end
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: "text/x-crystal",
|
||||
matchBrackets: true,
|
||||
indentUnit: 2
|
||||
});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-crystal</code>.</p>
|
||||
</article>
|
|
@ -12,6 +12,7 @@
|
|||
"use strict";
|
||||
|
||||
CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
var inline = parserConfig.inline
|
||||
if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
|
||||
|
||||
var indentUnit = config.indentUnit,
|
||||
|
@ -19,13 +20,15 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
documentTypes = parserConfig.documentTypes || {},
|
||||
mediaTypes = parserConfig.mediaTypes || {},
|
||||
mediaFeatures = parserConfig.mediaFeatures || {},
|
||||
mediaValueKeywords = parserConfig.mediaValueKeywords || {},
|
||||
propertyKeywords = parserConfig.propertyKeywords || {},
|
||||
nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
|
||||
fontProperties = parserConfig.fontProperties || {},
|
||||
counterDescriptors = parserConfig.counterDescriptors || {},
|
||||
colorKeywords = parserConfig.colorKeywords || {},
|
||||
valueKeywords = parserConfig.valueKeywords || {},
|
||||
allowNested = parserConfig.allowNested;
|
||||
allowNested = parserConfig.allowNested,
|
||||
supportsAtComponent = parserConfig.supportsAtComponent === true;
|
||||
|
||||
var type, override;
|
||||
function ret(style, tp) { type = tp; return style; }
|
||||
|
@ -119,13 +122,14 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
this.prev = prev;
|
||||
}
|
||||
|
||||
function pushContext(state, stream, type) {
|
||||
state.context = new Context(type, stream.indentation() + indentUnit, state.context);
|
||||
function pushContext(state, stream, type, indent) {
|
||||
state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
|
||||
return type;
|
||||
}
|
||||
|
||||
function popContext(state) {
|
||||
state.context = state.context.prev;
|
||||
if (state.context.prev)
|
||||
state.context = state.context.prev;
|
||||
return state.context.type;
|
||||
}
|
||||
|
||||
|
@ -157,9 +161,13 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
return pushContext(state, stream, "block");
|
||||
} else if (type == "}" && state.context.prev) {
|
||||
return popContext(state);
|
||||
} else if (/@(media|supports|(-moz-)?document)/.test(type)) {
|
||||
} else if (supportsAtComponent && /@component/.test(type)) {
|
||||
return pushContext(state, stream, "atComponentBlock");
|
||||
} else if (/^@(-moz-)?document$/.test(type)) {
|
||||
return pushContext(state, stream, "documentTypes");
|
||||
} else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
|
||||
return pushContext(state, stream, "atBlock");
|
||||
} else if (/@(font-face|counter-style)/.test(type)) {
|
||||
} else if (/^@(font-face|counter-style)/.test(type)) {
|
||||
state.stateArg = type;
|
||||
return "restricted_atBlock_before";
|
||||
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
|
||||
|
@ -219,7 +227,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
if (type == "}" || type == "{") return popAndPass(type, stream, state);
|
||||
if (type == "(") return pushContext(state, stream, "parens");
|
||||
|
||||
if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
|
||||
if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
|
||||
override += " error";
|
||||
} else if (type == "word") {
|
||||
wordAsValue(stream);
|
||||
|
@ -252,33 +260,56 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
return pass(type, stream, state);
|
||||
};
|
||||
|
||||
states.documentTypes = function(type, stream, state) {
|
||||
if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
|
||||
override = "tag";
|
||||
return state.context.type;
|
||||
} else {
|
||||
return states.atBlock(type, stream, state);
|
||||
}
|
||||
};
|
||||
|
||||
states.atBlock = function(type, stream, state) {
|
||||
if (type == "(") return pushContext(state, stream, "atBlock_parens");
|
||||
if (type == "}") return popAndPass(type, stream, state);
|
||||
if (type == "}" || type == ";") return popAndPass(type, stream, state);
|
||||
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
|
||||
|
||||
if (type == "interpolation") return pushContext(state, stream, "interpolation");
|
||||
|
||||
if (type == "word") {
|
||||
var word = stream.current().toLowerCase();
|
||||
if (word == "only" || word == "not" || word == "and" || word == "or")
|
||||
override = "keyword";
|
||||
else if (documentTypes.hasOwnProperty(word))
|
||||
override = "tag";
|
||||
else if (mediaTypes.hasOwnProperty(word))
|
||||
override = "attribute";
|
||||
else if (mediaFeatures.hasOwnProperty(word))
|
||||
override = "property";
|
||||
else if (mediaValueKeywords.hasOwnProperty(word))
|
||||
override = "keyword";
|
||||
else if (propertyKeywords.hasOwnProperty(word))
|
||||
override = "property";
|
||||
else if (nonStandardPropertyKeywords.hasOwnProperty(word))
|
||||
override = "string-2";
|
||||
else if (valueKeywords.hasOwnProperty(word))
|
||||
override = "atom";
|
||||
else if (colorKeywords.hasOwnProperty(word))
|
||||
override = "keyword";
|
||||
else
|
||||
override = "error";
|
||||
}
|
||||
return state.context.type;
|
||||
};
|
||||
|
||||
states.atComponentBlock = function(type, stream, state) {
|
||||
if (type == "}")
|
||||
return popAndPass(type, stream, state);
|
||||
if (type == "{")
|
||||
return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
|
||||
if (type == "word")
|
||||
override = "error";
|
||||
return state.context.type;
|
||||
};
|
||||
|
||||
states.atBlock_parens = function(type, stream, state) {
|
||||
if (type == ")") return popContext(state);
|
||||
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
|
||||
|
@ -336,9 +367,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
return {
|
||||
startState: function(base) {
|
||||
return {tokenize: null,
|
||||
state: "top",
|
||||
state: inline ? "block" : "top",
|
||||
stateArg: null,
|
||||
context: new Context("top", base || 0, null)};
|
||||
context: new Context(inline ? "block" : "top", base || 0, null)};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
|
@ -357,12 +388,18 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
var cx = state.context, ch = textAfter && textAfter.charAt(0);
|
||||
var indent = cx.indent;
|
||||
if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
|
||||
if (cx.prev &&
|
||||
(ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "restricted_atBlock") ||
|
||||
ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
|
||||
ch == "{" && (cx.type == "at" || cx.type == "atBlock"))) {
|
||||
indent = cx.indent - indentUnit;
|
||||
cx = cx.prev;
|
||||
if (cx.prev) {
|
||||
if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
|
||||
cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
|
||||
// Resume indentation from parent context.
|
||||
cx = cx.prev;
|
||||
indent = cx.indent;
|
||||
} else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
|
||||
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
|
||||
// Dedent relative to current context.
|
||||
indent = Math.max(0, cx.indent - indentUnit);
|
||||
cx = cx.prev;
|
||||
}
|
||||
}
|
||||
return indent;
|
||||
},
|
||||
|
@ -399,17 +436,24 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
|
||||
"max-color", "color-index", "min-color-index", "max-color-index",
|
||||
"monochrome", "min-monochrome", "max-monochrome", "resolution",
|
||||
"min-resolution", "max-resolution", "scan", "grid"
|
||||
"min-resolution", "max-resolution", "scan", "grid", "orientation",
|
||||
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
|
||||
"pointer", "any-pointer", "hover", "any-hover"
|
||||
], mediaFeatures = keySet(mediaFeatures_);
|
||||
|
||||
var mediaValueKeywords_ = [
|
||||
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
|
||||
"interlace", "progressive"
|
||||
], mediaValueKeywords = keySet(mediaValueKeywords_);
|
||||
|
||||
var propertyKeywords_ = [
|
||||
"align-content", "align-items", "align-self", "alignment-adjust",
|
||||
"alignment-baseline", "anchor-point", "animation", "animation-delay",
|
||||
"animation-direction", "animation-duration", "animation-fill-mode",
|
||||
"animation-iteration-count", "animation-name", "animation-play-state",
|
||||
"animation-timing-function", "appearance", "azimuth", "backface-visibility",
|
||||
"background", "background-attachment", "background-clip", "background-color",
|
||||
"background-image", "background-origin", "background-position",
|
||||
"background", "background-attachment", "background-blend-mode", "background-clip",
|
||||
"background-color", "background-image", "background-origin", "background-position",
|
||||
"background-repeat", "background-size", "baseline-shift", "binding",
|
||||
"bleed", "bookmark-label", "bookmark-level", "bookmark-state",
|
||||
"bookmark-target", "border", "border-bottom", "border-bottom-color",
|
||||
|
@ -553,11 +597,12 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
|
||||
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
|
||||
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
|
||||
"col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
|
||||
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
|
||||
"compact", "condensed", "contain", "content",
|
||||
"content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
|
||||
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "dashed", "decimal",
|
||||
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
|
||||
"decimal-leading-zero", "default", "default-button", "destination-atop",
|
||||
"destination-in", "destination-out", "destination-over", "devanagari",
|
||||
"destination-in", "destination-out", "destination-over", "devanagari", "difference",
|
||||
"disc", "discard", "disclosure-closed", "disclosure-open", "document",
|
||||
"dot-dash", "dot-dot-dash",
|
||||
"dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
|
||||
|
@ -568,23 +613,23 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
|
||||
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
|
||||
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
|
||||
"ethiopic-numeric", "ew-resize", "expanded", "extends", "extra-condensed",
|
||||
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "footnotes",
|
||||
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
|
||||
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
|
||||
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
|
||||
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
|
||||
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
|
||||
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
|
||||
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
|
||||
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
|
||||
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
|
||||
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
|
||||
"inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
|
||||
"italic", "japanese-formal", "japanese-informal", "justify", "kannada",
|
||||
"katakana", "katakana-iroha", "keep-all", "khmer",
|
||||
"korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
|
||||
"landscape", "lao", "large", "larger", "left", "level", "lighter",
|
||||
"landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
|
||||
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
|
||||
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
|
||||
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
|
||||
"lower-roman", "lowercase", "ltr", "malayalam", "match", "matrix", "matrix3d",
|
||||
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
|
||||
"media-controls-background", "media-current-time-display",
|
||||
"media-fullscreen-button", "media-mute-button", "media-play-button",
|
||||
"media-return-to-realtime-button", "media-rewind-button",
|
||||
|
@ -593,7 +638,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"media-volume-slider-container", "media-volume-sliderthumb", "medium",
|
||||
"menu", "menulist", "menulist-button", "menulist-text",
|
||||
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
|
||||
"mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
|
||||
"mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
|
||||
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
|
||||
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
|
||||
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
|
||||
|
@ -606,8 +651,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"relative", "repeat", "repeating-linear-gradient",
|
||||
"repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
|
||||
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
|
||||
"rotateZ", "round", "row-resize", "rtl", "run-in", "running",
|
||||
"s-resize", "sans-serif", "scale", "scale3d", "scaleX", "scaleY", "scaleZ",
|
||||
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
|
||||
"s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
|
||||
"scroll", "scrollbar", "se-resize", "searchfield",
|
||||
"searchfield-cancel-button", "searchfield-decoration",
|
||||
"searchfield-results-button", "searchfield-results-decoration",
|
||||
|
@ -615,8 +660,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"simp-chinese-formal", "simp-chinese-informal", "single",
|
||||
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
|
||||
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
|
||||
"small", "small-caps", "small-caption", "smaller", "solid", "somali",
|
||||
"source-atop", "source-in", "source-out", "source-over", "space", "spell-out", "square",
|
||||
"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",
|
||||
"table-caption", "table-cell", "table-column", "table-column-group",
|
||||
|
@ -633,12 +678,13 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
|
||||
"var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
|
||||
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
|
||||
"window", "windowframe", "windowtext", "words", "x-large", "x-small", "xor",
|
||||
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
|
||||
"xx-large", "xx-small"
|
||||
], valueKeywords = keySet(valueKeywords_);
|
||||
|
||||
var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(propertyKeywords_)
|
||||
.concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
|
||||
var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
|
||||
.concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
|
||||
.concat(valueKeywords_);
|
||||
CodeMirror.registerHelper("hintWords", "css", allWords);
|
||||
|
||||
function tokenCComment(stream, state) {
|
||||
|
@ -657,6 +703,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
documentTypes: documentTypes,
|
||||
mediaTypes: mediaTypes,
|
||||
mediaFeatures: mediaFeatures,
|
||||
mediaValueKeywords: mediaValueKeywords,
|
||||
propertyKeywords: propertyKeywords,
|
||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
||||
fontProperties: fontProperties,
|
||||
|
@ -676,6 +723,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
CodeMirror.defineMIME("text/x-scss", {
|
||||
mediaTypes: mediaTypes,
|
||||
mediaFeatures: mediaFeatures,
|
||||
mediaValueKeywords: mediaValueKeywords,
|
||||
propertyKeywords: propertyKeywords,
|
||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
||||
colorKeywords: colorKeywords,
|
||||
|
@ -717,6 +765,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
CodeMirror.defineMIME("text/x-less", {
|
||||
mediaTypes: mediaTypes,
|
||||
mediaFeatures: mediaFeatures,
|
||||
mediaValueKeywords: mediaValueKeywords,
|
||||
propertyKeywords: propertyKeywords,
|
||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
||||
colorKeywords: colorKeywords,
|
||||
|
@ -751,4 +800,26 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
|||
helperType: "less"
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-gss", {
|
||||
documentTypes: documentTypes,
|
||||
mediaTypes: mediaTypes,
|
||||
mediaFeatures: mediaFeatures,
|
||||
propertyKeywords: propertyKeywords,
|
||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
||||
fontProperties: fontProperties,
|
||||
counterDescriptors: counterDescriptors,
|
||||
colorKeywords: colorKeywords,
|
||||
valueKeywords: valueKeywords,
|
||||
supportsAtComponent: true,
|
||||
tokenHooks: {
|
||||
"/": function(stream, state) {
|
||||
if (!stream.eat("*")) return false;
|
||||
state.tokenize = tokenCComment;
|
||||
return tokenCComment(stream, state);
|
||||
}
|
||||
},
|
||||
name: "css",
|
||||
helperType: "gss"
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue