Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -1061,12 +1061,13 @@ class FilteredList {
|| (a.caption || a.value).localeCompare(b.caption || b.value);
});

// make unique
var prev = null;
// make unique: completions are the same only when they read the same in the popup
// and insert the same text, and duplicates need not be next to each other
var seen = new Set();
matches = matches.filter(function(item){
var caption = item.snippet || item.caption || item.value;
if (caption === prev) return false;
prev = caption;
var key = (item.caption || item.value || item.snippet) + "\0" + (item.snippet || item.value);
if (seen.has(key)) return false;
seen.add(key);
return true;
});

Expand Down
43 changes: 43 additions & 0 deletions src/autocomplete_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,49 @@ module.exports = {
assert.equal(completer.popup.isOpen, true);
assert.equal(completer.popup.data.length, 1);
},
"test: duplicate completions are removed regardless of their position": function() {
editor = initEditor("");

editor.completers = [
{
getCompletions: function (editor, session, pos, prefix, callback) {
var completions = [
{
value: "foo",
meta: "higher",
score: 5
}, {
value: "bar",
score: 3
}, {
value: "foo",
meta: "lower",
score: 1
}, {
caption: "snippet a",
snippet: "shared body"
}, {
caption: "snippet b",
snippet: "shared body"
}
];
callback(null, completions);
}
}
];

editor.execCommand('startAutocomplete');
var data = editor.completer.popup.data;

// sorting by score keeps the two identical completions apart, while the two snippets
// read differently in the popup and are therefore not duplicates of each other
assert.jsonEquals(data.map(function(item) {
return item.caption || item.value;
}), ["foo", "bar", "snippet a", "snippet b"]);

// of a set of duplicates the first one after sorting survives, which is the highest scored
assert.equal(data[0].meta, "higher");
},

"test: should add inline preview content to aria-describedby": function() {
editor = initEditor("fun");
Expand Down
Loading