aboutsummaryrefslogtreecommitdiff
path: root/menubar/search.swift
diff options
context:
space:
mode:
Diffstat (limited to 'menubar/search.swift')
-rw-r--r--menubar/search.swift15
1 files changed, 14 insertions, 1 deletions
diff --git a/menubar/search.swift b/menubar/search.swift
index c62c612..ed9adaa 100644
--- a/menubar/search.swift
+++ b/menubar/search.swift
@@ -72,12 +72,15 @@ func searchFields(_ row: Row) -> [String] {
}
/// Rows matching every word of `query`, best first; ties keep the given
-/// order. An empty query returns every row in order.
+/// order. An empty query returns every row in order. A word also matches
+/// the draft in an agent's input box, as written (not fuzzily: a long text
+/// would match almost anything), ranking below the other fields.
func search(_ rows: [Row], _ query: String) -> [SearchMatch] {
let terms = query.split(whereSeparator: \.isWhitespace).map { lowered(String($0)) }
var matches: [(match: SearchMatch, order: Int)] = []
for (order, row) in rows.enumerated() {
let fields = searchFields(row)
+ let draft = String(lowered(row.draft))
var total = 0
var labelPositions = Set<Int>()
var matchedAll = true
@@ -88,6 +91,9 @@ func search(_ rows: [Row], _ query: String) -> [SearchMatch] {
best = (found.score, field, found.positions)
}
}
+ if best == nil, draft.contains(String(term)) {
+ best = (term.count * 8, fields.count, [])
+ }
guard let best else { matchedAll = false; break }
total += best.score
if best.field == 0 { labelPositions.formUnion(best.positions) }
@@ -476,6 +482,13 @@ func searchSelftest() -> [String] {
check(ids(search(rows, "lgsc")) == ["%1"], "query: fuzzy name")
check(ids(search(rows, "langgraph")) == ["%1", "%3"], "query: directories match too")
check(ids(search(rows, "temporal demo")) == ["%2"], "query: every word must match")
+ var drafted = rows
+ drafted[3].draft = "also check the Sidecar restart"
+ check(ids(search(drafted, "sidecar")) == ["%4"], "query: a draft's words match")
+ check(ids(search(drafted, "scr")).first == "%1" && !ids(search(drafted, "sdcr")).contains("%4"),
+ "query: a draft matches as written, not fuzzily")
+ drafted[0].draft = "deploy"
+ check(ids(search(drafted, "deploy")) == ["%3", "%1"], "query: a draft ranks below a name")
check(ids(search(rows, "done")) == ["%1"], "query: status word")
check(ids(search(rows, "notes")) == ["%4"], "query: window")
check(ids(search(rows, "zzz")).isEmpty, "query: no match")