Skip to content

feat: add multiline item rendering#999

Merged
LoricAndre merged 10 commits intomasterfrom
feat/multiline
Mar 30, 2026
Merged

feat: add multiline item rendering#999
LoricAndre merged 10 commits intomasterfrom
feat/multiline

Conversation

@LoricAndre
Copy link
Copy Markdown
Contributor

@LoricAndre LoricAndre commented Mar 7, 2026

Checklist

  • The title of my PR follows conventional commits
  • I have updated the documentation (README.md, comments, src/manpage.rs and/or src/options.rs if applicable)
  • I have added unit tests
  • I have added integration tests
  • I have linked all related issues or PRs

Description of the changes

Note: codecov runs on the PR on this repo, but feel free to ignore it.

Summary by CodeRabbit

  • New Features

    • Added --highlight-line and --multiline (configurable separator) flags; UI supports multi-line item/header rendering, full-line highlighting, and improved row-wise scrolling.
  • Documentation

    • Added comprehensive Insta snapshot testing guide and updated the man page to document the new flags and behaviors.
  • Tests

    • Large snapshot suite added to exercise multiline rendering, navigation, selection, separators, tabs, layouts, and related options.
  • Chores

    • CI now surfaces snapshot diffs on test failures; shell completions and key bindings updated for new flags.

@LoricAndre LoricAndre linked an issue Mar 7, 2026 that may be closed by this pull request
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 7, 2026

Codecov Report

❌ Patch coverage is 82.49097% with 97 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/tui/item_renderer.rs 82.58% 47 Missing and 7 partials ⚠️
src/tui/item_list.rs 71.29% 30 Missing and 1 partial ⚠️
src/tui/app.rs 42.10% 11 Missing ⚠️
src/tui/util.rs 98.64% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 30, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Introduces multiline item rendering and full-line highlighting across the stack: CLI flags and parsing, TUI header and item rendering, a new ItemRenderer, row-based scrolling, util helpers, extensive Insta snapshot tests and macros, shell completions/key-bindings, manpage/docs, and CI snapshot logging.

Changes

Cohort / File(s) Summary
Documentation & Manpage
AGENTS.md, man/man1/sk.1
Added Insta snapshot testing docs and documented new CLI flags --multiline and --highlight-line.
Shell Completions
shell/completion.bash, shell/completion.fish, shell/completion.nu, shell/completion.zsh
Added completions for --multiline and --highlight-line; bash provides file-completion for --multiline; updated declarations across shells.
Shell Key Bindings / History Widgets
shell/key-bindings.bash, shell/key-bindings.fish, shell/key-bindings.zsh
Updated history widgets to include --multiline, adjusted pipelines/formatting for multiline-safe input, and tweaked numeric range syntax passed to sk.
CLI Options
src/options.rs
Added options: multiline: Option<Option<String>> and highlight_line: bool; changed ellipsis default to "..."; post-processes multiline to infer separator from read0.
TUI Integration & Layout
src/tui/app.rs, src/tui/mod.rs
Track last_header_height and rebuild layout when header height changes; registered new item_renderer module.
Header Rendering
src/tui/header.rs
Header gained multiline: Option<String> and now computes and renders per-item sub-lines when multiline is enabled.
Item List & Scrolling
src/tui/item_list.rs
Refactored to support per-item sub-lines and row-based scrolling: added sub_offset, scroll_by_rows, exposed fields as pub(crate), added multiline and highlight_line, and switched to flattened row rendering.
Item Rendering Module
src/tui/item_renderer.rs
New ItemRenderer that performs multiline splitting, horizontal scroll/windowing, span construction, match highlighting, full-row highlight styling, and row trimming/ellipsizing.
Utilities & Tests Helper
src/tui/util.rs, tests/common/insta.rs
Added clip_line_to_chars() with unit tests; extended snap! macro, added fmt_opts() and enter_bytes() to support numbered/multi-snapshot DSL and richer snapshot descriptions.
Snapshot & Option Tests
tests/multiline.rs, tests/options.rs
Added many Insta snapshot tests covering multiline rendering, custom separators, tabstops, layouts, selection/navigation, preselection, header interactions, read0, and option-specific scenarios.
CI Snapshot Logging
.github/workflows/test.yml
Set INSTA_UPDATE=new for CI tests and added a failure-only step to surface generated *.snap.new files and diffs in job logs.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI (args)
    participant Options as SkimOptions
    participant App as App
    participant Header as Header
    participant Layout as LayoutTemplate
    participant ItemList as ItemList
    participant ItemRenderer as ItemRenderer
    participant TUI as Ratatui Widget

    CLI->>Options: parse (--multiline, --highlight-line, ...)
    Options->>Options: set multiline separator based on read0
    App->>Header: set header lines + multiline sep
    Header->>Header: compute height() (split by sep)
    Header-->>App: header height
    App->>App: compare with last_header_height
    alt header height changed
        App->>Layout: rebuild with new header height
        Layout-->>App: updated bounds
    end
    App->>ItemList: request render (multiline, highlight_line)
    ItemList->>ItemRenderer: ItemRenderer::new_for(list, width)
    ItemRenderer-->>ItemList: renderer
    ItemList->>ItemRenderer: render_item() for each matched item
    ItemRenderer->>ItemRenderer: split into sub-rows, compute hscroll
    ItemRenderer-->>ItemList: flattened ListItem rows
    ItemList->>TUI: render flattened rows into frame
    TUI-->>App: display frame
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • feat: windows support #1010 — Modifies the same test helper (tests/common/insta.rs) and TUI initialization in the test harness; likely related to the test/macro changes in this PR.
🚥 Pre-merge checks | ✅ 1 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Test Coverage ⚠️ Warning Snapshot file exists but corresponding test definition is missing from source file, preventing feature testing in CI. Add missing multiline_highlight_line test definition to tests/multiline.rs and fix test infrastructure issues including render() call, @shift Tab key event, and fmt_opts() whitespace escaping.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add multiline item rendering' follows conventional commits format with a descriptive 'feat' prefix and clearly summarizes the main change: multiline item rendering functionality added throughout the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@LoricAndre LoricAndre marked this pull request as ready for review March 30, 2026 10:35
Copy link
Copy Markdown
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: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@AGENTS.md`:
- Around line 41-121: Add missing blank lines before the code fences and specify
a language for the YAML fence in the "Snapshot front-matter" example: insert a
blank line before the three code blocks under "Simple variant", "DSL variant",
and the front-matter example, and change the front-matter fence from ``` to
```yaml so the snippet beginning with description: is marked as YAML; update the
text near "Snapshot front-matter" and the examples accordingly (refer to the
DSL/example code blocks and the YAML front-matter snippet).

In `@shell/completion.bash`:
- Around line 172-175: In the --multiline case replace the unsafe array
assignment COMPREPLY=($(compgen -f "${cur}")) with a safe array population using
mapfile/readarray (or read -a) to avoid word-splitting; call compgen with the
positional separator (--) and the quoted variable "${cur}" and feed its output
into mapfile/readarray to populate COMPREPLY in the --multiline branch.

In `@shell/completion.fish`:
- Line 64: The Fish completion incorrectly uses the `-r` flag for the
--multiline long option which forces an argument; remove the `-r` attribute from
the `complete` invocation that defines `-l multiline` so the option can accept 0
or 1 arguments (matching num_args = 0..=1 in src/options.rs), keeping the rest
of the `complete -c sk -l multiline -d '...'` arguments and description
unchanged.

In `@src/tui/item_list.rs`:
- Around line 422-425: The multiline separator fallback in ItemList (field
multiline using options.multiline.unwrap_or(String::from("\\n"))) always uses a
literal "\\n" and ignores the --read0 behavior; ensure SkimOptions::build() is
called before constructing ItemList so that options.multiline already contains
the correct default (actual "\n" when read0 is set, "\\n" otherwise), and remove
the hardcoded fallback in ItemList (or at least respect the already-built
options.multiline value) so ItemList uses the separator established by
SkimOptions::build().

In `@src/tui/item_renderer.rs`:
- Around line 420-432: current_width is being updated with
display_width(span_text) which treats tabs as single chars, so when a span
contained tabs that you expanded via expand_tabs(...) the subsequent spans get
the wrong start column; fix by computing the displayed text after tab-expansion
and use its display width to update current_width: for each span, determine
processed_visible = if visible.contains('\t') { self.expand_tabs(&visible,
current_width) } else { visible.clone() } (or reuse processed), push
processed_visible into result, then increment current_width by
display_width(&processed_visible) (and keep current_char_index update using
span_chars.len()); update references around expand_tabs, processed, span_text,
span_chars, and current_width accordingly.

In `@tests/multiline.rs`:
- Around line 212-227: The section headers jump from "Section 10: Cycle
interaction" to "Section 12: read0 — null-byte-delimited input (Unix only)";
update the numbering to remove the gap by renaming "Section 12: read0 —
null-byte-delimited input (Unix only)" to "Section 11: read0 —
null-byte-delimited input (Unix only)" (the surrounding test is
insta_test!(multiline_cycle, ...) in tests/multiline.rs), ensuring sequential
section numbers throughout the file.
🪄 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 UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 819ee6d6-16ce-4241-aff6-d0144d7fd021

📥 Commits

Reviewing files that changed from the base of the PR and between 7e5d441 and 582d0ff.

⛔ Files ignored due to path filters (281)
  • tests/snapshots/ansi__prompt_ansi.snap is excluded by !**/*.snap
  • tests/snapshots/ansi__prompt_ansi@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_append_and_select-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_append_and_select-3.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_append_and_select.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_append_and_select@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_append_and_select@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_append_and_select@003.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_change-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_change-3.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_change.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_change@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_change@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_change@003.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_first_last-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_first_last-3.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_first_last-4.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_first_last.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_first_last@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_first_last@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_first_last@003.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_first_last@004.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_if_non_matched-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_if_non_matched-3.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_if_non_matched.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_if_non_matched@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_if_non_matched@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_if_non_matched@003.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_change-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_change.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_change@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_change@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_from_empty-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_from_empty.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_from_empty@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_from_empty@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_to_empty-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_to_empty.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_to_empty@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_header_to_empty@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_preview_cmd-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_preview_cmd-3.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_preview_cmd.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_preview_cmd@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_preview_cmd@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_preview_cmd@003.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_basic-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_basic.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_basic@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_basic@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_expand-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_expand.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_expand@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_expand@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_fields-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_fields.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_fields@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_fields@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_to_itself-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_to_itself-3.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_to_itself-4.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_to_itself.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_to_itself@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_to_itself@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_to_itself@003.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_set_query_to_itself@004.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive_queries-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive_queries-3.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive_queries-4.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive_queries-5.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive_queries.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive_queries@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive_queries@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive_queries@003.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive_queries@004.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_toggle_interactive_queries@005.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_top_alias-2.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_top_alias-3.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_top_alias.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_top_alias@001.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_top_alias@002.snap is excluded by !**/*.snap
  • tests/snapshots/binds__bind_top_alias@003.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_different-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_different.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_different@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_different@002.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_exact-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_exact.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_exact@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_exact@002.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_lower-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_lower.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_lower@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_lower@002.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_no_match-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_no_match.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_no_match@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_ignore_no_match@002.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_non_ascii-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_non_ascii-3.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_non_ascii.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_non_ascii@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_non_ascii@002.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_non_ascii@003.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_exact-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_exact.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_exact@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_exact@002.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_lower-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_lower.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_lower@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_lower@002.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_no_match-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_no_match.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_no_match@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_respect_no_match@002.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_exact-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_exact.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_exact@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_exact@002.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_lower-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_lower.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_lower@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_lower@002.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_no_match-2.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_no_match.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_no_match@001.snap is excluded by !**/*.snap
  • tests/snapshots/case__case_smart_no_match@002.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__interactive_mode_command_execution-2.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__interactive_mode_command_execution-3.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__interactive_mode_command_execution.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__interactive_mode_command_execution@001.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__interactive_mode_command_execution@002.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__interactive_mode_command_execution@003.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__unicode_input-2.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__unicode_input-3.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__unicode_input-4.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__unicode_input.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__unicode_input@001.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__unicode_input@002.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__unicode_input@003.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__unicode_input@004.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__vanilla.snap is excluded by !**/*.snap
  • tests/snapshots/defaults__vanilla_basic.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_359_multi_regex_unicode.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_359_multi_regex_unicode@001.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_361_literal_space_control.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_361_literal_space_control@001.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_361_literal_space_invert.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_361_literal_space_invert@001.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_547_null_match-2.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_547_null_match.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_547_null_match@001.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_547_null_match@002.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_929_double_width_chars-2.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_929_double_width_chars.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_929_double_width_chars@001.snap is excluded by !**/*.snap
  • tests/snapshots/issues__issue_929_double_width_chars@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_b-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_b.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_b@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_b@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_bspace-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_bspace.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_bspace@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_bspace@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_d-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_d-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_d-4.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_d.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_d@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_d@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_d@003.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_d@004.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_f-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_f-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_f.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_f@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_f@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_alt_f@003.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_arrows-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_arrows-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_arrows.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_arrows@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_arrows@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_arrows@003.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_basic-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_basic.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_basic@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_basic@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_bspace-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_bspace.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_bspace@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_bspace@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_btab-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_btab.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_btab@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_btab@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_a-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_a.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_a@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_a@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_arrows-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_arrows-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_arrows-4.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_arrows.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_arrows@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_arrows@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_arrows@003.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_arrows@004.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_b-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_b-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_b.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_b@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_b@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_b@003.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_c.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_c@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_d-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_d-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_d.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_d@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_e-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_e-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_e.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_e@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_e@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_e@003.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_f-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_f-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_f.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_f@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_f@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_f@003.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_h-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_h.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_h@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_h@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_k-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_k.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_k@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_k@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_u-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_u.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_u@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_u@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_w-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_w.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_w@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_w@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_y-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_y-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_y.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_y@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_y@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_ctrl_y@003.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab@003.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab_empty-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab_empty-3.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab_empty.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab_empty@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab_empty@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys__keys_tab_empty@003.snap is excluded by !**/*.snap
  • tests/snapshots/keys_interactive__keys_interactive_alt_b-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys_interactive__keys_interactive_alt_b.snap is excluded by !**/*.snap
  • tests/snapshots/keys_interactive__keys_interactive_alt_b@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys_interactive__keys_interactive_alt_b@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys_interactive__keys_interactive_alt_bspace-2.snap is excluded by !**/*.snap
  • tests/snapshots/keys_interactive__keys_interactive_alt_bspace.snap is excluded by !**/*.snap
  • tests/snapshots/keys_interactive__keys_interactive_alt_bspace@001.snap is excluded by !**/*.snap
  • tests/snapshots/keys_interactive__keys_interactive_alt_bspace@002.snap is excluded by !**/*.snap
  • tests/snapshots/keys_interactive__keys_interactive_alt_d-2.snap is excluded by !**/*.snap
📒 Files selected for processing (19)
  • AGENTS.md
  • man/man1/sk.1
  • shell/completion.bash
  • shell/completion.fish
  • shell/completion.nu
  • shell/completion.zsh
  • shell/key-bindings.bash
  • shell/key-bindings.fish
  • shell/key-bindings.zsh
  • src/options.rs
  • src/tui/app.rs
  • src/tui/header.rs
  • src/tui/item_list.rs
  • src/tui/item_renderer.rs
  • src/tui/mod.rs
  • src/tui/util.rs
  • tests/common/insta.rs
  • tests/multiline.rs
  • tests/options.rs

Comment thread AGENTS.md
Comment thread shell/completion.bash
Comment thread shell/completion.fish
Comment thread src/tui/item_list.rs
Comment thread src/tui/item_renderer.rs
Comment thread tests/multiline.rs
Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/test.yml:
- Line 75: The find invocation "find . -name \"*.snap.new\" | while read -r
new_snap; do" is too broad and can traverse heavy directories like target/;
restrict the search to known snapshot locations (e.g., tests/, spec/, snapshots/
or your project's snapshot dir) by replacing "." with those directory globs or
explicit paths so only snapshot folders are scanned, e.g. "find tests -name
\"*.snap.new\"" or "find . -path \"*/__snapshots__\" -name \"*.snap.new\""
(apply the same pattern where new_snap is consumed) to speed failing job logs.
🪄 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 UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 79493887-1162-4fee-a7c1-4b09cbd7884d

📥 Commits

Reviewing files that changed from the base of the PR and between 5e37a0e and f5be9e1.

📒 Files selected for processing (1)
  • .github/workflows/test.yml

Comment thread .github/workflows/test.yml Outdated
@LoricAndre LoricAndre merged commit 987d2a5 into master Mar 30, 2026
17 of 18 checks passed
@LoricAndre LoricAndre deleted the feat/multiline branch March 30, 2026 11:57
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.

Multi-line support

1 participant