Mercurial
comparison .cms/lib/codemirror/mode/cypher/cypher.js @ 0:78edf6b517a0 draft
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Fri, 11 Oct 2024 22:40:23 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78edf6b517a0 |
---|---|
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others | |
2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE | |
3 | |
4 // By the Neo4j Team and contributors. | |
5 // https://github.com/neo4j-contrib/CodeMirror | |
6 | |
7 (function(mod) { | |
8 if (typeof exports == "object" && typeof module == "object") // CommonJS | |
9 mod(require("../../lib/codemirror")); | |
10 else if (typeof define == "function" && define.amd) // AMD | |
11 define(["../../lib/codemirror"], mod); | |
12 else // Plain browser env | |
13 mod(CodeMirror); | |
14 })(function(CodeMirror) { | |
15 "use strict"; | |
16 var wordRegexp = function(words) { | |
17 return new RegExp("^(?:" + words.join("|") + ")$", "i"); | |
18 }; | |
19 | |
20 CodeMirror.defineMode("cypher", function(config) { | |
21 var tokenBase = function(stream/*, state*/) { | |
22 curPunc = null | |
23 var ch = stream.next(); | |
24 if (ch ==='"') { | |
25 stream.match(/^[^"]*"/); | |
26 return "string"; | |
27 } | |
28 if (ch === "'") { | |
29 stream.match(/^[^']*'/); | |
30 return "string"; | |
31 } | |
32 if (/[{}\(\),\.;\[\]]/.test(ch)) { | |
33 curPunc = ch; | |
34 return "node"; | |
35 } else if (ch === "/" && stream.eat("/")) { | |
36 stream.skipToEnd(); | |
37 return "comment"; | |
38 } else if (operatorChars.test(ch)) { | |
39 stream.eatWhile(operatorChars); | |
40 return null; | |
41 } else { | |
42 stream.eatWhile(/[_\w\d]/); | |
43 if (stream.eat(":")) { | |
44 stream.eatWhile(/[\w\d_\-]/); | |
45 return "atom"; | |
46 } | |
47 var word = stream.current(); | |
48 if (funcs.test(word)) return "builtin"; | |
49 if (preds.test(word)) return "def"; | |
50 if (keywords.test(word) || systemKeywords.test(word)) return "keyword"; | |
51 return "variable"; | |
52 } | |
53 }; | |
54 var pushContext = function(state, type, col) { | |
55 return state.context = { | |
56 prev: state.context, | |
57 indent: state.indent, | |
58 col: col, | |
59 type: type | |
60 }; | |
61 }; | |
62 var popContext = function(state) { | |
63 state.indent = state.context.indent; | |
64 return state.context = state.context.prev; | |
65 }; | |
66 var indentUnit = config.indentUnit; | |
67 var curPunc; | |
68 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", "keys", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "reverse", "right", "round", "rtrim", "shortestPath", "sign", "sin", "size", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "toString", "trim", "type", "upper"]); | |
69 var preds = wordRegexp(["all", "and", "any", "contains", "exists", "has", "in", "none", "not", "or", "single", "xor"]); | |
70 var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "detach", "distinct", "drop", "else", "end", "ends", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "join", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "starts", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with", "call", "yield"]); | |
71 var systemKeywords = wordRegexp(["access", "active", "assign", "all", "alter", "as", "catalog", "change", "copy", "create", "constraint", "constraints", "current", "database", "databases", "dbms", "default", "deny", "drop", "element", "elements", "exists", "from", "grant", "graph", "graphs", "if", "index", "indexes", "label", "labels", "management", "match", "name", "names", "new", "node", "nodes", "not", "of", "on", "or", "password", "populated", "privileges", "property", "read", "relationship", "relationships", "remove", "replace", "required", "revoke", "role", "roles", "set", "show", "start", "status", "stop", "suspended", "to", "traverse", "type", "types", "user", "users", "with", "write"]); | |
72 var operatorChars = /[*+\-<>=&|~%^]/; | |
73 | |
74 return { | |
75 startState: function(/*base*/) { | |
76 return { | |
77 tokenize: tokenBase, | |
78 context: null, | |
79 indent: 0, | |
80 col: 0 | |
81 }; | |
82 }, | |
83 token: function(stream, state) { | |
84 if (stream.sol()) { | |
85 if (state.context && (state.context.align == null)) { | |
86 state.context.align = false; | |
87 } | |
88 state.indent = stream.indentation(); | |
89 } | |
90 if (stream.eatSpace()) { | |
91 return null; | |
92 } | |
93 var style = state.tokenize(stream, state); | |
94 if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") { | |
95 state.context.align = true; | |
96 } | |
97 if (curPunc === "(") { | |
98 pushContext(state, ")", stream.column()); | |
99 } else if (curPunc === "[") { | |
100 pushContext(state, "]", stream.column()); | |
101 } else if (curPunc === "{") { | |
102 pushContext(state, "}", stream.column()); | |
103 } else if (/[\]\}\)]/.test(curPunc)) { | |
104 while (state.context && state.context.type === "pattern") { | |
105 popContext(state); | |
106 } | |
107 if (state.context && curPunc === state.context.type) { | |
108 popContext(state); | |
109 } | |
110 } else if (curPunc === "." && state.context && state.context.type === "pattern") { | |
111 popContext(state); | |
112 } else if (/atom|string|variable/.test(style) && state.context) { | |
113 if (/[\}\]]/.test(state.context.type)) { | |
114 pushContext(state, "pattern", stream.column()); | |
115 } else if (state.context.type === "pattern" && !state.context.align) { | |
116 state.context.align = true; | |
117 state.context.col = stream.column(); | |
118 } | |
119 } | |
120 return style; | |
121 }, | |
122 indent: function(state, textAfter) { | |
123 var firstChar = textAfter && textAfter.charAt(0); | |
124 var context = state.context; | |
125 if (/[\]\}]/.test(firstChar)) { | |
126 while (context && context.type === "pattern") { | |
127 context = context.prev; | |
128 } | |
129 } | |
130 var closing = context && firstChar === context.type; | |
131 if (!context) return 0; | |
132 if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent; | |
133 if (context.align) return context.col + (closing ? 0 : 1); | |
134 return context.indent + (closing ? 0 : indentUnit); | |
135 } | |
136 }; | |
137 }); | |
138 | |
139 CodeMirror.modeExtensions["cypher"] = { | |
140 autoFormatLineBreaks: function(text) { | |
141 var i, lines, reProcessedPortion; | |
142 var lines = text.split("\n"); | |
143 var reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g; | |
144 for (var i = 0; i < lines.length; i++) | |
145 lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim(); | |
146 return lines.join("\n"); | |
147 } | |
148 }; | |
149 | |
150 CodeMirror.defineMIME("application/x-cypher-query", "cypher"); | |
151 | |
152 }); |