Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add penalty on case mismatch to completion filter #5626

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
20 changes: 14 additions & 6 deletions src/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,6 @@ class FilteredList {

filterCompletions(items, needle) {
var results = [];
var upper = needle.toUpperCase();
var lower = needle.toLowerCase();
loop: for (var i = 0, item; item = items[i]; i++) {
var caption = (!this.ignoreCaption && item.caption) || item.value || item.snippet;
Expand All @@ -1043,23 +1042,32 @@ class FilteredList {
if (needle !== caption.substr(0, needle.length))
continue loop;
} else {
var captionLower = caption.toLowerCase();
/**
* It is for situation then, for example, we find some like 'tab' in item.value="Check the table"
* and want to see "Check the TABle" but see "Check The tABle".
*/
var fullMatchIndex = caption.toLowerCase().indexOf(lower);
var fullMatchIndex = captionLower.indexOf(lower);
if (fullMatchIndex > -1) {
penalty = fullMatchIndex;
for (var j = 0; j < needle.length; j++) {
index = fullMatchIndex + j;
// Adding a penalty on case mismatch
if ((lower[j] == needle[j]) != (captionLower[index] == caption[index])) {
penalty += 3;
}
}
} else {
// 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;
index = captionLower.indexOf(lower[j], lastIndex + 1);
if (index < 0)
continue loop;
distance = index - lastIndex - 1;
// Adding a penalty on case mismatch
if ((lower[j] == needle[j]) != (captionLower[index] == caption[index])) {
penalty += 3;
}
if (distance > 0) {
// first char mismatch should be more sensitive
if (lastIndex === -1)
Expand Down
43 changes: 43 additions & 0 deletions src/autocomplete_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"use strict";

var sendKey = require("./test/user").type;
var {buildDom} = require("./lib/dom");

Check warning on line 8 in src/autocomplete_test.js

View workflow job for this annotation

GitHub Actions / build (16.x)

'buildDom' is assigned a value but never used
var ace = require("./ace");
var assert = require("./test/assertions");
var user = require("./test/user");
Expand Down Expand Up @@ -1542,6 +1542,49 @@

// Popup should be closed now
assert.equal(completer.popup.isOpen, false);
},
"test: penalty on case mismatch": function (done) {
var editor = initEditor("");
editor.completers = [
{
getCompletions: function (editor, session, pos, prefix, callback) {
var completions = [
{
caption: "array",
value: "array"
}, {
caption: "aRray",
value: "aRray"
}
];
callback(null, completions);
}
}
];

sendKey("R");
var popup = editor.completer.popup;

check(function() {
assert.equal(popup.data.length, 2);
assert.equal(popup.container.querySelector(".ace_selected").textContent.trim(), "aRray");

sendKey("y");

check(function() {
assert.equal(popup.container.querySelector(".ace_selected").textContent.trim(), "aRray");

editor.destroy();
editor.container.remove();
done();
});
});

function check(callback) {
setTimeout(function wait() {
callback();
}, 10);
}
}
};

Expand Down
Loading