You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Find and Replace: Replace row, Replace all and match toggles (backlog, lowest priority) #394
Backlog. Lowest priority. Do not start before #393 ships.
Parent: #393. The maintainer moved Replace and the match toggles out of #393 on 2026-10-05. This issue starts only after the #393 Find bar ships. It was slices 7 and 8 there.
Scope
A chevron button at the left of the Find bar. It has aria-expanded and aria-controls. It shows the Replace row.
Replace row: a replace input, then Replace and Replace all. Replace changes the current match, then steps to the next one.
Toggles on the find input: Match case, Whole word and Regex. Each is a ToolbarButton with aria-pressed and the is-active recipe.
Whole word uses Unicode letter classes (\p{L} with the u flag). A plain \b does not see Persian or Arabic letters.
An invalid regex shows an inline error and paints nothing. It never throws.
Risks and rules
One transaction. Replace all scans the whole document at click time, with no 200 cap. It applies every change in one ProseMirror transaction, in reverse document order, with tr.insertText. That is one Yjs update, so collaborators see one change. One Mod-z undoes it all.
Read-only pads and visitors. Show the chevron and the Replace row only when the editor is editable. Hide them under Read-only for a non-owner, under the editing lock (selectDocumentEditingLocked), and in History. Find itself stays available to every viewer.
Headings, sections and chatrooms. Each heading is a section with its own chatroom, keyed by toc-id. A match never crosses a textblock, so a replace never joins or splits blocks. The heading node and its toc-id must survive. A test pins this.
Heading text. A replace inside a heading changes the TOC title and the ?h= slug trail. Links use id=, so they still resolve.
Link edges.insertText takes the marks at the match start. A match that crosses a hyperlink edge can lose part of the link. See 393-replace-link-edge.
Comment anchors.scrollToCommentAnchor finds a text comment by its quoted text. A replace that changes that text sends the jump to the heading fallback.
Title. Replace may empty Title. Title must stay a heading.
Regex cost. A slow pattern blocks the main thread of the user's own tab. Cap the scan and fail closed.
Concurrent edits. A peer who types inside a match during Replace all merges through Yjs. Accept that.
Open decisions
Each needs a maintainer ruling. The recommendation comes from #393.
393-replace-chord (Find in document: minimal floating Find bar (⌘F), then Find and Replace #393 decision 10). Recommend: ⌥⌘F on macOS, as VS Code uses. On Windows and Linux, choose between Ctrl+H and Ctrl+Alt+F. Ctrl+H is the browser's History key. Ctrl+Alt+F is AltGr on some layouts. Mod-Shift-h is already Highlight (@tiptap/extension-highlight).
Backlog. Lowest priority. Do not start before #393 ships.
Parent: #393. The maintainer moved Replace and the match toggles out of #393 on 2026-10-05. This issue starts only after the #393 Find bar ships. It was slices 7 and 8 there.
Scope
aria-expandedandaria-controls. It shows the Replace row.ToolbarButtonwitharia-pressedand theis-activerecipe.\p{L}with theuflag). A plain\bdoes not see Persian or Arabic letters.Risks and rules
tr.insertText. That is one Yjs update, so collaborators see one change. One Mod-z undoes it all.selectDocumentEditingLocked), and in History. Find itself stays available to every viewer.toc-id. A match never crosses a textblock, so a replace never joins or splits blocks. The heading node and itstoc-idmust survive. A test pins this.?h=slug trail. Links useid=, so they still resolve.insertTexttakes the marks at the match start. A match that crosses a hyperlink edge can lose part of the link. See393-replace-link-edge.scrollToCommentAnchorfinds a text comment by its quoted text. A replace that changes that text sends the jump to the heading fallback.Open decisions
Each needs a maintainer ruling. The recommendation comes from #393.
393-case-default(Find in document: minimal floating Find bar (⌘F), then Find and Replace #393 decision 4). Recommend: case-insensitive, as today. Match case arrives as a toggle.393-toggles-timing(Find in document: minimal floating Find bar (⌘F), then Find and Replace #393 decision 9). Recommend: ship the toggles with Replace, not in the Find in document: minimal floating Find bar (⌘F), then Find and Replace #393 Find bar. Find text in the open pad #250 ruled a literal search.393-replace-all-auth(Find in document: minimal floating Find bar (⌘F), then Find and Replace #393 decision 10). Recommend: Replace all needs a signed-in user (isVisitor(), thenopenInlineSignInDialog()). Single Replace follows the normal edit rule.393-replace-chord(Find in document: minimal floating Find bar (⌘F), then Find and Replace #393 decision 10). Recommend: ⌥⌘F on macOS, as VS Code uses. On Windows and Linux, choose between Ctrl+H and Ctrl+Alt+F. Ctrl+H is the browser's History key. Ctrl+Alt+F is AltGr on some layouts.Mod-Shift-his already Highlight (@tiptap/extension-highlight).393-replace-link-edge(Find in document: minimal floating Find bar (⌘F), then Find and Replace #393 Risks, Marks). Decide whether to refuse a match that crosses a hyperlink edge, or to keep the first mark. No recommendation was given in Find in document: minimal floating Find bar (⌘F), then Find and Replace #393.Before any code, the maintainer approves the Replace row look from a visual preview, per
AGENTS.md§Workflow And Review Expectations.Acceptance criteria
aria-expandedfollows it.toc-id. Each section keeps its chatroom.393-replace-link-edgeruling..cursor/docs/design-system.md, in every theme.toc-id. Extendapps/webapp/cypress/e2e/editor/find/caret-find.cy.ts.