mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-27 00:16:21 +00:00
96d4a3ecf7
Due to historical reasons, the code is in subfolder "1". With SVN removal, we place the code back and remove the annoying "1" folder.
147 lines
6.0 KiB
JavaScript
147 lines
6.0 KiB
JavaScript
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
|
|
|
// By the Neo4j Team and contributors.
|
|
// https://github.com/neo4j-contrib/CodeMirror
|
|
|
|
(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";
|
|
var wordRegexp = function(words) {
|
|
return new RegExp("^(?:" + words.join("|") + ")$", "i");
|
|
};
|
|
|
|
CodeMirror.defineMode("cypher", function(config) {
|
|
var tokenBase = function(stream/*, state*/) {
|
|
var ch = stream.next(), curPunc = null;
|
|
if (ch === "\"" || ch === "'") {
|
|
stream.match(/.+?["']/);
|
|
return "string";
|
|
}
|
|
if (/[{}\(\),\.;\[\]]/.test(ch)) {
|
|
curPunc = ch;
|
|
return "node";
|
|
} else if (ch === "/" && stream.eat("/")) {
|
|
stream.skipToEnd();
|
|
return "comment";
|
|
} else if (operatorChars.test(ch)) {
|
|
stream.eatWhile(operatorChars);
|
|
return null;
|
|
} else {
|
|
stream.eatWhile(/[_\w\d]/);
|
|
if (stream.eat(":")) {
|
|
stream.eatWhile(/[\w\d_\-]/);
|
|
return "atom";
|
|
}
|
|
var word = stream.current();
|
|
if (funcs.test(word)) return "builtin";
|
|
if (preds.test(word)) return "def";
|
|
if (keywords.test(word)) return "keyword";
|
|
return "variable";
|
|
}
|
|
};
|
|
var pushContext = function(state, type, col) {
|
|
return state.context = {
|
|
prev: state.context,
|
|
indent: state.indent,
|
|
col: col,
|
|
type: type
|
|
};
|
|
};
|
|
var popContext = function(state) {
|
|
state.indent = state.context.indent;
|
|
return state.context = state.context.prev;
|
|
};
|
|
var indentUnit = config.indentUnit;
|
|
var curPunc;
|
|
var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "right", "round", "rtrim", "shortestPath", "sign", "sin", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "trim", "type", "upper"]);
|
|
var preds = wordRegexp(["all", "and", "any", "has", "in", "none", "not", "or", "single", "xor"]);
|
|
var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "distinct", "drop", "else", "end", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "remove", "return", "scan", "set", "skip", "start", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
|
|
var operatorChars = /[*+\-<>=&|~%^]/;
|
|
|
|
return {
|
|
startState: function(/*base*/) {
|
|
return {
|
|
tokenize: tokenBase,
|
|
context: null,
|
|
indent: 0,
|
|
col: 0
|
|
};
|
|
},
|
|
token: function(stream, state) {
|
|
if (stream.sol()) {
|
|
if (state.context && (state.context.align == null)) {
|
|
state.context.align = false;
|
|
}
|
|
state.indent = stream.indentation();
|
|
}
|
|
if (stream.eatSpace()) {
|
|
return null;
|
|
}
|
|
var style = state.tokenize(stream, state);
|
|
if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") {
|
|
state.context.align = true;
|
|
}
|
|
if (curPunc === "(") {
|
|
pushContext(state, ")", stream.column());
|
|
} else if (curPunc === "[") {
|
|
pushContext(state, "]", stream.column());
|
|
} else if (curPunc === "{") {
|
|
pushContext(state, "}", stream.column());
|
|
} else if (/[\]\}\)]/.test(curPunc)) {
|
|
while (state.context && state.context.type === "pattern") {
|
|
popContext(state);
|
|
}
|
|
if (state.context && curPunc === state.context.type) {
|
|
popContext(state);
|
|
}
|
|
} else if (curPunc === "." && state.context && state.context.type === "pattern") {
|
|
popContext(state);
|
|
} else if (/atom|string|variable/.test(style) && state.context) {
|
|
if (/[\}\]]/.test(state.context.type)) {
|
|
pushContext(state, "pattern", stream.column());
|
|
} else if (state.context.type === "pattern" && !state.context.align) {
|
|
state.context.align = true;
|
|
state.context.col = stream.column();
|
|
}
|
|
}
|
|
return style;
|
|
},
|
|
indent: function(state, textAfter) {
|
|
var firstChar = textAfter && textAfter.charAt(0);
|
|
var context = state.context;
|
|
if (/[\]\}]/.test(firstChar)) {
|
|
while (context && context.type === "pattern") {
|
|
context = context.prev;
|
|
}
|
|
}
|
|
var closing = context && firstChar === context.type;
|
|
if (!context) return 0;
|
|
if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent;
|
|
if (context.align) return context.col + (closing ? 0 : 1);
|
|
return context.indent + (closing ? 0 : indentUnit);
|
|
}
|
|
};
|
|
});
|
|
|
|
CodeMirror.modeExtensions["cypher"] = {
|
|
autoFormatLineBreaks: function(text) {
|
|
var i, lines, reProcessedPortion;
|
|
var lines = text.split("\n");
|
|
var reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g;
|
|
for (var i = 0; i < lines.length; i++)
|
|
lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim();
|
|
return lines.join("\n");
|
|
}
|
|
};
|
|
|
|
CodeMirror.defineMIME("application/x-cypher-query", "cypher");
|
|
|
|
});
|