diff options
| author | Igor Soarez <igor@soarez.org> | 2026-10-30 18:59:43 +0200 |
|---|---|---|
| committer | Igor Soarez <igor@soarez.org> | 2026-10-30 18:59:43 +0200 |
| commit | 959f0d46cac1a09d0821da599d8dff54d1147892 (patch) | |
| tree | 499b38261ccfdc88f60ea8cbac7d279f202709c1 /menubar/search.swift | |
| parent | b0cfd10b80443d3f67d263ff4db177bb53cc90ed (diff) | |
mark forgotten drafts in pi agents' input boxes, and keep them across a crash or restore
Diffstat (limited to 'menubar/search.swift')
| -rw-r--r-- | menubar/search.swift | 15 |
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") |
