feat(extension-find-and-replace): support capture groups in replacements - #8129
feat(extension-find-and-replace): support capture groups in replacements#8129Aslam97 wants to merge 18 commits into
Conversation
✅ Deploy Preview for tiptap-embed ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
🦋 Changeset detectedLatest commit: 1094147 The changes in this PR will be included in the next version bump. This PR includes changesets to release 76 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughSummary
WalkthroughRegex-mode find-and-replace now supports capture-based substitutions for single and bulk replacements, Unicode-aware whole-word matching, and matcher-aware search. Tests and React/Vue demos document the updated behavior. ChangesRegex replacement capture expansion
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Editor
participant FindAndReplace
participant SearchMatcher
participant ReplacementEngine
participant ProseMirror
Editor->>FindAndReplace: submit search and replacement terms
FindAndReplace->>SearchMatcher: create matcher from search options
SearchMatcher-->>FindAndReplace: return matches and capture-group metadata
FindAndReplace->>ReplacementEngine: expand replacement for each result
ReplacementEngine-->>FindAndReplace: return result-specific text
FindAndReplace->>ProseMirror: apply grouped document replacements
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0956eef217
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
.changeset/moody-sheep-kiss.md (1)
5-5: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueWorth one extra line about escaping.
Existing users with a literal
$1in their replace term will see different output in regex mode. Mentioning that$$produces a literal$saves a support round-trip.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.changeset/moody-sheep-kiss.md at line 5, Update the regex-mode changeset description to document the escaping behavior: users can produce a literal dollar sign with `$$`, including when replacement text would otherwise be interpreted as a capture-group substitution.packages/extension-find-and-replace/__tests__/find-and-replace.spec.ts (2)
624-641: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueGuard the transaction listener against unrelated transactions.
transactionsrecords every transaction after the listener is attached, so any future change that dispatches an extra transaction duringreplaceAll()(a re-search, a selection update) turns this into a confusing failure. Filtering to transactions that actually change the doc keeps the assertion focused on "one step".♻️ Suggested tightening
editor.on('transaction', ({ transaction }) => { - transactions.push(transaction.steps.length) + if (transaction.docChanged) { + transactions.push(transaction.steps.length) + } })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-find-and-replace/__tests__/find-and-replace.spec.ts` around lines 624 - 641, Update the transaction listener in the “expands many regex captures with one indexed pass and one transaction step” test to record only transactions that change the document, while preserving the existing transaction.steps.length assertion for the replacement transaction.
358-380: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueNice coverage. Optional: pull the setup boilerplate into a helper.
Almost every new test repeats
editor.destroy(); editor = createEditor(...)plus the same four command calls. Something likesetupRegexEditor(html, { search, replace })would make the intent of each test easier to spot for a newcomer.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-find-and-replace/__tests__/find-and-replace.spec.ts` around lines 358 - 380, Extract the repeated regex test setup into a local helper such as setupRegexEditor, accepting the initial HTML and search/replace terms, and have it destroy the existing editor, create the new editor, enable regex mode, and configure both terms. Update the affected tests, including “expands capture groups per regex match when replacing all” and “reorders multiple regex capture groups,” to use the helper while preserving their assertions.packages/extension-find-and-replace/src/find-and-replace.ts (1)
380-388: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSmall duplication: same "regex or null" block appears in
replaceResulttoo (Lines 190-192).A tiny helper like
replacementRegex(pluginState)would keep the two call sites in sync if the options ever change.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-find-and-replace/src/find-and-replace.ts` around lines 380 - 388, Extract the duplicated regex-or-null construction from replaceAllResults and replaceResult into a shared helper such as replacementRegex(pluginState). Update both call sites to use the helper, preserving the existing createSearchRegex options and null behavior when useRegex is disabled.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/extension-find-and-replace/src/utils/createResultReplacement.ts`:
- Around line 37-52: Replace the WeakMap<Node, ReplacementContext> cache in the
result callback with a cache keyed by each textblock’s resolved start position,
such as $from.start() - 1. Update the lookup and insertion in the context
initialization path while preserving the existing createTextblockSearchContext
and replacement-expander behavior.
---
Nitpick comments:
In @.changeset/moody-sheep-kiss.md:
- Line 5: Update the regex-mode changeset description to document the escaping
behavior: users can produce a literal dollar sign with `$$`, including when
replacement text would otherwise be interpreted as a capture-group substitution.
In `@packages/extension-find-and-replace/__tests__/find-and-replace.spec.ts`:
- Around line 624-641: Update the transaction listener in the “expands many
regex captures with one indexed pass and one transaction step” test to record
only transactions that change the document, while preserving the existing
transaction.steps.length assertion for the replacement transaction.
- Around line 358-380: Extract the repeated regex test setup into a local helper
such as setupRegexEditor, accepting the initial HTML and search/replace terms,
and have it destroy the existing editor, create the new editor, enable regex
mode, and configure both terms. Update the affected tests, including “expands
capture groups per regex match when replacing all” and “reorders multiple regex
capture groups,” to use the helper while preserving their assertions.
In `@packages/extension-find-and-replace/src/find-and-replace.ts`:
- Around line 380-388: Extract the duplicated regex-or-null construction from
replaceAllResults and replaceResult into a shared helper such as
replacementRegex(pluginState). Update both call sites to use the helper,
preserving the existing createSearchRegex options and null behavior when
useRegex is disabled.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: a2472ed0-7436-4424-9043-fccf159dd6f1
📒 Files selected for processing (12)
.changeset/moody-sheep-kiss.mddemos/src/Extensions/FindAndReplace/React/index.jsxdemos/src/Extensions/FindAndReplace/Vue/index.vuepackages/extension-find-and-replace/__tests__/expandReplacement.spec.tspackages/extension-find-and-replace/__tests__/find-and-replace.spec.tspackages/extension-find-and-replace/src/find-and-replace.tspackages/extension-find-and-replace/src/search/text-segments.tspackages/extension-find-and-replace/src/search/textblock-search.tspackages/extension-find-and-replace/src/utils/createResultReplacement.tspackages/extension-find-and-replace/src/utils/expandReplacement.tspackages/extension-find-and-replace/src/utils/replaceAllResults.tspackages/extension-find-and-replace/src/utils/replaceGroup.ts
|
@coderabbitai review |
✅ Action performedReview finished.
|
…lacements and combine whole-word with match case
…ase search and replace features
…ase search and replace features
|
@coderabbitai please do another review of the changes since your last review |
|
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/extension-find-and-replace/src/utils/expandReplacement.ts (1)
31-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winShare the Unicode advancement helper.
The Unicode code-point advancement logic is duplicated in
packages/extension-find-and-replace/src/search/find-safe-matcher-matches.tsLines 31-42. If the two implementations diverge, search results and replacement lookups can use different offsets. Extract one utility, such aspackages/extension-find-and-replace/src/utils/advanceStringIndex.ts, and use it from both files. (raw.githubusercontent.com)As per coding guidelines, TypeScript should use one reusable utility per file and name the file after its export.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/extension-find-and-replace/src/utils/expandReplacement.ts` around lines 31 - 41, Extract advanceStringIndex into a dedicated utility file named after the export, preserving its non-Unicode and UTF-16 code-point behavior. Remove the duplicate implementation from find-safe-matcher-matches.ts and update both that file and expandReplacement.ts to import and reuse the shared utility.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.changeset/moody-sheep-kiss.md:
- Around line 5-6: Update the changeset description to one short sentence
covering the complete regex replacement syntax, including capture groups such as
$1, the whole-match token $&, and the literal-dollar token $$; retain the
separate whole-word and match-case search behavior in that same sentence.
---
Nitpick comments:
In `@packages/extension-find-and-replace/src/utils/expandReplacement.ts`:
- Around line 31-41: Extract advanceStringIndex into a dedicated utility file
named after the export, preserving its non-Unicode and UTF-16 code-point
behavior. Remove the duplicate implementation from find-safe-matcher-matches.ts
and update both that file and expandReplacement.ts to import and reuse the
shared utility.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: bf33d7c8-6531-4142-a2fb-db21f5cf1a90
📒 Files selected for processing (13)
.changeset/moody-sheep-kiss.mddemos/src/Extensions/FindAndReplace/React/index.jsxdemos/src/Extensions/FindAndReplace/Vue/index.vuepackages/extension-find-and-replace/__tests__/expandReplacement.spec.tspackages/extension-find-and-replace/__tests__/find-and-replace.spec.tspackages/extension-find-and-replace/src/find-and-replace.tspackages/extension-find-and-replace/src/search/find-safe-matcher-matches.tspackages/extension-find-and-replace/src/search/regex.tspackages/extension-find-and-replace/src/search/search-matcher.tspackages/extension-find-and-replace/src/search/unicode-word-character.tspackages/extension-find-and-replace/src/types.tspackages/extension-find-and-replace/src/utils/createResultReplacement.tspackages/extension-find-and-replace/src/utils/expandReplacement.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- packages/extension-find-and-replace/src/search/unicode-word-character.ts
- packages/extension-find-and-replace/src/search/find-safe-matcher-matches.ts
- packages/extension-find-and-replace/src/utils/createResultReplacement.ts
- packages/extension-find-and-replace/src/types.ts
- packages/extension-find-and-replace/src/search/regex.ts
- packages/extension-find-and-replace/tests/expandReplacement.spec.ts
- packages/extension-find-and-replace/tests/find-and-replace.spec.ts
- packages/extension-find-and-replace/src/find-and-replace.ts
- packages/extension-find-and-replace/src/search/search-matcher.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…s and fix non-participating capture group handling
…ches with parameter and return details
…rce RE2JS matcher type in expandReplacement
Changes and review
This PR improves the standalone, headless Find and Replace extension:
Checklist
Responsibility
AI assistance
This contribution was developed with assistance from OpenAI Codex. I reviewed all generated changes and manually verified the resulting behavior.
UI Component requirement