feat(files): find in an open markdown document with Cmd/Ctrl+F - #7196
Merged
Conversation
Adds find-in-document to the rich markdown editor, reusing the shared FindBar. A ProseMirror plugin owns the match set and paints inline decorations, so the search never touches the document, the undo history, or the collaborative Y.Doc, and it re-searches on every document change so a highlight can't go stale. Occurrence semantics come from the shared forEachSearchOccurrence rather than a fourth private definition. That helper normalized case with a plain toLowerCase(), which can grow a string and slide every later index, breaking its documented guarantee that bounds index the caller's own string; it now folds case length-preservingly for all three consumers. The Cmd/Ctrl+F open shortcut was a fourth copy of the same effect. It moves to a shared useFindShortcut beside FindBar, which the Files list now uses too.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Greptile SummaryThe PR adds find-in-document support to markdown viewers while keeping search state outside document and collaboration history.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/find/find-extension.ts | Adds transaction-metadata-driven search state and inline decorations without modifying editor content. |
| apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/find/find-matches.ts | Flattens text blocks, finds bounded occurrences, and maps match offsets back to ProseMirror positions. |
| apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/rich-markdown-editor/find/use-markdown-find.ts | Connects shortcut, query, navigation, tally synchronization, and active-match scrolling to the editor plugin. |
| apps/sim/app/workspace/[workspaceId]/components/find-bar/use-find-shortcut.ts | Centralizes document-level Cmd/Ctrl+F handling behind explicit surface ownership. |
| packages/utils/src/string.ts | Preserves caller-string offsets while applying case-insensitive search normalization. |
Sequence Diagram
sequenceDiagram
actor User
participant Shortcut as useFindShortcut
participant Bar as FindBar
participant Hook as useMarkdownFind
participant Plugin as RichMarkdownFind
participant Doc as ProseMirror document
User->>Shortcut: Cmd/Ctrl+F
Shortcut->>Hook: open()
Hook->>Bar: render and focus input
User->>Bar: enter query
Bar->>Hook: setQuery(query)
Hook->>Plugin: dispatch query metadata
Plugin->>Doc: scan visible text
Plugin-->>Hook: matches and active index
Hook-->>Bar: update tally
User->>Bar: next or previous
Bar->>Hook: step match
Hook->>Plugin: dispatch active index
Plugin-->>Doc: update decorations
Reviews (2): Last reviewed commit: "fix(files): close three find edge cases ..." | Re-trigger Greptile
There was a problem hiding this comment.
All reported issues were addressed across 17 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
- Keep context-sensitive lowercasing in the length-preserving case fold. A word-final sigma lowercases differently in a string than on its own, so folding character by character let one unrelated expanding code point change how every sigma in the string matched. The fallback now reads each character's replacement out of the whole-string result. - Decline Cmd/Ctrl+F while a collaborative document is still seeding. The text on screen then belongs to the read-only placeholder's editor, not the empty hidden one find is attached to, so the bar answered "No results" for visible text. The browser's native find reads the placeholder correctly in that window; the shortcut becomes ours once the seed lands. - Re-apply a pending term when the editor instance arrives, so a query typed before TipTap mounts is searched instead of sitting at zero matches until the next keystroke.
Collaborator
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
FindBar(Files page, mothership file view, public share page)forEachSearchOccurrenceinstead of adding a fourth private definition of "an occurrence"; that also inherits the whitespace fold, so a typed space matches a non-breaking onetoLowerCase(), which can grow a string (a few code points lowercase to two characters) and slide every later index, breaking its documented guarantee that bounds index the caller's own string. Now folds case length-preservingly, which also fixes workflow search and the canvas Note carduseFindShortcutbesideFindBar, which the Files list now uses too, with the one-owner-at-a-time invariant documented in one placeType of Change
Testing
Tested via unit tests — 19 new tests covering match positions across mark boundaries, inline atoms, and length-changing lowercase, plus plugin behavior against a real TipTap editor (decoration painting, stepping/wrapping, re-search on edit, active-index clamping, and no document/selection/undo writes). Each new test verified to fail when its fix is reverted.
Full suite green: 865 tests across the file viewer, collab-doc converter and share page; 39 utils tests;
bun run lint(26/26),bun run check:audits(37/37),bun run type-check, andcheck-block-registryall pass.Not verified in a browser.
Checklist