PluginProbe ʕ •ᴥ•ʔ
SiteOrigin CSS / 1.5.3
SiteOrigin CSS v1.5.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 6 years ago css-hint.js 11 years ago css-hint.min.js 6 years ago html-hint.js 11 years ago html-hint.min.js 6 years ago javascript-hint.js 9 years ago javascript-hint.min.js 6 years ago show-hint.css 9 years ago show-hint.js 9 years ago show-hint.min.js 6 years ago sql-hint.js 9 years ago sql-hint.min.js 6 years ago xml-hint.js 11 years ago xml-hint.min.js 6 years ago
sql-hint.js
288 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 identifierQuote;
18 var CONS = {
19 QUERY_DIV: ";",
20 ALIAS_KEYWORD: "AS"
21 };
22 var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
23
24 function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" }
25
26 function getKeywords(editor) {
27 var mode = editor.doc.modeOption;
28 if (mode === "sql") mode = "text/x-sql";
29 return CodeMirror.resolveMode(mode).keywords;
30 }
31
32 function getIdentifierQuote(editor) {
33 var mode = editor.doc.modeOption;
34 if (mode === "sql") mode = "text/x-sql";
35 return CodeMirror.resolveMode(mode).identifierQuote || "`";
36 }
37
38 function getText(item) {
39 return typeof item == "string" ? item : item.text;
40 }
41
42 function wrapTable(name, value) {
43 if (isArray(value)) value = {columns: value}
44 if (!value.text) value.text = name
45 return value
46 }
47
48 function parseTables(input) {
49 var result = {}
50 if (isArray(input)) {
51 for (var i = input.length - 1; i >= 0; i--) {
52 var item = input[i]
53 result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
54 }
55 } else if (input) {
56 for (var name in input)
57 result[name.toUpperCase()] = wrapTable(name, input[name])
58 }
59 return result
60 }
61
62 function getTable(name) {
63 return tables[name.toUpperCase()]
64 }
65
66 function shallowClone(object) {
67 var result = {};
68 for (var key in object) if (object.hasOwnProperty(key))
69 result[key] = object[key];
70 return result;
71 }
72
73 function match(string, word) {
74 var len = string.length;
75 var sub = getText(word).substr(0, len);
76 return string.toUpperCase() === sub.toUpperCase();
77 }
78
79 function addMatches(result, search, wordlist, formatter) {
80 if (isArray(wordlist)) {
81 for (var i = 0; i < wordlist.length; i++)
82 if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
83 } else {
84 for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
85 var val = wordlist[word]
86 if (!val || val === true)
87 val = word
88 else
89 val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
90 if (match(search, val)) result.push(formatter(val))
91 }
92 }
93 }
94
95 function cleanName(name) {
96 // Get rid name from identifierQuote and preceding dot(.)
97 if (name.charAt(0) == ".") {
98 name = name.substr(1);
99 }
100 // replace doublicated identifierQuotes with single identifierQuotes
101 // and remove single identifierQuotes
102 var nameParts = name.split(identifierQuote+identifierQuote);
103 for (var i = 0; i < nameParts.length; i++)
104 nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote,"g"), "");
105 return nameParts.join(identifierQuote);
106 }
107
108 function insertIdentifierQuotes(name) {
109 var nameParts = getText(name).split(".");
110 for (var i = 0; i < nameParts.length; i++)
111 nameParts[i] = identifierQuote +
112 // doublicate identifierQuotes
113 nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) +
114 identifierQuote;
115 var escaped = nameParts.join(".");
116 if (typeof name == "string") return escaped;
117 name = shallowClone(name);
118 name.text = escaped;
119 return name;
120 }
121
122 function nameCompletion(cur, token, result, editor) {
123 // Try to complete table, column names and return start position of completion
124 var useIdentifierQuotes = false;
125 var nameParts = [];
126 var start = token.start;
127 var cont = true;
128 while (cont) {
129 cont = (token.string.charAt(0) == ".");
130 useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote);
131
132 start = token.start;
133 nameParts.unshift(cleanName(token.string));
134
135 token = editor.getTokenAt(Pos(cur.line, token.start));
136 if (token.string == ".") {
137 cont = true;
138 token = editor.getTokenAt(Pos(cur.line, token.start));
139 }
140 }
141
142 // Try to complete table names
143 var string = nameParts.join(".");
144 addMatches(result, string, tables, function(w) {
145 return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
146 });
147
148 // Try to complete columns from defaultTable
149 addMatches(result, string, defaultTable, function(w) {
150 return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
151 });
152
153 // Try to complete columns
154 string = nameParts.pop();
155 var table = nameParts.join(".");
156
157 var alias = false;
158 var aliasTable = table;
159 // Check if table is available. If not, find table by Alias
160 if (!getTable(table)) {
161 var oldTable = table;
162 table = findTableByAlias(table, editor);
163 if (table !== oldTable) alias = true;
164 }
165
166 var columns = getTable(table);
167 if (columns && columns.columns)
168 columns = columns.columns;
169
170 if (columns) {
171 addMatches(result, string, columns, function(w) {
172 var tableInsert = table;
173 if (alias == true) tableInsert = aliasTable;
174 if (typeof w == "string") {
175 w = tableInsert + "." + w;
176 } else {
177 w = shallowClone(w);
178 w.text = tableInsert + "." + w.text;
179 }
180 return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
181 });
182 }
183
184 return start;
185 }
186
187 function eachWord(lineText, f) {
188 if (!lineText) return;
189 var excepted = /[,;]/g;
190 var words = lineText.split(" ");
191 for (var i = 0; i < words.length; i++) {
192 f(words[i]?words[i].replace(excepted, '') : '');
193 }
194 }
195
196 function findTableByAlias(alias, editor) {
197 var doc = editor.doc;
198 var fullQuery = doc.getValue();
199 var aliasUpperCase = alias.toUpperCase();
200 var previousWord = "";
201 var table = "";
202 var separator = [];
203 var validRange = {
204 start: Pos(0, 0),
205 end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
206 };
207
208 //add separator
209 var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
210 while(indexOfSeparator != -1) {
211 separator.push(doc.posFromIndex(indexOfSeparator));
212 indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);
213 }
214 separator.unshift(Pos(0, 0));
215 separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
216
217 //find valid range
218 var prevItem = null;
219 var current = editor.getCursor()
220 for (var i = 0; i < separator.length; i++) {
221 if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
222 validRange = {start: prevItem, end: separator[i]};
223 break;
224 }
225 prevItem = separator[i];
226 }
227
228 var query = doc.getRange(validRange.start, validRange.end, false);
229
230 for (var i = 0; i < query.length; i++) {
231 var lineText = query[i];
232 eachWord(lineText, function(word) {
233 var wordUpperCase = word.toUpperCase();
234 if (wordUpperCase === aliasUpperCase && getTable(previousWord))
235 table = previousWord;
236 if (wordUpperCase !== CONS.ALIAS_KEYWORD)
237 previousWord = word;
238 });
239 if (table) break;
240 }
241 return table;
242 }
243
244 CodeMirror.registerHelper("hint", "sql", function(editor, options) {
245 tables = parseTables(options && options.tables)
246 var defaultTableName = options && options.defaultTable;
247 var disableKeywords = options && options.disableKeywords;
248 defaultTable = defaultTableName && getTable(defaultTableName);
249 keywords = getKeywords(editor);
250 identifierQuote = getIdentifierQuote(editor);
251
252 if (defaultTableName && !defaultTable)
253 defaultTable = findTableByAlias(defaultTableName, editor);
254
255 defaultTable = defaultTable || [];
256
257 if (defaultTable.columns)
258 defaultTable = defaultTable.columns;
259
260 var cur = editor.getCursor();
261 var result = [];
262 var token = editor.getTokenAt(cur), start, end, search;
263 if (token.end > cur.ch) {
264 token.end = cur.ch;
265 token.string = token.string.slice(0, cur.ch - token.start);
266 }
267
268 if (token.string.match(/^[.`"\w@]\w*$/)) {
269 search = token.string;
270 start = token.start;
271 end = token.end;
272 } else {
273 start = end = cur.ch;
274 search = "";
275 }
276 if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) {
277 start = nameCompletion(cur, token, result, editor);
278 } else {
279 addMatches(result, search, tables, function(w) {return w;});
280 addMatches(result, search, defaultTable, function(w) {return w;});
281 if (!disableKeywords)
282 addMatches(result, search, keywords, function(w) {return w.toUpperCase();});
283 }
284
285 return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
286 });
287 });
288