Pick OSC 8 hyperlink targets, not just the text on screen #3

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

Summary

Offer the OSC 8 hyperlink target as a pick candidate, alongside the regex matches — so a cell
whose text is 詳細はこちら can still hand over the URL it links to.

Why

felis_grid::Cell carries link: Option<NonZeroU16> into the grid's link table
(Grid::hyperlink), and src/source.rs read_row drops it. No pipe-fed hint tool can do this:
tmux-thumbs and tmux-fingers only ever see plain text, so they can only match what is displayed.
docs/research.md notes foot resolves overlaps with "OSC-8 wins" — it can, because it is the
terminal. spoor parses the bytes itself, so it is in the same position without being tied to a
terminal.

The value is exactly the case a regex cannot reach: the link target is not in the text.

Sketch

  • source::Cell carries the link handle; source::screen (or the matcher) resolves it through the
    grid's link table.
  • A separate opt-in switch, not a --preset: presets expand to regexes and share the regex
    pipeline, while a link is a different kind of candidate. Something like --links.
  • A link run is one candidate spanning the linked cells: anchor at its first glyph like any match,
    value = the URI, label drawn the same way.
  • Overlap with regex matches needs a rule, stated like the existing one (declaration order wins):
    a link probably wins over a regex hit inside it, since it is a fact rather than a guess.

Producer requirement

The producer has to emit the OSC 8 sequences, and the blind-pipe rule applies as always.
Note this is not free from felis today: felis_grid::ansi::row_ansi emits OSC 8 only when
RowAnsiOptions.links is set, and row_ansi (the daemon's region path) leaves it None.
Feeding spoor from felis' pipe action would need the felis side to pass the link table.

Related: #2 (cell colours) reads Cell.style from the same cells this reads Cell.link from.

## Summary Offer the OSC 8 hyperlink target as a pick candidate, alongside the regex matches — so a cell whose *text* is `詳細はこちら` can still hand over the URL it links to. ## Why `felis_grid::Cell` carries `link: Option<NonZeroU16>` into the grid's link table (`Grid::hyperlink`), and `src/source.rs` `read_row` drops it. No pipe-fed hint tool can do this: tmux-thumbs and tmux-fingers only ever see plain text, so they can only match what is *displayed*. `docs/research.md` notes foot resolves overlaps with "OSC-8 wins" — it can, because it is the terminal. `spoor` parses the bytes itself, so it is in the same position without being tied to a terminal. The value is exactly the case a regex cannot reach: the link target is not in the text. ## Sketch - `source::Cell` carries the link handle; `source::screen` (or the matcher) resolves it through the grid's link table. - A separate opt-in switch, not a `--preset`: presets expand to regexes and share the regex pipeline, while a link is a different *kind* of candidate. Something like `--links`. - A link run is one candidate spanning the linked cells: anchor at its first glyph like any match, `value` = the URI, label drawn the same way. - Overlap with regex matches needs a rule, stated like the existing one (declaration order wins): a link probably wins over a regex hit inside it, since it is a fact rather than a guess. ## Producer requirement The producer has to emit the OSC 8 sequences, and the blind-pipe rule applies as always. Note this is *not* free from felis today: `felis_grid::ansi::row_ansi` emits OSC 8 only when `RowAnsiOptions.links` is set, and `row_ansi` (the daemon's region path) leaves it `None`. Feeding spoor from felis' pipe action would need the felis side to pass the link table. Related: #2 (cell colours) reads `Cell.style` from the same cells this reads `Cell.link` from.
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#3
No description provided.