Skip to content

feat(pr-files-changed): add search with case toggle and match highlights#1029

Closed
blinkeye-lcm wants to merge 2 commits into
entrius:testfrom
blinkeye-lcm:feat/pr-files-search
Closed

feat(pr-files-changed): add search with case toggle and match highlights#1029
blinkeye-lcm wants to merge 2 commits into
entrius:testfrom
blinkeye-lcm:feat/pr-files-search

Conversation

@blinkeye-lcm
Copy link
Copy Markdown
Contributor

@blinkeye-lcm blinkeye-lcm commented May 10, 2026

Summary

Adds a search subsystem to the PR Files Changed view. The search input sits above the file tree, filters the tree to files with matches, highlights every match inline across both Split and Unified diff views (layered on top of the existing add/del/word-diff tints), and surfaces a per-file match count badge.

Behavior

  • Case-insensitive by default. An inline Aa toggle inside the input switches to case-sensitive matching, with visible pressed/unpressed state.
  • A status line under the input summarizes results as N matches in M files, shown only while a search is active.
  • Empty states in both the sidebar and the diff panel echo the query as No matches for "X" when nothing matches.
  • The query persists through Split/Unified, Wrap Lines, and Only Changed toggles.
  • On the inactive to active transition, the first matching file scrolls into view. Toggling case sensitivity mid-search keeps the current selection.
  • Folders force-open during search so matched files are immediately visible. Clearing the query does not re-collapse them; folders can still be closed manually.

Implementation notes

  • All search state flows through a single SearchSpec object ({ query, caseSensitive }) so the query and the matching mode cannot drift apart between props.
  • Per-file haystacks (FileSearchIndex) cache both raw and lowercased forms once per file load, so toggling case sensitivity does not re-lowercase patches on every keystroke.
  • Heavy work (hitsByFilename, visibleFiles, fileTree, hitsByPath, in-line highlights) runs against useDeferredValue(searchQuery), so fast typing never blocks the input on large PRs.
  • Shared helpers (isFolder, sortTreeNodes, pluralize, splitByQuery, buildSearchIndex, buildHitsByPath) keep the parent component readable and eliminate duplicated logic at the call sites.
  • Reuses the existing ClearSearchAdornment from src/components/common/ for the clear button so the search field matches the other table search inputs in the app.

Related Issues

Fixes #1030

Type of Change

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • Other (describe below)

Screenshots

before:
before

after:
after.webm

Checklist

  • New components are modularized/separated where sensible
  • Uses predefined theme (e.g. no hardcoded colors)
  • Responsive/mobile checked
  • Tested against the test API
  • npm run format and npm run lint:fix have been run
  • npm run build passes
  • Screenshots included for any UI/visual changes

@xiao-xiao-mao xiao-xiao-mao Bot added the enhancement New feature or request label May 10, 2026
@ventura-oss
Copy link
Copy Markdown
Contributor

Skipping in this review pass — no CI checks reported yet (workflow waiting for maintainer approval). Will revisit once CI runs.

@ventura-oss
Copy link
Copy Markdown
Contributor

Auto-skipping this pass: no CI checks have been reported on this branch (no build / format green from Actions). The same author's other PRs (#1041, #1024) have CI running, so this looks like a re-trigger gap rather than a workflow approval issue — pushing an empty commit or asking a maintainer to re-run Actions should make it eligible again.

@anderdc anderdc closed this May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a search box to the PR Files Changed view

3 participants