Skip to content

feat(tui): add interactive session search#36526

Open
albertdbio wants to merge 5 commits into
anomalyco:devfrom
albertdbio:session-search
Open

feat(tui): add interactive session search#36526
albertdbio wants to merge 5 commits into
anomalyco:devfrom
albertdbio:session-search

Conversation

@albertdbio

@albertdbio albertdbio commented Jul 12, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #4714

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds interactive incremental search over the current session transcript — readline/less-style rather than a modal prompt.

Press ctrl+r and a search bar attaches to the top of the prompt input:

 │  …transcript scrolls live to the nearest match as you type…       │
 │                                                                    │
 ┃  markdown_hash                            3/17  ↵ keep · esc back  ← search bar
 ┃  > prompt input (untouched)                                        ← prompt

Behavior

  • Typing live-jumps the viewport to the nearest match at-or-above your position (reverse-i-search semantics); refining the query stays on the current match when it still matches
  • ctrl+r/up = older match, ctrl+s/down = newer, wraparound with a 3/17 counter; bar turns red on zero matches
  • esc/ctrl+c cancels and restores the exact scroll position (sticky-bottom aware); enter accepts and keeps position; ctrl+r on an empty bar recalls the last query
  • Smartcase (any uppercase in the query = case-sensitive), literal matching, unicode-safe offsets
  • Matches are occurrence-level (a term appearing 5x in one long reply is 5 distinct stops) with soft-wrap-aware row estimation so matches center on screen
  • Also available as /search, /find, and command palette entries; search state resets on session switch

In-place highlighting (including inside markdown)

Markdown prose and code blocks render through CodeRenderable, so this uses its public onHighlight hook to append match spans to the tree-sitter highlights — no opentui changes needed. Non-active matches render in a neutral tone, the active match in warning (bold), via two new syntax scopes (search.match, search.match.active). User messages get the same treatment with text spans. Highlighting only engages when total hits <= 200 so broad one-letter queries don't re-highlight every part per keystroke.

Keybind note (deliberate, happy to change)

messages_search defaults to ctrl+r, and session_rename moves to none (still available in the command palette and remappable). Rationale: reverse-search muscle memory is strong, and rename felt like a lower-frequency action to hold a prime binding. If you'd rather keep rename on ctrl+r, I can default search to <leader>/ or anything else — one-line change.

Related prior art: #34297 takes a dialog-based approach with message-level granularity; this PR went inline/incremental after reading the feedback in #4714 about UI placement.

How did you verify your code works?

  • bun test from packages/tui (25 new unit tests over the pure search core: unit collection mirroring rendered content, occurrence offsets/lines, smartcase, regex-literal escaping, astral unicode offsets, wraparound, viewport-relative initial-match selection, highlight tuples, soft-wrap row estimation) — 217 pass
  • bun typecheck from packages/tui — clean
  • Extensive manual TUI testing in a real terminal: open, live jump, cycle+wrap, esc restore, ctrl+c close, empty-bar recall, 0/0 state, smartcase, in-markdown highlight rendering (prose + code blocks), active-match cycling, streaming sessions, session switching, light/dark theme input visibility

Screenshots / recordings

Happy to attach a recording if useful.

opencode-isearch

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Adds readline-style incremental search over the session transcript,
bound to ctrl+r (session_rename moves to none; still in the palette).

- Inline search bar above the prompt: typing live-jumps to the nearest
  match at-or-above the viewport (reverse-i-search), ctrl+r/up cycles
  older, ctrl+s/down newer with wraparound and a match counter
- esc restores the original scroll position (sticky-bottom aware),
  enter accepts and keeps position; empty-bar ctrl+r recalls the last
  query; refining a query stays on the current match when it still
  matches
- Occurrence-level matches over user text, assistant text, and
  reasoning parts, with smartcase and literal-escaped unicode-aware
  matching
- Substring highlights in user messages (active match accented),
  background tint on the active assistant part, and a clipped context
  preview line in the bar
- Also available as /search and /find plus command palette entries;
  search state resets on session switch
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Found related PR:

These are related but not duplicates; they represent different design choices for the same underlying feature (session search).

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.

[FEATURE]: TUI - Search for and find string in session buffer

1 participant