From 1da1dc2e17dfcb0315c065c80fa801f869227a2d Mon Sep 17 00:00:00 2001 From: Albert Graef <aggraef@gmail.com> Date: Mon, 15 Aug 2022 03:37:21 +0200 Subject: [PATCH] Sort completion results. Fuse's result lists are ordered according to similarity scores, which may look pretty arbitrary at times. Since we only display at most 8 results at a time, this is a problem, because a rather random selection of completions may be shown in the menu. To improve this, we now also order results for the same score alphabetically, which makes the results look much more sensible IMHO. --- pd/nw/pdgui.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index 80d25b066..baf588cf1 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -764,6 +764,35 @@ function repopulate_autocomplete_dd(doc, ac_dropdown, obj_class, text) { well. */ let results = (arg.length > 0) ? (search_arg(title, arg).slice(1,)) : have_arg ? (obj_exact_match(title)) : (search_obj(title)); + /* AG: Massage the result list from what Fuse delivers, which is based on + scoring similarity and can appear pretty random at times. For now, we + just do a lexicographic sort on score first, then the completion text + (in particular, the latter makes sure that for each score the shortest + matches come first, which you'd expect but isn't always guaranteed with + Fuse). In the future we may incorporate the occurrence counts which are + already in GB's implementation, but AFAICT aren't currently used + anywhere. */ + if (arg.length < 1 && have_arg) { + // here all results are in item.args, order them lexicographically + results[0].item.args.sort((a, b) => + a.text == b.text ? 0 : a.text < b.text ? -1 : 1); + } else if (arg.length > 0) { + // matching arguments, order them lexicographically + results.sort((a, b) => + a.value == b.value ? 0 : a.value < b.value ? -1 : 1); + } else { + // object completions, sort by score and item.title + results.sort(function (a, b) { + if (a.score == b.score) { + return a.item.title == b.item.title ? 0 + : a.item.title < b.item.title ? -1 : 1; + } else { + let d = a.score - b.score; + return d == 0 ? 0 : d < 0 ? -1 : 1; + } + }); + } + // GB TODO: ideally we should be able to show all the results in a limited window with a scroll bar let n = 8; // Maximum number of suggestions if (results.length > n) results = results.slice(0,n); -- GitLab