Skip to content

Conversation

@carl2027
Copy link

  • Fixed: The search dialog now correctly receives focus when opened in the current block.
  • Implemented direct search for selected text.

@CLAassistant
Copy link

CLAassistant commented Dec 23, 2025

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Walkthrough

An optional blockId?: string was added to SearchProps and SearchOptions, propagated through the Search component, injected as data-blockid on the rendered search container, and returned from useSearch (as blockId: options?.blockId). TerminalView and WebView now pass their blockId into useSearch. The global key handling in the store gained helpers getSelectedText, focusSearchInput, activateSearch, and deactivateSearch; Cmd+F now opens/resets search with the selected text and focuses a block-scoped input when available, and Escape deactivates search or closes modals.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Improve search functionality' is vague and overly broad. While it relates to the changeset, it lacks specificity about the main improvements (focus handling and selected text search). Consider using a more specific title like 'Add block-scoped search with focus and selected text support' to better describe the key changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description directly addresses the changes made: fixing search dialog focus when opened in the current block and implementing direct search for selected text, both of which align with the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7afb70d and 8ef705c.

📒 Files selected for processing (4)
  • frontend/app/element/search.tsx
  • frontend/app/store/keymodel.ts
  • frontend/app/view/term/term.tsx
  • frontend/app/view/webview/webview.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/app/view/webview/webview.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/app/store/keymodel.ts (3)
frontend/app/store/global.ts (2)
  • getBlockComponentModel (853-853)
  • globalStore (865-865)
frontend/app/view/term/term-model.ts (1)
  • TermViewModel (37-905)
pkg/vdom/vdom_types.go (1)
  • WaveKeyboardEvent (233-247)
🔇 Additional comments (6)
frontend/app/view/term/term.tsx (1)

181-181: LGTM! Block-scoped search correctly enabled.

The addition of blockId to the useSearch options correctly enables per-block search scoping, aligning with the broader changes in this PR.

frontend/app/element/search.tsx (1)

19-19: LGTM! Block ID support consistently implemented.

The changes consistently add optional blockId support throughout the search component:

  • Type definitions updated (SearchProps, SearchOptions)
  • Props correctly destructured and propagated
  • data-blockid attribute injected on the DOM element for querying
  • Return value includes blockId for consumers

This enables the per-block search scoping used by the key handler.

Also applies to: 36-36, 149-149, 193-193, 218-218

frontend/app/store/keymodel.ts (4)

656-675: LGTM! Focus logic correctly scoped to block.

The function properly focuses the search input using the block-specific data-blockid selector. The past review concern about an ambiguous fallback selector has been addressed—the current implementation uses only the block-scoped query.


677-701: LGTM! Selection-based search activation correctly implemented.

The function correctly:

  • Avoids interfering with terminal shell's Ctrl+f (line 680)
  • Opens search dialog when closed
  • Populates search with current selection (terminal or page text)
  • Resets search results

Note: The behavior of replacing the existing search value when the dialog is already open is intentional per the PR objectives ("Implemented direct search for selected text").


702-709: LGTM! Clean search deactivation logic.

The function correctly closes the search dialog when open and returns an appropriate boolean to indicate whether the action was handled.


632-654: Terminal selection API usage is correct.

The terminal.getSelection() method is a documented xterm.js API that returns the terminal's current selection as a string. The function implementation correctly prioritizes terminal selection over window selection and properly handles empty selections.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
frontend/app/element/search.tsx (1)

149-149: Consider conditionally rendering the data-blockid attribute.

When blockId is undefined, this will render data-blockid="" or data-blockid="undefined". The selector in keymodel.ts (.search-container[data-blockid="${blockId}"]) would fail to match if blockId is undefined there, which is fine since there's a fallback. However, for cleaner DOM output, you could conditionally add the attribute.

🔎 Optional: Conditionally render attribute
-                    <div className="search-container" style={{ ...floatingStyles }} ref={refs.setFloating} data-blockid={blockId}>
+                    <div className="search-container" style={{ ...floatingStyles }} ref={refs.setFloating} {...(blockId && { "data-blockid": blockId })}>
frontend/app/store/keymodel.ts (1)

631-652: Consider adding a guard for missing block component model.

The getSelectedText function accesses bcm.viewModel without checking if bcm is null first. While this is currently only called from activateSearch where bcm exists, the function could be reused elsewhere. Also, the as any cast loses type safety.

🔎 Optional: Add defensive check
     function getSelectedText(): string {
         // Check for terminal selection first
         const bcm = getBlockComponentModel(getFocusedBlockInStaticTab());
+        if (!bcm?.viewModel) {
+            return window.getSelection()?.toString().trim() || "";
+        }
         if (bcm?.viewModel?.viewType === "term") {
             const termViewModel = bcm.viewModel as any;
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 90011a7 and 6531cf9.

📒 Files selected for processing (4)
  • frontend/app/element/search.tsx
  • frontend/app/store/keymodel.ts
  • frontend/app/view/term/term.tsx
  • frontend/app/view/webview/webview.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/app/view/webview/webview.tsx (1)
frontend/app/element/search.tsx (1)
  • useSearch (196-219)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: merge-gatekeeper
🔇 Additional comments (7)
frontend/app/view/term/term.tsx (1)

181-181: LGTM!

Correctly wires blockId to the useSearch hook, enabling block-scoped search context for the terminal view. This aligns with the broader PR pattern.

frontend/app/view/webview/webview.tsx (1)

824-824: LGTM!

Correctly passes model.blockId to useSearch, ensuring the webview search context is block-aware and consistent with the terminal view implementation.

frontend/app/element/search.tsx (2)

19-19: LGTM!

Adding optional blockId to SearchProps enables block-scoped search context.


218-218: LGTM!

Properly propagates blockId from options to the return value of useSearch.

frontend/app/store/keymodel.ts (3)

654-681: LGTM with a minor observation.

The setTimeout(..., 0) pattern is appropriate here to ensure the DOM has updated after React renders the search component. The fallback to any .search-container input provides good resilience.


683-713: LGTM!

The enhanced activateSearch function correctly handles both opening the search dialog with selected text and resetting the search state when already open. The logic properly distinguishes between the two cases and resets resultsIndex and resultsCount when the search is reset.


714-721: LGTM!

Clean implementation of deactivateSearch that properly closes the search dialog when open and returns true to indicate the event was handled.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
frontend/app/store/keymodel.ts (1)

631-652: Consider improving type safety.

The function correctly prioritizes terminal selection over browser selection. However, the type cast to any at line 635 bypasses type safety.

💡 Consider adding proper typing

If the terminal view model has a consistent interface, consider defining a proper type instead of using any:

+interface TerminalViewModel {
+    viewType: string;
+    termRef?: React.RefObject<{
+        terminal: {
+            getSelection: () => string;
+        };
+    }>;
+}
+
 function getSelectedText(): string {
     // Check for terminal selection first
     const bcm = getBlockComponentModel(getFocusedBlockInStaticTab());
     if (bcm?.viewModel?.viewType === "term") {
-        const termViewModel = bcm.viewModel as any;
+        const termViewModel = bcm.viewModel as TerminalViewModel;
         if (termViewModel.termRef?.current?.terminal) {
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6531cf9 and 6e1ad62.

📒 Files selected for processing (4)
  • frontend/app/element/search.tsx
  • frontend/app/store/keymodel.ts
  • frontend/app/view/term/term.tsx
  • frontend/app/view/webview/webview.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/app/view/term/term.tsx
  • frontend/app/view/webview/webview.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/app/store/keymodel.ts (2)
frontend/app/store/global.ts (2)
  • getBlockComponentModel (853-853)
  • globalStore (865-865)
pkg/vdom/vdom_types.go (1)
  • WaveKeyboardEvent (233-247)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: merge-gatekeeper
🔇 Additional comments (6)
frontend/app/element/search.tsx (4)

19-19: LGTM: Clean addition of block-scoped search support.

The optional blockId prop is properly typed and destructured, enabling block-specific search contexts without breaking existing usage.

Also applies to: 36-36


149-149: LGTM: DOM attribute enables block-scoped search targeting.

The data-blockid attribute correctly propagates the block identifier to the DOM, allowing the key handler in keymodel.ts to focus the appropriate search input via querySelector.


193-193: LGTM: Type definition aligned with SearchProps.

The addition of blockId to SearchOptions maintains consistency with SearchProps and supports the block-scoped search feature.


218-218: LGTM: Completes blockId propagation chain.

The useSearch hook correctly returns blockId from options, completing the propagation path that enables block-scoped search behavior.

frontend/app/store/keymodel.ts (2)

683-713: LGTM: Enhanced search activation with selection support.

The updated activateSearch function correctly implements the PR objective:

  • Pre-fills search with selected text when opening the dialog
  • Resets search to current selection when already open
  • Properly focuses the search input in both scenarios

The guard for Ctrl+f in terminal blocks (lines 686-688) is preserved, maintaining existing behavior.


714-732: LGTM: Clean search activation/deactivation integration.

The deactivateSearch function correctly closes the search dialog when open, and the key bindings are properly integrated:

  • Cmd:f opens/resets search with selected text
  • Escape closes search (after checking for modals first)

The priority order for Escape (modals → search → no-op) provides good UX.

@carl2027 carl2027 force-pushed the impr_find branch 2 times, most recently from eb678b6 to 7afb70d Compare December 24, 2025 00:59
- Fixed: The search dialog now correctly receives focus when opened in the current block.
- Implemented direct search for selected text.
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.

2 participants