Keep OSC 8 hyperlink targets in the pane, so `^a u` can label and open them

Open
#910 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
30/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
rust
Domain
cli

Research direction

Start in crates/spyc-vt-sys/src/bindings.rs to see the OSC 8 hyperlink constants and cell and grid-ref accessors, then read how engine_ghostty reads cell content and width. Next, read src/pane/quick_select.rs, since ^a u matches plain text only. Done means the printf example in the acceptance list labels link, yanks the target, opens only http, https and mailto, and yanks other schemes. The re-emit spike is open and needs a decision first.

Written by the indexing model from the issue text.

Description

area:pane needs-design type:feat

Problem

With OSC 8 a program prints a link whose text differs from its target, as ls --hyperlink, delta, gh and agent CLIs do. In a spyc pane only the text survives. A row reading PR #12 can't be followed to the URL behind it, ^a u labels only URLs in plain sight, and the host terminal's own link click never sees the target, since spyc redraws the pane itself.

Where spyc stands

  • Nothing under src/ reads or writes OSC 8.
  • libghostty-vt at the pin parses it (GHOSTTY_OSC_COMMAND_HYPERLINK_START / …_END in crates/spyc-vt-sys/src/bindings.rs) and exposes it per cell: GHOSTTY_CELL_DATA_HAS_HYPERLINK through ghostty_cell_get, on the raw cell engine_ghostty already reads for content and width; GHOSTTY_ROW_DATA_HYPERLINK, a per-row hint that may report a false positive; and the target through ghostty_grid_ref_hyperlink_uri, on the grid refs the engine already builds for its scrollback fill.
  • scan (src/pane/quick_select.rs) matches regexes over plain text only.
  • ratatui's Cell has no hyperlink field.

Proposal

  1. Carry the target through the engine seam. The frame records a link id per cell, and TerminalScreen reads a cell's target on demand, skipping rows the per-row hint clears.
  2. ^a u labels links by target. A run of cells sharing one target is one match, labelled where the run starts. Yank copies the target. Open hands an http, https or mailto target to the system opener, and yanks any other scheme with a note saying why.
  3. Open question: re-emit OSC 8 to the host, so the host terminal's click opens the real target. With no hyperlink in ratatui's Cell, the sequence would ride inside a cell's symbol, which the frame diff and width pass must tolerate. Worth a spike first.

Acceptance

  • printf '\e]8;;https://example.com/a\e\\link\e]8;;\e\\\n' in a shell tab, then ^a u, labels link, and its label yanks https://example.com/a.
  • Uppercase on that label opens it; a javascript: target is yanked, never opened.
  • A row without links costs no extra FFI call per cell.
  • docs/features/pane.md ("Quick Select") describes link targets.

Prior art: tuios — https://tuios.dev/docs/links

Dominant language
Rust
Stars
17
Forks
2
Avg merge
39m
Merged PRs (30d)
413

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Tripstack-Corp/spyc

All issues in Tripstack-Corp/spyc

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.