Skip to content

feat(switch): show a scrollbar on the interactive picker list#3198

Merged
max-sixty merged 2 commits into
mainfrom
picker-scrollbar
Jun 24, 2026
Merged

feat(switch): show a scrollbar on the interactive picker list#3198
max-sixty merged 2 commits into
mainfrom
picker-scrollbar

Conversation

@max-sixty

@max-sixty max-sixty commented Jun 24, 2026

Copy link
Copy Markdown
Owner

wt switch's picker rendered no scrollbar. Scrolling a long worktree list (or a long wt switch --prs list) gave no sense of position, and since the builder already sets no_info(true) to hide skim's matched/total counter, there was no positional feedback at all.

Why it was silently absent

skim's scrollbar option documents a default, but that default is a clap default_value on the field, gated on skim's cli feature:

// skim-4.8.0/src/options.rs
#[cfg_attr(feature = "cli", arg(long, default_value = "▐", ...))]
pub scrollbar: String,

The picker depends on skim with default-features = false — it drives the library directly and doesn't want skim's own clap CLI compiled in. With cli off, the default_value never applies, so the library Default for scrollbar is String::default(): the empty string. skim draws the thumb only when the indicator is non-empty and the list overflows (!scrollbar_thumb.is_empty() && items.len() > available_rows), so an empty indicator means no scrollbar, ever. The picker had been getting skim's library default, not its CLI default.

The fix

Set the indicator explicitly on the builder, next to the other display options:

.scrollbar("▐".to_string())

skim draws it as a thumb-only widget (no track, no arrows) at the rightmost column of the list. It appears only when the list overflows the visible height, so short lists are unchanged and the existing picker snapshots are unaffected.

Known limitation: the thumb inherits the row's color

skim styles the scrollbar thumb with no color of its own, so the takes on the color of whatever row sits beneath it — most visibly the current-line highlight as the cursor scrolls past the thumb's track. The fix lives upstream in skim-rs/skim#1097, which styles the thumb with the theme's border color so it stays uniform. Once that lands and the skim dependency is bumped, the picker's thumb picks up the border color (dark256's 59) with no further change here.

Shipping ahead of that fix: the position cue is the point, and the color bleed is cosmetic.

Verification

Driven interactively against a 48-row --branches list in a 30-row terminal, the thumb renders down the right edge of the item pane (column 59, just left of the preview separator), at the top of its track since the cursor starts on @ main:

> @ main                ^                                 ▐│
  + feature-wt-1      ? ↑                ↑15              ▐│○ main has no uncommitted changes
  + feature-wt-2      ? ↑                ↑15              ▐│
  + feature-wt-3      ? ·                ↑15              ▐│
  + feature-wt-4      ? ↑                ↑15              ▐│
  / demo-scroll-01     /_                                 ▐│
  / demo-scroll-02     /_                                 ▐│
  / demo-scroll-03     /_                                 ▐│
  / demo-scroll-04     /_                                  │
  ...

test_switch_picker_scrollbar_on_overflow (a PTY test) creates enough branches to overflow the test terminal and asserts the thumb renders.

This was written by Claude Code on behalf of max

The picker drives skim with `default-features = false`, which drops
skim's `cli` feature and with it the clap `default_value = "▐"` for the
`scrollbar` option. The library `Default` for the field is then the
empty string, which skim reads as "no scrollbar", so the picker rendered
none. A long worktree (or `--prs`) list scrolled with no position cue,
made worse by `no_info(true)` hiding the matched/total counter.

Set `.scrollbar("▐")` explicitly on the builder. skim paints it only
when the list overflows, as a thumb-only widget (no track) in the
default style, so it reads against the picker's fzf-light theme like
fzf's own scrollbar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@max-sixty
max-sixty marked this pull request as draft June 24, 2026 17:07
# Conflicts:
#	src/commands/picker/mod.rs
@max-sixty
max-sixty marked this pull request as ready for review June 24, 2026 17:52
@max-sixty
max-sixty merged commit 321494b into main Jun 24, 2026
37 of 38 checks passed
@max-sixty
max-sixty deleted the picker-scrollbar branch June 24, 2026 18:10
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