feat: add regex mode to search (#209) - #224
Merged
Merged
Conversation
Search mode gains a regex toggle bound to `Ctrl+E` (mirroring the `Ctrl+W` case-sensitivity toggle). A new box in the search bar shows the state next to the case box: `[.*]` when on, `[ ]` when off. When on, each line is matched with a regular expression instead of a literal substring; case sensitivity is folded into the compiled regex, so the two toggles compose. The two match computations — the navigation entries built in `update_search_state` and the highlighted spans built in `search_line` — now share a single `SearchMatcher` that is compiled once per search change (not per rendered line) and returns character-offset match positions. Matching happens on the whole decoded line so regex anchors (`^`, `$`, `\b`) behave against the real line boundaries and the two paths stay column-aligned. An invalid / in-progress pattern matches nothing, which the existing red "0 matches" bar already signals. The issue asked for `Ctrl+Shift+F`, but control combos collapse Shift on most terminals (indistinguishable from `Ctrl+F` without the Kitty keyboard protocol), so `Ctrl+E` is used instead for a reliable, cross-platform toggle. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The e2e test searched for a bare \d+, but on Linux the PTY serial port connects and adds a "Connected at .../dev/pts/N with 115200bps" log line whose digits also matched, giving 4 hits instead of the 2 asserted (macOS never connects, so it saw 2 and passed). Anchor the pattern to `err ` so the connection line is excluded and the count is a deterministic 2 on both. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
matheuswhite
force-pushed
the
feat/209-regex-search
branch
from
July 19, 2026 17:25
0360746 to
c2e0ac9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #209.
Problem
Search mode only matched raw substrings, so patterns (digit runs, alternations, anchored matches, …) couldn't be found.
Solution
A regex toggle is added to search mode:
Ctrl+Etoggles regex on/off (mirrors the existingCtrl+Wcase toggle).[.*]when on,[ ]when off — e.g.[Aa][.*][1/4] Search Mode.RegexBuilder::case_insensitive), so the case toggle and regex toggle compose.[--/--]) signals it — no log spam.A note on the keybinding
The issue proposed
Ctrl+Shift+F, but control combos collapse Shift on most terminals — without the Kitty keyboard protocol,Ctrl+Shift+Fis indistinguishable fromCtrl+Fand the toggle would silently never fire.Ctrl+Ewas chosen instead: reliable on every terminal, works in headless-adjacent decoders, and follows the same pattern asCtrl+W.Implementation
The two previously-independent, substring-only match computations — the navigation
entriesbuilt inupdate_search_stateand the highlighted spans built insearch_line— now share a singleSearchMatcherstored inScreenMode::Search:(start, len), so the navigation entries and highlight columns stay aligned (the "current" match's black-on-yellow style depends on that alignment).^,$,\b) behave against real line boundaries — the old tail-basedto_special_charclosure would have mis-anchored them..*) so they don't inflate the count with nothing to highlight.is_regexis threaded fromInputsSharedthrough the threeupdate_search_statecall sites,ChangeToSearchMode, and the search-bar renderer, following the existingis_case_sensitivepath exactly.Testing
SearchMatcher(screen.rs): plain case-sensitive/insensitive, char (not byte) columns for multi-byte input, regex digit-runs, case-insensitive flag,^anchoring, zero-width-match skipping, invalid regex → no match, empty query.regex_search_toggles_with_ctrl_e_and_matches_each_line(tests/tui_e2e.rs): literal\d+matches nothing →Ctrl+E→ two digit runs match, box reads[.*].cargo fmtclean, no new clippy lints.Ctrl+W×regex interaction,^anchoring, invalid/no-match red bar, and match navigation (Up/Down).🤖 Generated with Claude Code