Highlight the matched cells, with per-row extents across a soft wrap #4

Open
opened 2026-09-19 16:33:41 +09:00 by natsukium · 0 comments
Owner

Summary

Draw the match itself, not only its label: highlight the matched cells, and give a soft-wrapped
match a per-row extent so the highlight follows it across the wrap. Implement the --contrast
flag from the design draft while here.

Why

src/picker.rs draw prints the whole row dim and then prints the label at (m.row, m.col).
Nothing marks where the match ends, so with dense text it is not obvious what a label will
actually hand over — the label sits on top of the first cells of the value, hiding them.

docs/design.md "Extension surface" lists --contrast (bracketed labels) among the draft flags;
--reverse and --multi from the same row are implemented, --contrast is not.

The wrapped case

matcher::Match documents this gap already: end_col is "the column past the final glyph on
whatever row that glyph sits", which for a wrapped match is not the anchor row, and the doc
comment says a consumer that highlights a wrapped match wants per-row extents anyway.

So highlighting needs the matcher to hand over the extents per physical row, not one end_col.
docs/research.md "Soft-wrapped matches" already prescribes the rendering rule: the highlight is
split per row and the label is drawn onto the leading cells following the wrap. The edge cases it
names: a wide leading glyph, a match shorter than its label, a label at the right edge.

Sketch

  • Match carries the per-row extents (or the spans it was built from) instead of a single end_col.
  • draw paints the matched cells with their own attributes before overlaying the label.
  • --contrast brackets the label so it reads against a busy background.
  • Interacts with #2: once rows repaint in colour, "highlight" has to mean something that survives
    arbitrary cell colours (reverse video rather than a fixed background, most likely).
## Summary Draw the match itself, not only its label: highlight the matched cells, and give a soft-wrapped match a per-row extent so the highlight follows it across the wrap. Implement the `--contrast` flag from the design draft while here. ## Why `src/picker.rs` `draw` prints the whole row dim and then prints the label at `(m.row, m.col)`. Nothing marks where the match *ends*, so with dense text it is not obvious what a label will actually hand over — the label sits on top of the first cells of the value, hiding them. `docs/design.md` "Extension surface" lists `--contrast` (bracketed labels) among the draft flags; `--reverse` and `--multi` from the same row are implemented, `--contrast` is not. ## The wrapped case `matcher::Match` documents this gap already: `end_col` is "the column past the final glyph on whatever row that glyph sits", which for a wrapped match is *not* the anchor row, and the doc comment says a consumer that highlights a wrapped match wants per-row extents anyway. So highlighting needs the matcher to hand over the extents per physical row, not one `end_col`. `docs/research.md` "Soft-wrapped matches" already prescribes the rendering rule: the highlight is split per row and the label is drawn onto the leading cells following the wrap. The edge cases it names: a wide leading glyph, a match shorter than its label, a label at the right edge. ## Sketch - `Match` carries the per-row extents (or the spans it was built from) instead of a single `end_col`. - `draw` paints the matched cells with their own attributes before overlaying the label. - `--contrast` brackets the label so it reads against a busy background. - Interacts with #2: once rows repaint in colour, "highlight" has to mean something that survives arbitrary cell colours (reverse video rather than a fixed background, most likely).
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
natsukium/spoor#4
No description provided.