codemirror 4.13
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
var DEFAULT_BRACKETS = "()[]{}''\"\"";
|
||||
var DEFAULT_TRIPLES = "'\"";
|
||||
var DEFAULT_EXPLODE_ON_ENTER = "[]{}";
|
||||
var SPACE_CHAR_REGEX = /\s/;
|
||||
|
||||
@@ -19,13 +20,14 @@
|
||||
if (old != CodeMirror.Init && old)
|
||||
cm.removeKeyMap("autoCloseBrackets");
|
||||
if (!val) return;
|
||||
var pairs = DEFAULT_BRACKETS, explode = DEFAULT_EXPLODE_ON_ENTER;
|
||||
var pairs = DEFAULT_BRACKETS, triples = DEFAULT_TRIPLES, 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.triples != null) triples = val.triples;
|
||||
if (val.explode != null) explode = val.explode;
|
||||
}
|
||||
var map = buildKeymap(pairs);
|
||||
var map = buildKeymap(pairs, triples);
|
||||
if (explode) map.Enter = buildExplodeHandler(explode);
|
||||
cm.addKeyMap(map);
|
||||
});
|
||||
@@ -52,7 +54,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
function buildKeymap(pairs) {
|
||||
function buildKeymap(pairs, triples) {
|
||||
var map = {
|
||||
name : "autoCloseBrackets",
|
||||
Backspace: function(cm) {
|
||||
@@ -85,7 +87,7 @@
|
||||
curType = "skipThree";
|
||||
else
|
||||
curType = "skip";
|
||||
} else if (left == right && cur.ch > 1 &&
|
||||
} else if (left == right && cur.ch > 1 && triples.indexOf(left) >= 0 &&
|
||||
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";
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
|
||||
function autoCloseSlash(cm) {
|
||||
if (cm.getOption("disableInput")) return CodeMirror.Pass;
|
||||
autoCloseCurrent(cm, true);
|
||||
return autoCloseCurrent(cm, true);
|
||||
}
|
||||
|
||||
CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };
|
||||
|
||||
@@ -94,20 +94,26 @@
|
||||
}
|
||||
|
||||
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;
|
||||
cm.foldCode(Pos(line, 0), opts.rangeFinder);
|
||||
}
|
||||
|
||||
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;
|
||||
clearTimeout(state.changeUpdate);
|
||||
state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
|
||||
}
|
||||
|
||||
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);
|
||||
state.changeUpdate = setTimeout(function() {
|
||||
var vp = cm.getViewport();
|
||||
@@ -129,7 +135,9 @@
|
||||
}
|
||||
|
||||
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)
|
||||
updateFoldInfo(cm, line, line + 1);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,18 @@
|
||||
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) {
|
||||
// We want a single cursor position.
|
||||
if (this.listSelections().length > 1 || this.somethingSelected()) return;
|
||||
@@ -34,10 +46,7 @@
|
||||
if (!getHints) return;
|
||||
|
||||
CodeMirror.signal(this, "startCompletion", this);
|
||||
if (getHints.async)
|
||||
getHints(this, function(hints) { completion.showHints(hints); }, completion.options);
|
||||
else
|
||||
return completion.showHints(getHints(this, completion.options));
|
||||
return retrieveHints(getHints, this, completion.options, function(hints) { completion.showHints(hints); });
|
||||
});
|
||||
|
||||
function Completion(cm, options) {
|
||||
@@ -102,11 +111,7 @@
|
||||
function update() {
|
||||
if (finished) return;
|
||||
CodeMirror.signal(data, "update");
|
||||
var getHints = completion.options.hint;
|
||||
if (getHints.async)
|
||||
getHints(completion.cm, finishUpdate, completion.options);
|
||||
else
|
||||
finishUpdate(getHints(completion.cm, completion.options));
|
||||
retrieveHints(completion.options.hint, completion.cm, completion.options, finishUpdate);
|
||||
}
|
||||
function finishUpdate(data_) {
|
||||
data = data_;
|
||||
|
||||
+94
-51
@@ -26,9 +26,26 @@
|
||||
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) {
|
||||
var len = string.length;
|
||||
var sub = word.substr(0, len);
|
||||
var sub = getText(word).substr(0, len);
|
||||
return string.toUpperCase() === sub.toUpperCase();
|
||||
}
|
||||
|
||||
@@ -44,53 +61,81 @@
|
||||
}
|
||||
}
|
||||
|
||||
function nameCompletion(cur, token, result, editor) {
|
||||
var useBacktick = (token.string.charAt(0) == "`");
|
||||
var string = token.string.substr(1);
|
||||
var prevToken = editor.getTokenAt(Pos(cur.line, token.start));
|
||||
if (token.string.charAt(0) == "." || prevToken.string == "."){
|
||||
//Suggest colunm names
|
||||
if (prevToken.string == ".") {
|
||||
var prevToken = editor.getTokenAt(Pos(cur.line, token.start - 1));
|
||||
}
|
||||
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;
|
||||
function cleanName(name) {
|
||||
// Get rid name from backticks(`) and preceding dot(.)
|
||||
if (name.charAt(0) == ".") {
|
||||
name = name.substr(1);
|
||||
}
|
||||
return name.replace(/`/g, "");
|
||||
}
|
||||
|
||||
if (useBacktick) {
|
||||
addMatches(result, string, columns, function(w) {return "`" + w + "`";});
|
||||
}
|
||||
else if(useBacktickTable) {
|
||||
addMatches(result, string, columns, function(w) {return ".`" + w + "`";});
|
||||
}
|
||||
else {
|
||||
addMatches(result, string, columns, function(w) {return "." + w;});
|
||||
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) {
|
||||
// Try to complete table, colunm names and return start position of completion
|
||||
var useBacktick = false;
|
||||
var nameParts = [];
|
||||
var start = token.start;
|
||||
var cont = true;
|
||||
while (cont) {
|
||||
cont = (token.string.charAt(0) == ".");
|
||||
useBacktick = useBacktick || (token.string.charAt(0) == "`");
|
||||
|
||||
start = token.start;
|
||||
nameParts.unshift(cleanName(token.string));
|
||||
|
||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
||||
if (token.string == ".") {
|
||||
cont = true;
|
||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Suggest table names or colums in defaultTable
|
||||
while (token.start && string.charAt(0) == ".") {
|
||||
token = editor.getTokenAt(Pos(cur.line, token.start - 1));
|
||||
string = token.string + string;
|
||||
}
|
||||
if (useBacktick) {
|
||||
addMatches(result, string, tables, function(w) {return "`" + w + "`";});
|
||||
addMatches(result, string, defaultTable, function(w) {return "`" + w + "`";});
|
||||
}
|
||||
else {
|
||||
addMatches(result, string, tables, function(w) {return w;});
|
||||
addMatches(result, string, defaultTable, function(w) {return w;});
|
||||
}
|
||||
|
||||
// Try to complete table names
|
||||
var string = nameParts.join(".");
|
||||
addMatches(result, string, tables, function(w) {
|
||||
return useBacktick ? insertBackticks(w) : w;
|
||||
});
|
||||
|
||||
// Try to complete columns from defaultTable
|
||||
addMatches(result, string, defaultTable, function(w) {
|
||||
return useBacktick ? insertBackticks(w) : 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 && Array.isArray(tables) && 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) {
|
||||
@@ -150,12 +195,10 @@
|
||||
var lineText = query[i];
|
||||
eachWord(lineText, function(word) {
|
||||
var wordUpperCase = word.toUpperCase();
|
||||
if (wordUpperCase === aliasUpperCase && tables.hasOwnProperty(previousWord)) {
|
||||
table = previousWord;
|
||||
}
|
||||
if (wordUpperCase !== CONS.ALIAS_KEYWORD) {
|
||||
if (wordUpperCase === aliasUpperCase && getItem(tables, previousWord))
|
||||
table = previousWord;
|
||||
if (wordUpperCase !== CONS.ALIAS_KEYWORD)
|
||||
previousWord = word;
|
||||
}
|
||||
});
|
||||
if (table) break;
|
||||
}
|
||||
@@ -165,7 +208,7 @@
|
||||
CodeMirror.registerHelper("hint", "sql", function(editor, options) {
|
||||
tables = (options && options.tables) || {};
|
||||
var defaultTableName = options && options.defaultTable;
|
||||
defaultTable = (defaultTableName && tables[defaultTableName] || []);
|
||||
defaultTable = (defaultTableName && getItem(tables, defaultTableName)) || [];
|
||||
keywords = keywords || getKeywords(editor);
|
||||
|
||||
var cur = editor.getCursor();
|
||||
@@ -185,7 +228,7 @@
|
||||
search = "";
|
||||
}
|
||||
if (search.charAt(0) == "." || search.charAt(0) == "`") {
|
||||
nameCompletion(cur, token, result, editor);
|
||||
start = nameCompletion(cur, token, result, editor);
|
||||
} else {
|
||||
addMatches(result, search, tables, function(w) {return w;});
|
||||
addMatches(result, search, defaultTable, function(w) {return w;});
|
||||
|
||||
@@ -11,13 +11,18 @@
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, className) {
|
||||
return new SearchAnnotation(this, query, caseFold, className);
|
||||
CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) {
|
||||
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.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.caseFold = caseFold;
|
||||
this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1};
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
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;
|
||||
@@ -26,12 +27,14 @@
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user