From 15cecc9748dab07b2752fa476e98958fa077a598 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 31 Jul 2026 20:22:05 -0400 Subject: [PATCH] Rank apps matching a whole word of the query above exact menu entries Co-Authored-By: Claude Fable 5 --- shell/plugins/menu/MenuModel.js | 3 +++ test/shell.d/menu-test.sh | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/shell/plugins/menu/MenuModel.js b/shell/plugins/menu/MenuModel.js index b26822ed..e6bd990b 100644 --- a/shell/plugins/menu/MenuModel.js +++ b/shell/plugins/menu/MenuModel.js @@ -313,6 +313,9 @@ function searchScore(items, entry, query) { var score = 80 if (label === needle) score = entry.parent === "root" ? 2 : 0 + // An installed app whose name contains the query as a whole word ("zen" + // for Zen Browser) beats exact-labeled menu entries like Install > Zen. + else if (entry.kind === "app" && label.split(/\s+/).indexOf(needle) >= 0) score = 0 else if (label.indexOf(needle) === 0) score = 10 else if (label.indexOf(needle) >= 0) score = 30 else if (nameText.indexOf(needle) >= 0) score = 40 diff --git a/test/shell.d/menu-test.sh b/test/shell.d/menu-test.sh index 312bffd6..6ff4f015 100644 --- a/test/shell.d/menu-test.sh +++ b/test/shell.d/menu-test.sh @@ -115,7 +115,8 @@ const defaultById = Object.fromEntries(defaultItems.map(item => [item.id, item]) const rankBase = menu.mergeMenuSources(defaultItems, []) const ranked = menu.mergeAppRows(rankBase.items, rankBase.itemOrder, [ { id: 'apps.brave', parent: 'apps', kind: 'app', label: 'Brave', description: '', aliases: [] }, - { id: 'apps.fontforge', parent: 'apps', kind: 'app', label: 'FontForge', description: '', aliases: [] } + { id: 'apps.fontforge', parent: 'apps', kind: 'app', label: 'FontForge', description: '', aliases: [] }, + { id: 'apps.zen', parent: 'apps', kind: 'app', label: 'Zen Browser', description: '', aliases: [] } ]) const rankScore = (id, query) => menu.searchScore(ranked.items, ranked.items[id], query) assert( @@ -124,6 +125,12 @@ assert( ), 'menu ranks an installed app above menu entries matching the query equally well' ) +assert( + ['install.browser.zen', 'remove.browser.zen', 'setup.default.browser.zen'].every( + id => rankScore('apps.zen', 'zen') < rankScore(id, 'zen') + ), + 'menu ranks an app matching the query as a whole word above exact-labeled menu entries' +) assert( rankScore('style.font', 'font') < rankScore('apps.fontforge', 'font'), 'menu keeps a better-matching menu entry above a weaker app match'