diff options
Diffstat (limited to 'docs/superpowers/plans')
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md | 39 | ||||
| -rw-r--r-- | docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md | 34 |
2 files changed, 40 insertions, 33 deletions
diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md index 8ae8dff..cfa119b 100644 --- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md +++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability-closed.md @@ -4802,3 +4802,42 @@ failed, which is what a missing `accept()` does to `exec()`. **Item 78 stays open**, carrying the rule shortcut alone. The road from a search to a rule already exists: save the query, then create a rule from it. + +## 86. A right-click search can replace or narrow, but never exclude + +**Done 2026-08-14, unreleased.** See +`specs/2026-08-14-exclude-from-search-design.md`. + +**Observed (user, 2026-08-14):** "we've added the possibility to search clicking +on any element in the message pane, the current available search options are to +run the query from scratch or add to the existing query. A missing option is to +add negatively (not)." + +**Cause (verified in the code before any was written).** Item 85 shipped exactly +two operations and wired them through as a single boolean, so the gap was not a +missing menu entry over an existing capability: there was no third state for an +entry to select, and the signature could not express one. `SearchTerm` had +`extend()` and no exclusion form at all. + +**Shipped as five commits.** `SearchTerm::exclude()`, then the `SearchMode` enum +alone, then the four signatures widened as one mechanical change, then the +`hasQuery` guard, then the menu entries. Each step left the suite green, which +is what made the enum change safe to do in one commit across three files. + +**Two decisions the user made, recorded because they are not recoverable from +the code.** Excluding from an EMPTY query would mean the whole Maildir minus one +value, so the entry is greyed rather than hidden, and `exclude()` returns empty +as a second layer against a caller that forgets the guard. And the two shipped +labels were left untouched, so nothing the user already knew moved. + +**The plan under-counted the signature change.** It predicted one test file and +the compiler found three: `test_messageview.cpp` and `test_mainwindow.cpp` also +emit `searchRequested` directly. Four extra call sites, no design consequence, +but a reminder that "four signatures" is not the same as "four call sites" and +grepping for the latter is cheap. + +**Verified:** 23 of 23 tests passing. The guard's mutation check fails on the +blocked emit when the condition is disabled, and it did not hang, which is the +outcome item 85's trap made worth checking for. The user hand tested all three +surfaces with an empty query bar and with one, including the disjunction case +the parenthesising exists for. diff --git a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md index 087ce95..f578a3a 100644 --- a/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md +++ b/docs/superpowers/plans/2026-08-03-post-0.1.0-usability.md @@ -150,7 +150,7 @@ taking that too literally. | 83 | A rule named with spaces is written to the file and dropped by every reader | defect | S | **done** 2026-08-14, unreleased. The name is sanitised into an id, save validates, a bad id loads for repair | | 84 | A config problem blocks `test_mainwindow` on a modal nobody can dismiss | testing | S | open; measured 2026-08-14, `showWarnings()` calls `QMessageBox::warning` from the constructor | | 85 | Nothing on screen can be searched for by right-clicking it | workflow | M | **done** 2026-08-14, unreleased; see `specs/2026-08-14-search-from-message-design.md`. Split from 78; rebuilt the details dialog as rows | -| 86 | A right-click search can replace or narrow, but never exclude | workflow | S | open, specced 2026-08-14; see `specs/2026-08-14-exclude-from-search-design.md`. Follows 85. The `extend` bool has no room for a third choice, so this widens a signature rather than adding a menu entry | +| 86 | A right-click search can replace or narrow, but never exclude | workflow | S | **done** 2026-08-14, unreleased; see `specs/2026-08-14-exclude-from-search-design.md`. Follows 85. The `extend` bool became a `SearchMode` enum across four signatures | Sizes are rough: XS under an hour, S a sitting, M a session. @@ -578,38 +578,6 @@ here. **Size: S.** The diagnosis is the expensive part and it is already done. -## 86. A right-click search can replace or narrow, but never exclude - -**Observed (user, 2026-08-14):** "we've added the possibility to search clicking -on any element in the message pane, the current available search options are to -run the query from scratch or add to the existing query. A missing option is to -add negatively (not)." - -**Cause (verified in the code, 2026-08-14).** Item 85 shipped exactly two -operations and wired them through as a single boolean. Every surface builds the -same pair: `MessageView::addSearchEntries` (`src/messageview.cpp:566`) adds -"Search for this" and "Add to search" per offer, and -`MessageDetailsDialog` (`src/messagedetailsdialog.cpp:92`) repeats that pair per -row. Both emit `searchRequested(query, extend)`, and -`MainWindow::runSearchFromPane` (`src/mainwindow.cpp:1654`) branches on that one -bool: `extend ? SearchTerm::extend(m_queryEdit->text(), query) : query`. -`SearchTerm` has `extend()` and no exclusion form at all. So the gap is not a -missing menu entry over an existing capability; there is no third state for a -menu entry to select, and the signature cannot express one. - -**Specced 2026-08-14: read -`specs/2026-08-14-exclude-from-search-design.md` rather than planning from -here.** Three constraints decide whether it can be picked up. The `bool extend` -becomes a `SearchMode` enum across four signatures, which is the bulk of the -work and touches three files. Excluding from an EMPTY query would mean the whole -Maildir minus one value, so the entry is greyed when the query bar is empty and -the grammar returns empty as a second layer. And correctness is asserted against -the constructed string, never a result count, because notmuch parses `from:((((` -cleanly and matches zero. - -**Size: S.** The grammar is one function beside an existing one with existing -tests; the spread is the signature change across three files. - ## Deferred, unsized, or split out Items noted while triaging but not part of the original list. Same numbering |
