PluginProbe ʕ •ᴥ•ʔ
SiteOrigin CSS / 1.1.3
SiteOrigin CSS v1.1.3
1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.10 1.5.11 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 trunk 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2.0
so-css / lib / codemirror / addon / hint / sql-hint.js
so-css / lib / codemirror / addon / hint Last commit date
anyword-hint.js 10 years ago anyword-hint.min.js 9 years ago css-hint.js 11 years ago css-hint.min.js 9 years ago html-hint.js 11 years ago html-hint.min.js 9 years ago javascript-hint.js 9 years ago javascript-hint.min.js 9 years ago show-hint.css 9 years ago show-hint.js 9 years ago show-hint.min.js 9 years ago sql-hint.js 9 years ago sql-hint.min.js 9 years ago xml-hint.js 11 years ago xml-hint.min.js 10 years ago
sql-hint.js
272 lines
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11 })(function(CodeMirror) {
12 "use strict";
13
14 var tables;
15 var defaultTable;
16 var keywords;
17 var CONS = {
18 QUERY_DIV: ";",
19 ALIAS_KEYWORD: "AS"
20 };
21 var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
22
23 function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" }
24
25 function getKeywords(editor) {
26 var mode = editor.doc.modeOption;
27 if (mode === "sql") mode = "text/x-sql";
28 return CodeMirror.resolveMode(mode).keywords;
29 }
30
31 function getText(item) {
32 return typeof item == "string" ? item : item.text;
33 }
34
35 function wrapTable(name, value) {
36 if (isArray(value)) value = {columns: value}
37 if (!value.text) value.text = name
38 return value
39 }
40
41 function parseTables(input) {
42 var result = {}
43 if (isArray(input)) {
44 for (var i = input.length - 1; i >= 0; i--) {
45 var item = input[i]
46 result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
47 }
48 } else if (input) {
49 for (var name in input)
50 result[name.toUpperCase()] = wrapTable(name, input[name])
51 }
52 return result
53 }
54
55 function getTable(name) {
56 return tables[name.toUpperCase()]
57 }
58
59 function shallowClone(object) {
60 var result = {};
61 for (var key in object) if (object.hasOwnProperty(key))
62 result[key] = object[key];
63 return result;
64 }
65
66 function match(string, word) {
67 var len = string.length;
68 var sub = getText(word).substr(0, len);
69 return string.toUpperCase() === sub.toUpperCase();
70 }
71
72 function addMatches(result, search, wordlist, formatter) {
73 if (isArray(wordlist)) {
74 for (var i = 0; i < wordlist.length; i++)
75 if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
76 } else {
77 for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
78 var val = wordlist[word]
79 if (!val || val === true)
80 val = word
81 else
82 val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
83 if (match(search, val)) result.push(formatter(val))
84 }
85 }
86 }
87
88 function cleanName(name) {
89 // Get rid name from backticks(`) and preceding dot(.)
90 if (name.charAt(0) == ".") {
91 name = name.substr(1);
92 }
93 return name.replace(/`/g, "");
94 }
95
96 function insertBackticks(name) {
97 var nameParts = getText(name).split(".");
98 for (var i = 0; i < nameParts.length; i++)
99 nameParts[i] = "`" + nameParts[i] + "`";
100 var escaped = nameParts.join(".");
101 if (typeof name == "string") return escaped;
102 name = shallowClone(name);
103 name.text = escaped;
104 return name;
105 }
106
107 function nameCompletion(cur, token, result, editor) {
108 // Try to complete table, column names and return start position of completion
109 var useBacktick = false;
110 var nameParts = [];
111 var start = token.start;
112 var cont = true;
113 while (cont) {
114 cont = (token.string.charAt(0) == ".");
115 useBacktick = useBacktick || (token.string.charAt(0) == "`");
116
117 start = token.start;
118 nameParts.unshift(cleanName(token.string));
119
120 token = editor.getTokenAt(Pos(cur.line, token.start));
121 if (token.string == ".") {
122 cont = true;
123 token = editor.getTokenAt(Pos(cur.line, token.start));
124 }
125 }
126
127 // Try to complete table names
128 var string = nameParts.join(".");
129 addMatches(result, string, tables, function(w) {
130 return useBacktick ? insertBackticks(w) : w;
131 });
132
133 // Try to complete columns from defaultTable
134 addMatches(result, string, defaultTable, function(w) {
135 return useBacktick ? insertBackticks(w) : w;
136 });
137
138 // Try to complete columns
139 string = nameParts.pop();
140 var table = nameParts.join(".");
141
142 var alias = false;
143 var aliasTable = table;
144 // Check if table is available. If not, find table by Alias
145 if (!getTable(table)) {
146 var oldTable = table;
147 table = findTableByAlias(table, editor);
148 if (table !== oldTable) alias = true;
149 }
150
151 var columns = getTable(table);
152 if (columns && columns.columns)
153 columns = columns.columns;
154
155 if (columns) {
156 addMatches(result, string, columns, function(w) {
157 var tableInsert = table;
158 if (alias == true) tableInsert = aliasTable;
159 if (typeof w == "string") {
160 w = tableInsert + "." + w;
161 } else {
162 w = shallowClone(w);
163 w.text = tableInsert + "." + w.text;
164 }
165 return useBacktick ? insertBackticks(w) : w;
166 });
167 }
168
169 return start;
170 }
171
172 function eachWord(lineText, f) {
173 if (!lineText) return;
174 var excepted = /[,;]/g;
175 var words = lineText.split(" ");
176 for (var i = 0; i < words.length; i++) {
177 f(words[i]?words[i].replace(excepted, '') : '');
178 }
179 }
180
181 function findTableByAlias(alias, editor) {
182 var doc = editor.doc;
183 var fullQuery = doc.getValue();
184 var aliasUpperCase = alias.toUpperCase();
185 var previousWord = "";
186 var table = "";
187 var separator = [];
188 var validRange = {
189 start: Pos(0, 0),
190 end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
191 };
192
193 //add separator
194 var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
195 while(indexOfSeparator != -1) {
196 separator.push(doc.posFromIndex(indexOfSeparator));
197 indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);
198 }
199 separator.unshift(Pos(0, 0));
200 separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
201
202 //find valid range
203 var prevItem = null;
204 var current = editor.getCursor()
205 for (var i = 0; i < separator.length; i++) {
206 if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
207 validRange = {start: prevItem, end: separator[i]};
208 break;
209 }
210 prevItem = separator[i];
211 }
212
213 var query = doc.getRange(validRange.start, validRange.end, false);
214
215 for (var i = 0; i < query.length; i++) {
216 var lineText = query[i];
217 eachWord(lineText, function(word) {
218 var wordUpperCase = word.toUpperCase();
219 if (wordUpperCase === aliasUpperCase && getTable(previousWord))
220 table = previousWord;
221 if (wordUpperCase !== CONS.ALIAS_KEYWORD)
222 previousWord = word;
223 });
224 if (table) break;
225 }
226 return table;
227 }
228
229 CodeMirror.registerHelper("hint", "sql", function(editor, options) {
230 tables = parseTables(options && options.tables)
231 var defaultTableName = options && options.defaultTable;
232 var disableKeywords = options && options.disableKeywords;
233 defaultTable = defaultTableName && getTable(defaultTableName);
234 keywords = getKeywords(editor);
235
236 if (defaultTableName && !defaultTable)
237 defaultTable = findTableByAlias(defaultTableName, editor);
238
239 defaultTable = defaultTable || [];
240
241 if (defaultTable.columns)
242 defaultTable = defaultTable.columns;
243
244 var cur = editor.getCursor();
245 var result = [];
246 var token = editor.getTokenAt(cur), start, end, search;
247 if (token.end > cur.ch) {
248 token.end = cur.ch;
249 token.string = token.string.slice(0, cur.ch - token.start);
250 }
251
252 if (token.string.match(/^[.`\w@]\w*$/)) {
253 search = token.string;
254 start = token.start;
255 end = token.end;
256 } else {
257 start = end = cur.ch;
258 search = "";
259 }
260 if (search.charAt(0) == "." || search.charAt(0) == "`") {
261 start = nameCompletion(cur, token, result, editor);
262 } else {
263 addMatches(result, search, tables, function(w) {return w;});
264 addMatches(result, search, defaultTable, function(w) {return w;});
265 if (!disableKeywords)
266 addMatches(result, search, keywords, function(w) {return w.toUpperCase();});
267 }
268
269 return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
270 });
271 });
272