Skip to content

feat(app): show matches in context and scope in search - #170

Merged
aicayzer merged 6 commits into
mainfrom
feat/search-results
Oct 26, 2026
Merged

aicayzer merged 6 commits into
mainfrom
feat/search-results

Conversation

@aicayzer

Copy link
Copy Markdown
Contributor

Summary

Search in MAPP now shows why each item matched, says plainly when the results may be incomplete, and lets the person look in the open place or everywhere. All of it comes from the working copy through the marfa-swift SDK, so it still works offline and MAPP does no matching of its own.

  • Each result row shows the matching excerpt with the hit in bold. The excerpt is the copy's own, and it is shown only while it is still true of the item, so an item edited after the search never shows old text.
  • While the copy is still filling or catching up, the results carry a line saying so, and an empty list says "Still Looking" instead of claiming nothing matched. The search runs again by itself once the copy is whole.
  • A scope control (Everywhere, or the open place) sits above the results wherever the place stands for a query: Inbox, Favorites, a type, a collection, a source, Files and a saved view. Recents, Recently Deleted, All Items and the indexes do not offer it, since searching them alone would find nothing different.
  • At most 500 results are listed, and a line says when there were more.
  • The search field's placeholder now reads "Search or “exact phrase”", which tells people that quotes search for a phrase. No new control was added for it.
  • The command palette shows the same excerpts.

Chosen: the existing list sort still orders results, as before, rather than best match first. The scope control is a native segmented picker in a top safe-area bar, and it shows only while searching.

Changes

  • ItemSource.search and ItemLibrary.search(_:in:) now take a scope and return excerpts, an incomplete flag and a cap flag (MAPP/Model/Items/ItemSearch.swift). items(matching:) is gone.
  • MarfaSource maps a place onto the SDK's SearchFilters (type, tier, tags, listing filter, beneath, state) or search(inView:) for a saved view. MarfaLibrary reruns a partial search once the copy is whole and keeps the earlier results when a search fails, as before.
  • SearchViews.swift holds the status bar and the empty state. The list, table, gallery, board and agenda use them, and the list rows and the palette show excerpts.
  • NoteText.snippet and its test are removed, since the SDK's excerpts replace it.
  • Seven String Catalog keys are appended by hand; MAPP/Model/AGENTS.md has a new Search section.

Testing

  • Built with xcodebuild build-for-testing and ran the whole Unit plan once: all 1047 test cases passed.
  • New tests in MAPPTests/SearchTests.swift cover excerpt parsing (marks, entities, an empty excerpt, a very long excerpt), the stale-excerpt guard, the scope rules, an empty query, words that find nothing, a quoted query, an item removed while shown, partial then whole, a capped answer, and the target each place sends. The existing test for a failing search (keeps results, tells the person) still passes. These tests cover APIs that did not exist on main, so none could be run against it first.
  • Not tested: the UI plan and the Live plan were not run, and the app was not launched, so the look of the status bar, the highlighted rows and the placeholder at narrow widths is unchecked. Nothing was run against a real server's search ranking or its partial answers.

Notes for reviewers

SDK gaps found:

  • The fake working copy (WorkingCopy.fake, used by the sample library, previews and the UI tests) throws unsupported for search and search(inView:). The sample library therefore cannot show results, excerpts or the incomplete state, and UI tests that search the sample probably fail on main already.
  • Type and tag filtering are supported by SearchFilters, so they are not a gap.
  • Completeness.stale is treated like .partial: both say the results may be incomplete. That is a judgement call.

Follow-up: results are still ordered by the chosen sort (and by recency in the palette), not by the copy's relevance score.

Review depth: a normal review is enough. The riskiest parts are the rerun when the copy becomes whole (MarfaLibrary.search) and the place-to-filter mapping (MarfaLibrary.target(for:)).

Open pull requests #127, #98 and #169 also touch MarfaLibrary.swift, ItemLibrary.swift or the library test files, so whichever merges second may need a small rebase.

Checklist

  • The title is a scoped Conventional Commit.
  • New behavior has a test that was seen failing first, or no test was needed and the reason is above.
  • Docs, comments and the contract still say what is true after this change.

@aicayzer
aicayzer marked this pull request as ready for review October 26, 2026 16:20
@aicayzer
aicayzer merged commit 3c3243a into main Oct 26, 2026
4 checks passed
@aicayzer
aicayzer deleted the feat/search-results branch October 26, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant