Skip to content

Commit a4a25ef

Browse files
authored
feat(search): Check keywords when searching applications
1 parent a336b7b commit a4a25ef

File tree

3 files changed

+62
-29
lines changed

3 files changed

+62
-29
lines changed

TESTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ Tasks for a tester to verify when approving a patch. Use complex window layouts
8888
- [ ] t: executes a command in a terminal
8989
- [ ] : executes a command in sh
9090
- [ ] = calculates an equation
91+
- [ ] Search results are as expected:
92+
- `cal` returns Calendar and Calculator before Color
93+
- `pops` returns Popsicle first
94+
- `shop` returns the Pop!_Shop first
9195

9296
### Window Titles
9397

src/dialog_launcher.ts

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -109,53 +109,80 @@ export class Launcher extends search.Search {
109109
// Filter matching desktop apps
110110
for (const [where, app] of this.desktop_apps) {
111111
const name = app.name()
112-
const name_match = name.toLowerCase()
113-
const retain = name_match.startsWith(pattern)
114-
|| name_match.includes(pattern)
115-
|| levenshtein.compare(name_match, pattern) < 3
116-
117-
if (retain) {
118-
const generic = app.generic_name();
119-
120-
const button = new launch.SearchOption(
121-
name,
122-
generic ? generic + " — " + where : where,
123-
'application-default-symbolic',
124-
{ gicon: app.icon() },
125-
this.icon_size(),
126-
{ app }
127-
)
112+
const keywords = app.keywords()
113+
const app_items = keywords !== null ? name.split().concat(keywords) : [name]
114+
115+
for (const item of app_items) {
116+
const item_match = item.toLowerCase()
117+
if ( item_match.startsWith(pattern)
118+
|| item_match.includes(pattern)
119+
|| levenshtein.compare(item_match, pattern) < 3 {
120+
const generic = app.generic_name();
121+
const button = new launch.SearchOption(
122+
name,
123+
generic ? generic + " — " + where : where,
124+
'application-default-symbolic',
125+
{ gicon: app.icon() },
126+
this.icon_size(),
127+
{ app },
128+
keywords
129+
)
128130

129-
DedicatedGPU.addPopup(app, button.widget)
131+
DedicatedGPU.addPopup(app, button.widget)
130132

131-
this.options.push(button)
133+
this.options.push(button)
134+
break
135+
}
132136
}
133137
}
134138

135139
const sorter = (a: launch.SearchOption, b: launch.SearchOption) => {
136140
const a_name = a.title.toLowerCase()
137141
const b_name = b.title.toLowerCase()
138142

139-
let a_name_weight = 0, b_name_weight = 0;
143+
let a_weight = 0, b_weight = 0;
140144

141145
if (!a_name.startsWith(pattern)) {
142-
a_name_weight = levenshtein.compare(a_name, pattern)
143-
if (a.description) {
144-
a_name_weight = Math.min(a_name_weight, levenshtein.compare(pattern, a.description.toLowerCase()))
146+
a_weight = 1
147+
if (!a_name.includes(pattern) {
148+
a_weight = levenshtein.compare(a_name, pattern)
149+
if (a.description) {
150+
a_weight = Math.min(a_weight, levenshtein.compare(pattern, a.description.toLowerCase()))
151+
}
152+
if (a.keywords) {
153+
for (const keyword of a.keywords) {
154+
if keyword.toLowerCase().startsWith(pattern) || keyword.toLowerCase().includes(pattern) {
155+
a_weight = 1
156+
} else {
157+
a_weight = Math.min(a_weight, (levenshtein.compare(pattern, keyword.toLowerCase()) + 1))
158+
}
159+
}
160+
}
145161
}
146162
}
147163

148164
if (!b_name.startsWith(pattern)) {
149-
b_name_weight = levenshtein.compare(b_name, pattern)
150-
151-
if (b.description) {
152-
b_name_weight = Math.min(b_name_weight, levenshtein.compare(pattern, b.description.toLowerCase()))
165+
b_weight = 1
166+
if (!b_name.includes(pattern)) {
167+
b_weight = levenshtein.compare(b_name, pattern)
168+
if (b.description) {
169+
b_weight = Math.min(b_weight, levenshtein.compare(pattern, b.description.toLowerCase()))
170+
}
171+
if (b.keywords) {
172+
for (const keyword of b.keywords) {
173+
if keyword.toLowerCase().startsWith(pattern) || keyword.toLowerCase().includes(pattern) {
174+
b_weight = 1
175+
} else {
176+
b_weight = Math.min(b_weight, (levenshtein.compare(pattern, keyword.toLowerCase()) + 1))
177+
}
178+
}
179+
}
153180
}
154181
}
155182

156-
return a_name_weight === b_name_weight
183+
return a_weight === b_weight
157184
? a_name.length > b_name.length ? 1 : 0
158-
: a_name_weight > b_name_weight ? 1 : 0
185+
: a_weight > b_weight ? 1 : 0
159186
}
160187

161188
// Sort the list of matched selections

src/launcher_service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,15 +178,17 @@ export class SearchOption {
178178
title: string
179179
description: null | string
180180
id: Identity
181+
keywords: null | array
181182

182183
widget: St.Button
183184

184185
shortcut: St.Widget = new St.Label({ text: "", y_align: Clutter.ActorAlign.CENTER, style: "padding-left: 6px;padding-right: 6px" })
185186

186-
constructor(title: string, description: null | string, category_icon: string, icon: null | IconSrc, icon_size: number, id: Identity) {
187+
constructor(title: string, description: null | string, category_icon: string, icon: null | IconSrc, icon_size: number, id: Identity, keywords: null | array) {
187188
this.title = title
188189
this.description = description
189190
this.id = id
191+
this.keywords = keywords
190192

191193
let cat_icon
192194
const cat_icon_file = Gio.File.new_for_path(category_icon)

0 commit comments

Comments
 (0)