upgrade CodeMirror
This commit is contained in:
parent
e3c07ed720
commit
f87cabc558
|
@ -41,7 +41,7 @@ const (
|
||||||
// WideVersion holds the current wide version.
|
// WideVersion holds the current wide version.
|
||||||
WideVersion = "1.2.0"
|
WideVersion = "1.2.0"
|
||||||
// CodeMirrorVer holds the current editor version.
|
// CodeMirrorVer holds the current editor version.
|
||||||
CodeMirrorVer = "4.10"
|
CodeMirrorVer = "5.1"
|
||||||
|
|
||||||
HelloWorld = `package main
|
HelloWorld = `package main
|
||||||
|
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
// 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) {
|
|
||||||
var DEFAULT_BRACKETS = "()[]{}''\"\"";
|
|
||||||
var DEFAULT_EXPLODE_ON_ENTER = "[]{}";
|
|
||||||
var SPACE_CHAR_REGEX = /\s/;
|
|
||||||
|
|
||||||
var Pos = CodeMirror.Pos;
|
|
||||||
|
|
||||||
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
|
|
||||||
if (old != CodeMirror.Init && old)
|
|
||||||
cm.removeKeyMap("autoCloseBrackets");
|
|
||||||
if (!val) return;
|
|
||||||
var pairs = DEFAULT_BRACKETS, explode = DEFAULT_EXPLODE_ON_ENTER;
|
|
||||||
if (typeof val == "string") pairs = val;
|
|
||||||
else if (typeof val == "object") {
|
|
||||||
if (val.pairs != null) pairs = val.pairs;
|
|
||||||
if (val.explode != null) explode = val.explode;
|
|
||||||
}
|
|
||||||
var map = buildKeymap(pairs);
|
|
||||||
if (explode) map.Enter = buildExplodeHandler(explode);
|
|
||||||
cm.addKeyMap(map);
|
|
||||||
});
|
|
||||||
|
|
||||||
function charsAround(cm, pos) {
|
|
||||||
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
|
|
||||||
Pos(pos.line, pos.ch + 1));
|
|
||||||
return str.length == 2 ? str : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Project the token type that will exists after the given char is
|
|
||||||
// typed, and use it to determine whether it would cause the start
|
|
||||||
// of a string token.
|
|
||||||
function enteringString(cm, pos, ch) {
|
|
||||||
var line = cm.getLine(pos.line);
|
|
||||||
var token = cm.getTokenAt(pos);
|
|
||||||
if (/\bstring2?\b/.test(token.type)) return false;
|
|
||||||
var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4);
|
|
||||||
stream.pos = stream.start = token.start;
|
|
||||||
for (;;) {
|
|
||||||
var type1 = cm.getMode().token(stream, token.state);
|
|
||||||
if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1);
|
|
||||||
stream.start = stream.pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildKeymap(pairs) {
|
|
||||||
var map = {
|
|
||||||
name : "autoCloseBrackets",
|
|
||||||
Backspace: function(cm) {
|
|
||||||
if (cm.getOption("disableInput")) return CodeMirror.Pass;
|
|
||||||
var ranges = cm.listSelections();
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
if (!ranges[i].empty()) return CodeMirror.Pass;
|
|
||||||
var around = charsAround(cm, ranges[i].head);
|
|
||||||
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
|
|
||||||
}
|
|
||||||
for (var i = ranges.length - 1; i >= 0; i--) {
|
|
||||||
var cur = ranges[i].head;
|
|
||||||
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var closingBrackets = "";
|
|
||||||
for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
|
|
||||||
closingBrackets += right;
|
|
||||||
map["'" + left + "'"] = function(cm) {
|
|
||||||
if (cm.getOption("disableInput")) return CodeMirror.Pass;
|
|
||||||
var ranges = cm.listSelections(), type, next;
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
var range = ranges[i], cur = range.head, curType;
|
|
||||||
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
|
|
||||||
if (!range.empty()) {
|
|
||||||
curType = "surround";
|
|
||||||
} else if (left == right && next == right) {
|
|
||||||
if (cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == left + left + left)
|
|
||||||
curType = "skipThree";
|
|
||||||
else
|
|
||||||
curType = "skip";
|
|
||||||
} else if (left == right && cur.ch > 1 &&
|
|
||||||
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == left + left &&
|
|
||||||
(cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != left)) {
|
|
||||||
curType = "addFour";
|
|
||||||
} else if (left == '"' || left == "'") {
|
|
||||||
if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, left)) curType = "both";
|
|
||||||
else return CodeMirror.Pass;
|
|
||||||
} else if (cm.getLine(cur.line).length == cur.ch || closingBrackets.indexOf(next) >= 0 || SPACE_CHAR_REGEX.test(next)) {
|
|
||||||
curType = "both";
|
|
||||||
} else {
|
|
||||||
return CodeMirror.Pass;
|
|
||||||
}
|
|
||||||
if (!type) type = curType;
|
|
||||||
else if (type != curType) return CodeMirror.Pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
cm.operation(function() {
|
|
||||||
if (type == "skip") {
|
|
||||||
cm.execCommand("goCharRight");
|
|
||||||
} else if (type == "skipThree") {
|
|
||||||
for (var i = 0; i < 3; i++)
|
|
||||||
cm.execCommand("goCharRight");
|
|
||||||
} else if (type == "surround") {
|
|
||||||
var sels = cm.getSelections();
|
|
||||||
for (var i = 0; i < sels.length; i++)
|
|
||||||
sels[i] = left + sels[i] + right;
|
|
||||||
cm.replaceSelections(sels, "around");
|
|
||||||
} else if (type == "both") {
|
|
||||||
cm.replaceSelection(left + right, null);
|
|
||||||
cm.execCommand("goCharLeft");
|
|
||||||
} else if (type == "addFour") {
|
|
||||||
cm.replaceSelection(left + left + left + left, "before");
|
|
||||||
cm.execCommand("goCharRight");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
if (left != right) map["'" + right + "'"] = function(cm) {
|
|
||||||
var ranges = cm.listSelections();
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
var range = ranges[i];
|
|
||||||
if (!range.empty() ||
|
|
||||||
cm.getRange(range.head, Pos(range.head.line, range.head.ch + 1)) != right)
|
|
||||||
return CodeMirror.Pass;
|
|
||||||
}
|
|
||||||
cm.execCommand("goCharRight");
|
|
||||||
};
|
|
||||||
})(pairs.charAt(i), pairs.charAt(i + 1));
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildExplodeHandler(pairs) {
|
|
||||||
return function(cm) {
|
|
||||||
if (cm.getOption("disableInput")) return CodeMirror.Pass;
|
|
||||||
var ranges = cm.listSelections();
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
if (!ranges[i].empty()) return CodeMirror.Pass;
|
|
||||||
var around = charsAround(cm, ranges[i].head);
|
|
||||||
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
|
|
||||||
}
|
|
||||||
cm.operation(function() {
|
|
||||||
cm.replaceSelection("\n\n", null);
|
|
||||||
cm.execCommand("goCharLeft");
|
|
||||||
ranges = cm.listSelections();
|
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
|
||||||
var line = ranges[i].head.line;
|
|
||||||
cm.indentLine(line, null, true);
|
|
||||||
cm.indentLine(line + 1, null, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -1,86 +0,0 @@
|
||||||
// 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"), require("../htmlmixed/htmlmixed"));
|
|
||||||
else if (typeof define == "function" && define.amd) // AMD
|
|
||||||
define(["../../lib/codemirror", "../htmlmixed/htmlmixed"], mod);
|
|
||||||
else // Plain browser env
|
|
||||||
mod(CodeMirror);
|
|
||||||
})(function(CodeMirror) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
|
|
||||||
|
|
||||||
//config settings
|
|
||||||
var scriptStartRegex = parserConfig.scriptStartRegex || /^<%/i,
|
|
||||||
scriptEndRegex = parserConfig.scriptEndRegex || /^%>/i;
|
|
||||||
|
|
||||||
//inner modes
|
|
||||||
var scriptingMode, htmlMixedMode;
|
|
||||||
|
|
||||||
//tokenizer when in html mode
|
|
||||||
function htmlDispatch(stream, state) {
|
|
||||||
if (stream.match(scriptStartRegex, false)) {
|
|
||||||
state.token=scriptingDispatch;
|
|
||||||
return scriptingMode.token(stream, state.scriptState);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return htmlMixedMode.token(stream, state.htmlState);
|
|
||||||
}
|
|
||||||
|
|
||||||
//tokenizer when in scripting mode
|
|
||||||
function scriptingDispatch(stream, state) {
|
|
||||||
if (stream.match(scriptEndRegex, false)) {
|
|
||||||
state.token=htmlDispatch;
|
|
||||||
return htmlMixedMode.token(stream, state.htmlState);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return scriptingMode.token(stream, state.scriptState);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
startState: function() {
|
|
||||||
scriptingMode = scriptingMode || CodeMirror.getMode(config, parserConfig.scriptingModeSpec);
|
|
||||||
htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed");
|
|
||||||
return {
|
|
||||||
token : parserConfig.startOpen ? scriptingDispatch : htmlDispatch,
|
|
||||||
htmlState : CodeMirror.startState(htmlMixedMode),
|
|
||||||
scriptState : CodeMirror.startState(scriptingMode)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
token: function(stream, state) {
|
|
||||||
return state.token(stream, state);
|
|
||||||
},
|
|
||||||
|
|
||||||
indent: function(state, textAfter) {
|
|
||||||
if (state.token == htmlDispatch)
|
|
||||||
return htmlMixedMode.indent(state.htmlState, textAfter);
|
|
||||||
else if (scriptingMode.indent)
|
|
||||||
return scriptingMode.indent(state.scriptState, textAfter);
|
|
||||||
},
|
|
||||||
|
|
||||||
copyState: function(state) {
|
|
||||||
return {
|
|
||||||
token : state.token,
|
|
||||||
htmlState : CodeMirror.copyState(htmlMixedMode, state.htmlState),
|
|
||||||
scriptState : CodeMirror.copyState(scriptingMode, state.scriptState)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
innerMode: function(state) {
|
|
||||||
if (state.token == scriptingDispatch) return {state: state.scriptState, mode: scriptingMode};
|
|
||||||
else return {state: state.htmlState, mode: htmlMixedMode};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, "htmlmixed");
|
|
||||||
|
|
||||||
CodeMirror.defineMIME("application/x-ejs", { name: "htmlembedded", scriptingModeSpec:"javascript"});
|
|
||||||
CodeMirror.defineMIME("application/x-aspx", { name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
|
|
||||||
CodeMirror.defineMIME("application/x-jsp", { name: "htmlembedded", scriptingModeSpec:"text/x-java"});
|
|
||||||
CodeMirror.defineMIME("application/x-erb", { name: "htmlembedded", scriptingModeSpec:"ruby"});
|
|
||||||
|
|
||||||
});
|
|
|
@ -1,221 +0,0 @@
|
||||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
||||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Smarty 2 and 3 mode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
(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("smarty", function(config) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// our default settings; check to see if they're overridden
|
|
||||||
var settings = {
|
|
||||||
rightDelimiter: '}',
|
|
||||||
leftDelimiter: '{',
|
|
||||||
smartyVersion: 2 // for backward compatibility
|
|
||||||
};
|
|
||||||
if (config.hasOwnProperty("leftDelimiter")) {
|
|
||||||
settings.leftDelimiter = config.leftDelimiter;
|
|
||||||
}
|
|
||||||
if (config.hasOwnProperty("rightDelimiter")) {
|
|
||||||
settings.rightDelimiter = config.rightDelimiter;
|
|
||||||
}
|
|
||||||
if (config.hasOwnProperty("smartyVersion") && config.smartyVersion === 3) {
|
|
||||||
settings.smartyVersion = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
var keyFunctions = ["debug", "extends", "function", "include", "literal"];
|
|
||||||
var last;
|
|
||||||
var regs = {
|
|
||||||
operatorChars: /[+\-*&%=<>!?]/,
|
|
||||||
validIdentifier: /[a-zA-Z0-9_]/,
|
|
||||||
stringChar: /['"]/
|
|
||||||
};
|
|
||||||
|
|
||||||
var helpers = {
|
|
||||||
cont: function(style, lastType) {
|
|
||||||
last = lastType;
|
|
||||||
return style;
|
|
||||||
},
|
|
||||||
chain: function(stream, state, parser) {
|
|
||||||
state.tokenize = parser;
|
|
||||||
return parser(stream, state);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// our various parsers
|
|
||||||
var parsers = {
|
|
||||||
|
|
||||||
// the main tokenizer
|
|
||||||
tokenizer: function(stream, state) {
|
|
||||||
if (stream.match(settings.leftDelimiter, true)) {
|
|
||||||
if (stream.eat("*")) {
|
|
||||||
return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
|
|
||||||
} else {
|
|
||||||
// Smarty 3 allows { and } surrounded by whitespace to NOT slip into Smarty mode
|
|
||||||
state.depth++;
|
|
||||||
var isEol = stream.eol();
|
|
||||||
var isFollowedByWhitespace = /\s/.test(stream.peek());
|
|
||||||
if (settings.smartyVersion === 3 && settings.leftDelimiter === "{" && (isEol || isFollowedByWhitespace)) {
|
|
||||||
state.depth--;
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
state.tokenize = parsers.smarty;
|
|
||||||
last = "startTag";
|
|
||||||
return "tag";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stream.next();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// parsing Smarty content
|
|
||||||
smarty: function(stream, state) {
|
|
||||||
if (stream.match(settings.rightDelimiter, true)) {
|
|
||||||
if (settings.smartyVersion === 3) {
|
|
||||||
state.depth--;
|
|
||||||
if (state.depth <= 0) {
|
|
||||||
state.tokenize = parsers.tokenizer;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state.tokenize = parsers.tokenizer;
|
|
||||||
}
|
|
||||||
return helpers.cont("tag", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream.match(settings.leftDelimiter, true)) {
|
|
||||||
state.depth++;
|
|
||||||
return helpers.cont("tag", "startTag");
|
|
||||||
}
|
|
||||||
|
|
||||||
var ch = stream.next();
|
|
||||||
if (ch == "$") {
|
|
||||||
stream.eatWhile(regs.validIdentifier);
|
|
||||||
return helpers.cont("variable-2", "variable");
|
|
||||||
} else if (ch == "|") {
|
|
||||||
return helpers.cont("operator", "pipe");
|
|
||||||
} else if (ch == ".") {
|
|
||||||
return helpers.cont("operator", "property");
|
|
||||||
} else if (regs.stringChar.test(ch)) {
|
|
||||||
state.tokenize = parsers.inAttribute(ch);
|
|
||||||
return helpers.cont("string", "string");
|
|
||||||
} else if (regs.operatorChars.test(ch)) {
|
|
||||||
stream.eatWhile(regs.operatorChars);
|
|
||||||
return helpers.cont("operator", "operator");
|
|
||||||
} else if (ch == "[" || ch == "]") {
|
|
||||||
return helpers.cont("bracket", "bracket");
|
|
||||||
} else if (ch == "(" || ch == ")") {
|
|
||||||
return helpers.cont("bracket", "operator");
|
|
||||||
} else if (/\d/.test(ch)) {
|
|
||||||
stream.eatWhile(/\d/);
|
|
||||||
return helpers.cont("number", "number");
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (state.last == "variable") {
|
|
||||||
if (ch == "@") {
|
|
||||||
stream.eatWhile(regs.validIdentifier);
|
|
||||||
return helpers.cont("property", "property");
|
|
||||||
} else if (ch == "|") {
|
|
||||||
stream.eatWhile(regs.validIdentifier);
|
|
||||||
return helpers.cont("qualifier", "modifier");
|
|
||||||
}
|
|
||||||
} else if (state.last == "pipe") {
|
|
||||||
stream.eatWhile(regs.validIdentifier);
|
|
||||||
return helpers.cont("qualifier", "modifier");
|
|
||||||
} else if (state.last == "whitespace") {
|
|
||||||
stream.eatWhile(regs.validIdentifier);
|
|
||||||
return helpers.cont("attribute", "modifier");
|
|
||||||
} if (state.last == "property") {
|
|
||||||
stream.eatWhile(regs.validIdentifier);
|
|
||||||
return helpers.cont("property", null);
|
|
||||||
} else if (/\s/.test(ch)) {
|
|
||||||
last = "whitespace";
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var str = "";
|
|
||||||
if (ch != "/") {
|
|
||||||
str += ch;
|
|
||||||
}
|
|
||||||
var c = null;
|
|
||||||
while (c = stream.eat(regs.validIdentifier)) {
|
|
||||||
str += c;
|
|
||||||
}
|
|
||||||
for (var i=0, j=keyFunctions.length; i<j; i++) {
|
|
||||||
if (keyFunctions[i] == str) {
|
|
||||||
return helpers.cont("keyword", "keyword");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (/\s/.test(ch)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return helpers.cont("tag", "tag");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
inAttribute: function(quote) {
|
|
||||||
return function(stream, state) {
|
|
||||||
var prevChar = null;
|
|
||||||
var currChar = null;
|
|
||||||
while (!stream.eol()) {
|
|
||||||
currChar = stream.peek();
|
|
||||||
if (stream.next() == quote && prevChar !== '\\') {
|
|
||||||
state.tokenize = parsers.smarty;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
prevChar = currChar;
|
|
||||||
}
|
|
||||||
return "string";
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
inBlock: function(style, terminator) {
|
|
||||||
return function(stream, state) {
|
|
||||||
while (!stream.eol()) {
|
|
||||||
if (stream.match(terminator)) {
|
|
||||||
state.tokenize = parsers.tokenizer;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
stream.next();
|
|
||||||
}
|
|
||||||
return style;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// the public API for CodeMirror
|
|
||||||
return {
|
|
||||||
startState: function() {
|
|
||||||
return {
|
|
||||||
tokenize: parsers.tokenizer,
|
|
||||||
mode: "smarty",
|
|
||||||
last: null,
|
|
||||||
depth: 0
|
|
||||||
};
|
|
||||||
},
|
|
||||||
token: function(stream, state) {
|
|
||||||
var style = state.tokenize(stream, state);
|
|
||||||
state.last = last;
|
|
||||||
return style;
|
|
||||||
},
|
|
||||||
electricChars: ""
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
CodeMirror.defineMIME("text/x-smarty", "smarty");
|
|
||||||
|
|
||||||
});
|
|
|
@ -1,114 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
|
|
||||||
<title>CodeMirror: Smarty mixed 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="../../mode/xml/xml.js"></script>
|
|
||||||
<script src="../../mode/javascript/javascript.js"></script>
|
|
||||||
<script src="../../mode/css/css.js"></script>
|
|
||||||
<script src="../../mode/htmlmixed/htmlmixed.js"></script>
|
|
||||||
<script src="../../mode/smarty/smarty.js"></script>
|
|
||||||
<script src="../../mode/smartymixed/smartymixed.js"></script>
|
|
||||||
<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="#">Smarty mixed</a>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
<h2>Smarty mixed mode</h2>
|
|
||||||
<form><textarea id="code" name="code">
|
|
||||||
{**
|
|
||||||
* @brief Smarty mixed mode
|
|
||||||
* @author Ruslan Osmanov
|
|
||||||
* @date 29.06.2013
|
|
||||||
*}
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>{$title|htmlspecialchars|truncate:30}</title>
|
|
||||||
</head>
|
|
||||||
<body class="{$bodyclass}">
|
|
||||||
{* Multiline smarty
|
|
||||||
* comment, no {$variables} here
|
|
||||||
*}
|
|
||||||
{literal}
|
|
||||||
{literal} is just an HTML text.
|
|
||||||
<script type="text/javascript">//<![CDATA[
|
|
||||||
var a = {$just_a_normal_js_object : "value"};
|
|
||||||
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("code"), {
|
|
||||||
mode : "smartymixed",
|
|
||||||
tabSize : 2,
|
|
||||||
indentUnit : 2,
|
|
||||||
indentWithTabs : false,
|
|
||||||
lineNumbers : true,
|
|
||||||
smartyVersion : 3
|
|
||||||
});
|
|
||||||
// ]]>
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
/* CSS content
|
|
||||||
{$no_smarty} */
|
|
||||||
.some-class { font-weight: bolder; color: "orange"; }
|
|
||||||
</style>
|
|
||||||
{/literal}
|
|
||||||
|
|
||||||
{extends file="parent.tpl"}
|
|
||||||
{include file="template.tpl"}
|
|
||||||
|
|
||||||
{* some example Smarty content *}
|
|
||||||
{if isset($name) && $name == 'Blog'}
|
|
||||||
This is a {$var}.
|
|
||||||
{$integer = 4511}, {$array[] = "a"}, {$stringvar = "string"}
|
|
||||||
{$integer = 4512} {$array[] = "a"} {$stringvar = "string"}
|
|
||||||
{assign var='bob' value=$var.prop}
|
|
||||||
{elseif $name == $foo}
|
|
||||||
{function name=menu level=0}
|
|
||||||
{foreach $data as $entry}
|
|
||||||
{if is_array($entry)}
|
|
||||||
- {$entry@key}
|
|
||||||
{menu data=$entry level=$level+1}
|
|
||||||
{else}
|
|
||||||
{$entry}
|
|
||||||
{* One
|
|
||||||
* Two
|
|
||||||
* Three
|
|
||||||
*}
|
|
||||||
{/if}
|
|
||||||
{/foreach}
|
|
||||||
{/function}
|
|
||||||
{/if}
|
|
||||||
</body>
|
|
||||||
<!-- R.O. -->
|
|
||||||
</html>
|
|
||||||
</textarea></form>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("code"), {
|
|
||||||
mode : "smartymixed",
|
|
||||||
tabSize : 2,
|
|
||||||
indentUnit : 2,
|
|
||||||
indentWithTabs : false,
|
|
||||||
lineNumbers : true,
|
|
||||||
smartyVersion : 3,
|
|
||||||
matchBrackets : true,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<p>The Smarty mixed mode depends on the Smarty and HTML mixed modes. HTML
|
|
||||||
mixed mode itself depends on XML, JavaScript, and CSS modes.</p>
|
|
||||||
|
|
||||||
<p>It takes the same options, as Smarty and HTML mixed modes.</p>
|
|
||||||
|
|
||||||
<p><strong>MIME types defined:</strong> <code>text/x-smarty</code>.</p>
|
|
||||||
</article>
|
|
|
@ -1,197 +0,0 @@
|
||||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
||||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file smartymixed.js
|
|
||||||
* @brief Smarty Mixed Codemirror mode (Smarty + Mixed HTML)
|
|
||||||
* @author Ruslan Osmanov <rrosmanov at gmail dot com>
|
|
||||||
* @version 3.0
|
|
||||||
* @date 05.07.2013
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Warning: Don't base other modes on this one. This here is a
|
|
||||||
// terrible way to write a mixed mode.
|
|
||||||
|
|
||||||
(function(mod) {
|
|
||||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
||||||
mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../smarty/smarty"));
|
|
||||||
else if (typeof define == "function" && define.amd) // AMD
|
|
||||||
define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../smarty/smarty"], mod);
|
|
||||||
else // Plain browser env
|
|
||||||
mod(CodeMirror);
|
|
||||||
})(function(CodeMirror) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
CodeMirror.defineMode("smartymixed", function(config) {
|
|
||||||
var htmlMixedMode = CodeMirror.getMode(config, "htmlmixed");
|
|
||||||
var smartyMode = CodeMirror.getMode(config, "smarty");
|
|
||||||
|
|
||||||
var settings = {
|
|
||||||
rightDelimiter: '}',
|
|
||||||
leftDelimiter: '{'
|
|
||||||
};
|
|
||||||
|
|
||||||
if (config.hasOwnProperty("leftDelimiter")) {
|
|
||||||
settings.leftDelimiter = config.leftDelimiter;
|
|
||||||
}
|
|
||||||
if (config.hasOwnProperty("rightDelimiter")) {
|
|
||||||
settings.rightDelimiter = config.rightDelimiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
function reEsc(str) { return str.replace(/[^\s\w]/g, "\\$&"); }
|
|
||||||
|
|
||||||
var reLeft = reEsc(settings.leftDelimiter), reRight = reEsc(settings.rightDelimiter);
|
|
||||||
var regs = {
|
|
||||||
smartyComment: new RegExp("^" + reRight + "\\*"),
|
|
||||||
literalOpen: new RegExp(reLeft + "literal" + reRight),
|
|
||||||
literalClose: new RegExp(reLeft + "\/literal" + reRight),
|
|
||||||
hasLeftDelimeter: new RegExp(".*" + reLeft),
|
|
||||||
htmlHasLeftDelimeter: new RegExp("[^<>]*" + reLeft)
|
|
||||||
};
|
|
||||||
|
|
||||||
var helpers = {
|
|
||||||
chain: function(stream, state, parser) {
|
|
||||||
state.tokenize = parser;
|
|
||||||
return parser(stream, state);
|
|
||||||
},
|
|
||||||
|
|
||||||
cleanChain: function(stream, state, parser) {
|
|
||||||
state.tokenize = null;
|
|
||||||
state.localState = null;
|
|
||||||
state.localMode = null;
|
|
||||||
return (typeof parser == "string") ? (parser ? parser : null) : parser(stream, state);
|
|
||||||
},
|
|
||||||
|
|
||||||
maybeBackup: function(stream, pat, style) {
|
|
||||||
var cur = stream.current();
|
|
||||||
var close = cur.search(pat),
|
|
||||||
m;
|
|
||||||
if (close > - 1) stream.backUp(cur.length - close);
|
|
||||||
else if (m = cur.match(/<\/?$/)) {
|
|
||||||
stream.backUp(cur.length);
|
|
||||||
if (!stream.match(pat, false)) stream.match(cur[0]);
|
|
||||||
}
|
|
||||||
return style;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var parsers = {
|
|
||||||
html: function(stream, state) {
|
|
||||||
var htmlTagName = state.htmlMixedState.htmlState.context && state.htmlMixedState.htmlState.context.tagName
|
|
||||||
? state.htmlMixedState.htmlState.context.tagName
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (!state.inLiteral && stream.match(regs.htmlHasLeftDelimeter, false) && htmlTagName === null) {
|
|
||||||
state.tokenize = parsers.smarty;
|
|
||||||
state.localMode = smartyMode;
|
|
||||||
state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
|
|
||||||
return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState));
|
|
||||||
} else if (!state.inLiteral && stream.match(settings.leftDelimiter, false)) {
|
|
||||||
state.tokenize = parsers.smarty;
|
|
||||||
state.localMode = smartyMode;
|
|
||||||
state.localState = smartyMode.startState(htmlMixedMode.indent(state.htmlMixedState, ""));
|
|
||||||
return helpers.maybeBackup(stream, settings.leftDelimiter, smartyMode.token(stream, state.localState));
|
|
||||||
}
|
|
||||||
return htmlMixedMode.token(stream, state.htmlMixedState);
|
|
||||||
},
|
|
||||||
|
|
||||||
smarty: function(stream, state) {
|
|
||||||
if (stream.match(settings.leftDelimiter, false)) {
|
|
||||||
if (stream.match(regs.smartyComment, false)) {
|
|
||||||
return helpers.chain(stream, state, parsers.inBlock("comment", "*" + settings.rightDelimiter));
|
|
||||||
}
|
|
||||||
} else if (stream.match(settings.rightDelimiter, false)) {
|
|
||||||
stream.eat(settings.rightDelimiter);
|
|
||||||
state.tokenize = parsers.html;
|
|
||||||
state.localMode = htmlMixedMode;
|
|
||||||
state.localState = state.htmlMixedState;
|
|
||||||
return "tag";
|
|
||||||
}
|
|
||||||
|
|
||||||
return helpers.maybeBackup(stream, settings.rightDelimiter, smartyMode.token(stream, state.localState));
|
|
||||||
},
|
|
||||||
|
|
||||||
inBlock: function(style, terminator) {
|
|
||||||
return function(stream, state) {
|
|
||||||
while (!stream.eol()) {
|
|
||||||
if (stream.match(terminator)) {
|
|
||||||
helpers.cleanChain(stream, state, "");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
stream.next();
|
|
||||||
}
|
|
||||||
return style;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
startState: function() {
|
|
||||||
var state = htmlMixedMode.startState();
|
|
||||||
return {
|
|
||||||
token: parsers.html,
|
|
||||||
localMode: null,
|
|
||||||
localState: null,
|
|
||||||
htmlMixedState: state,
|
|
||||||
tokenize: null,
|
|
||||||
inLiteral: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
copyState: function(state) {
|
|
||||||
var local = null, tok = (state.tokenize || state.token);
|
|
||||||
if (state.localState) {
|
|
||||||
local = CodeMirror.copyState((tok != parsers.html ? smartyMode : htmlMixedMode), state.localState);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
token: state.token,
|
|
||||||
tokenize: state.tokenize,
|
|
||||||
localMode: state.localMode,
|
|
||||||
localState: local,
|
|
||||||
htmlMixedState: CodeMirror.copyState(htmlMixedMode, state.htmlMixedState),
|
|
||||||
inLiteral: state.inLiteral
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
token: function(stream, state) {
|
|
||||||
if (stream.match(settings.leftDelimiter, false)) {
|
|
||||||
if (!state.inLiteral && stream.match(regs.literalOpen, true)) {
|
|
||||||
state.inLiteral = true;
|
|
||||||
return "keyword";
|
|
||||||
} else if (state.inLiteral && stream.match(regs.literalClose, true)) {
|
|
||||||
state.inLiteral = false;
|
|
||||||
return "keyword";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (state.inLiteral && state.localState != state.htmlMixedState) {
|
|
||||||
state.tokenize = parsers.html;
|
|
||||||
state.localMode = htmlMixedMode;
|
|
||||||
state.localState = state.htmlMixedState;
|
|
||||||
}
|
|
||||||
|
|
||||||
var style = (state.tokenize || state.token)(stream, state);
|
|
||||||
return style;
|
|
||||||
},
|
|
||||||
|
|
||||||
indent: function(state, textAfter) {
|
|
||||||
if (state.localMode == smartyMode
|
|
||||||
|| (state.inLiteral && !state.localMode)
|
|
||||||
|| regs.hasLeftDelimeter.test(textAfter)) {
|
|
||||||
return CodeMirror.Pass;
|
|
||||||
}
|
|
||||||
return htmlMixedMode.indent(state.htmlMixedState, textAfter);
|
|
||||||
},
|
|
||||||
|
|
||||||
innerMode: function(state) {
|
|
||||||
return {
|
|
||||||
state: state.localState || state.htmlMixedState,
|
|
||||||
mode: state.localMode || htmlMixedMode
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, "htmlmixed", "smarty");
|
|
||||||
|
|
||||||
CodeMirror.defineMIME("text/x-smarty", "smartymixed");
|
|
||||||
// vim: et ts=2 sts=2 sw=2
|
|
||||||
|
|
||||||
});
|
|
|
@ -58,8 +58,10 @@
|
||||||
if (inp) {
|
if (inp) {
|
||||||
if (options.value) {
|
if (options.value) {
|
||||||
inp.value = options.value;
|
inp.value = options.value;
|
||||||
|
if (options.selectValueOnOpen !== false) {
|
||||||
inp.select();
|
inp.select();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.onInput)
|
if (options.onInput)
|
||||||
CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
|
CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
|
|
@ -0,0 +1,184 @@
|
||||||
|
// 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) {
|
||||||
|
var defaults = {
|
||||||
|
pairs: "()[]{}''\"\"",
|
||||||
|
triples: "",
|
||||||
|
explode: "[]{}"
|
||||||
|
};
|
||||||
|
|
||||||
|
var Pos = CodeMirror.Pos;
|
||||||
|
|
||||||
|
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
|
||||||
|
if (old && old != CodeMirror.Init) {
|
||||||
|
cm.removeKeyMap(keyMap);
|
||||||
|
cm.state.closeBrackets = null;
|
||||||
|
}
|
||||||
|
if (val) {
|
||||||
|
cm.state.closeBrackets = val;
|
||||||
|
cm.addKeyMap(keyMap);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function getOption(conf, name) {
|
||||||
|
if (name == "pairs" && typeof conf == "string") return conf;
|
||||||
|
if (typeof conf == "object" && conf[name] != null) return conf[name];
|
||||||
|
return defaults[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
var bind = defaults.pairs + "`";
|
||||||
|
var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
|
||||||
|
for (var i = 0; i < bind.length; i++)
|
||||||
|
keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i));
|
||||||
|
|
||||||
|
function handler(ch) {
|
||||||
|
return function(cm) { return handleChar(cm, ch); };
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConfig(cm) {
|
||||||
|
var deflt = cm.state.closeBrackets;
|
||||||
|
if (!deflt) return null;
|
||||||
|
var mode = cm.getModeAt(cm.getCursor());
|
||||||
|
return mode.closeBrackets || deflt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleBackspace(cm) {
|
||||||
|
var conf = getConfig(cm);
|
||||||
|
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||||
|
|
||||||
|
var pairs = getOption(conf, "pairs");
|
||||||
|
var ranges = cm.listSelections();
|
||||||
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
|
if (!ranges[i].empty()) return CodeMirror.Pass;
|
||||||
|
var around = charsAround(cm, ranges[i].head);
|
||||||
|
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
|
||||||
|
}
|
||||||
|
for (var i = ranges.length - 1; i >= 0; i--) {
|
||||||
|
var cur = ranges[i].head;
|
||||||
|
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEnter(cm) {
|
||||||
|
var conf = getConfig(cm);
|
||||||
|
var explode = conf && getOption(conf, "explode");
|
||||||
|
if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||||
|
|
||||||
|
var ranges = cm.listSelections();
|
||||||
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
|
if (!ranges[i].empty()) return CodeMirror.Pass;
|
||||||
|
var around = charsAround(cm, ranges[i].head);
|
||||||
|
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
|
||||||
|
}
|
||||||
|
cm.operation(function() {
|
||||||
|
cm.replaceSelection("\n\n", null);
|
||||||
|
cm.execCommand("goCharLeft");
|
||||||
|
ranges = cm.listSelections();
|
||||||
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
|
var line = ranges[i].head.line;
|
||||||
|
cm.indentLine(line, null, true);
|
||||||
|
cm.indentLine(line + 1, null, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleChar(cm, ch) {
|
||||||
|
var conf = getConfig(cm);
|
||||||
|
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||||
|
|
||||||
|
var pairs = getOption(conf, "pairs");
|
||||||
|
var pos = pairs.indexOf(ch);
|
||||||
|
if (pos == -1) return CodeMirror.Pass;
|
||||||
|
var triples = getOption(conf, "triples");
|
||||||
|
|
||||||
|
var identical = pairs.charAt(pos + 1) == ch;
|
||||||
|
var ranges = cm.listSelections();
|
||||||
|
var opening = pos % 2 == 0;
|
||||||
|
|
||||||
|
var type, next;
|
||||||
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
|
var range = ranges[i], cur = range.head, curType;
|
||||||
|
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
|
||||||
|
if (opening && !range.empty()) {
|
||||||
|
curType = "surround";
|
||||||
|
} else if ((identical || !opening) && next == ch) {
|
||||||
|
if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
|
||||||
|
curType = "skipThree";
|
||||||
|
else
|
||||||
|
curType = "skip";
|
||||||
|
} else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
|
||||||
|
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch &&
|
||||||
|
(cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) {
|
||||||
|
curType = "addFour";
|
||||||
|
} else if (identical) {
|
||||||
|
if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both";
|
||||||
|
else return CodeMirror.Pass;
|
||||||
|
} else if (opening && (cm.getLine(cur.line).length == cur.ch ||
|
||||||
|
isClosingBracket(next, pairs) ||
|
||||||
|
/\s/.test(next))) {
|
||||||
|
curType = "both";
|
||||||
|
} else {
|
||||||
|
return CodeMirror.Pass;
|
||||||
|
}
|
||||||
|
if (!type) type = curType;
|
||||||
|
else if (type != curType) return CodeMirror.Pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
|
||||||
|
var right = pos % 2 ? ch : pairs.charAt(pos + 1);
|
||||||
|
cm.operation(function() {
|
||||||
|
if (type == "skip") {
|
||||||
|
cm.execCommand("goCharRight");
|
||||||
|
} else if (type == "skipThree") {
|
||||||
|
for (var i = 0; i < 3; i++)
|
||||||
|
cm.execCommand("goCharRight");
|
||||||
|
} else if (type == "surround") {
|
||||||
|
var sels = cm.getSelections();
|
||||||
|
for (var i = 0; i < sels.length; i++)
|
||||||
|
sels[i] = left + sels[i] + right;
|
||||||
|
cm.replaceSelections(sels, "around");
|
||||||
|
} else if (type == "both") {
|
||||||
|
cm.replaceSelection(left + right, null);
|
||||||
|
cm.execCommand("goCharLeft");
|
||||||
|
} else if (type == "addFour") {
|
||||||
|
cm.replaceSelection(left + left + left + left, "before");
|
||||||
|
cm.execCommand("goCharRight");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function isClosingBracket(ch, pairs) {
|
||||||
|
var pos = pairs.lastIndexOf(ch);
|
||||||
|
return pos > -1 && pos % 2 == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function charsAround(cm, pos) {
|
||||||
|
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
|
||||||
|
Pos(pos.line, pos.ch + 1));
|
||||||
|
return str.length == 2 ? str : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Project the token type that will exists after the given char is
|
||||||
|
// typed, and use it to determine whether it would cause the start
|
||||||
|
// of a string token.
|
||||||
|
function enteringString(cm, pos, ch) {
|
||||||
|
var line = cm.getLine(pos.line);
|
||||||
|
var token = cm.getTokenAt(pos);
|
||||||
|
if (/\bstring2?\b/.test(token.type)) return false;
|
||||||
|
var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4);
|
||||||
|
stream.pos = stream.start = token.start;
|
||||||
|
for (;;) {
|
||||||
|
var type1 = cm.getMode().token(stream, token.state);
|
||||||
|
if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1);
|
||||||
|
stream.start = stream.pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -94,15 +94,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function autoCloseSlash(cm) {
|
function autoCloseCurrent(cm, typingSlash) {
|
||||||
if (cm.getOption("disableInput")) return CodeMirror.Pass;
|
|
||||||
var ranges = cm.listSelections(), replacements = [];
|
var ranges = cm.listSelections(), replacements = [];
|
||||||
|
var head = typingSlash ? "/" : "</";
|
||||||
for (var i = 0; i < ranges.length; i++) {
|
for (var i = 0; i < ranges.length; i++) {
|
||||||
if (!ranges[i].empty()) return CodeMirror.Pass;
|
if (!ranges[i].empty()) return CodeMirror.Pass;
|
||||||
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
|
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
|
||||||
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
|
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
|
||||||
if (tok.type == "string" || tok.string.charAt(0) != "<" ||
|
if (typingSlash && (tok.type == "string" || tok.string.charAt(0) != "<" ||
|
||||||
tok.start != pos.ch - 1)
|
tok.start != pos.ch - 1))
|
||||||
return CodeMirror.Pass;
|
return CodeMirror.Pass;
|
||||||
// Kludge to get around the fact that we are not in XML mode
|
// Kludge to get around the fact that we are not in XML mode
|
||||||
// when completing in JS/CSS snippet in htmlmixed mode. Does not
|
// when completing in JS/CSS snippet in htmlmixed mode. Does not
|
||||||
|
@ -110,16 +110,16 @@
|
||||||
// way to go from a mixed mode to its current XML state).
|
// way to go from a mixed mode to its current XML state).
|
||||||
if (inner.mode.name != "xml") {
|
if (inner.mode.name != "xml") {
|
||||||
if (cm.getMode().name == "htmlmixed" && inner.mode.name == "javascript")
|
if (cm.getMode().name == "htmlmixed" && inner.mode.name == "javascript")
|
||||||
replacements[i] = "/script>";
|
replacements[i] = head + "script>";
|
||||||
else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css")
|
else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css")
|
||||||
replacements[i] = "/style>";
|
replacements[i] = head + "style>";
|
||||||
else
|
else
|
||||||
return CodeMirror.Pass;
|
return CodeMirror.Pass;
|
||||||
} else {
|
} else {
|
||||||
if (!state.context || !state.context.tagName ||
|
if (!state.context || !state.context.tagName ||
|
||||||
closingTagExists(cm, state.context.tagName, pos, state))
|
closingTagExists(cm, state.context.tagName, pos, state))
|
||||||
return CodeMirror.Pass;
|
return CodeMirror.Pass;
|
||||||
replacements[i] = "/" + state.context.tagName + ">";
|
replacements[i] = head + state.context.tagName + ">";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cm.replaceSelections(replacements);
|
cm.replaceSelections(replacements);
|
||||||
|
@ -129,6 +129,13 @@
|
||||||
cm.indentLine(ranges[i].head.line);
|
cm.indentLine(ranges[i].head.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function autoCloseSlash(cm) {
|
||||||
|
if (cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||||
|
return autoCloseCurrent(cm, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };
|
||||||
|
|
||||||
function indexOf(collection, elt) {
|
function indexOf(collection, elt) {
|
||||||
if (collection.indexOf) return collection.indexOf(elt);
|
if (collection.indexOf) return collection.indexOf(elt);
|
||||||
for (var i = 0, e = collection.length; i < e; ++i)
|
for (var i = 0, e = collection.length; i < e; ++i)
|
|
@ -81,7 +81,7 @@
|
||||||
if (marks.length) {
|
if (marks.length) {
|
||||||
// Kludge to work around the IE bug from issue #1193, where text
|
// Kludge to work around the IE bug from issue #1193, where text
|
||||||
// input stops going to the textare whever this fires.
|
// input stops going to the textare whever this fires.
|
||||||
if (ie_lt8 && cm.state.focused) cm.display.input.focus();
|
if (ie_lt8 && cm.state.focused) cm.focus();
|
||||||
|
|
||||||
var clear = function() {
|
var clear = function() {
|
||||||
cm.operation(function() {
|
cm.operation(function() {
|
|
@ -142,4 +142,8 @@
|
||||||
return editorOptions[name];
|
return editorOptions[name];
|
||||||
return defaultOptions[name];
|
return defaultOptions[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CodeMirror.defineExtension("foldOption", function(options, name) {
|
||||||
|
return getOption(this, options, name);
|
||||||
|
});
|
||||||
});
|
});
|
|
@ -52,7 +52,7 @@
|
||||||
function isFolded(cm, line) {
|
function isFolded(cm, line) {
|
||||||
var marks = cm.findMarksAt(Pos(line));
|
var marks = cm.findMarksAt(Pos(line));
|
||||||
for (var i = 0; i < marks.length; ++i)
|
for (var i = 0; i < marks.length; ++i)
|
||||||
if (marks[i].__isFold && marks[i].find().from.line == line) return true;
|
if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
function marker(spec) {
|
function marker(spec) {
|
||||||
|
@ -67,14 +67,16 @@
|
||||||
|
|
||||||
function updateFoldInfo(cm, from, to) {
|
function updateFoldInfo(cm, from, to) {
|
||||||
var opts = cm.state.foldGutter.options, cur = from;
|
var opts = cm.state.foldGutter.options, cur = from;
|
||||||
|
var minSize = cm.foldOption(opts, "minFoldSize");
|
||||||
|
var func = cm.foldOption(opts, "rangeFinder");
|
||||||
cm.eachLine(from, to, function(line) {
|
cm.eachLine(from, to, function(line) {
|
||||||
var mark = null;
|
var mark = null;
|
||||||
if (isFolded(cm, cur)) {
|
if (isFolded(cm, cur)) {
|
||||||
mark = marker(opts.indicatorFolded);
|
mark = marker(opts.indicatorFolded);
|
||||||
} else {
|
} else {
|
||||||
var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto;
|
var pos = Pos(cur, 0);
|
||||||
var range = func && func(cm, pos);
|
var range = func && func(cm, pos);
|
||||||
if (range && range.from.line + 1 < range.to.line)
|
if (range && range.to.line - range.from.line >= minSize)
|
||||||
mark = marker(opts.indicatorOpen);
|
mark = marker(opts.indicatorOpen);
|
||||||
}
|
}
|
||||||
cm.setGutterMarker(line, opts.gutter, mark);
|
cm.setGutterMarker(line, opts.gutter, mark);
|
||||||
|
@ -92,20 +94,28 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function onGutterClick(cm, line, gutter) {
|
function onGutterClick(cm, line, gutter) {
|
||||||
var opts = cm.state.foldGutter.options;
|
var state = cm.state.foldGutter;
|
||||||
|
if (!state) return;
|
||||||
|
var opts = state.options;
|
||||||
if (gutter != opts.gutter) return;
|
if (gutter != opts.gutter) return;
|
||||||
cm.foldCode(Pos(line, 0), opts.rangeFinder);
|
var folded = isFolded(cm, line);
|
||||||
|
if (folded) folded.clear();
|
||||||
|
else cm.foldCode(Pos(line, 0), opts.rangeFinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChange(cm) {
|
function onChange(cm) {
|
||||||
var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
|
var state = cm.state.foldGutter;
|
||||||
|
if (!state) return;
|
||||||
|
var opts = state.options;
|
||||||
state.from = state.to = 0;
|
state.from = state.to = 0;
|
||||||
clearTimeout(state.changeUpdate);
|
clearTimeout(state.changeUpdate);
|
||||||
state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
|
state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onViewportChange(cm) {
|
function onViewportChange(cm) {
|
||||||
var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
|
var state = cm.state.foldGutter;
|
||||||
|
if (!state) return;
|
||||||
|
var opts = state.options;
|
||||||
clearTimeout(state.changeUpdate);
|
clearTimeout(state.changeUpdate);
|
||||||
state.changeUpdate = setTimeout(function() {
|
state.changeUpdate = setTimeout(function() {
|
||||||
var vp = cm.getViewport();
|
var vp = cm.getViewport();
|
||||||
|
@ -127,7 +137,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFold(cm, from) {
|
function onFold(cm, from) {
|
||||||
var state = cm.state.foldGutter, line = from.line;
|
var state = cm.state.foldGutter;
|
||||||
|
if (!state) return;
|
||||||
|
var line = from.line;
|
||||||
if (line >= state.from && line < state.to)
|
if (line >= state.from && line < state.to)
|
||||||
updateFoldInfo(cm, line, line + 1);
|
updateFoldInfo(cm, line, line + 1);
|
||||||
}
|
}
|
|
@ -20,6 +20,10 @@
|
||||||
var inner = CodeMirror.innerMode(cm.getMode(), token.state);
|
var inner = CodeMirror.innerMode(cm.getMode(), token.state);
|
||||||
if (inner.mode.name != "css") return;
|
if (inner.mode.name != "css") return;
|
||||||
|
|
||||||
|
if (token.type == "keyword" && "!important".indexOf(token.string) == 0)
|
||||||
|
return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start),
|
||||||
|
to: CodeMirror.Pos(cur.line, token.end)};
|
||||||
|
|
||||||
var start = token.start, end = cur.ch, word = token.string.slice(0, end - start);
|
var start = token.start, end = cur.ch, word = token.string.slice(0, end - start);
|
||||||
if (/[^\w$_-]/.test(word)) {
|
if (/[^\w$_-]/.test(word)) {
|
||||||
word = ""; start = end = cur.ch;
|
word = ""; start = end = cur.ch;
|
|
@ -24,6 +24,18 @@
|
||||||
return cm.showHint(newOpts);
|
return cm.showHint(newOpts);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var asyncRunID = 0;
|
||||||
|
function retrieveHints(getter, cm, options, then) {
|
||||||
|
if (getter.async) {
|
||||||
|
var id = ++asyncRunID;
|
||||||
|
getter(cm, function(hints) {
|
||||||
|
if (asyncRunID == id) then(hints);
|
||||||
|
}, options);
|
||||||
|
} else {
|
||||||
|
then(getter(cm, options));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CodeMirror.defineExtension("showHint", function(options) {
|
CodeMirror.defineExtension("showHint", function(options) {
|
||||||
// We want a single cursor position.
|
// We want a single cursor position.
|
||||||
if (this.listSelections().length > 1 || this.somethingSelected()) return;
|
if (this.listSelections().length > 1 || this.somethingSelected()) return;
|
||||||
|
@ -34,10 +46,7 @@
|
||||||
if (!getHints) return;
|
if (!getHints) return;
|
||||||
|
|
||||||
CodeMirror.signal(this, "startCompletion", this);
|
CodeMirror.signal(this, "startCompletion", this);
|
||||||
if (getHints.async)
|
return retrieveHints(getHints, this, completion.options, function(hints) { completion.showHints(hints); });
|
||||||
getHints(this, function(hints) { completion.showHints(hints); }, completion.options);
|
|
||||||
else
|
|
||||||
return completion.showHints(getHints(this, completion.options));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function Completion(cm, options) {
|
function Completion(cm, options) {
|
||||||
|
@ -102,11 +111,7 @@
|
||||||
function update() {
|
function update() {
|
||||||
if (finished) return;
|
if (finished) return;
|
||||||
CodeMirror.signal(data, "update");
|
CodeMirror.signal(data, "update");
|
||||||
var getHints = completion.options.hint;
|
retrieveHints(completion.options.hint, completion.cm, completion.options, finishUpdate);
|
||||||
if (getHints.async)
|
|
||||||
getHints(completion.cm, finishUpdate, completion.options);
|
|
||||||
else
|
|
||||||
finishUpdate(getHints(completion.cm, completion.options));
|
|
||||||
}
|
}
|
||||||
function finishUpdate(data_) {
|
function finishUpdate(data_) {
|
||||||
data = data_;
|
data = data_;
|
|
@ -26,71 +26,113 @@
|
||||||
return CodeMirror.resolveMode(mode).keywords;
|
return CodeMirror.resolveMode(mode).keywords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getText(item) {
|
||||||
|
return typeof item == "string" ? item : item.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItem(list, item) {
|
||||||
|
if (!list.slice) return list[item];
|
||||||
|
for (var i = list.length - 1; i >= 0; i--) if (getText(list[i]) == item)
|
||||||
|
return list[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
function shallowClone(object) {
|
||||||
|
var result = {};
|
||||||
|
for (var key in object) if (object.hasOwnProperty(key))
|
||||||
|
result[key] = object[key];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
function match(string, word) {
|
function match(string, word) {
|
||||||
var len = string.length;
|
var len = string.length;
|
||||||
var sub = word.substr(0, len);
|
var sub = getText(word).substr(0, len);
|
||||||
return string.toUpperCase() === sub.toUpperCase();
|
return string.toUpperCase() === sub.toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addMatches(result, search, wordlist, formatter) {
|
function addMatches(result, search, wordlist, formatter) {
|
||||||
for (var word in wordlist) {
|
for (var word in wordlist) {
|
||||||
if (!wordlist.hasOwnProperty(word)) continue;
|
if (!wordlist.hasOwnProperty(word)) continue;
|
||||||
if (Array.isArray(wordlist)) {
|
if (wordlist.slice) word = wordlist[word];
|
||||||
word = wordlist[word];
|
|
||||||
}
|
if (match(search, word)) result.push(formatter(word));
|
||||||
if (match(search, word)) {
|
|
||||||
result.push(formatter(word));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cleanName(name) {
|
||||||
|
// Get rid name from backticks(`) and preceding dot(.)
|
||||||
|
if (name.charAt(0) == ".") {
|
||||||
|
name = name.substr(1);
|
||||||
|
}
|
||||||
|
return name.replace(/`/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertBackticks(name) {
|
||||||
|
var nameParts = getText(name).split(".");
|
||||||
|
for (var i = 0; i < nameParts.length; i++)
|
||||||
|
nameParts[i] = "`" + nameParts[i] + "`";
|
||||||
|
var escaped = nameParts.join(".");
|
||||||
|
if (typeof name == "string") return escaped;
|
||||||
|
name = shallowClone(name);
|
||||||
|
name.text = escaped;
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function nameCompletion(cur, token, result, editor) {
|
function nameCompletion(cur, token, result, editor) {
|
||||||
var useBacktick = (token.string.charAt(0) == "`");
|
// Try to complete table, colunm names and return start position of completion
|
||||||
var string = token.string.substr(1);
|
var useBacktick = false;
|
||||||
var prevToken = editor.getTokenAt(Pos(cur.line, token.start));
|
var nameParts = [];
|
||||||
if (token.string.charAt(0) == "." || prevToken.string == "."){
|
var start = token.start;
|
||||||
//Suggest colunm names
|
var cont = true;
|
||||||
if (prevToken.string == ".") {
|
while (cont) {
|
||||||
var prevToken = editor.getTokenAt(Pos(cur.line, token.start - 1));
|
cont = (token.string.charAt(0) == ".");
|
||||||
}
|
useBacktick = useBacktick || (token.string.charAt(0) == "`");
|
||||||
var table = prevToken.string;
|
|
||||||
//Check if backtick is used in table name. If yes, use it for columns too.
|
|
||||||
var useBacktickTable = false;
|
|
||||||
if (table.match(/`/g)) {
|
|
||||||
useBacktickTable = true;
|
|
||||||
table = table.replace(/`/g, "");
|
|
||||||
}
|
|
||||||
//Check if table is available. If not, find table by Alias
|
|
||||||
if (!tables.hasOwnProperty(table))
|
|
||||||
table = findTableByAlias(table, editor);
|
|
||||||
var columns = tables[table];
|
|
||||||
if (!columns) return;
|
|
||||||
|
|
||||||
if (useBacktick) {
|
start = token.start;
|
||||||
addMatches(result, string, columns, function(w) {return "`" + w + "`";});
|
nameParts.unshift(cleanName(token.string));
|
||||||
}
|
|
||||||
else if(useBacktickTable) {
|
token = editor.getTokenAt(Pos(cur.line, token.start));
|
||||||
addMatches(result, string, columns, function(w) {return ".`" + w + "`";});
|
if (token.string == ".") {
|
||||||
}
|
cont = true;
|
||||||
else {
|
token = editor.getTokenAt(Pos(cur.line, token.start));
|
||||||
addMatches(result, string, columns, function(w) {return "." + w;});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
//Suggest table names or colums in defaultTable
|
// Try to complete table names
|
||||||
while (token.start && string.charAt(0) == ".") {
|
var string = nameParts.join(".");
|
||||||
token = editor.getTokenAt(Pos(cur.line, token.start - 1));
|
addMatches(result, string, tables, function(w) {
|
||||||
string = token.string + string;
|
return useBacktick ? insertBackticks(w) : w;
|
||||||
}
|
});
|
||||||
if (useBacktick) {
|
|
||||||
addMatches(result, string, tables, function(w) {return "`" + w + "`";});
|
// Try to complete columns from defaultTable
|
||||||
addMatches(result, string, defaultTable, function(w) {return "`" + w + "`";});
|
addMatches(result, string, defaultTable, function(w) {
|
||||||
}
|
return useBacktick ? insertBackticks(w) : w;
|
||||||
else {
|
});
|
||||||
addMatches(result, string, tables, function(w) {return w;});
|
|
||||||
addMatches(result, string, defaultTable, function(w) {return w;});
|
// Try to complete columns
|
||||||
|
string = nameParts.pop();
|
||||||
|
var table = nameParts.join(".");
|
||||||
|
|
||||||
|
// Check if table is available. If not, find table by Alias
|
||||||
|
if (!getItem(tables, table))
|
||||||
|
table = findTableByAlias(table, editor);
|
||||||
|
|
||||||
|
var columns = getItem(tables, table);
|
||||||
|
if (columns && columns.columns)
|
||||||
|
columns = columns.columns;
|
||||||
|
|
||||||
|
if (columns) {
|
||||||
|
addMatches(result, string, columns, function(w) {
|
||||||
|
if (typeof w == "string") {
|
||||||
|
w = table + "." + w;
|
||||||
|
} else {
|
||||||
|
w = shallowClone(w);
|
||||||
|
w.text = table + "." + w.text;
|
||||||
}
|
}
|
||||||
|
return useBacktick ? insertBackticks(w) : w;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
function eachWord(lineText, f) {
|
function eachWord(lineText, f) {
|
||||||
|
@ -150,12 +192,10 @@
|
||||||
var lineText = query[i];
|
var lineText = query[i];
|
||||||
eachWord(lineText, function(word) {
|
eachWord(lineText, function(word) {
|
||||||
var wordUpperCase = word.toUpperCase();
|
var wordUpperCase = word.toUpperCase();
|
||||||
if (wordUpperCase === aliasUpperCase && tables.hasOwnProperty(previousWord)) {
|
if (wordUpperCase === aliasUpperCase && getItem(tables, previousWord))
|
||||||
table = previousWord;
|
table = previousWord;
|
||||||
}
|
if (wordUpperCase !== CONS.ALIAS_KEYWORD)
|
||||||
if (wordUpperCase !== CONS.ALIAS_KEYWORD) {
|
|
||||||
previousWord = word;
|
previousWord = word;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (table) break;
|
if (table) break;
|
||||||
}
|
}
|
||||||
|
@ -165,9 +205,17 @@
|
||||||
CodeMirror.registerHelper("hint", "sql", function(editor, options) {
|
CodeMirror.registerHelper("hint", "sql", function(editor, options) {
|
||||||
tables = (options && options.tables) || {};
|
tables = (options && options.tables) || {};
|
||||||
var defaultTableName = options && options.defaultTable;
|
var defaultTableName = options && options.defaultTable;
|
||||||
defaultTable = (defaultTableName && tables[defaultTableName] || []);
|
defaultTable = defaultTableName && getItem(tables, defaultTableName);
|
||||||
keywords = keywords || getKeywords(editor);
|
keywords = keywords || getKeywords(editor);
|
||||||
|
|
||||||
|
if (defaultTableName && !defaultTable)
|
||||||
|
defaultTable = findTableByAlias(defaultTableName, editor);
|
||||||
|
|
||||||
|
defaultTable = defaultTable || [];
|
||||||
|
|
||||||
|
if (defaultTable.columns)
|
||||||
|
defaultTable = defaultTable.columns;
|
||||||
|
|
||||||
var cur = editor.getCursor();
|
var cur = editor.getCursor();
|
||||||
var result = [];
|
var result = [];
|
||||||
var token = editor.getTokenAt(cur), start, end, search;
|
var token = editor.getTokenAt(cur), start, end, search;
|
||||||
|
@ -185,7 +233,7 @@
|
||||||
search = "";
|
search = "";
|
||||||
}
|
}
|
||||||
if (search.charAt(0) == "." || search.charAt(0) == "`") {
|
if (search.charAt(0) == "." || search.charAt(0) == "`") {
|
||||||
nameCompletion(cur, token, result, editor);
|
start = nameCompletion(cur, token, result, editor);
|
||||||
} else {
|
} else {
|
||||||
addMatches(result, search, tables, function(w) {return w;});
|
addMatches(result, search, tables, function(w) {return w;});
|
||||||
addMatches(result, search, defaultTable, function(w) {return w;});
|
addMatches(result, search, defaultTable, function(w) {return w;});
|
|
@ -46,6 +46,7 @@
|
||||||
}
|
}
|
||||||
var poll = setInterval(function() {
|
var poll = setInterval(function() {
|
||||||
if (tooltip) for (var n = node;; n = n.parentNode) {
|
if (tooltip) for (var n = node;; n = n.parentNode) {
|
||||||
|
if (n && n.nodeType == 11) n = n.host;
|
||||||
if (n == document.body) return;
|
if (n == document.body) return;
|
||||||
if (!n) { hide(); break; }
|
if (!n) { hide(); break; }
|
||||||
}
|
}
|
||||||
|
@ -119,7 +120,7 @@
|
||||||
function startLinting(cm) {
|
function startLinting(cm) {
|
||||||
var state = cm.state.lint, options = state.options;
|
var state = cm.state.lint, options = state.options;
|
||||||
var passOptions = options.options || options; // Support deprecated passing of `options` property in options
|
var passOptions = options.options || options; // Support deprecated passing of `options` property in options
|
||||||
if (options.async)
|
if (options.async || options.getAnnotations.async)
|
||||||
options.getAnnotations(cm.getValue(), updateLinting, passOptions, cm);
|
options.getAnnotations(cm.getValue(), updateLinting, passOptions, cm);
|
||||||
else
|
else
|
||||||
updateLinting(cm, options.getAnnotations(cm.getValue(), passOptions, cm));
|
updateLinting(cm, options.getAnnotations(cm.getValue(), passOptions, cm));
|
||||||
|
@ -162,6 +163,7 @@
|
||||||
|
|
||||||
function onChange(cm) {
|
function onChange(cm) {
|
||||||
var state = cm.state.lint;
|
var state = cm.state.lint;
|
||||||
|
if (!state) return;
|
||||||
clearTimeout(state.timeout);
|
clearTimeout(state.timeout);
|
||||||
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
|
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
|
||||||
}
|
}
|
||||||
|
@ -187,6 +189,7 @@
|
||||||
clearMarks(cm);
|
clearMarks(cm);
|
||||||
cm.off("change", onChange);
|
cm.off("change", onChange);
|
||||||
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
|
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
|
||||||
|
clearTimeout(cm.state.lint.timeout);
|
||||||
delete cm.state.lint;
|
delete cm.state.lint;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,18 +31,19 @@
|
||||||
insert: "CodeMirror-merge-r-inserted",
|
insert: "CodeMirror-merge-r-inserted",
|
||||||
del: "CodeMirror-merge-r-deleted",
|
del: "CodeMirror-merge-r-deleted",
|
||||||
connect: "CodeMirror-merge-r-connect"};
|
connect: "CodeMirror-merge-r-connect"};
|
||||||
if (mv.options.connect == "align")
|
|
||||||
this.aligners = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DiffView.prototype = {
|
DiffView.prototype = {
|
||||||
constructor: DiffView,
|
constructor: DiffView,
|
||||||
init: function(pane, orig, options) {
|
init: function(pane, orig, options) {
|
||||||
this.edit = this.mv.edit;
|
this.edit = this.mv.edit;
|
||||||
|
(this.edit.state.diffViews || (this.edit.state.diffViews = [])).push(this);
|
||||||
this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: !this.mv.options.allowEditingOriginals}, copyObj(options)));
|
this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: !this.mv.options.allowEditingOriginals}, copyObj(options)));
|
||||||
|
this.orig.state.diffViews = [this];
|
||||||
|
|
||||||
this.diff = getDiff(asString(orig), asString(options.value));
|
this.diff = getDiff(asString(orig), asString(options.value));
|
||||||
this.diffOutOfDate = false;
|
this.chunks = getChunks(this.diff);
|
||||||
|
this.diffOutOfDate = this.dealigned = false;
|
||||||
|
|
||||||
this.showDifferences = options.showDifferences !== false;
|
this.showDifferences = options.showDifferences !== false;
|
||||||
this.forceUpdate = registerUpdate(this);
|
this.forceUpdate = registerUpdate(this);
|
||||||
|
@ -61,16 +62,20 @@
|
||||||
function ensureDiff(dv) {
|
function ensureDiff(dv) {
|
||||||
if (dv.diffOutOfDate) {
|
if (dv.diffOutOfDate) {
|
||||||
dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
|
dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue());
|
||||||
|
dv.chunks = getChunks(dv.diff);
|
||||||
dv.diffOutOfDate = false;
|
dv.diffOutOfDate = false;
|
||||||
CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
|
CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var updating = false;
|
||||||
function registerUpdate(dv) {
|
function registerUpdate(dv) {
|
||||||
var edit = {from: 0, to: 0, marked: []};
|
var edit = {from: 0, to: 0, marked: []};
|
||||||
var orig = {from: 0, to: 0, marked: []};
|
var orig = {from: 0, to: 0, marked: []};
|
||||||
var debounceChange;
|
var debounceChange, updatingFast = false;
|
||||||
function update(mode) {
|
function update(mode) {
|
||||||
|
updating = true;
|
||||||
|
updatingFast = false;
|
||||||
if (mode == "full") {
|
if (mode == "full") {
|
||||||
if (dv.svg) clear(dv.svg);
|
if (dv.svg) clear(dv.svg);
|
||||||
if (dv.copyButtons) clear(dv.copyButtons);
|
if (dv.copyButtons) clear(dv.copyButtons);
|
||||||
|
@ -84,26 +89,38 @@
|
||||||
updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
|
updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
|
||||||
}
|
}
|
||||||
makeConnections(dv);
|
makeConnections(dv);
|
||||||
|
|
||||||
|
if (dv.mv.options.connect == "align")
|
||||||
|
alignChunks(dv);
|
||||||
|
updating = false;
|
||||||
}
|
}
|
||||||
function set(slow) {
|
function setDealign(fast) {
|
||||||
|
if (updating) return;
|
||||||
|
dv.dealigned = true;
|
||||||
|
set(fast);
|
||||||
|
}
|
||||||
|
function set(fast) {
|
||||||
|
if (updating || updatingFast) return;
|
||||||
clearTimeout(debounceChange);
|
clearTimeout(debounceChange);
|
||||||
debounceChange = setTimeout(update, slow == true ? 250 : 100);
|
if (fast === true) updatingFast = true;
|
||||||
|
debounceChange = setTimeout(update, fast === true ? 20 : 250);
|
||||||
}
|
}
|
||||||
function change() {
|
function change(_cm, change) {
|
||||||
if (!dv.diffOutOfDate) {
|
if (!dv.diffOutOfDate) {
|
||||||
dv.diffOutOfDate = true;
|
dv.diffOutOfDate = true;
|
||||||
edit.from = edit.to = orig.from = orig.to = 0;
|
edit.from = edit.to = orig.from = orig.to = 0;
|
||||||
}
|
}
|
||||||
set(true);
|
// Update faster when a line was added/removed
|
||||||
|
setDealign(change.text.length - 1 != change.to.line - change.from.line);
|
||||||
}
|
}
|
||||||
dv.edit.on("change", change);
|
dv.edit.on("change", change);
|
||||||
dv.orig.on("change", change);
|
dv.orig.on("change", change);
|
||||||
dv.edit.on("markerAdded", set);
|
dv.edit.on("markerAdded", setDealign);
|
||||||
dv.edit.on("markerCleared", set);
|
dv.edit.on("markerCleared", setDealign);
|
||||||
dv.orig.on("markerAdded", set);
|
dv.orig.on("markerAdded", setDealign);
|
||||||
dv.orig.on("markerCleared", set);
|
dv.orig.on("markerCleared", setDealign);
|
||||||
dv.edit.on("viewportChange", set);
|
dv.edit.on("viewportChange", function() { set(false); });
|
||||||
dv.orig.on("viewportChange", set);
|
dv.orig.on("viewportChange", function() { set(false); });
|
||||||
update();
|
update();
|
||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
|
@ -134,7 +151,7 @@
|
||||||
} else {
|
} else {
|
||||||
var halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen;
|
var halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen;
|
||||||
var mid = editor.lineAtHeight(midY, "local");
|
var mid = editor.lineAtHeight(midY, "local");
|
||||||
var around = chunkBoundariesAround(dv.diff, mid, type == DIFF_INSERT);
|
var around = chunkBoundariesAround(dv.chunks, mid, type == DIFF_INSERT);
|
||||||
var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig);
|
var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig);
|
||||||
var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit);
|
var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit);
|
||||||
var ratio = (midY - off.top) / (off.bot - off.top);
|
var ratio = (midY - off.top) / (off.bot - off.top);
|
||||||
|
@ -259,17 +276,6 @@
|
||||||
function makeConnections(dv) {
|
function makeConnections(dv) {
|
||||||
if (!dv.showDifferences) return;
|
if (!dv.showDifferences) return;
|
||||||
|
|
||||||
var align = dv.mv.options.connect == "align";
|
|
||||||
if (align) {
|
|
||||||
if (!dv.orig.curOp) return dv.orig.operation(function() {
|
|
||||||
makeConnections(dv);
|
|
||||||
});
|
|
||||||
for (var i = 0; i < dv.aligners.length; i++)
|
|
||||||
dv.aligners[i].clear();
|
|
||||||
dv.aligners.length = 0;
|
|
||||||
var extraSpaceAbove = {edit: 0, orig: 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dv.svg) {
|
if (dv.svg) {
|
||||||
clear(dv.svg);
|
clear(dv.svg);
|
||||||
var w = dv.gap.offsetWidth;
|
var w = dv.gap.offsetWidth;
|
||||||
|
@ -279,32 +285,118 @@
|
||||||
|
|
||||||
var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport();
|
var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport();
|
||||||
var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top;
|
var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top;
|
||||||
iterateChunks(dv.diff, function(topOrig, botOrig, topEdit, botEdit) {
|
for (var i = 0; i < dv.chunks.length; i++) {
|
||||||
if (topEdit <= vpEdit.to && botEdit >= vpEdit.from &&
|
var ch = dv.chunks[i];
|
||||||
topOrig <= vpOrig.to && botOrig >= vpOrig.from)
|
if (ch.editFrom <= vpEdit.to && ch.editTo >= vpEdit.from &&
|
||||||
drawConnectorsForChunk(dv, topOrig, botOrig, topEdit, botEdit, sTopOrig, sTopEdit, w);
|
ch.origFrom <= vpOrig.to && ch.origTo >= vpOrig.from)
|
||||||
if (align && (topEdit <= vpEdit.to || topOrig <= vpOrig.to)) {
|
drawConnectorsForChunk(dv, ch, sTopOrig, sTopEdit, w);
|
||||||
var above = (botEdit < vpEdit.from && botOrig < vpOrig.from);
|
|
||||||
alignChunks(dv, topOrig, botOrig, topEdit, botEdit, above && extraSpaceAbove);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (align) {
|
|
||||||
if (extraSpaceAbove.edit)
|
|
||||||
dv.aligners.push(padBelow(dv.edit, 0, extraSpaceAbove.edit));
|
|
||||||
if (extraSpaceAbove.orig)
|
|
||||||
dv.aligners.push(padBelow(dv.orig, 0, extraSpaceAbove.orig));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawConnectorsForChunk(dv, topOrig, botOrig, topEdit, botEdit, sTopOrig, sTopEdit, w) {
|
function getMatchingOrigLine(editLine, chunks) {
|
||||||
|
var editStart = 0, origStart = 0;
|
||||||
|
for (var i = 0; i < chunks.length; i++) {
|
||||||
|
var chunk = chunks[i];
|
||||||
|
if (chunk.editTo > editLine && chunk.editFrom <= editLine) return null;
|
||||||
|
if (chunk.editFrom > editLine) break;
|
||||||
|
editStart = chunk.editTo;
|
||||||
|
origStart = chunk.origTo;
|
||||||
|
}
|
||||||
|
return origStart + (editLine - editStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
function findAlignedLines(dv, other) {
|
||||||
|
var linesToAlign = [];
|
||||||
|
for (var i = 0; i < dv.chunks.length; i++) {
|
||||||
|
var chunk = dv.chunks[i];
|
||||||
|
linesToAlign.push([chunk.origTo, chunk.editTo, other ? getMatchingOrigLine(chunk.editTo, other.chunks) : null]);
|
||||||
|
}
|
||||||
|
if (other) {
|
||||||
|
for (var i = 0; i < other.chunks.length; i++) {
|
||||||
|
var chunk = other.chunks[i];
|
||||||
|
for (var j = 0; j < linesToAlign.length; j++) {
|
||||||
|
var align = linesToAlign[j];
|
||||||
|
if (align[1] == chunk.editTo) {
|
||||||
|
j = -1;
|
||||||
|
break;
|
||||||
|
} else if (align[1] > chunk.editTo) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j > -1)
|
||||||
|
linesToAlign.splice(j - 1, 0, [getMatchingOrigLine(chunk.editTo, dv.chunks), chunk.editTo, chunk.origTo]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return linesToAlign;
|
||||||
|
}
|
||||||
|
|
||||||
|
function alignChunks(dv, force) {
|
||||||
|
if (!dv.dealigned && !force) return;
|
||||||
|
if (!dv.orig.curOp) return dv.orig.operation(function() {
|
||||||
|
alignChunks(dv, force);
|
||||||
|
});
|
||||||
|
|
||||||
|
dv.dealigned = false;
|
||||||
|
var other = dv.mv.left == dv ? dv.mv.right : dv.mv.left;
|
||||||
|
if (other) {
|
||||||
|
ensureDiff(other);
|
||||||
|
other.dealigned = false;
|
||||||
|
}
|
||||||
|
var linesToAlign = findAlignedLines(dv, other);
|
||||||
|
|
||||||
|
// Clear old aligners
|
||||||
|
var aligners = dv.mv.aligners;
|
||||||
|
for (var i = 0; i < aligners.length; i++)
|
||||||
|
aligners[i].clear();
|
||||||
|
aligners.length = 0;
|
||||||
|
|
||||||
|
var cm = [dv.orig, dv.edit], scroll = [];
|
||||||
|
if (other) cm.push(other.orig);
|
||||||
|
for (var i = 0; i < cm.length; i++)
|
||||||
|
scroll.push(cm[i].getScrollInfo().top);
|
||||||
|
|
||||||
|
for (var ln = 0; ln < linesToAlign.length; ln++)
|
||||||
|
alignLines(cm, linesToAlign[ln], aligners);
|
||||||
|
|
||||||
|
for (var i = 0; i < cm.length; i++)
|
||||||
|
cm[i].scrollTo(null, scroll[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function alignLines(cm, lines, aligners) {
|
||||||
|
var maxOffset = 0, offset = [];
|
||||||
|
for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
|
||||||
|
var off = cm[i].heightAtLine(lines[i], "local");
|
||||||
|
offset[i] = off;
|
||||||
|
maxOffset = Math.max(maxOffset, off);
|
||||||
|
}
|
||||||
|
for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
|
||||||
|
var diff = maxOffset - offset[i];
|
||||||
|
if (diff > 1)
|
||||||
|
aligners.push(padAbove(cm[i], lines[i], diff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function padAbove(cm, line, size) {
|
||||||
|
var above = true;
|
||||||
|
if (line > cm.lastLine()) {
|
||||||
|
line--;
|
||||||
|
above = false;
|
||||||
|
}
|
||||||
|
var elt = document.createElement("div");
|
||||||
|
elt.className = "CodeMirror-merge-spacer";
|
||||||
|
elt.style.height = size + "px"; elt.style.minWidth = "1px";
|
||||||
|
return cm.addLineWidget(line, elt, {height: size, above: above});
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawConnectorsForChunk(dv, chunk, sTopOrig, sTopEdit, w) {
|
||||||
var flip = dv.type == "left";
|
var flip = dv.type == "left";
|
||||||
var top = dv.orig.heightAtLine(topOrig, "local") - sTopOrig;
|
var top = dv.orig.heightAtLine(chunk.origFrom, "local") - sTopOrig;
|
||||||
if (dv.svg) {
|
if (dv.svg) {
|
||||||
var topLpx = top;
|
var topLpx = top;
|
||||||
var topRpx = dv.edit.heightAtLine(topEdit, "local") - sTopEdit;
|
var topRpx = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit;
|
||||||
if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; }
|
if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; }
|
||||||
var botLpx = dv.orig.heightAtLine(botOrig, "local") - sTopOrig;
|
var botLpx = dv.orig.heightAtLine(chunk.origTo, "local") - sTopOrig;
|
||||||
var botRpx = dv.edit.heightAtLine(botEdit, "local") - sTopEdit;
|
var botRpx = dv.edit.heightAtLine(chunk.editTo, "local") - sTopEdit;
|
||||||
if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; }
|
if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; }
|
||||||
var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx;
|
var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx;
|
||||||
var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx;
|
var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx;
|
||||||
|
@ -317,48 +409,26 @@
|
||||||
"CodeMirror-merge-copy"));
|
"CodeMirror-merge-copy"));
|
||||||
var editOriginals = dv.mv.options.allowEditingOriginals;
|
var editOriginals = dv.mv.options.allowEditingOriginals;
|
||||||
copy.title = editOriginals ? "Push to left" : "Revert chunk";
|
copy.title = editOriginals ? "Push to left" : "Revert chunk";
|
||||||
copy.chunk = {topEdit: topEdit, botEdit: botEdit, topOrig: topOrig, botOrig: botOrig};
|
copy.chunk = chunk;
|
||||||
copy.style.top = top + "px";
|
copy.style.top = top + "px";
|
||||||
|
|
||||||
if (editOriginals) {
|
if (editOriginals) {
|
||||||
var topReverse = dv.orig.heightAtLine(topEdit, "local") - sTopEdit;
|
var topReverse = dv.orig.heightAtLine(chunk.editFrom, "local") - sTopEdit;
|
||||||
var copyReverse = dv.copyButtons.appendChild(elt("div", dv.type == "right" ? "\u21dd" : "\u21dc",
|
var copyReverse = dv.copyButtons.appendChild(elt("div", dv.type == "right" ? "\u21dd" : "\u21dc",
|
||||||
"CodeMirror-merge-copy-reverse"));
|
"CodeMirror-merge-copy-reverse"));
|
||||||
copyReverse.title = "Push to right";
|
copyReverse.title = "Push to right";
|
||||||
copyReverse.chunk = {topEdit: topOrig, botEdit: botOrig, topOrig: topEdit, botOrig: botEdit};
|
copyReverse.chunk = {editFrom: chunk.origFrom, editTo: chunk.origTo,
|
||||||
|
origFrom: chunk.editFrom, origTo: chunk.editTo};
|
||||||
copyReverse.style.top = topReverse + "px";
|
copyReverse.style.top = topReverse + "px";
|
||||||
dv.type == "right" ? copyReverse.style.left = "2px" : copyReverse.style.right = "2px";
|
dv.type == "right" ? copyReverse.style.left = "2px" : copyReverse.style.right = "2px";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function alignChunks(dv, topOrig, botOrig, topEdit, botEdit, aboveViewport) {
|
|
||||||
var topOrigPx = dv.orig.heightAtLine(topOrig, "local");
|
|
||||||
var botOrigPx = dv.orig.heightAtLine(botOrig, "local");
|
|
||||||
var topEditPx = dv.edit.heightAtLine(topEdit, "local");
|
|
||||||
var botEditPx = dv.edit.heightAtLine(botEdit, "local");
|
|
||||||
var origH = botOrigPx -topOrigPx, editH = botEditPx - topEditPx;
|
|
||||||
var diff = editH - origH;
|
|
||||||
if (diff > 1) {
|
|
||||||
if (aboveViewport) aboveViewport.orig += diff;
|
|
||||||
else dv.aligners.push(padBelow(dv.orig, botOrig - 1, diff));
|
|
||||||
} else if (diff < -1) {
|
|
||||||
if (aboveViewport) aboveViewport.edit -= diff;
|
|
||||||
else dv.aligners.push(padBelow(dv.edit, botEdit - 1, -diff));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function padBelow(cm, line, size) {
|
|
||||||
var elt = document.createElement("div");
|
|
||||||
elt.style.height = size + "px"; elt.style.minWidth = "1px";
|
|
||||||
return cm.addLineWidget(line, elt, {height: size});
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyChunk(dv, to, from, chunk) {
|
function copyChunk(dv, to, from, chunk) {
|
||||||
if (dv.diffOutOfDate) return;
|
if (dv.diffOutOfDate) return;
|
||||||
to.replaceRange(from.getRange(Pos(chunk.topOrig, 0), Pos(chunk.botOrig, 0)),
|
to.replaceRange(from.getRange(Pos(chunk.origFrom, 0), Pos(chunk.origTo, 0)),
|
||||||
Pos(chunk.topEdit, 0), Pos(chunk.botEdit, 0));
|
Pos(chunk.editFrom, 0), Pos(chunk.editTo, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge view, containing 0, 1, or 2 diff views.
|
// Merge view, containing 0, 1, or 2 diff views.
|
||||||
|
@ -368,16 +438,11 @@
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
var origLeft = options.origLeft, origRight = options.origRight == null ? options.orig : options.origRight;
|
var origLeft = options.origLeft, origRight = options.origRight == null ? options.orig : options.origRight;
|
||||||
if (origLeft && origRight) {
|
|
||||||
if (options.connect == "align")
|
|
||||||
throw new Error("connect: \"align\" is not supported for three-way merge views");
|
|
||||||
if (options.collapseIdentical)
|
|
||||||
throw new Error("collapseIdentical option is not supported for three-way merge views");
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasLeft = origLeft != null, hasRight = origRight != null;
|
var hasLeft = origLeft != null, hasRight = origRight != null;
|
||||||
var panes = 1 + (hasLeft ? 1 : 0) + (hasRight ? 1 : 0);
|
var panes = 1 + (hasLeft ? 1 : 0) + (hasRight ? 1 : 0);
|
||||||
var wrap = [], left = this.left = null, right = this.right = null;
|
var wrap = [], left = this.left = null, right = this.right = null;
|
||||||
|
var self = this;
|
||||||
|
|
||||||
if (hasLeft) {
|
if (hasLeft) {
|
||||||
left = this.left = new DiffView(this, "left");
|
left = this.left = new DiffView(this, "left");
|
||||||
|
@ -406,8 +471,17 @@
|
||||||
if (left) left.init(leftPane, origLeft, options);
|
if (left) left.init(leftPane, origLeft, options);
|
||||||
if (right) right.init(rightPane, origRight, options);
|
if (right) right.init(rightPane, origRight, options);
|
||||||
|
|
||||||
if (options.collapseIdentical)
|
if (options.collapseIdentical) {
|
||||||
collapseIdenticalStretches(left || right, options.collapseIdentical);
|
updating = true;
|
||||||
|
this.editor().operation(function() {
|
||||||
|
collapseIdenticalStretches(self, options.collapseIdentical);
|
||||||
|
});
|
||||||
|
updating = false;
|
||||||
|
}
|
||||||
|
if (options.connect == "align") {
|
||||||
|
this.aligners = [];
|
||||||
|
alignChunks(this.left || this.right, true);
|
||||||
|
}
|
||||||
|
|
||||||
var onResize = function() {
|
var onResize = function() {
|
||||||
if (left) makeConnections(left);
|
if (left) makeConnections(left);
|
||||||
|
@ -459,10 +533,10 @@
|
||||||
if (this.left) this.left.setShowDifferences(val);
|
if (this.left) this.left.setShowDifferences(val);
|
||||||
},
|
},
|
||||||
rightChunks: function() {
|
rightChunks: function() {
|
||||||
return this.right && getChunks(this.right);
|
if (this.right) { ensureDiff(this.right); return this.right.chunks; }
|
||||||
},
|
},
|
||||||
leftChunks: function() {
|
leftChunks: function() {
|
||||||
return this.left && getChunks(this.left);
|
if (this.left) { ensureDiff(this.left); return this.left.chunks; }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -490,7 +564,8 @@
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
function iterateChunks(diff, f) {
|
function getChunks(diff) {
|
||||||
|
var chunks = [];
|
||||||
var startEdit = 0, startOrig = 0;
|
var startEdit = 0, startOrig = 0;
|
||||||
var edit = Pos(0, 0), orig = Pos(0, 0);
|
var edit = Pos(0, 0), orig = Pos(0, 0);
|
||||||
for (var i = 0; i < diff.length; ++i) {
|
for (var i = 0; i < diff.length; ++i) {
|
||||||
|
@ -502,7 +577,8 @@
|
||||||
var endOff = endOfLineClean(diff, i) ? 1 : 0;
|
var endOff = endOfLineClean(diff, i) ? 1 : 0;
|
||||||
var cleanToEdit = edit.line + endOff, cleanToOrig = orig.line + endOff;
|
var cleanToEdit = edit.line + endOff, cleanToOrig = orig.line + endOff;
|
||||||
if (cleanToEdit > cleanFromEdit) {
|
if (cleanToEdit > cleanFromEdit) {
|
||||||
if (i) f(startOrig, cleanFromOrig, startEdit, cleanFromEdit);
|
if (i) chunks.push({origFrom: startOrig, origTo: cleanFromOrig,
|
||||||
|
editFrom: startEdit, editTo: cleanFromEdit});
|
||||||
startEdit = cleanToEdit; startOrig = cleanToOrig;
|
startEdit = cleanToEdit; startOrig = cleanToOrig;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -510,17 +586,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (startEdit <= edit.line || startOrig <= orig.line)
|
if (startEdit <= edit.line || startOrig <= orig.line)
|
||||||
f(startOrig, orig.line + 1, startEdit, edit.line + 1);
|
chunks.push({origFrom: startOrig, origTo: orig.line + 1,
|
||||||
}
|
editFrom: startEdit, editTo: edit.line + 1});
|
||||||
|
return chunks;
|
||||||
function getChunks(dv) {
|
|
||||||
ensureDiff(dv);
|
|
||||||
var collect = [];
|
|
||||||
iterateChunks(dv.diff, function(topOrig, botOrig, topEdit, botEdit) {
|
|
||||||
collect.push({origFrom: topOrig, origTo: botOrig,
|
|
||||||
editFrom: topEdit, editTo: botEdit});
|
|
||||||
});
|
|
||||||
return collect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function endOfLineClean(diff, i) {
|
function endOfLineClean(diff, i) {
|
||||||
|
@ -541,18 +609,19 @@
|
||||||
return last.charCodeAt(last.length - 1) == 10;
|
return last.charCodeAt(last.length - 1) == 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
function chunkBoundariesAround(diff, n, nInEdit) {
|
function chunkBoundariesAround(chunks, n, nInEdit) {
|
||||||
var beforeE, afterE, beforeO, afterO;
|
var beforeE, afterE, beforeO, afterO;
|
||||||
iterateChunks(diff, function(fromOrig, toOrig, fromEdit, toEdit) {
|
for (var i = 0; i < chunks.length; i++) {
|
||||||
var fromLocal = nInEdit ? fromEdit : fromOrig;
|
var chunk = chunks[i];
|
||||||
var toLocal = nInEdit ? toEdit : toOrig;
|
var fromLocal = nInEdit ? chunk.editFrom : chunk.origFrom;
|
||||||
|
var toLocal = nInEdit ? chunk.editTo : chunk.origTo;
|
||||||
if (afterE == null) {
|
if (afterE == null) {
|
||||||
if (fromLocal > n) { afterE = fromEdit; afterO = fromOrig; }
|
if (fromLocal > n) { afterE = chunk.editFrom; afterO = chunk.origFrom; }
|
||||||
else if (toLocal > n) { afterE = toEdit; afterO = toOrig; }
|
else if (toLocal > n) { afterE = chunk.editTo; afterO = chunk.origTo; }
|
||||||
|
}
|
||||||
|
if (toLocal <= n) { beforeE = chunk.editTo; beforeO = chunk.origTo; }
|
||||||
|
else if (fromLocal <= n) { beforeE = chunk.editFrom; beforeO = chunk.origFrom; }
|
||||||
}
|
}
|
||||||
if (toLocal <= n) { beforeE = toEdit; beforeO = toOrig; }
|
|
||||||
else if (fromLocal <= n) { beforeE = fromEdit; beforeO = fromOrig; }
|
|
||||||
});
|
|
||||||
return {edit: {before: beforeE, after: afterE}, orig: {before: beforeO, after: afterO}};
|
return {edit: {before: beforeE, after: afterE}, orig: {before: beforeO, after: afterO}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,25 +644,50 @@
|
||||||
return {mark: mark, clear: clear};
|
return {mark: mark, clear: clear};
|
||||||
}
|
}
|
||||||
|
|
||||||
function collapseStretch(dv, origStart, editStart, size) {
|
function collapseStretch(size, editors) {
|
||||||
var mOrig = collapseSingle(dv.orig, origStart, origStart + size);
|
var marks = [];
|
||||||
var mEdit = collapseSingle(dv.edit, editStart, editStart + size);
|
function clear() {
|
||||||
mOrig.mark.on("clear", function() { mEdit.clear(); });
|
for (var i = 0; i < marks.length; i++) marks[i].clear();
|
||||||
mEdit.mark.on("clear", function() { mOrig.clear(); });
|
}
|
||||||
|
for (var i = 0; i < editors.length; i++) {
|
||||||
|
var editor = editors[i];
|
||||||
|
var mark = collapseSingle(editor.cm, editor.line, editor.line + size);
|
||||||
|
marks.push(mark);
|
||||||
|
mark.mark.on("clear", clear);
|
||||||
|
}
|
||||||
|
return marks[0].mark;
|
||||||
}
|
}
|
||||||
|
|
||||||
function collapseIdenticalStretches(dv, margin) {
|
function unclearNearChunks(dv, margin, off, clear) {
|
||||||
|
for (var i = 0; i < dv.chunks.length; i++) {
|
||||||
|
var chunk = dv.chunks[i];
|
||||||
|
for (var l = chunk.editFrom - margin; l < chunk.editTo + margin; l++) {
|
||||||
|
var pos = l + off;
|
||||||
|
if (pos >= 0 && pos < clear.length) clear[pos] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function collapseIdenticalStretches(mv, margin) {
|
||||||
if (typeof margin != "number") margin = 2;
|
if (typeof margin != "number") margin = 2;
|
||||||
var lastOrig = dv.orig.firstLine(), lastEdit = dv.edit.firstLine();
|
var clear = [], edit = mv.editor(), off = edit.firstLine();
|
||||||
iterateChunks(dv.diff, function(topOrig, botOrig, _topEdit, botEdit) {
|
for (var l = off, e = edit.lastLine(); l <= e; l++) clear.push(true);
|
||||||
var identicalSize = topOrig - margin - lastOrig;
|
if (mv.left) unclearNearChunks(mv.left, margin, off, clear);
|
||||||
if (identicalSize > margin)
|
if (mv.right) unclearNearChunks(mv.right, margin, off, clear);
|
||||||
collapseStretch(dv, lastOrig, lastEdit, identicalSize);
|
|
||||||
lastOrig = botOrig + margin; lastEdit = botEdit + margin;
|
for (var i = 0; i < clear.length; i++) {
|
||||||
});
|
if (clear[i]) {
|
||||||
var bottomSize = dv.orig.lastLine() + 1 - lastOrig;
|
var line = i + off;
|
||||||
if (bottomSize > margin)
|
for (var size = 1; i < clear.length - 1 && clear[i + 1]; i++, size++) {}
|
||||||
collapseStretch(dv, lastOrig, lastEdit, bottomSize);
|
if (size > margin) {
|
||||||
|
var editors = [{line: line, cm: edit}];
|
||||||
|
if (mv.left) editors.push({line: getMatchingOrigLine(line, mv.left.chunks), cm: mv.left.orig});
|
||||||
|
if (mv.right) editors.push({line: getMatchingOrigLine(line, mv.right.chunks), cm: mv.right.orig});
|
||||||
|
var mark = collapseStretch(size, editors);
|
||||||
|
if (mv.options.onCollapse) mv.options.onCollapse(mv, line, size, mark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// General utilities
|
// General utilities
|
||||||
|
@ -640,4 +734,42 @@
|
||||||
function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; }
|
function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; }
|
||||||
function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; }
|
function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; }
|
||||||
function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }
|
function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }
|
||||||
|
|
||||||
|
function findPrevDiff(chunks, start, isOrig) {
|
||||||
|
for (var i = chunks.length - 1; i >= 0; i--) {
|
||||||
|
var chunk = chunks[i];
|
||||||
|
var to = (isOrig ? chunk.origTo : chunk.editTo) - 1;
|
||||||
|
if (to < start) return to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findNextDiff(chunks, start, isOrig) {
|
||||||
|
for (var i = 0; i < chunks.length; i++) {
|
||||||
|
var chunk = chunks[i];
|
||||||
|
var from = (isOrig ? chunk.origFrom : chunk.editFrom);
|
||||||
|
if (from > start) return from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function goNearbyDiff(cm, dir) {
|
||||||
|
var found = null, views = cm.state.diffViews, line = cm.getCursor().line;
|
||||||
|
if (views) for (var i = 0; i < views.length; i++) {
|
||||||
|
var dv = views[i], isOrig = cm == dv.orig;
|
||||||
|
ensureDiff(dv);
|
||||||
|
var pos = dir < 0 ? findPrevDiff(dv.chunks, line, isOrig) : findNextDiff(dv.chunks, line, isOrig);
|
||||||
|
if (pos != null && (found == null || (dir < 0 ? pos > found : pos < found)))
|
||||||
|
found = pos;
|
||||||
|
}
|
||||||
|
if (found != null)
|
||||||
|
cm.setCursor(found, 0);
|
||||||
|
else
|
||||||
|
return CodeMirror.Pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeMirror.commands.goNextDiff = function(cm) {
|
||||||
|
return goNearbyDiff(cm, 1);
|
||||||
|
};
|
||||||
|
CodeMirror.commands.goPrevDiff = function(cm) {
|
||||||
|
return goNearbyDiff(cm, -1);
|
||||||
|
};
|
||||||
});
|
});
|
|
@ -116,7 +116,7 @@
|
||||||
var curState = states[state.state];
|
var curState = states[state.state];
|
||||||
for (var i = 0; i < curState.length; i++) {
|
for (var i = 0; i < curState.length; i++) {
|
||||||
var rule = curState[i];
|
var rule = curState[i];
|
||||||
var matches = stream.match(rule.regex);
|
var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
if (rule.data.next) {
|
if (rule.data.next) {
|
||||||
state.state = rule.data.next;
|
state.state = rule.data.next;
|
|
@ -11,27 +11,46 @@
|
||||||
})(function(CodeMirror) {
|
})(function(CodeMirror) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
CodeMirror.defineExtension("annotateScrollbar", function(className) {
|
CodeMirror.defineExtension("annotateScrollbar", function(options) {
|
||||||
return new Annotation(this, className);
|
if (typeof options == "string") options = {className: options};
|
||||||
|
return new Annotation(this, options);
|
||||||
});
|
});
|
||||||
|
|
||||||
function Annotation(cm, className) {
|
CodeMirror.defineOption("scrollButtonHeight", 0);
|
||||||
|
|
||||||
|
function Annotation(cm, options) {
|
||||||
this.cm = cm;
|
this.cm = cm;
|
||||||
this.className = className;
|
this.options = options;
|
||||||
|
this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight");
|
||||||
this.annotations = [];
|
this.annotations = [];
|
||||||
|
this.doRedraw = this.doUpdate = null;
|
||||||
this.div = cm.getWrapperElement().appendChild(document.createElement("div"));
|
this.div = cm.getWrapperElement().appendChild(document.createElement("div"));
|
||||||
this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none";
|
this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none";
|
||||||
this.computeScale();
|
this.computeScale();
|
||||||
|
|
||||||
|
function scheduleRedraw(delay) {
|
||||||
|
clearTimeout(self.doRedraw);
|
||||||
|
self.doRedraw = setTimeout(function() { self.redraw(); }, delay);
|
||||||
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
cm.on("refresh", this.resizeHandler = function() {
|
cm.on("refresh", this.resizeHandler = function() {
|
||||||
if (self.computeScale()) self.redraw();
|
clearTimeout(self.doUpdate);
|
||||||
|
self.doUpdate = setTimeout(function() {
|
||||||
|
if (self.computeScale()) scheduleRedraw(20);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
cm.on("markerAdded", this.resizeHandler);
|
||||||
|
cm.on("markerCleared", this.resizeHandler);
|
||||||
|
if (options.listenForChanges !== false)
|
||||||
|
cm.on("change", this.changeHandler = function() {
|
||||||
|
scheduleRedraw(250);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Annotation.prototype.computeScale = function() {
|
Annotation.prototype.computeScale = function() {
|
||||||
var cm = this.cm;
|
var cm = this.cm;
|
||||||
var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight) /
|
var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) /
|
||||||
cm.heightAtLine(cm.lastLine() + 1, "local");
|
cm.heightAtLine(cm.lastLine() + 1, "local");
|
||||||
if (hScale != this.hScale) {
|
if (hScale != this.hScale) {
|
||||||
this.hScale = hScale;
|
this.hScale = hScale;
|
||||||
|
@ -44,12 +63,12 @@
|
||||||
this.redraw();
|
this.redraw();
|
||||||
};
|
};
|
||||||
|
|
||||||
Annotation.prototype.redraw = function() {
|
Annotation.prototype.redraw = function(compute) {
|
||||||
|
if (compute !== false) this.computeScale();
|
||||||
var cm = this.cm, hScale = this.hScale;
|
var cm = this.cm, hScale = this.hScale;
|
||||||
if (!cm.display.barWidth) return;
|
|
||||||
|
|
||||||
var frag = document.createDocumentFragment(), anns = this.annotations;
|
var frag = document.createDocumentFragment(), anns = this.annotations;
|
||||||
for (var i = 0, nextTop; i < anns.length; i++) {
|
if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) {
|
||||||
var ann = anns[i];
|
var ann = anns[i];
|
||||||
var top = nextTop || cm.charCoords(ann.from, "local").top * hScale;
|
var top = nextTop || cm.charCoords(ann.from, "local").top * hScale;
|
||||||
var bottom = cm.charCoords(ann.to, "local").bottom * hScale;
|
var bottom = cm.charCoords(ann.to, "local").bottom * hScale;
|
||||||
|
@ -59,11 +78,13 @@
|
||||||
ann = anns[++i];
|
ann = anns[++i];
|
||||||
bottom = cm.charCoords(ann.to, "local").bottom * hScale;
|
bottom = cm.charCoords(ann.to, "local").bottom * hScale;
|
||||||
}
|
}
|
||||||
|
if (bottom == top) continue;
|
||||||
var height = Math.max(bottom - top, 3);
|
var height = Math.max(bottom - top, 3);
|
||||||
|
|
||||||
var elt = frag.appendChild(document.createElement("div"));
|
var elt = frag.appendChild(document.createElement("div"));
|
||||||
elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: " + top + "px; height: " + height + "px";
|
elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: "
|
||||||
elt.className = this.className;
|
+ (top + this.buttonHeight) + "px; height: " + height + "px";
|
||||||
|
elt.className = this.options.className;
|
||||||
}
|
}
|
||||||
this.div.textContent = "";
|
this.div.textContent = "";
|
||||||
this.div.appendChild(frag);
|
this.div.appendChild(frag);
|
||||||
|
@ -71,6 +92,9 @@
|
||||||
|
|
||||||
Annotation.prototype.clear = function() {
|
Annotation.prototype.clear = function() {
|
||||||
this.cm.off("refresh", this.resizeHandler);
|
this.cm.off("refresh", this.resizeHandler);
|
||||||
|
this.cm.off("markerAdded", this.resizeHandler);
|
||||||
|
this.cm.off("markerCleared", this.resizeHandler);
|
||||||
|
if (this.changeHandler) this.cm.off("change", this.changeHandler);
|
||||||
this.div.parentNode.removeChild(this.div);
|
this.div.parentNode.removeChild(this.div);
|
||||||
};
|
};
|
||||||
});
|
});
|
|
@ -27,14 +27,16 @@
|
||||||
CodeMirror.e_preventDefault(e);
|
CodeMirror.e_preventDefault(e);
|
||||||
var axis = self.orientation == "horizontal" ? "pageX" : "pageY";
|
var axis = self.orientation == "horizontal" ? "pageX" : "pageY";
|
||||||
var start = e[axis], startpos = self.pos;
|
var start = e[axis], startpos = self.pos;
|
||||||
function move(e) {
|
function done() {
|
||||||
if (e.which != 1) {
|
|
||||||
CodeMirror.off(document, "mousemove", move);
|
CodeMirror.off(document, "mousemove", move);
|
||||||
return;
|
CodeMirror.off(document, "mouseup", done);
|
||||||
}
|
}
|
||||||
|
function move(e) {
|
||||||
|
if (e.which != 1) return done();
|
||||||
self.moveTo(startpos + (e[axis] - start) * (self.total / self.size));
|
self.moveTo(startpos + (e[axis] - start) * (self.total / self.size));
|
||||||
}
|
}
|
||||||
CodeMirror.on(document, "mousemove", move);
|
CodeMirror.on(document, "mousemove", move);
|
||||||
|
CodeMirror.on(document, "mouseup", done);
|
||||||
});
|
});
|
||||||
|
|
||||||
CodeMirror.on(this.node, "click", function(e) {
|
CodeMirror.on(this.node, "click", function(e) {
|
||||||
|
@ -67,14 +69,20 @@
|
||||||
if (update !== false) this.scroll(pos, this.orientation);
|
if (update !== false) this.scroll(pos, this.orientation);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var minButtonSize = 10;
|
||||||
|
|
||||||
Bar.prototype.update = function(scrollSize, clientSize, barSize) {
|
Bar.prototype.update = function(scrollSize, clientSize, barSize) {
|
||||||
this.screen = clientSize;
|
this.screen = clientSize;
|
||||||
this.total = scrollSize;
|
this.total = scrollSize;
|
||||||
this.size = barSize;
|
this.size = barSize;
|
||||||
|
|
||||||
// FIXME clip to min size?
|
var buttonSize = this.screen * (this.size / this.total);
|
||||||
|
if (buttonSize < minButtonSize) {
|
||||||
|
this.size -= minButtonSize - buttonSize;
|
||||||
|
buttonSize = minButtonSize;
|
||||||
|
}
|
||||||
this.inner.style[this.orientation == "horizontal" ? "width" : "height"] =
|
this.inner.style[this.orientation == "horizontal" ? "width" : "height"] =
|
||||||
this.screen * (this.size / this.total) + "px";
|
buttonSize + "px";
|
||||||
this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
|
this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
|
||||||
this.pos * (this.size / this.total) + "px";
|
this.pos * (this.size / this.total) + "px";
|
||||||
};
|
};
|
|
@ -11,13 +11,18 @@
|
||||||
})(function(CodeMirror) {
|
})(function(CodeMirror) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, className) {
|
CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) {
|
||||||
return new SearchAnnotation(this, query, caseFold, className);
|
if (typeof options == "string") options = {className: options};
|
||||||
|
if (!options) options = {};
|
||||||
|
return new SearchAnnotation(this, query, caseFold, options);
|
||||||
});
|
});
|
||||||
|
|
||||||
function SearchAnnotation(cm, query, caseFold, className) {
|
function SearchAnnotation(cm, query, caseFold, options) {
|
||||||
this.cm = cm;
|
this.cm = cm;
|
||||||
this.annotation = cm.annotateScrollbar(className || "CodeMirror-search-match");
|
var annotateOptions = {listenForChanges: false};
|
||||||
|
for (var prop in options) annotateOptions[prop] = options[prop];
|
||||||
|
if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match";
|
||||||
|
this.annotation = cm.annotateScrollbar(annotateOptions);
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.caseFold = caseFold;
|
this.caseFold = caseFold;
|
||||||
this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1};
|
this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1};
|
|
@ -0,0 +1,98 @@
|
||||||
|
// 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("selectionPointer", false, function(cm, val) {
|
||||||
|
var data = cm.state.selectionPointer;
|
||||||
|
if (data) {
|
||||||
|
CodeMirror.off(cm.getWrapperElement(), "mousemove", data.mousemove);
|
||||||
|
CodeMirror.off(cm.getWrapperElement(), "mouseout", data.mouseout);
|
||||||
|
CodeMirror.off(window, "scroll", data.windowScroll);
|
||||||
|
cm.off("cursorActivity", reset);
|
||||||
|
cm.off("scroll", reset);
|
||||||
|
cm.state.selectionPointer = null;
|
||||||
|
cm.display.lineDiv.style.cursor = "";
|
||||||
|
}
|
||||||
|
if (val) {
|
||||||
|
data = cm.state.selectionPointer = {
|
||||||
|
value: typeof val == "string" ? val : "default",
|
||||||
|
mousemove: function(event) { mousemove(cm, event); },
|
||||||
|
mouseout: function(event) { mouseout(cm, event); },
|
||||||
|
windowScroll: function() { reset(cm); },
|
||||||
|
rects: null,
|
||||||
|
mouseX: null, mouseY: null,
|
||||||
|
willUpdate: false
|
||||||
|
};
|
||||||
|
CodeMirror.on(cm.getWrapperElement(), "mousemove", data.mousemove);
|
||||||
|
CodeMirror.on(cm.getWrapperElement(), "mouseout", data.mouseout);
|
||||||
|
CodeMirror.on(window, "scroll", data.windowScroll);
|
||||||
|
cm.on("cursorActivity", reset);
|
||||||
|
cm.on("scroll", reset);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function mousemove(cm, event) {
|
||||||
|
var data = cm.state.selectionPointer;
|
||||||
|
if (event.buttons == null ? event.which : event.buttons) {
|
||||||
|
data.mouseX = data.mouseY = null;
|
||||||
|
} else {
|
||||||
|
data.mouseX = event.clientX;
|
||||||
|
data.mouseY = event.clientY;
|
||||||
|
}
|
||||||
|
scheduleUpdate(cm);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseout(cm, event) {
|
||||||
|
if (!cm.getWrapperElement().contains(event.relatedTarget)) {
|
||||||
|
var data = cm.state.selectionPointer;
|
||||||
|
data.mouseX = data.mouseY = null;
|
||||||
|
scheduleUpdate(cm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset(cm) {
|
||||||
|
cm.state.selectionPointer.rects = null;
|
||||||
|
scheduleUpdate(cm);
|
||||||
|
}
|
||||||
|
|
||||||
|
function scheduleUpdate(cm) {
|
||||||
|
if (!cm.state.selectionPointer.willUpdate) {
|
||||||
|
cm.state.selectionPointer.willUpdate = true;
|
||||||
|
setTimeout(function() {
|
||||||
|
update(cm);
|
||||||
|
cm.state.selectionPointer.willUpdate = false;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(cm) {
|
||||||
|
var data = cm.state.selectionPointer;
|
||||||
|
if (!data) return;
|
||||||
|
if (data.rects == null && data.mouseX != null) {
|
||||||
|
data.rects = [];
|
||||||
|
if (cm.somethingSelected()) {
|
||||||
|
for (var sel = cm.display.selectionDiv.firstChild; sel; sel = sel.nextSibling)
|
||||||
|
data.rects.push(sel.getBoundingClientRect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var inside = false;
|
||||||
|
if (data.mouseX != null) for (var i = 0; i < data.rects.length; i++) {
|
||||||
|
var rect = data.rects[i];
|
||||||
|
if (rect.left <= data.mouseX && rect.right >= data.mouseX &&
|
||||||
|
rect.top <= data.mouseY && rect.bottom >= data.mouseY)
|
||||||
|
inside = true;
|
||||||
|
}
|
||||||
|
var cursor = inside ? data.value : "";
|
||||||
|
if (cm.display.lineDiv.style.cursor != cursor)
|
||||||
|
cm.display.lineDiv.style.cursor = cursor;
|
||||||
|
}
|
||||||
|
});
|
|
@ -130,6 +130,13 @@
|
||||||
data = self.options.responseFilter(doc, query, request, error, data);
|
data = self.options.responseFilter(doc, query, request, error, data);
|
||||||
c(error, data);
|
c(error, data);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function () {
|
||||||
|
if (this.worker) {
|
||||||
|
this.worker.terminate();
|
||||||
|
this.worker = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -252,7 +259,9 @@
|
||||||
tip.appendChild(document.createTextNode(" — " + data.doc));
|
tip.appendChild(document.createTextNode(" — " + data.doc));
|
||||||
if (data.url) {
|
if (data.url) {
|
||||||
tip.appendChild(document.createTextNode(" "));
|
tip.appendChild(document.createTextNode(" "));
|
||||||
tip.appendChild(elt("a", null, "[docs]")).href = data.url;
|
var child = tip.appendChild(elt("a", null, "[docs]"));
|
||||||
|
child.href = data.url;
|
||||||
|
child.target = "_blank";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tempTooltip(cm, tip);
|
tempTooltip(cm, tip);
|
||||||
|
@ -434,7 +443,7 @@
|
||||||
function atInterestingExpression(cm) {
|
function atInterestingExpression(cm) {
|
||||||
var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos);
|
var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos);
|
||||||
if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false;
|
if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false;
|
||||||
return /\w/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
|
return /[\w)\]]/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variable renaming
|
// Variable renaming
|
||||||
|
@ -582,15 +591,33 @@
|
||||||
// Tooltips
|
// Tooltips
|
||||||
|
|
||||||
function tempTooltip(cm, content) {
|
function tempTooltip(cm, content) {
|
||||||
|
if (cm.state.ternTooltip) remove(cm.state.ternTooltip);
|
||||||
var where = cm.cursorCoords();
|
var where = cm.cursorCoords();
|
||||||
var tip = makeTooltip(where.right + 1, where.bottom, content);
|
var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content);
|
||||||
|
function maybeClear() {
|
||||||
|
old = true;
|
||||||
|
if (!mouseOnTip) clear();
|
||||||
|
}
|
||||||
function clear() {
|
function clear() {
|
||||||
|
cm.state.ternTooltip = null;
|
||||||
if (!tip.parentNode) return;
|
if (!tip.parentNode) return;
|
||||||
cm.off("cursorActivity", clear);
|
cm.off("cursorActivity", clear);
|
||||||
|
cm.off('blur', clear);
|
||||||
|
cm.off('scroll', clear);
|
||||||
fadeOut(tip);
|
fadeOut(tip);
|
||||||
}
|
}
|
||||||
setTimeout(clear, 1700);
|
var mouseOnTip = false, old = false;
|
||||||
|
CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; });
|
||||||
|
CodeMirror.on(tip, "mouseout", function(e) {
|
||||||
|
if (!CodeMirror.contains(tip, e.relatedTarget || e.toElement)) {
|
||||||
|
if (old) clear();
|
||||||
|
else mouseOnTip = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setTimeout(maybeClear, 1700);
|
||||||
cm.on("cursorActivity", clear);
|
cm.on("cursorActivity", clear);
|
||||||
|
cm.on('blur', clear);
|
||||||
|
cm.on('scroll', clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeTooltip(x, y, content) {
|
function makeTooltip(x, y, content) {
|
||||||
|
@ -631,7 +658,7 @@
|
||||||
// Worker wrapper
|
// Worker wrapper
|
||||||
|
|
||||||
function WorkerServer(ts) {
|
function WorkerServer(ts) {
|
||||||
var worker = new Worker(ts.options.workerScript);
|
var worker = ts.worker = new Worker(ts.options.workerScript);
|
||||||
worker.postMessage({type: "init",
|
worker.postMessage({type: "init",
|
||||||
defs: ts.options.defs,
|
defs: ts.options.defs,
|
||||||
plugins: ts.options.plugins,
|
plugins: ts.options.plugins,
|
|
@ -4,6 +4,7 @@
|
||||||
/* Set height, width, borders, and global font properties here */
|
/* Set height, width, borders, and global font properties here */
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PADDING */
|
/* PADDING */
|
||||||
|
@ -32,8 +33,7 @@
|
||||||
min-width: 20px;
|
min-width: 20px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
color: #999;
|
color: #999;
|
||||||
-moz-box-sizing: content-box;
|
white-space: nowrap;
|
||||||
box-sizing: content-box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.CodeMirror-guttermarker { color: black; }
|
.CodeMirror-guttermarker { color: black; }
|
||||||
|
@ -139,11 +139,9 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||||
the editor. You probably shouldn't touch them. */
|
the editor. You probably shouldn't touch them. */
|
||||||
|
|
||||||
.CodeMirror {
|
.CodeMirror {
|
||||||
line-height: 1;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: white;
|
background: white;
|
||||||
color: black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.CodeMirror-scroll {
|
.CodeMirror-scroll {
|
||||||
|
@ -155,14 +153,10 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||||
height: 100%;
|
height: 100%;
|
||||||
outline: none; /* Prevent dragging from highlighting the element */
|
outline: none; /* Prevent dragging from highlighting the element */
|
||||||
position: relative;
|
position: relative;
|
||||||
-moz-box-sizing: content-box;
|
|
||||||
box-sizing: content-box;
|
|
||||||
}
|
}
|
||||||
.CodeMirror-sizer {
|
.CodeMirror-sizer {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-right: 30px solid transparent;
|
border-right: 30px solid transparent;
|
||||||
-moz-box-sizing: content-box;
|
|
||||||
box-sizing: content-box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||||
|
@ -197,8 +191,6 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||||
.CodeMirror-gutter {
|
.CodeMirror-gutter {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
-moz-box-sizing: content-box;
|
|
||||||
box-sizing: content-box;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-bottom: -30px;
|
margin-bottom: -30px;
|
||||||
/* Hack to make IE7 behave */
|
/* Hack to make IE7 behave */
|
||||||
|
@ -215,6 +207,11 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||||
cursor: default;
|
cursor: default;
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
.CodeMirror-gutter-wrapper {
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
.CodeMirror-lines {
|
.CodeMirror-lines {
|
||||||
cursor: text;
|
cursor: text;
|
||||||
|
@ -235,6 +232,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
.CodeMirror-wrap pre {
|
.CodeMirror-wrap pre {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
@ -256,6 +254,20 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||||
|
|
||||||
.CodeMirror-widget {}
|
.CodeMirror-widget {}
|
||||||
|
|
||||||
|
.CodeMirror-code {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Force content-box sizing for the elements where we expect it */
|
||||||
|
.CodeMirror-scroll,
|
||||||
|
.CodeMirror-sizer,
|
||||||
|
.CodeMirror-gutter,
|
||||||
|
.CodeMirror-gutters,
|
||||||
|
.CodeMirror-linenumber {
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
.CodeMirror-measure {
|
.CodeMirror-measure {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -283,6 +295,8 @@ div.CodeMirror-cursors {
|
||||||
.CodeMirror-selected { background: #d9d9d9; }
|
.CodeMirror-selected { background: #d9d9d9; }
|
||||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
|
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
|
||||||
.CodeMirror-crosshair { cursor: crosshair; }
|
.CodeMirror-crosshair { cursor: crosshair; }
|
||||||
|
.CodeMirror ::selection { background: #d7d4f0; }
|
||||||
|
.CodeMirror ::-moz-selection { background: #d7d4f0; }
|
||||||
|
|
||||||
.cm-searching {
|
.cm-searching {
|
||||||
background: #ffa;
|
background: #ffa;
|
File diff suppressed because one or more lines are too long
|
@ -395,6 +395,7 @@
|
||||||
"Ctrl-X U": repeated("undo"),
|
"Ctrl-X U": repeated("undo"),
|
||||||
"Ctrl-X K": "close",
|
"Ctrl-X K": "close",
|
||||||
"Ctrl-X Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), true); },
|
"Ctrl-X Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), true); },
|
||||||
|
"Ctrl-X H": "selectAll",
|
||||||
|
|
||||||
"Ctrl-Q Tab": repeated("insertTab"),
|
"Ctrl-Q Tab": repeated("insertTab"),
|
||||||
"Ctrl-U": addPrefixMap
|
"Ctrl-U": addPrefixMap
|
|
@ -409,6 +409,19 @@
|
||||||
|
|
||||||
map[cK + ctrl + "Backspace"] = "delLineLeft";
|
map[cK + ctrl + "Backspace"] = "delLineLeft";
|
||||||
|
|
||||||
|
cmds[map["Backspace"] = "smartBackspace"] = function(cm) {
|
||||||
|
if (cm.somethingSelected()) return CodeMirror.Pass;
|
||||||
|
|
||||||
|
var cursor = cm.getCursor();
|
||||||
|
var toStartOfLine = cm.getRange({line: cursor.line, ch: 0}, cursor);
|
||||||
|
var column = CodeMirror.countColumn(toStartOfLine, null, cm.getOption("tabSize"));
|
||||||
|
|
||||||
|
if (!/\S/.test(toStartOfLine) && column % cm.getOption("indentUnit") == 0)
|
||||||
|
return cm.indentSelection("subtract");
|
||||||
|
else
|
||||||
|
return CodeMirror.Pass;
|
||||||
|
};
|
||||||
|
|
||||||
cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) {
|
cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) {
|
||||||
cm.operation(function() {
|
cm.operation(function() {
|
||||||
var ranges = cm.listSelections();
|
var ranges = cm.listSelections();
|
|
@ -336,7 +336,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var numberRegex = /[\d]/;
|
var numberRegex = /[\d]/;
|
||||||
var wordRegexp = [(/\w/), (/[^\w\s]/)], bigWordRegexp = [(/\S/)];
|
var wordCharTest = [CodeMirror.isWordChar, function(ch) {
|
||||||
|
return ch && !CodeMirror.isWordChar(ch) && !/\s/.test(ch);
|
||||||
|
}], bigWordCharTest = [function(ch) {
|
||||||
|
return /\S/.test(ch);
|
||||||
|
}];
|
||||||
function makeKeyRange(start, size) {
|
function makeKeyRange(start, size) {
|
||||||
var keys = [];
|
var keys = [];
|
||||||
for (var i = start; i < start + size; i++) {
|
for (var i = start; i < start + size; i++) {
|
||||||
|
@ -776,7 +780,16 @@
|
||||||
},
|
},
|
||||||
handleEx: function(cm, input) {
|
handleEx: function(cm, input) {
|
||||||
exCommandDispatcher.processCommand(cm, input);
|
exCommandDispatcher.processCommand(cm, input);
|
||||||
}
|
},
|
||||||
|
|
||||||
|
defineMotion: defineMotion,
|
||||||
|
defineAction: defineAction,
|
||||||
|
defineOperator: defineOperator,
|
||||||
|
mapCommand: mapCommand,
|
||||||
|
_mapCommand: _mapCommand,
|
||||||
|
|
||||||
|
exitVisualMode: exitVisualMode,
|
||||||
|
exitInsertMode: exitInsertMode
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents the current input state.
|
// Represents the current input state.
|
||||||
|
@ -1026,12 +1039,10 @@
|
||||||
break;
|
break;
|
||||||
case 'search':
|
case 'search':
|
||||||
this.processSearch(cm, vim, command);
|
this.processSearch(cm, vim, command);
|
||||||
clearInputState(cm);
|
|
||||||
break;
|
break;
|
||||||
case 'ex':
|
case 'ex':
|
||||||
case 'keyToEx':
|
case 'keyToEx':
|
||||||
this.processEx(cm, vim, command);
|
this.processEx(cm, vim, command);
|
||||||
clearInputState(cm);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1124,6 +1135,7 @@
|
||||||
updateSearchQuery(cm, query, ignoreCase, smartCase);
|
updateSearchQuery(cm, query, ignoreCase, smartCase);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showConfirm(cm, 'Invalid regex: ' + query);
|
showConfirm(cm, 'Invalid regex: ' + query);
|
||||||
|
clearInputState(cm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
commandDispatcher.processMotion(cm, vim, {
|
commandDispatcher.processMotion(cm, vim, {
|
||||||
|
@ -1173,6 +1185,7 @@
|
||||||
clearSearchHighlight(cm);
|
clearSearchHighlight(cm);
|
||||||
cm.scrollTo(originalScrollPos.left, originalScrollPos.top);
|
cm.scrollTo(originalScrollPos.left, originalScrollPos.top);
|
||||||
CodeMirror.e_stop(e);
|
CodeMirror.e_stop(e);
|
||||||
|
clearInputState(cm);
|
||||||
close();
|
close();
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
|
@ -1239,6 +1252,7 @@
|
||||||
vimGlobalState.exCommandHistoryController.pushInput(input);
|
vimGlobalState.exCommandHistoryController.pushInput(input);
|
||||||
vimGlobalState.exCommandHistoryController.reset();
|
vimGlobalState.exCommandHistoryController.reset();
|
||||||
CodeMirror.e_stop(e);
|
CodeMirror.e_stop(e);
|
||||||
|
clearInputState(cm);
|
||||||
close();
|
close();
|
||||||
cm.focus();
|
cm.focus();
|
||||||
}
|
}
|
||||||
|
@ -1449,7 +1463,7 @@
|
||||||
var operatorMoveTo = operators[operator](
|
var operatorMoveTo = operators[operator](
|
||||||
cm, operatorArgs, cmSel.ranges, oldAnchor, newHead);
|
cm, operatorArgs, cmSel.ranges, oldAnchor, newHead);
|
||||||
if (vim.visualMode) {
|
if (vim.visualMode) {
|
||||||
exitVisualMode(cm);
|
exitVisualMode(cm, operatorMoveTo != null);
|
||||||
}
|
}
|
||||||
if (operatorMoveTo) {
|
if (operatorMoveTo) {
|
||||||
cm.setCursor(operatorMoveTo);
|
cm.setCursor(operatorMoveTo);
|
||||||
|
@ -1817,6 +1831,10 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function defineMotion(name, fn) {
|
||||||
|
motions[name] = fn;
|
||||||
|
}
|
||||||
|
|
||||||
function fillArray(val, times) {
|
function fillArray(val, times) {
|
||||||
var arr = [];
|
var arr = [];
|
||||||
for (var i = 0; i < times; i++) {
|
for (var i = 0; i < times; i++) {
|
||||||
|
@ -1899,7 +1917,7 @@
|
||||||
vimGlobalState.registerController.pushText(
|
vimGlobalState.registerController.pushText(
|
||||||
args.registerName, 'delete', text,
|
args.registerName, 'delete', text,
|
||||||
args.linewise, vim.visualBlock);
|
args.linewise, vim.visualBlock);
|
||||||
return finalHead;
|
return clipCursorToContent(cm, finalHead);
|
||||||
},
|
},
|
||||||
indent: function(cm, args, ranges) {
|
indent: function(cm, args, ranges) {
|
||||||
var vim = cm.state.vim;
|
var vim = cm.state.vim;
|
||||||
|
@ -1967,6 +1985,10 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function defineOperator(name, fn) {
|
||||||
|
operators[name] = fn;
|
||||||
|
}
|
||||||
|
|
||||||
var actions = {
|
var actions = {
|
||||||
jumpListWalk: function(cm, actionArgs, vim) {
|
jumpListWalk: function(cm, actionArgs, vim) {
|
||||||
if (vim.visualMode) {
|
if (vim.visualMode) {
|
||||||
|
@ -2183,6 +2205,11 @@
|
||||||
if (vim.visualMode) {
|
if (vim.visualMode) {
|
||||||
curStart = cm.getCursor('anchor');
|
curStart = cm.getCursor('anchor');
|
||||||
curEnd = cm.getCursor('head');
|
curEnd = cm.getCursor('head');
|
||||||
|
if (cursorIsBefore(curEnd, curStart)) {
|
||||||
|
var tmp = curEnd;
|
||||||
|
curEnd = curStart;
|
||||||
|
curStart = tmp;
|
||||||
|
}
|
||||||
curEnd.ch = lineLength(cm, curEnd.line) - 1;
|
curEnd.ch = lineLength(cm, curEnd.line) - 1;
|
||||||
} else {
|
} else {
|
||||||
// Repeat is the number of lines to join. Minimum 2 lines.
|
// Repeat is the number of lines to join. Minimum 2 lines.
|
||||||
|
@ -2201,10 +2228,10 @@
|
||||||
cm.replaceRange(text, curStart, tmp);
|
cm.replaceRange(text, curStart, tmp);
|
||||||
}
|
}
|
||||||
var curFinalPos = Pos(curStart.line, finalCh);
|
var curFinalPos = Pos(curStart.line, finalCh);
|
||||||
cm.setCursor(curFinalPos);
|
|
||||||
if (vim.visualMode) {
|
if (vim.visualMode) {
|
||||||
exitVisualMode(cm);
|
exitVisualMode(cm, false);
|
||||||
}
|
}
|
||||||
|
cm.setCursor(curFinalPos);
|
||||||
},
|
},
|
||||||
newLineAndEnterInsertMode: function(cm, actionArgs, vim) {
|
newLineAndEnterInsertMode: function(cm, actionArgs, vim) {
|
||||||
vim.insertMode = true;
|
vim.insertMode = true;
|
||||||
|
@ -2367,7 +2394,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (vim.visualMode) {
|
if (vim.visualMode) {
|
||||||
exitVisualMode(cm);
|
exitVisualMode(cm, false);
|
||||||
}
|
}
|
||||||
cm.setCursor(curPosFinal);
|
cm.setCursor(curPosFinal);
|
||||||
},
|
},
|
||||||
|
@ -2425,7 +2452,7 @@
|
||||||
curStart = cursorIsBefore(selections[0].anchor, selections[0].head) ?
|
curStart = cursorIsBefore(selections[0].anchor, selections[0].head) ?
|
||||||
selections[0].anchor : selections[0].head;
|
selections[0].anchor : selections[0].head;
|
||||||
cm.setCursor(curStart);
|
cm.setCursor(curStart);
|
||||||
exitVisualMode(cm);
|
exitVisualMode(cm, false);
|
||||||
} else {
|
} else {
|
||||||
cm.setCursor(offsetCursor(curEnd, 0, -1));
|
cm.setCursor(offsetCursor(curEnd, 0, -1));
|
||||||
}
|
}
|
||||||
|
@ -2473,6 +2500,10 @@
|
||||||
exitInsertMode: exitInsertMode
|
exitInsertMode: exitInsertMode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function defineAction(name, fn) {
|
||||||
|
actions[name] = fn;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Below are miscellaneous utility functions used by vim.js
|
* Below are miscellaneous utility functions used by vim.js
|
||||||
*/
|
*/
|
||||||
|
@ -2602,9 +2633,6 @@
|
||||||
function lineLength(cm, lineNum) {
|
function lineLength(cm, lineNum) {
|
||||||
return cm.getLine(lineNum).length;
|
return cm.getLine(lineNum).length;
|
||||||
}
|
}
|
||||||
function reverse(s){
|
|
||||||
return s.split('').reverse().join('');
|
|
||||||
}
|
|
||||||
function trim(s) {
|
function trim(s) {
|
||||||
if (s.trim) {
|
if (s.trim) {
|
||||||
return s.trim();
|
return s.trim();
|
||||||
|
@ -2918,59 +2946,38 @@
|
||||||
|
|
||||||
// Seek to first word or non-whitespace character, depending on if
|
// Seek to first word or non-whitespace character, depending on if
|
||||||
// noSymbol is true.
|
// noSymbol is true.
|
||||||
var textAfterIdx = line.substring(idx);
|
var test = noSymbol ? wordCharTest[0] : bigWordCharTest [0];
|
||||||
var firstMatchedChar;
|
while (!test(line.charAt(idx))) {
|
||||||
if (noSymbol) {
|
idx++;
|
||||||
firstMatchedChar = textAfterIdx.search(/\w/);
|
if (idx >= line.length) { return null; }
|
||||||
} else {
|
|
||||||
firstMatchedChar = textAfterIdx.search(/\S/);
|
|
||||||
}
|
}
|
||||||
if (firstMatchedChar == -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
idx += firstMatchedChar;
|
|
||||||
textAfterIdx = line.substring(idx);
|
|
||||||
var textBeforeIdx = line.substring(0, idx);
|
|
||||||
|
|
||||||
var matchRegex;
|
|
||||||
// Greedy matchers for the "word" we are trying to expand.
|
|
||||||
if (bigWord) {
|
if (bigWord) {
|
||||||
matchRegex = /^\S+/;
|
test = bigWordCharTest[0];
|
||||||
} else {
|
} else {
|
||||||
if ((/\w/).test(line.charAt(idx))) {
|
test = wordCharTest[0];
|
||||||
matchRegex = /^\w+/;
|
if (!test(line.charAt(idx))) {
|
||||||
} else {
|
test = wordCharTest[1];
|
||||||
matchRegex = /^[^\w\s]+/;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var wordAfterRegex = matchRegex.exec(textAfterIdx);
|
var end = idx, start = idx;
|
||||||
var wordStart = idx;
|
while (test(line.charAt(end)) && end < line.length) { end++; }
|
||||||
var wordEnd = idx + wordAfterRegex[0].length;
|
while (test(line.charAt(start)) && start >= 0) { start--; }
|
||||||
// TODO: Find a better way to do this. It will be slow on very long lines.
|
start++;
|
||||||
var revTextBeforeIdx = reverse(textBeforeIdx);
|
|
||||||
var wordBeforeRegex = matchRegex.exec(revTextBeforeIdx);
|
|
||||||
if (wordBeforeRegex) {
|
|
||||||
wordStart -= wordBeforeRegex[0].length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inclusive) {
|
if (inclusive) {
|
||||||
// If present, trim all whitespace after word.
|
// If present, include all whitespace after word.
|
||||||
// Otherwise, trim all whitespace before word.
|
// Otherwise, include all whitespace before word, except indentation.
|
||||||
var textAfterWordEnd = line.substring(wordEnd);
|
var wordEnd = end;
|
||||||
var whitespacesAfterWord = textAfterWordEnd.match(/^\s*/)[0].length;
|
while (/\s/.test(line.charAt(end)) && end < line.length) { end++; }
|
||||||
if (whitespacesAfterWord > 0) {
|
if (wordEnd == end) {
|
||||||
wordEnd += whitespacesAfterWord;
|
var wordStart = start;
|
||||||
} else {
|
while (/\s/.test(line.charAt(start - 1)) && start > 0) { start--; }
|
||||||
var revTrim = revTextBeforeIdx.length - wordStart;
|
if (!start) { start = wordStart; }
|
||||||
var textBeforeWordStart = revTextBeforeIdx.substring(revTrim);
|
|
||||||
var whitespacesBeforeWord = textBeforeWordStart.match(/^\s*/)[0].length;
|
|
||||||
wordStart -= whitespacesBeforeWord;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return { start: Pos(cur.line, start), end: Pos(cur.line, end) };
|
||||||
return { start: Pos(cur.line, wordStart),
|
|
||||||
end: Pos(cur.line, wordEnd) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function recordJumpPosition(cm, oldCur, newCur) {
|
function recordJumpPosition(cm, oldCur, newCur) {
|
||||||
|
@ -3128,7 +3135,7 @@
|
||||||
var pos = cur.ch;
|
var pos = cur.ch;
|
||||||
var line = cm.getLine(lineNum);
|
var line = cm.getLine(lineNum);
|
||||||
var dir = forward ? 1 : -1;
|
var dir = forward ? 1 : -1;
|
||||||
var regexps = bigWord ? bigWordRegexp : wordRegexp;
|
var charTests = bigWord ? bigWordCharTest: wordCharTest;
|
||||||
|
|
||||||
if (emptyLineIsWord && line == '') {
|
if (emptyLineIsWord && line == '') {
|
||||||
lineNum += dir;
|
lineNum += dir;
|
||||||
|
@ -3148,11 +3155,11 @@
|
||||||
// Find bounds of next word.
|
// Find bounds of next word.
|
||||||
while (pos != stop) {
|
while (pos != stop) {
|
||||||
var foundWord = false;
|
var foundWord = false;
|
||||||
for (var i = 0; i < regexps.length && !foundWord; ++i) {
|
for (var i = 0; i < charTests.length && !foundWord; ++i) {
|
||||||
if (regexps[i].test(line.charAt(pos))) {
|
if (charTests[i](line.charAt(pos))) {
|
||||||
wordStart = pos;
|
wordStart = pos;
|
||||||
// Advance to end of word.
|
// Advance to end of word.
|
||||||
while (pos != stop && regexps[i].test(line.charAt(pos))) {
|
while (pos != stop && charTests[i](line.charAt(pos))) {
|
||||||
pos += dir;
|
pos += dir;
|
||||||
}
|
}
|
||||||
wordEnd = pos;
|
wordEnd = pos;
|
||||||
|
@ -3469,6 +3476,12 @@
|
||||||
},
|
},
|
||||||
setReversed: function(reversed) {
|
setReversed: function(reversed) {
|
||||||
vimGlobalState.isReversed = reversed;
|
vimGlobalState.isReversed = reversed;
|
||||||
|
},
|
||||||
|
getScrollbarAnnotate: function() {
|
||||||
|
return this.annotate;
|
||||||
|
},
|
||||||
|
setScrollbarAnnotate: function(annotate) {
|
||||||
|
this.annotate = annotate;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
function getSearchState(cm) {
|
function getSearchState(cm) {
|
||||||
|
@ -3478,7 +3491,8 @@
|
||||||
function dialog(cm, template, shortText, onClose, options) {
|
function dialog(cm, template, shortText, onClose, options) {
|
||||||
if (cm.openDialog) {
|
if (cm.openDialog) {
|
||||||
cm.openDialog(template, onClose, { bottom: true, value: options.value,
|
cm.openDialog(template, onClose, { bottom: true, value: options.value,
|
||||||
onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp });
|
onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp,
|
||||||
|
selectValueOnOpen: false});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
onClose(prompt(shortText, ''));
|
onClose(prompt(shortText, ''));
|
||||||
|
@ -3747,14 +3761,21 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function highlightSearchMatches(cm, query) {
|
function highlightSearchMatches(cm, query) {
|
||||||
var overlay = getSearchState(cm).getOverlay();
|
var searchState = getSearchState(cm);
|
||||||
|
var overlay = searchState.getOverlay();
|
||||||
if (!overlay || query != overlay.query) {
|
if (!overlay || query != overlay.query) {
|
||||||
if (overlay) {
|
if (overlay) {
|
||||||
cm.removeOverlay(overlay);
|
cm.removeOverlay(overlay);
|
||||||
}
|
}
|
||||||
overlay = searchOverlay(query);
|
overlay = searchOverlay(query);
|
||||||
cm.addOverlay(overlay);
|
cm.addOverlay(overlay);
|
||||||
getSearchState(cm).setOverlay(overlay);
|
if (cm.showMatchesOnScrollbar) {
|
||||||
|
if (searchState.getScrollbarAnnotate()) {
|
||||||
|
searchState.getScrollbarAnnotate().clear();
|
||||||
|
}
|
||||||
|
searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query));
|
||||||
|
}
|
||||||
|
searchState.setOverlay(overlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function findNext(cm, prev, query, repeat) {
|
function findNext(cm, prev, query, repeat) {
|
||||||
|
@ -3779,8 +3800,13 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function clearSearchHighlight(cm) {
|
function clearSearchHighlight(cm) {
|
||||||
|
var state = getSearchState(cm);
|
||||||
cm.removeOverlay(getSearchState(cm).getOverlay());
|
cm.removeOverlay(getSearchState(cm).getOverlay());
|
||||||
getSearchState(cm).setOverlay(null);
|
state.setOverlay(null);
|
||||||
|
if (state.getScrollbarAnnotate()) {
|
||||||
|
state.getScrollbarAnnotate().clear();
|
||||||
|
state.setScrollbarAnnotate(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Check if pos is in the specified range, INCLUSIVE.
|
* Check if pos is in the specified range, INCLUSIVE.
|
||||||
|
@ -3844,6 +3870,13 @@
|
||||||
};
|
};
|
||||||
ExCommandDispatcher.prototype = {
|
ExCommandDispatcher.prototype = {
|
||||||
processCommand: function(cm, input, opt_params) {
|
processCommand: function(cm, input, opt_params) {
|
||||||
|
var that = this;
|
||||||
|
cm.operation(function () {
|
||||||
|
cm.curOp.isVimOp = true;
|
||||||
|
that._processCommand(cm, input, opt_params);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_processCommand: function(cm, input, opt_params) {
|
||||||
var vim = cm.state.vim;
|
var vim = cm.state.vim;
|
||||||
var commandHistoryRegister = vimGlobalState.registerController.getRegister(':');
|
var commandHistoryRegister = vimGlobalState.registerController.getRegister(':');
|
||||||
var previousCommand = commandHistoryRegister.toString();
|
var previousCommand = commandHistoryRegister.toString();
|
||||||
|
@ -4609,6 +4642,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _mapCommand(command) {
|
||||||
|
defaultKeymap.push(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapCommand(keys, type, name, args, extra) {
|
||||||
|
var command = {keys: keys, type: type};
|
||||||
|
command[type] = name;
|
||||||
|
command[type + "Args"] = args;
|
||||||
|
for (var key in extra)
|
||||||
|
command[key] = extra[key];
|
||||||
|
_mapCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
// The timeout in milliseconds for the two-character ESC keymap should be
|
// The timeout in milliseconds for the two-character ESC keymap should be
|
||||||
// adjusted according to your typing speed to prevent false positives.
|
// adjusted according to your typing speed to prevent false positives.
|
||||||
defineOption('insertModeEscKeysTimeout', 200, 'number');
|
defineOption('insertModeEscKeysTimeout', 200, 'number');
|
||||||
|
@ -4749,7 +4795,7 @@
|
||||||
var anchor = cm.getCursor('anchor');
|
var anchor = cm.getCursor('anchor');
|
||||||
var head = cm.getCursor('head');
|
var head = cm.getCursor('head');
|
||||||
// Enter or exit visual mode to match mouse selection.
|
// Enter or exit visual mode to match mouse selection.
|
||||||
if (vim.visualMode && cursorEqual(head, anchor) && lineLength(cm, head.line) > head.ch) {
|
if (vim.visualMode && !cm.somethingSelected()) {
|
||||||
exitVisualMode(cm, false);
|
exitVisualMode(cm, false);
|
||||||
} else if (!vim.visualMode && !vim.insertMode && cm.somethingSelected()) {
|
} else if (!vim.visualMode && !vim.insertMode && cm.somethingSelected()) {
|
||||||
vim.visualMode = true;
|
vim.visualMode = true;
|
||||||
|
@ -4789,6 +4835,7 @@
|
||||||
var macroModeState = vimGlobalState.macroModeState;
|
var macroModeState = vimGlobalState.macroModeState;
|
||||||
var lastChange = macroModeState.lastInsertModeChanges;
|
var lastChange = macroModeState.lastInsertModeChanges;
|
||||||
var keyName = CodeMirror.keyName(e);
|
var keyName = CodeMirror.keyName(e);
|
||||||
|
if (!keyName) { return; }
|
||||||
function onKeyFound() {
|
function onKeyFound() {
|
||||||
lastChange.changes.push(new InsertModeKey(keyName));
|
lastChange.changes.push(new InsertModeKey(keyName));
|
||||||
return true;
|
return true;
|
|
@ -0,0 +1,73 @@
|
||||||
|
// 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";
|
||||||
|
|
||||||
|
function errorIfNotEmpty(stream) {
|
||||||
|
var nonWS = stream.match(/^\s*\S/);
|
||||||
|
stream.skipToEnd();
|
||||||
|
return nonWS ? "error" : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeMirror.defineMode("asciiarmor", function() {
|
||||||
|
return {
|
||||||
|
token: function(stream, state) {
|
||||||
|
var m;
|
||||||
|
if (state.state == "top") {
|
||||||
|
if (stream.sol() && (m = stream.match(/^-----BEGIN (.*)?-----\s*$/))) {
|
||||||
|
state.state = "headers";
|
||||||
|
state.type = m[1];
|
||||||
|
return "tag";
|
||||||
|
}
|
||||||
|
return errorIfNotEmpty(stream);
|
||||||
|
} else if (state.state == "headers") {
|
||||||
|
if (stream.sol() && stream.match(/^\w+:/)) {
|
||||||
|
state.state = "header";
|
||||||
|
return "atom";
|
||||||
|
} else {
|
||||||
|
var result = errorIfNotEmpty(stream);
|
||||||
|
if (result) state.state = "body";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} else if (state.state == "header") {
|
||||||
|
stream.skipToEnd();
|
||||||
|
state.state = "headers";
|
||||||
|
return "string";
|
||||||
|
} else if (state.state == "body") {
|
||||||
|
if (stream.sol() && (m = stream.match(/^-----END (.*)?-----\s*$/))) {
|
||||||
|
if (m[1] != state.type) return "error";
|
||||||
|
state.state = "end";
|
||||||
|
return "tag";
|
||||||
|
} else {
|
||||||
|
if (stream.eatWhile(/[A-Za-z0-9+\/=]/)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
stream.next();
|
||||||
|
return "error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (state.state == "end") {
|
||||||
|
return errorIfNotEmpty(stream);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
blankLine: function(state) {
|
||||||
|
if (state.state == "headers") state.state = "body";
|
||||||
|
},
|
||||||
|
startState: function() {
|
||||||
|
return {state: "top", type: null};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
CodeMirror.defineMIME("application/pgp", "asciiarmor");
|
||||||
|
CodeMirror.defineMIME("application/pgp-keys", "asciiarmor");
|
||||||
|
CodeMirror.defineMIME("application/pgp-signature", "asciiarmor");
|
||||||
|
});
|
|
@ -0,0 +1,46 @@
|
||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<title>CodeMirror: ASCII Armor (PGP) 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="asciiarmor.js"></script>
|
||||||
|
<style>.CodeMirror {background: #f8f8f8;}</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="#">ASCII Armor</a>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<h2>ASCII Armor (PGP) mode</h2>
|
||||||
|
<form><textarea id="code" name="code">
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
Version: OpenPrivacy 0.99
|
||||||
|
|
||||||
|
yDgBO22WxBHv7O8X7O/jygAEzol56iUKiXmV+XmpCtmpqQUKiQrFqclFqUDBovzS
|
||||||
|
vBSFjNSiVHsuAA==
|
||||||
|
=njUN
|
||||||
|
-----END PGP MESSAGE-----
|
||||||
|
</textarea></form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||||
|
lineNumbers: true
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p><strong>MIME types
|
||||||
|
defined:</strong> <code>application/pgp</code>, <code>application/pgp-keys</code>, <code>application/pgp-signature</code></p>
|
||||||
|
|
||||||
|
</article>
|
|
@ -354,7 +354,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
||||||
state.tokenize = null;
|
state.tokenize = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
escaped = stream.next() != "\\" && !escaped;
|
escaped = stream.next() == "\\" && !escaped;
|
||||||
}
|
}
|
||||||
return "string";
|
return "string";
|
||||||
}
|
}
|
||||||
|
@ -398,8 +398,13 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
||||||
if (!stream.match('""')) return false;
|
if (!stream.match('""')) return false;
|
||||||
state.tokenize = tokenTripleString;
|
state.tokenize = tokenTripleString;
|
||||||
return state.tokenize(stream, state);
|
return state.tokenize(stream, state);
|
||||||
|
},
|
||||||
|
"'": function(stream) {
|
||||||
|
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
|
||||||
|
return "atom";
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modeProps: {closeBrackets: {triples: '"'}}
|
||||||
});
|
});
|
||||||
|
|
||||||
def(["x-shader/x-vertex", "x-shader/x-fragment"], {
|
def(["x-shader/x-vertex", "x-shader/x-fragment"], {
|
||||||
|
@ -416,7 +421,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
||||||
blockKeywords: words("for while do if else struct"),
|
blockKeywords: words("for while do if else struct"),
|
||||||
builtin: words("radians degrees sin cos tan asin acos atan " +
|
builtin: words("radians degrees sin cos tan asin acos atan " +
|
||||||
"pow exp log exp2 sqrt inversesqrt " +
|
"pow exp log exp2 sqrt inversesqrt " +
|
||||||
"abs sign floor ceil fract mod min max clamp mix step smootstep " +
|
"abs sign floor ceil fract mod min max clamp mix step smoothstep " +
|
||||||
"length distance dot cross normalize ftransform faceforward " +
|
"length distance dot cross normalize ftransform faceforward " +
|
||||||
"reflect refract matrixCompMult " +
|
"reflect refract matrixCompMult " +
|
||||||
"lessThan lessThanEqual greaterThan greaterThanEqual " +
|
"lessThan lessThanEqual greaterThan greaterThanEqual " +
|
||||||
|
@ -433,12 +438,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
|
||||||
"gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
|
"gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
|
||||||
"gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
|
"gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
|
||||||
"gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
|
"gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
|
||||||
"gl_FogCoord " +
|
"gl_FogCoord gl_PointCoord " +
|
||||||
"gl_Position gl_PointSize gl_ClipVertex " +
|
"gl_Position gl_PointSize gl_ClipVertex " +
|
||||||
"gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
|
"gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
|
||||||
"gl_TexCoord gl_FogFragCoord " +
|
"gl_TexCoord gl_FogFragCoord " +
|
||||||
"gl_FragCoord gl_FrontFacing " +
|
"gl_FragCoord gl_FrontFacing " +
|
||||||
"gl_FragColor gl_FragData gl_FragDepth " +
|
"gl_FragData gl_FragDepth " +
|
||||||
"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
|
"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
|
||||||
"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
|
"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
|
||||||
"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
|
"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
|
|
@ -234,6 +234,7 @@ CodeMirror.defineMode("clojure", function (options) {
|
||||||
return state.indentStack.indent;
|
return state.indentStack.indent;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
closeBrackets: {pairs: "()[]{}\"\""},
|
||||||
lineComment: ";;"
|
lineComment: ";;"
|
||||||
};
|
};
|
||||||
});
|
});
|
|
@ -0,0 +1,97 @@
|
||||||
|
// 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")
|
||||||
|
mod(require("../../lib/codemirror"));
|
||||||
|
else if (typeof define == "function" && define.amd)
|
||||||
|
define(["../../lib/codemirror"], mod);
|
||||||
|
else
|
||||||
|
mod(CodeMirror);
|
||||||
|
})(function(CodeMirror) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
CodeMirror.defineMode("cmake", function () {
|
||||||
|
var variable_regex = /({)?[a-zA-Z0-9_]+(})?/;
|
||||||
|
|
||||||
|
function tokenString(stream, state) {
|
||||||
|
var current, prev, found_var = false;
|
||||||
|
while (!stream.eol() && (current = stream.next()) != state.pending) {
|
||||||
|
if (current === '$' && prev != '\\' && state.pending == '"') {
|
||||||
|
found_var = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev = current;
|
||||||
|
}
|
||||||
|
if (found_var) {
|
||||||
|
stream.backUp(1);
|
||||||
|
}
|
||||||
|
if (current == state.pending) {
|
||||||
|
state.continueString = false;
|
||||||
|
} else {
|
||||||
|
state.continueString = true;
|
||||||
|
}
|
||||||
|
return "string";
|
||||||
|
}
|
||||||
|
|
||||||
|
function tokenize(stream, state) {
|
||||||
|
var ch = stream.next();
|
||||||
|
|
||||||
|
// Have we found a variable?
|
||||||
|
if (ch === '$') {
|
||||||
|
if (stream.match(variable_regex)) {
|
||||||
|
return 'variable-2';
|
||||||
|
}
|
||||||
|
return 'variable';
|
||||||
|
}
|
||||||
|
// Should we still be looking for the end of a string?
|
||||||
|
if (state.continueString) {
|
||||||
|
// If so, go through the loop again
|
||||||
|
stream.backUp(1);
|
||||||
|
return tokenString(stream, state);
|
||||||
|
}
|
||||||
|
// Do we just have a function on our hands?
|
||||||
|
// In 'cmake_minimum_required (VERSION 2.8.8)', 'cmake_minimum_required' is matched
|
||||||
|
if (stream.match(/(\s+)?\w+\(/) || stream.match(/(\s+)?\w+\ \(/)) {
|
||||||
|
stream.backUp(1);
|
||||||
|
return 'def';
|
||||||
|
}
|
||||||
|
if (ch == "#") {
|
||||||
|
stream.skipToEnd();
|
||||||
|
return "comment";
|
||||||
|
}
|
||||||
|
// Have we found a string?
|
||||||
|
if (ch == "'" || ch == '"') {
|
||||||
|
// Store the type (single or double)
|
||||||
|
state.pending = ch;
|
||||||
|
// Perform the looping function to find the end
|
||||||
|
return tokenString(stream, state);
|
||||||
|
}
|
||||||
|
if (ch == '(' || ch == ')') {
|
||||||
|
return 'bracket';
|
||||||
|
}
|
||||||
|
if (ch.match(/[0-9]/)) {
|
||||||
|
return 'number';
|
||||||
|
}
|
||||||
|
stream.eatWhile(/[\w-]/);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
startState: function () {
|
||||||
|
var state = {};
|
||||||
|
state.inDefinition = false;
|
||||||
|
state.inInclude = false;
|
||||||
|
state.continueString = false;
|
||||||
|
state.pending = false;
|
||||||
|
return state;
|
||||||
|
},
|
||||||
|
token: function (stream, state) {
|
||||||
|
if (stream.eatSpace()) return null;
|
||||||
|
return tokenize(stream, state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
CodeMirror.defineMIME("text/x-cmake", "cmake");
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,129 @@
|
||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<title>CodeMirror: CMake 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="cmake.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="#">CMake</a>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<article>
|
||||||
|
<h2>CMake mode</h2>
|
||||||
|
<form><textarea id="code" name="code">
|
||||||
|
# vim: syntax=cmake
|
||||||
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
# default to Release build for GCC builds
|
||||||
|
set(CMAKE_BUILD_TYPE Release CACHE STRING
|
||||||
|
"Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel."
|
||||||
|
FORCE)
|
||||||
|
endif()
|
||||||
|
message(STATUS "cmake version ${CMAKE_VERSION}")
|
||||||
|
if(POLICY CMP0025)
|
||||||
|
cmake_policy(SET CMP0025 OLD) # report Apple's Clang as just Clang
|
||||||
|
endif()
|
||||||
|
if(POLICY CMP0042)
|
||||||
|
cmake_policy(SET CMP0042 NEW) # MACOSX_RPATH
|
||||||
|
endif()
|
||||||
|
|
||||||
|
project (x265)
|
||||||
|
cmake_minimum_required (VERSION 2.8.8) # OBJECT libraries require 2.8.8
|
||||||
|
include(CheckIncludeFiles)
|
||||||
|
include(CheckFunctionExists)
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
|
||||||
|
# X265_BUILD must be incremented each time the public API is changed
|
||||||
|
set(X265_BUILD 48)
|
||||||
|
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
|
||||||
|
"${PROJECT_BINARY_DIR}/x265.def")
|
||||||
|
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
|
||||||
|
"${PROJECT_BINARY_DIR}/x265_config.h")
|
||||||
|
|
||||||
|
SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}")
|
||||||
|
|
||||||
|
# System architecture detection
|
||||||
|
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" SYSPROC)
|
||||||
|
set(X86_ALIASES x86 i386 i686 x86_64 amd64)
|
||||||
|
list(FIND X86_ALIASES "${SYSPROC}" X86MATCH)
|
||||||
|
if("${SYSPROC}" STREQUAL "" OR X86MATCH GREATER "-1")
|
||||||
|
message(STATUS "Detected x86 target processor")
|
||||||
|
set(X86 1)
|
||||||
|
add_definitions(-DX265_ARCH_X86=1)
|
||||||
|
if("${CMAKE_SIZEOF_VOID_P}" MATCHES 8)
|
||||||
|
set(X64 1)
|
||||||
|
add_definitions(-DX86_64=1)
|
||||||
|
endif()
|
||||||
|
elseif(${SYSPROC} STREQUAL "armv6l")
|
||||||
|
message(STATUS "Detected ARM target processor")
|
||||||
|
set(ARM 1)
|
||||||
|
add_definitions(-DX265_ARCH_ARM=1 -DHAVE_ARMV6=1)
|
||||||
|
else()
|
||||||
|
message(STATUS "CMAKE_SYSTEM_PROCESSOR value `${CMAKE_SYSTEM_PROCESSOR}` is unknown")
|
||||||
|
message(STATUS "Please add this value near ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
list(APPEND PLATFORM_LIBS pthread)
|
||||||
|
find_library(LIBRT rt)
|
||||||
|
if(LIBRT)
|
||||||
|
list(APPEND PLATFORM_LIBS rt)
|
||||||
|
endif()
|
||||||
|
find_package(Numa)
|
||||||
|
if(NUMA_FOUND)
|
||||||
|
list(APPEND CMAKE_REQUIRED_LIBRARIES ${NUMA_LIBRARY})
|
||||||
|
check_symbol_exists(numa_node_of_cpu numa.h NUMA_V2)
|
||||||
|
if(NUMA_V2)
|
||||||
|
add_definitions(-DHAVE_LIBNUMA)
|
||||||
|
message(STATUS "libnuma found, building with support for NUMA nodes")
|
||||||
|
list(APPEND PLATFORM_LIBS ${NUMA_LIBRARY})
|
||||||
|
link_directories(${NUMA_LIBRARY_DIR})
|
||||||
|
include_directories(${NUMA_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
mark_as_advanced(LIBRT NUMA_FOUND)
|
||||||
|
endif(UNIX)
|
||||||
|
|
||||||
|
if(X64 AND NOT WIN32)
|
||||||
|
option(ENABLE_PIC "Enable Position Independent Code" ON)
|
||||||
|
else()
|
||||||
|
option(ENABLE_PIC "Enable Position Independent Code" OFF)
|
||||||
|
endif(X64 AND NOT WIN32)
|
||||||
|
|
||||||
|
# Compiler detection
|
||||||
|
if(CMAKE_GENERATOR STREQUAL "Xcode")
|
||||||
|
set(XCODE 1)
|
||||||
|
endif()
|
||||||
|
if (APPLE)
|
||||||
|
add_definitions(-DMACOS)
|
||||||
|
endif()
|
||||||
|
</textarea></form>
|
||||||
|
<script>
|
||||||
|
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||||
|
mode: "text/x-cmake",
|
||||||
|
matchBrackets: true,
|
||||||
|
indentUnit: 4
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p><strong>MIME types defined:</strong> <code>text/x-cmake</code>.</p>
|
||||||
|
|
||||||
|
</article>
|
|
@ -111,6 +111,7 @@ CodeMirror.defineMode("commonlisp", function (config) {
|
||||||
return typeof i == "number" ? i : state.ctx.start + 1;
|
return typeof i == "number" ? i : state.ctx.start + 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
closeBrackets: {pairs: "()[]{}\"\""},
|
||||||
lineComment: ";;",
|
lineComment: ";;",
|
||||||
blockCommentStart: "#|",
|
blockCommentStart: "#|",
|
||||||
blockCommentEnd: "|#"
|
blockCommentEnd: "|#"
|
|
@ -16,13 +16,15 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
|
|
||||||
var indentUnit = config.indentUnit,
|
var indentUnit = config.indentUnit,
|
||||||
tokenHooks = parserConfig.tokenHooks,
|
tokenHooks = parserConfig.tokenHooks,
|
||||||
|
documentTypes = parserConfig.documentTypes || {},
|
||||||
mediaTypes = parserConfig.mediaTypes || {},
|
mediaTypes = parserConfig.mediaTypes || {},
|
||||||
mediaFeatures = parserConfig.mediaFeatures || {},
|
mediaFeatures = parserConfig.mediaFeatures || {},
|
||||||
propertyKeywords = parserConfig.propertyKeywords || {},
|
propertyKeywords = parserConfig.propertyKeywords || {},
|
||||||
nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
|
nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
|
||||||
|
fontProperties = parserConfig.fontProperties || {},
|
||||||
|
counterDescriptors = parserConfig.counterDescriptors || {},
|
||||||
colorKeywords = parserConfig.colorKeywords || {},
|
colorKeywords = parserConfig.colorKeywords || {},
|
||||||
valueKeywords = parserConfig.valueKeywords || {},
|
valueKeywords = parserConfig.valueKeywords || {},
|
||||||
fontProperties = parserConfig.fontProperties || {},
|
|
||||||
allowNested = parserConfig.allowNested;
|
allowNested = parserConfig.allowNested;
|
||||||
|
|
||||||
var type, override;
|
var type, override;
|
||||||
|
@ -57,6 +59,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
if (/[\d.]/.test(stream.peek())) {
|
if (/[\d.]/.test(stream.peek())) {
|
||||||
stream.eatWhile(/[\w.%]/);
|
stream.eatWhile(/[\w.%]/);
|
||||||
return ret("number", "unit");
|
return ret("number", "unit");
|
||||||
|
} else if (stream.match(/^-[\w\\\-]+/)) {
|
||||||
|
stream.eatWhile(/[\w\\\-]/);
|
||||||
|
if (stream.match(/^\s*:/, false))
|
||||||
|
return ret("variable-2", "variable-definition");
|
||||||
|
return ret("variable-2", "variable");
|
||||||
} else if (stream.match(/^\w+-/)) {
|
} else if (stream.match(/^\w+-/)) {
|
||||||
return ret("meta", "meta");
|
return ret("meta", "meta");
|
||||||
}
|
}
|
||||||
|
@ -66,7 +73,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
return ret("qualifier", "qualifier");
|
return ret("qualifier", "qualifier");
|
||||||
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
|
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
|
||||||
return ret(null, ch);
|
return ret(null, ch);
|
||||||
} else if (ch == "u" && stream.match("rl(")) {
|
} else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
|
||||||
|
(ch == "d" && stream.match("omain(")) ||
|
||||||
|
(ch == "r" && stream.match("egexp("))) {
|
||||||
stream.backUp(1);
|
stream.backUp(1);
|
||||||
state.tokenize = tokenParenthesized;
|
state.tokenize = tokenParenthesized;
|
||||||
return ret("property", "word");
|
return ret("property", "word");
|
||||||
|
@ -148,10 +157,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
return pushContext(state, stream, "block");
|
return pushContext(state, stream, "block");
|
||||||
} else if (type == "}" && state.context.prev) {
|
} else if (type == "}" && state.context.prev) {
|
||||||
return popContext(state);
|
return popContext(state);
|
||||||
} else if (type == "@media") {
|
} else if (/@(media|supports|(-moz-)?document)/.test(type)) {
|
||||||
return pushContext(state, stream, "media");
|
return pushContext(state, stream, "atBlock");
|
||||||
} else if (type == "@font-face") {
|
} else if (/@(font-face|counter-style)/.test(type)) {
|
||||||
return "font_face_before";
|
state.stateArg = type;
|
||||||
|
return "restricted_atBlock_before";
|
||||||
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
|
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
|
||||||
return "keyframes";
|
return "keyframes";
|
||||||
} else if (type && type.charAt(0) == "@") {
|
} else if (type && type.charAt(0) == "@") {
|
||||||
|
@ -229,6 +239,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
if (type == "{" || type == "}") return popAndPass(type, stream, state);
|
||||||
if (type == ")") return popContext(state);
|
if (type == ")") return popContext(state);
|
||||||
if (type == "(") return pushContext(state, stream, "parens");
|
if (type == "(") return pushContext(state, stream, "parens");
|
||||||
|
if (type == "interpolation") return pushContext(state, stream, "interpolation");
|
||||||
if (type == "word") wordAsValue(stream);
|
if (type == "word") wordAsValue(stream);
|
||||||
return "parens";
|
return "parens";
|
||||||
};
|
};
|
||||||
|
@ -241,47 +252,63 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
return pass(type, stream, state);
|
return pass(type, stream, state);
|
||||||
};
|
};
|
||||||
|
|
||||||
states.media = function(type, stream, state) {
|
states.atBlock = function(type, stream, state) {
|
||||||
if (type == "(") return pushContext(state, stream, "media_parens");
|
if (type == "(") return pushContext(state, stream, "atBlock_parens");
|
||||||
if (type == "}") return popAndPass(type, stream, state);
|
if (type == "}") return popAndPass(type, stream, state);
|
||||||
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
|
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
|
||||||
|
|
||||||
if (type == "word") {
|
if (type == "word") {
|
||||||
var word = stream.current().toLowerCase();
|
var word = stream.current().toLowerCase();
|
||||||
if (word == "only" || word == "not" || word == "and")
|
if (word == "only" || word == "not" || word == "and" || word == "or")
|
||||||
override = "keyword";
|
override = "keyword";
|
||||||
|
else if (documentTypes.hasOwnProperty(word))
|
||||||
|
override = "tag";
|
||||||
else if (mediaTypes.hasOwnProperty(word))
|
else if (mediaTypes.hasOwnProperty(word))
|
||||||
override = "attribute";
|
override = "attribute";
|
||||||
else if (mediaFeatures.hasOwnProperty(word))
|
else if (mediaFeatures.hasOwnProperty(word))
|
||||||
override = "property";
|
override = "property";
|
||||||
|
else if (propertyKeywords.hasOwnProperty(word))
|
||||||
|
override = "property";
|
||||||
|
else if (nonStandardPropertyKeywords.hasOwnProperty(word))
|
||||||
|
override = "string-2";
|
||||||
|
else if (valueKeywords.hasOwnProperty(word))
|
||||||
|
override = "atom";
|
||||||
else
|
else
|
||||||
override = "error";
|
override = "error";
|
||||||
}
|
}
|
||||||
return state.context.type;
|
return state.context.type;
|
||||||
};
|
};
|
||||||
|
|
||||||
states.media_parens = function(type, stream, state) {
|
states.atBlock_parens = function(type, stream, state) {
|
||||||
if (type == ")") return popContext(state);
|
if (type == ")") return popContext(state);
|
||||||
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
|
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
|
||||||
return states.media(type, stream, state);
|
return states.atBlock(type, stream, state);
|
||||||
};
|
};
|
||||||
|
|
||||||
states.font_face_before = function(type, stream, state) {
|
states.restricted_atBlock_before = function(type, stream, state) {
|
||||||
if (type == "{")
|
if (type == "{")
|
||||||
return pushContext(state, stream, "font_face");
|
return pushContext(state, stream, "restricted_atBlock");
|
||||||
|
if (type == "word" && state.stateArg == "@counter-style") {
|
||||||
|
override = "variable";
|
||||||
|
return "restricted_atBlock_before";
|
||||||
|
}
|
||||||
return pass(type, stream, state);
|
return pass(type, stream, state);
|
||||||
};
|
};
|
||||||
|
|
||||||
states.font_face = function(type, stream, state) {
|
states.restricted_atBlock = function(type, stream, state) {
|
||||||
if (type == "}") return popContext(state);
|
if (type == "}") {
|
||||||
|
state.stateArg = null;
|
||||||
|
return popContext(state);
|
||||||
|
}
|
||||||
if (type == "word") {
|
if (type == "word") {
|
||||||
if (!fontProperties.hasOwnProperty(stream.current().toLowerCase()))
|
if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
|
||||||
|
(state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
|
||||||
override = "error";
|
override = "error";
|
||||||
else
|
else
|
||||||
override = "property";
|
override = "property";
|
||||||
return "maybeprop";
|
return "maybeprop";
|
||||||
}
|
}
|
||||||
return "font_face";
|
return "restricted_atBlock";
|
||||||
};
|
};
|
||||||
|
|
||||||
states.keyframes = function(type, stream, state) {
|
states.keyframes = function(type, stream, state) {
|
||||||
|
@ -309,6 +336,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
startState: function(base) {
|
startState: function(base) {
|
||||||
return {tokenize: null,
|
return {tokenize: null,
|
||||||
state: "top",
|
state: "top",
|
||||||
|
stateArg: null,
|
||||||
context: new Context("top", base || 0, null)};
|
context: new Context("top", base || 0, null)};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -329,9 +357,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
var indent = cx.indent;
|
var indent = cx.indent;
|
||||||
if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
|
if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
|
||||||
if (cx.prev &&
|
if (cx.prev &&
|
||||||
(ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
|
(ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "restricted_atBlock") ||
|
||||||
ch == ")" && (cx.type == "parens" || cx.type == "media_parens") ||
|
ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
|
||||||
ch == "{" && (cx.type == "at" || cx.type == "media"))) {
|
ch == "{" && (cx.type == "at" || cx.type == "atBlock"))) {
|
||||||
indent = cx.indent - indentUnit;
|
indent = cx.indent - indentUnit;
|
||||||
cx = cx.prev;
|
cx = cx.prev;
|
||||||
}
|
}
|
||||||
|
@ -353,6 +381,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var documentTypes_ = [
|
||||||
|
"domain", "regexp", "url", "url-prefix"
|
||||||
|
], documentTypes = keySet(documentTypes_);
|
||||||
|
|
||||||
var mediaTypes_ = [
|
var mediaTypes_ = [
|
||||||
"all", "aural", "braille", "handheld", "print", "projection", "screen",
|
"all", "aural", "braille", "handheld", "print", "projection", "screen",
|
||||||
"tty", "tv", "embossed"
|
"tty", "tv", "embossed"
|
||||||
|
@ -469,6 +501,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
"searchfield-results-decoration", "zoom"
|
"searchfield-results-decoration", "zoom"
|
||||||
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
|
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
|
||||||
|
|
||||||
|
var fontProperties_ = [
|
||||||
|
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
|
||||||
|
"font-stretch", "font-weight", "font-style"
|
||||||
|
], fontProperties = keySet(fontProperties_);
|
||||||
|
|
||||||
|
var counterDescriptors_ = [
|
||||||
|
"additive-symbols", "fallback", "negative", "pad", "prefix", "range",
|
||||||
|
"speak-as", "suffix", "symbols", "system"
|
||||||
|
], counterDescriptors = keySet(counterDescriptors_);
|
||||||
|
|
||||||
var colorKeywords_ = [
|
var colorKeywords_ = [
|
||||||
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
|
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
|
||||||
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
|
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
|
||||||
|
@ -499,46 +541,49 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
], colorKeywords = keySet(colorKeywords_);
|
], colorKeywords = keySet(colorKeywords_);
|
||||||
|
|
||||||
var valueKeywords_ = [
|
var valueKeywords_ = [
|
||||||
"above", "absolute", "activeborder", "activecaption", "afar",
|
"above", "absolute", "activeborder", "additive", "activecaption", "afar",
|
||||||
"after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
|
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
|
||||||
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
|
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
|
||||||
"arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
|
"arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page",
|
||||||
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
|
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
|
||||||
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
|
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
|
||||||
"both", "bottom", "break", "break-all", "break-word", "button", "button-bevel",
|
"both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
|
||||||
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
|
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
|
||||||
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
|
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
|
||||||
"cell", "center", "checkbox", "circle", "cjk-earthly-branch",
|
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
|
||||||
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
|
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
|
||||||
"col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
|
"col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
|
||||||
"content-box", "context-menu", "continuous", "copy", "cover", "crop",
|
"content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
|
||||||
"cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
|
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "dashed", "decimal",
|
||||||
"decimal-leading-zero", "default", "default-button", "destination-atop",
|
"decimal-leading-zero", "default", "default-button", "destination-atop",
|
||||||
"destination-in", "destination-out", "destination-over", "devanagari",
|
"destination-in", "destination-out", "destination-over", "devanagari",
|
||||||
"disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
|
"disc", "discard", "disclosure-closed", "disclosure-open", "document",
|
||||||
"double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
|
"dot-dash", "dot-dot-dash",
|
||||||
|
"dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
|
||||||
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
|
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
|
||||||
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
|
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
|
||||||
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
|
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
|
||||||
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
|
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
|
||||||
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
|
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
|
||||||
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
|
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
|
||||||
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
|
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
|
||||||
"ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
|
"ethiopic-numeric", "ew-resize", "expanded", "extends", "extra-condensed",
|
||||||
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
|
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "footnotes",
|
||||||
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
|
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
|
||||||
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
|
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
|
||||||
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
|
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
|
||||||
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
|
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
|
||||||
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
|
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
|
||||||
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
|
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
|
||||||
"inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
|
"inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
|
||||||
"italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
|
"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",
|
||||||
"line-through", "linear", "lines", "list-item", "listbox", "listitem",
|
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
|
||||||
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
|
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
|
||||||
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
|
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
|
||||||
"lower-roman", "lowercase", "ltr", "malayalam", "match",
|
"lower-roman", "lowercase", "ltr", "malayalam", "match", "matrix", "matrix3d",
|
||||||
"media-controls-background", "media-current-time-display",
|
"media-controls-background", "media-current-time-display",
|
||||||
"media-fullscreen-button", "media-mute-button", "media-play-button",
|
"media-fullscreen-button", "media-mute-button", "media-play-button",
|
||||||
"media-return-to-realtime-button", "media-rewind-button",
|
"media-return-to-realtime-button", "media-rewind-button",
|
||||||
|
@ -550,45 +595,48 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
"mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
|
"mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
|
||||||
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
|
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
|
||||||
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
|
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
|
||||||
"ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
|
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
|
||||||
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
|
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
|
||||||
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
|
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
|
||||||
"painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer",
|
"painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
|
||||||
"polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
|
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
|
||||||
"radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region",
|
"progress", "push-button", "radial-gradient", "radio", "read-only",
|
||||||
"relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
|
"read-write", "read-write-plaintext-only", "rectangle", "region",
|
||||||
"ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
|
"relative", "repeat", "repeating-linear-gradient",
|
||||||
"s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
|
"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",
|
||||||
|
"scroll", "scrollbar", "se-resize", "searchfield",
|
||||||
"searchfield-cancel-button", "searchfield-decoration",
|
"searchfield-cancel-button", "searchfield-decoration",
|
||||||
"searchfield-results-button", "searchfield-results-decoration",
|
"searchfield-results-button", "searchfield-results-decoration",
|
||||||
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
|
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
|
||||||
"single", "skip-white-space", "slide", "slider-horizontal",
|
"simp-chinese-formal", "simp-chinese-informal", "single",
|
||||||
|
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
|
||||||
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
|
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
|
||||||
"small", "small-caps", "small-caption", "smaller", "solid", "somali",
|
"small", "small-caps", "small-caption", "smaller", "solid", "somali",
|
||||||
"source-atop", "source-in", "source-out", "source-over", "space", "square",
|
"source-atop", "source-in", "source-out", "source-over", "space", "spell-out", "square",
|
||||||
"square-button", "start", "static", "status-bar", "stretch", "stroke",
|
"square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
|
||||||
"sub", "subpixel-antialiased", "super", "sw-resize", "table",
|
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
|
||||||
"table-caption", "table-cell", "table-column", "table-column-group",
|
"table-caption", "table-cell", "table-column", "table-column-group",
|
||||||
"table-footer-group", "table-header-group", "table-row", "table-row-group",
|
"table-footer-group", "table-header-group", "table-row", "table-row-group",
|
||||||
|
"tamil",
|
||||||
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
|
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
|
||||||
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
|
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
|
||||||
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
|
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
|
||||||
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
|
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
|
||||||
|
"trad-chinese-formal", "trad-chinese-informal",
|
||||||
|
"translate", "translate3d", "translateX", "translateY", "translateZ",
|
||||||
"transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
|
"transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
|
||||||
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
|
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
|
||||||
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
|
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
|
||||||
"vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
|
"var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
|
||||||
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
|
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
|
||||||
"window", "windowframe", "windowtext", "x-large", "x-small", "xor",
|
"window", "windowframe", "windowtext", "words", "x-large", "x-small", "xor",
|
||||||
"xx-large", "xx-small"
|
"xx-large", "xx-small"
|
||||||
], valueKeywords = keySet(valueKeywords_);
|
], valueKeywords = keySet(valueKeywords_);
|
||||||
|
|
||||||
var fontProperties_ = [
|
var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(propertyKeywords_)
|
||||||
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
|
|
||||||
"font-stretch", "font-weight", "font-style"
|
|
||||||
], fontProperties = keySet(fontProperties_);
|
|
||||||
|
|
||||||
var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_)
|
|
||||||
.concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
|
.concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
|
||||||
CodeMirror.registerHelper("hintWords", "css", allWords);
|
CodeMirror.registerHelper("hintWords", "css", allWords);
|
||||||
|
|
||||||
|
@ -615,13 +663,15 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeMirror.defineMIME("text/css", {
|
CodeMirror.defineMIME("text/css", {
|
||||||
|
documentTypes: documentTypes,
|
||||||
mediaTypes: mediaTypes,
|
mediaTypes: mediaTypes,
|
||||||
mediaFeatures: mediaFeatures,
|
mediaFeatures: mediaFeatures,
|
||||||
propertyKeywords: propertyKeywords,
|
propertyKeywords: propertyKeywords,
|
||||||
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
|
||||||
|
fontProperties: fontProperties,
|
||||||
|
counterDescriptors: counterDescriptors,
|
||||||
colorKeywords: colorKeywords,
|
colorKeywords: colorKeywords,
|
||||||
valueKeywords: valueKeywords,
|
valueKeywords: valueKeywords,
|
||||||
fontProperties: fontProperties,
|
|
||||||
tokenHooks: {
|
tokenHooks: {
|
||||||
"<": function(stream, state) {
|
"<": function(stream, state) {
|
||||||
if (!stream.match("!--")) return false;
|
if (!stream.match("!--")) return false;
|
|
@ -146,7 +146,7 @@ fieldset span button, fieldset span input[type="file"] {
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<p>The LESS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>.</p>
|
<p>The LESS mode is a sub-mode of the <a href="index.html">CSS mode</a> (defined in <code>css.js</code>).</p>
|
||||||
|
|
||||||
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#less_*">normal</a>, <a href="../../test/index.html#verbose,less_*">verbose</a>.</p>
|
<p><strong>Parsing/Highlighting Tests:</strong> <a href="../../test/index.html#less_*">normal</a>, <a href="../../test/index.html#verbose,less_*">verbose</a>.</p>
|
||||||
</article>
|
</article>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue