Merge remote-tracking branch 'remotes/pull/1560'
Conflicts: lib/ace/ext/language_tools.js
This commit is contained in:
commit
f8f8b00c61
5 changed files with 61 additions and 30 deletions
|
|
@ -165,6 +165,41 @@ var Autocomplete = function() {
|
||||||
"PageDown": function(editor) { editor.completer.popup.gotoPageUp(); }
|
"PageDown": function(editor) { editor.completer.popup.gotoPageUp(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.filterCompletions = function(items, needle) {
|
||||||
|
var results = [];
|
||||||
|
var upper = needle.toUpperCase();
|
||||||
|
var lower = needle.toLowerCase();
|
||||||
|
loop: for (var i = 0, item; item = items[i]; i++) {
|
||||||
|
var caption = item.value || item.caption;
|
||||||
|
var lastIndex = -1;
|
||||||
|
var matchMask = 0;
|
||||||
|
var penalty = 0;
|
||||||
|
var index, distance;
|
||||||
|
// caption char iteration is faster in Chrome but slower in Firefox, so lets use indexOf
|
||||||
|
for (var j = 0; j < needle.length; j++) {
|
||||||
|
// TODO add penalty on case mismatch
|
||||||
|
var i1 = caption.indexOf(lower[j], lastIndex + 1);
|
||||||
|
var i2 = caption.indexOf(upper[j], lastIndex + 1);
|
||||||
|
index = (i1 >= 0) ? ((i2 < 0 || i1 < i2) ? i1 : i2) : i2;
|
||||||
|
if (index < 0)
|
||||||
|
continue loop;
|
||||||
|
distance = index - lastIndex - 1;
|
||||||
|
if (distance > 0) {
|
||||||
|
// first char mismatch should be more sensitive
|
||||||
|
if (lastIndex == -1)
|
||||||
|
penalty += 10;
|
||||||
|
penalty += distance;
|
||||||
|
}
|
||||||
|
matchMask = matchMask | (1 << index);
|
||||||
|
lastIndex = index;
|
||||||
|
}
|
||||||
|
item.matchMask = matchMask;
|
||||||
|
item.score = (item.score || 0) - penalty;
|
||||||
|
results.push(item);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
this.gatherCompletions = function(editor, callback) {
|
this.gatherCompletions = function(editor, callback) {
|
||||||
var session = editor.getSession();
|
var session = editor.getSession();
|
||||||
var pos = editor.getCursorPosition();
|
var pos = editor.getCursorPosition();
|
||||||
|
|
@ -180,9 +215,6 @@ var Autocomplete = function() {
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}, function() {
|
}, function() {
|
||||||
matches.sort(function(a, b) {
|
|
||||||
return b.score - a.score;
|
|
||||||
});
|
|
||||||
callback(null, {
|
callback(null, {
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
matches: matches
|
matches: matches
|
||||||
|
|
@ -220,10 +252,14 @@ var Autocomplete = function() {
|
||||||
// if (matches.length == 1)
|
// if (matches.length == 1)
|
||||||
// return this.insertMatch(matches[0]);
|
// return this.insertMatch(matches[0]);
|
||||||
|
|
||||||
|
|
||||||
|
matches = this.filterCompletions(matches, results.prefix);
|
||||||
|
matches = matches.sort(function(a, b) {
|
||||||
|
return b.score - a.score;
|
||||||
|
});
|
||||||
this.completions = new FilteredList(matches);
|
this.completions = new FilteredList(matches);
|
||||||
this.completions.setFilter(results.prefix);
|
this.completions.setFilter(results.prefix);
|
||||||
this.openPopup(this.editor, keepPopupPosition);
|
this.openPopup(this.editor, keepPopupPosition);
|
||||||
this.popup.setHighlight(results.prefix);
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,19 @@ var AcePopup = function(parentNode) {
|
||||||
if (!data.caption)
|
if (!data.caption)
|
||||||
data.caption = data.value;
|
data.caption = data.value;
|
||||||
|
|
||||||
tokens.push({type: data.className || "", value: data.caption});
|
var last = -1;
|
||||||
|
var flag, c;
|
||||||
|
for (var i = 0; i < data.caption.length; i++) {
|
||||||
|
c = data.caption[i];
|
||||||
|
flag = data.matchMask & (1 << i) ? 1 : 0;
|
||||||
|
if (last !== flag) {
|
||||||
|
tokens.push({type: data.className || "" + ( flag ? ".bold" : ""), value: c});
|
||||||
|
last = flag;
|
||||||
|
} else {
|
||||||
|
tokens[tokens.length - 1].value += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (data.meta) {
|
if (data.meta) {
|
||||||
var maxW = popup.renderer.$size.scrollerWidth / popup.renderer.layerConfig.characterWidth;
|
var maxW = popup.renderer.$size.scrollerWidth / popup.renderer.layerConfig.characterWidth;
|
||||||
if (data.meta.length + data.caption.length < maxW - 2)
|
if (data.meta.length + data.caption.length < maxW - 2)
|
||||||
|
|
@ -167,11 +179,6 @@ var AcePopup = function(parentNode) {
|
||||||
popup.moveCursorTo(line, 0 || 0);
|
popup.moveCursorTo(line, 0 || 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
popup.setHighlight = function(re) {
|
|
||||||
popup.session.highlight(re);
|
|
||||||
popup.session._emit("changeFrontMarker");
|
|
||||||
};
|
|
||||||
|
|
||||||
popup.hide = function() {
|
popup.hide = function() {
|
||||||
this.container.style.display = "none";
|
this.container.style.display = "none";
|
||||||
this._signal("hide");
|
this._signal("hide");
|
||||||
|
|
|
||||||
|
|
@ -38,17 +38,6 @@ define(function(require, exports, module) {
|
||||||
return textBefore.split(splitRegex).length - 1;
|
return textBefore.split(splitRegex).length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Naive implementation O(n), can be O(log n) with binary search
|
|
||||||
function filterPrefix(prefix, words) {
|
|
||||||
var results = [];
|
|
||||||
for (var i = 0; i < words.length; i++) {
|
|
||||||
if (words[i].lastIndexOf(prefix, 0) === 0) {
|
|
||||||
results.push(words[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does a distance analysis of the word `prefix` at position `pos` in `doc`.
|
* Does a distance analysis of the word `prefix` at position `pos` in `doc`.
|
||||||
* @return Map
|
* @return Map
|
||||||
|
|
@ -76,7 +65,7 @@ define(function(require, exports, module) {
|
||||||
|
|
||||||
exports.getCompletions = function(editor, session, pos, prefix, callback) {
|
exports.getCompletions = function(editor, session, pos, prefix, callback) {
|
||||||
var wordScore = wordDistance(session, pos, prefix);
|
var wordScore = wordDistance(session, pos, prefix);
|
||||||
var wordList = filterPrefix(prefix, Object.keys(wordScore));
|
var wordList = Object.keys(wordScore);
|
||||||
callback(null, wordList.map(function(word) {
|
callback(null, wordList.map(function(word) {
|
||||||
return {
|
return {
|
||||||
name: word,
|
name: word,
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,11 @@ var snippetCompleter = {
|
||||||
var snippets = snippetMap[scope] || [];
|
var snippets = snippetMap[scope] || [];
|
||||||
for (var i = snippets.length; i--;) {
|
for (var i = snippets.length; i--;) {
|
||||||
var s = snippets[i];
|
var s = snippets[i];
|
||||||
if (s.tabTrigger && s.tabTrigger.indexOf(prefix) === 0)
|
completions.push({
|
||||||
completions.push({
|
caption: s.tabTrigger,
|
||||||
caption: s.tabTrigger,
|
snippet: s.content,
|
||||||
snippet: s.content,
|
meta: "snippet"
|
||||||
meta: "snippet"
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
callback(null, completions);
|
callback(null, completions);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ snippet fun
|
||||||
}
|
}
|
||||||
# Anonymous Function
|
# Anonymous Function
|
||||||
regex /((=)\s*|(:)\s*|(\()|\b)/f/(\))?/
|
regex /((=)\s*|(:)\s*|(\()|\b)/f/(\))?/
|
||||||
name f
|
snippet f
|
||||||
function${M1?: ${1:functionName}}($2) {
|
function${M1?: ${1:functionName}}($2) {
|
||||||
${0:$TM_SELECTED_TEXT}
|
${0:$TM_SELECTED_TEXT}
|
||||||
}${M2?;}${M3?,}${M4?)}
|
}${M2?;}${M3?,}${M4?)}
|
||||||
|
|
@ -149,7 +149,7 @@ snippet sing
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
# class
|
# class
|
||||||
name class
|
snippet class
|
||||||
regex /^\s*/clas{0,2}/
|
regex /^\s*/clas{0,2}/
|
||||||
var ${1:class} = function(${20}) {
|
var ${1:class} = function(${20}) {
|
||||||
$40$0
|
$40$0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue