diff --git a/pd/nw/dialog_prefs.html b/pd/nw/dialog_prefs.html
index 1af561488fa718d47ae520a9df7f59067781c5ef..6a01a941ea727701343e962e5ef4bfd6948a702c 100644
--- a/pd/nw/dialog_prefs.html
+++ b/pd/nw/dialog_prefs.html
@@ -453,6 +453,11 @@ select {
               <input type="checkbox" id="autocomplete_prefix" name="autocomplete_prefix">
               <span data-i18n="prefs.gui.autocomplete.autocomplete_prefix"></span>
             </label>
+            <br/>
+            <label data-i18n="[title]prefs.gui.autocomplete.autocomplete_relevance_tt">
+              <input type="checkbox" id="autocomplete_relevance" name="autocomplete_relevance">
+              <span data-i18n="prefs.gui.autocomplete.autocomplete_relevance"></span>
+            </label>
             <br/><br/>
             <span data-i18n="prefs.gui.browser.browser_title"></span>
             <br/>
@@ -806,6 +811,7 @@ function apply(save_prefs) {
         get_bool_elem("save_zoom"),
         get_bool_elem("autocomplete"),
         get_bool_elem("autocomplete_prefix"),
+        get_bool_elem("autocomplete_relevance"),
         get_bool_elem("browser_doc"),
         get_bool_elem("browser_path"),
         get_bool_elem("browser_init"),
@@ -817,7 +823,8 @@ function apply(save_prefs) {
         get_bool_elem("browser_doc"),
         get_bool_elem("browser_path"),
         get_bool_elem("autocomplete"),
-        get_bool_elem("autocomplete_prefix")
+        get_bool_elem("autocomplete_prefix"),
+        get_bool_elem("autocomplete_relevance")
     );
     // Update the grid on all open windows.
     pdgui.update_grid(get_bool_elem("show_grid"),
@@ -1071,7 +1078,7 @@ function autopatch_yoffset_toggle(checked) {
 }
 
 function gui_prefs_callback(name, show_grid, grid_size, save_zoom,
-    autocomplete, autocomplete_prefix,
+    autocomplete, autocomplete_prefix, autocomplete_relevance,
     browser_doc, browser_path, browser_init, autopatch_yoffset) {
     var s = document.getElementById("gui_preset");
 
@@ -1107,6 +1114,7 @@ function gui_prefs_callback(name, show_grid, grid_size, save_zoom,
     document.getElementById("save_zoom").checked = !!save_zoom;
     document.getElementById("autocomplete").checked = !!autocomplete;
     document.getElementById("autocomplete_prefix").checked = !!autocomplete_prefix;
+    document.getElementById("autocomplete_relevance").checked = !!autocomplete_relevance;
     document.getElementById("browser_doc").checked = !!browser_doc;
     document.getElementById("browser_path").checked = !!browser_path;
     document.getElementById("browser_init").checked = !!browser_init;
diff --git a/pd/nw/locales/de/translation.json b/pd/nw/locales/de/translation.json
index 5ff39dab72c248374969be60f7a4a3ba1c88e59b..8a5d495192d2aa3d9604e57c129b5764adb08e0c 100644
--- a/pd/nw/locales/de/translation.json
+++ b/pd/nw/locales/de/translation.json
@@ -444,7 +444,9 @@
         "autocomplete": "Autovervollständigung von Objekt-Namen und Argumenten (experimentell)",
         "autocomplete_tt": "Schlägt bei der Eingabe Vervollständigungen von Objekt-Namen und Argumenten vor",
         "autocomplete_prefix": "Vervollständigung per Objektnamens-Präfix",
-        "autocomplete_prefix_tt": "Vervollständigung nur per Objektnamens-Präfix (statt Übereinstimmung irgendwo im Objektnamen)"
+        "autocomplete_prefix_tt": "Vervollständigung nur per Objektnamens-Präfix (statt Übereinstimmung irgendwo im Objektnamen)",
+        "autocomplete_relevance": "Sortiere Vervollständigungen nach Relevanz",
+        "autocomplete_relevance_tt": "Zeigt die relevantesten Vervollständigungen zuerst (basierend auf der Nutzungshäufigkeit)"
       },
       "browser": {
         "browser_title": "Hilfe-Browser-Einstellungen (WARNUNG: Änderungen können Startup-Zeiten beeinflussen!)",
diff --git a/pd/nw/locales/en/translation.json b/pd/nw/locales/en/translation.json
index b18fd87d2dfd276122b6e312e76cf2132a734baf..d340835b204976d47a3c24a0b4d396540c971780 100644
--- a/pd/nw/locales/en/translation.json
+++ b/pd/nw/locales/en/translation.json
@@ -444,7 +444,9 @@
         "autocomplete": "auto-complete object names and arguments (experimental)",
         "autocomplete_tt": "Offers completions for object names and arguments as you type",
         "autocomplete_prefix": "match completions by object name prefix",
-        "autocomplete_prefix_tt": "Only list completions whose prefix matches (rather than matches anywhere in object names)"
+        "autocomplete_prefix_tt": "Only list completions whose prefix matches (rather than matches anywhere in object names)",
+        "autocomplete_relevance": "sort completions by relevance",
+        "autocomplete_relevance_tt": "List most relevant completions first (based on how frequently they are used)"
       },
       "browser": {
         "browser_title": "Help browser settings (WARNING: changing these may affect startup times!)",
diff --git a/pd/nw/locales/fr/translation.json b/pd/nw/locales/fr/translation.json
index f5dd974a93fe38c6b18b4a21d98d83cd9cb5920e..4721a9c13089a19b1fc91554409a9815f30da211 100644
--- a/pd/nw/locales/fr/translation.json
+++ b/pd/nw/locales/fr/translation.json
@@ -444,7 +444,9 @@
         "autocomplete": "autocompléter les noms et arguments des objets (expérimental)",
         "autocomplete_tt": "Offre complétion pour les noms et arguments des objets au fur et à mesure de la saisie",
         "autocomplete_prefix": "complétion par le préfixe du nom de l'objet",
-        "autocomplete_prefix_tt": "Complétion uniquement par le préfixe du nom de l'objet (ignorer les correspondances au milieu du nom des objets)"
+        "autocomplete_prefix_tt": "Complétion uniquement par le préfixe du nom de l'objet (ignorer les correspondances au milieu du nom des objets)",
+        "autocomplete_relevance": "Trier les complétions par pertinence",
+        "autocomplete_relevance_tt": "Affiche les complétions les plus pertinentes en premier (basé sur la fréquence d'utilisation)"
       },
       "browser": {
         "browser_title": "Paramètres du navigateur d'Aide (AVERTISSEMENT: les modifier peut affecter les temps de démarrage!)",
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index 8c9441eba107b69c95010c3757b89240ba1f5fe1..05ee5068477a9c02722c5d6530cc60a5d946e41a 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -3,7 +3,7 @@
 var pwd;
 var lib_dir;
 var help_path, browser_doc, browser_path, browser_init;
-var autocomplete, autocomplete_prefix;
+var autocomplete, autocomplete_prefix, autocomplete_relevance;
 var pd_engine_id;
 
 exports.autocomplete_enabled = function() {
@@ -33,7 +33,7 @@ exports.set_pd_engine_id = function (id) {
 exports.defunkify_windows_path = defunkify_windows_path;
 
 function gui_set_browser_config(doc_flag, path_flag, init_flag,
-                                ac_flag, ac_prefix_flag,
+                                ac_flag, ac_prefix_flag, ac_relevance_flag,
                                 helppath) {
     // post("gui_set_browser_config: " + helppath.join(":"));
     browser_doc = doc_flag;
@@ -49,6 +49,7 @@ function gui_set_browser_config(doc_flag, path_flag, init_flag,
     // user decides to enable it later.
     autocomplete = ac_flag;
     autocomplete_prefix = ac_prefix_flag;
+    autocomplete_relevance = ac_relevance_flag;
     make_completion_index();
     // AG: Start building the keyword index for dialog_search.html. We do this
     // here so that we can be sure that lib_dir and help_path are known
@@ -570,11 +571,12 @@ function rebuild_index()
 }
 
 // this is called from the gui tab of the prefs dialog
-function update_browser(doc_flag, path_flag, ac_flag, ac_prefix_flag)
+function update_browser(doc_flag, path_flag, ac_flag, ac_prefix_flag, ac_relevance_flag)
 {
     var changed = ac_flag == 1 && autocomplete == 0;
     autocomplete = ac_flag;
     autocomplete_prefix = ac_prefix_flag;
+    autocomplete_relevance = ac_relevance_flag;
     doc_flag = doc_flag?1:0;
     path_flag = path_flag?1:0;
     if (browser_doc !== doc_flag) {
@@ -643,7 +645,25 @@ function search_arg(title, arg) {
     if (!autocomplete) return [];
     // for the arguments, we are only interested on the obj that match exactly the 'title', so we return only the args from this obj
     let results = completion_index.search({$and: [{"title": "=\"" + title + "\""}, {"args.text": "^\"" + arg + "\""}]});
-    return (results.length > 0) ? results[0].matches : [];
+    if (results.length > 0) {
+        let args = results[0].item.args;
+        // AG: Matched args are in matches.slice(1,), extract them.
+        // This code originally just returned matches itself, which has the
+        // text of all matched arguments, but not the occurrence data, and we
+        // need the latter to sort based on relevance.
+        results = results[0].matches.slice(1,).map(a => args[a.refIndex]);
+    }
+    return results;
+}
+
+function search_args(title) {
+    // like above, but look up *all* arg completions for a given object
+    if (!autocomplete) return [];
+    // for the arguments, we are only interested on the obj that match exactly the 'title', so we return only the args from this obj
+    let results = obj_exact_match(title);
+    // item.args is live data from the fuse, make sure to take a shallow copy
+    // with slice() which can be safely sorted in-place later
+    return (results.length > 0) ? results[0].item.args.slice() : [];
 }
 
 function index_obj_completion(obj_or_msg, obj_or_msg_text) {
@@ -727,6 +747,13 @@ function select_result_autocomplete_dd(textbox, ac_dropdown, last, offs, res, di
 	    // We only come here if the user presses 'tab' and there is no
 	    // option selected.
             var n = res.length;
+            if (n == 0) {
+                // It seems that while pondering the mysteries of the
+                // universe, your computer has lost our completion list. This
+                // shouldn't happen, but a little bit of defensive programming
+                // can't hurt.
+                return [-1,-1];
+            }
             var next =
 		(dir==0 ? last : dir>0 ? last+1 : last<=0 ? n-1 : last-1) % n;
 	    // If the new index is outside the current scope of the popup,
@@ -777,36 +804,37 @@ function repopulate_autocomplete_dd(doc, ac_dropdown, obj_class, text) {
        (3) We're in the middle of argument completion (started typing some
        arguments) in which case have_arg is true and arg is non-empty as
        well. */
-    let results = (arg.length > 0) ? (search_arg(title, arg).slice(1,)) : have_arg ? (obj_exact_match(title)) : (search_obj(title));
-    if (arg.length < 1 && have_arg && results.length > 0) {
-        results = results[0].item.args;
-    }
+    let results = (arg.length > 0) ? (search_arg(title, arg)) : have_arg ? (search_args(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. Finally, we condense the result list to a simple string list,
-       since we don't use all the other data any more beyond this point. */
-    if (arg.length < 1 && have_arg) {
-        // all argument completions, order them lexicographically
+       scoring similarity and can appear pretty random at times. What we
+       actually want here is an order based on scores, which also takes into
+       account relevance (as determined by the occurences field), and, last
+       but not least, an alphabetic ordering of the available completions (in
+       particular, the latter makes sure that for each score and relevance the
+       shortest matches come first, which you'd expect but isn't always
+       guaranteed with Fuse). Finally, we condense the result list to a simple
+       string list, since we don't use all the other data anymore beyond this
+       point. */
+    if (arg.length > 0 || have_arg) {
+        // argument completions, these don't have scores, order them by
+        // just relevance and text
         results.sort((a, b) =>
-            a.text == b.text ? 0 : a.text < b.text ? -1 : 1);
+            a.occurrences == b.occurrences || !autocomplete_relevance
+                ? (a.text == b.text ? 0 : a.text < b.text ? -1 : 1)
+                : b.occurrences - a.occurrences);
         results = results.map(a => title + " " + a.text);
-    } 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);
-        results = results.map(a => title + " " + a.value);
     } else {
-        // object completions, sort by score and item.title
+        // object completions, order by score, relevance 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;
+                if (a.item.occurrences == b.item.occurrences ||
+                    !autocomplete_relevance) {
+                    return a.item.title == b.item.title ? 0
+                        : a.item.title < b.item.title ? -1 : 1;
+                } else {
+                    return b.item.occurrences - a.item.occurrences;
+                }
             } else {
                 let d = a.score - b.score;
                 return d == 0 ? 0 : d < 0 ? -1 : 1;
@@ -6888,12 +6916,12 @@ function gui_midi_properties(gfxstub, sys_indevs, sys_outdevs,
 }
 
 function gui_gui_properties(dummy, name, show_grid, grid_size, save_zoom,
-                            autocomplete, autocomplete_prefix,
+                            autocomplete, autocomplete_prefix, autocomplete_relevance,
                             browser_doc, browser_path, browser_init,
                             autopatch_yoffset) {
     if (dialogwin["prefs"] !== null) {
         dialogwin["prefs"].window.gui_prefs_callback(name, show_grid, grid_size,
-            save_zoom, autocomplete, autocomplete_prefix,
+            save_zoom, autocomplete, autocomplete_prefix, autocomplete_relevance,
             browser_doc, browser_path, browser_init, autopatch_yoffset);
     }
 }
diff --git a/pd/src/m_glob.c b/pd/src/m_glob.c
index d302ea9748dd717b061d0a03352db71c1da4e606..e4f9f85c92288149410c972668e9de98fc8ba83f 100644
--- a/pd/src/m_glob.c
+++ b/pd/src/m_glob.c
@@ -81,7 +81,7 @@ static void glob_perf(t_pd *dummy, float f)
 }
 
 extern int sys_snaptogrid, sys_gridsize, sys_zoom,
-    sys_autocomplete, sys_autocomplete_prefix,
+    sys_autocomplete, sys_autocomplete_prefix, sys_autocomplete_relevance,
     sys_browser_doc, sys_browser_path, sys_browser_init,
     sys_autopatch_yoffset;
 extern t_symbol *sys_gui_preset;
@@ -93,6 +93,7 @@ static void glob_gui_prefs(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
     sys_zoom = !!atom_getintarg(0, argc--, argv++);
     sys_autocomplete = !!atom_getintarg(0, argc--, argv++);
     sys_autocomplete_prefix = !!atom_getintarg(0, argc--, argv++);
+    sys_autocomplete_relevance = !!atom_getintarg(0, argc--, argv++);
     sys_browser_doc = !!atom_getintarg(0, argc--, argv++);
     sys_browser_path = !!atom_getintarg(0, argc--, argv++);
     sys_browser_init = !!atom_getintarg(0, argc--, argv++);
@@ -102,7 +103,7 @@ static void glob_gui_prefs(t_pd *dummy, t_symbol *s, int argc, t_atom *argv)
 /* just the gui-preset, the save-zoom toggle and various help browser options for now */
 static void glob_gui_properties(t_pd *dummy)
 {
-    gui_vmess("gui_gui_properties", "xsiiiiiiiii",
+    gui_vmess("gui_gui_properties", "xsiiiiiiiiii",
         dummy,
         sys_gui_preset->s_name,
         sys_snaptogrid,
@@ -110,6 +111,7 @@ static void glob_gui_properties(t_pd *dummy)
         sys_zoom,
         sys_autocomplete,
         sys_autocomplete_prefix,
+        sys_autocomplete_relevance,
         sys_browser_doc,
         sys_browser_path,
         sys_browser_init,
diff --git a/pd/src/s_file.c b/pd/src/s_file.c
index 02100c6214852e89159001d30e6aa8c079e591f1..a290215eec1ac8c51ed9183ca95855f25881507c 100644
--- a/pd/src/s_file.c
+++ b/pd/src/s_file.c
@@ -43,7 +43,8 @@
 #endif
 
 int sys_defeatrt, sys_autopatch_yoffset, sys_snaptogrid = 1, sys_gridsize = 10,
-    sys_zoom, sys_autocomplete = 1, sys_autocomplete_prefix,
+    sys_zoom,
+    sys_autocomplete = 1, sys_autocomplete_prefix, sys_autocomplete_relevance,
     sys_browser_doc = 1, sys_browser_path, sys_browser_init;
 t_symbol *sys_flags = &s_;
 void sys_doflags( void);
@@ -681,6 +682,8 @@ void sys_loadpreferences( void)
         sscanf(prefbuf, "%d", &sys_autocomplete);
     if (sys_getpreference("autocomplete_prefix", prefbuf, MAXPDSTRING))
         sscanf(prefbuf, "%d", &sys_autocomplete_prefix);
+    if (sys_getpreference("autocomplete_relevance", prefbuf, MAXPDSTRING))
+        sscanf(prefbuf, "%d", &sys_autocomplete_relevance);
     if (sys_getpreference("browser_doc", prefbuf, MAXPDSTRING))
         sscanf(prefbuf, "%d", &sys_browser_doc);
     if (sys_getpreference("browser_path", prefbuf, MAXPDSTRING))
@@ -836,6 +839,8 @@ void glob_savepreferences(t_pd *dummy)
     sys_putpreference("autocomplete", buf1);
     sprintf(buf1, "%d", sys_autocomplete_prefix);
     sys_putpreference("autocomplete_prefix", buf1);
+    sprintf(buf1, "%d", sys_autocomplete_relevance);
+    sys_putpreference("autocomplete_relevance", buf1);
     sprintf(buf1, "%d", sys_browser_doc);
     sys_putpreference("browser_doc", buf1);
     sprintf(buf1, "%d", sys_browser_path);
diff --git a/pd/src/s_main.c b/pd/src/s_main.c
index e002b2c3f8945d9e44c34c61faf77197466c74be..0fb8cc06556a53053ba314b961296393bee3221e 100644
--- a/pd/src/s_main.c
+++ b/pd/src/s_main.c
@@ -331,7 +331,8 @@ void glob_forward_files_from_secondary_instance(void)
 
 extern void glob_recent_files(t_pd *dummy);
 extern int sys_browser_doc, sys_browser_path, sys_browser_init;
-extern int sys_autocomplete, sys_autocomplete_prefix;
+extern int sys_autocomplete, sys_autocomplete_prefix,
+  sys_autocomplete_relevance;
 
 /* this is called from main() in s_entry.c */
 int sys_main(int argc, char **argv)
@@ -412,9 +413,10 @@ int sys_main(int argc, char **argv)
     glob_recent_files(0);
         /* AG: send the browser config; this must come *after* gui_set_lib_dir
            so that the lib_dir is available when help indexing starts */
-    gui_start_vmess("gui_set_browser_config", "iiiii",
+    gui_start_vmess("gui_set_browser_config", "iiiiii",
                     sys_browser_doc, sys_browser_path, sys_browser_init,
-                    sys_autocomplete, sys_autocomplete_prefix);
+                    sys_autocomplete, sys_autocomplete_prefix,
+                    sys_autocomplete_relevance);
     gui_start_array();
     for (nl = sys_helppath; nl; nl = nl->nl_next)
     {