Skip to content

Links in the terminal are highlighted, in a colour that adapts to the theme (#10) - #11

Merged
Maxaubert merged 1 commit into
mainfrom
feat/10-highlight-links
Sep 19, 2026
Merged

Maxaubert merged 1 commit into
mainfrom
feat/10-highlight-links

Conversation

@Maxaubert

Copy link
Copy Markdown
Owner

Closes #10.

What it does

A URL printed in the terminal is highlighted all the time, not only while the pointer is on it: the link colour, plus a faint underline. A click still opens it (that part was already there).

The colour

Blue by default (LINK_BLUE, #4ea1ff), moved only as far as the ground needs to reach 4.5:1:

  • on a dark ground it is that blue as it is;
  • on a light ground it is walked darker and stays a blue (GitHub light: rgb(52,106,168) at 5.1:1, measured on the page);
  • on a ground that is itself blue, where a blue link is exactly what gets hard to see, it is walked until it reads;
  • it is measured against the theme in force, so a custom background gets the same treatment, and it is recomputed when the theme changes.
    The underline is there for the last case: on a theme where the colour has to move close to the text's, a link is still told apart.

How

  • lib/termLinks.ts (pure, tested): findLinks and linkColor. A sentence's full stop or comma, and a closing bracket the link never opened, are given back to the sentence, so (https://a.io/x). is a link in brackets while .../Prism_(optics) keeps its own.
  • lib/termLinkPaint.ts: an xterm DECORATION per row a link sits on (foreground colour + an underline element with pointer-events: none). Scrollback is immutable, so its links are painted once and ride a marker; the live screen is redrawn in place by TUIs, so each pass repaints from the last finished line down, which is what keeps a rewritten row from carrying a stale blue run. Rebuilt on a resize (reflow) and a theme change; off on the alternate screen. Columns are counted in cells, since a wide character is one character and two cells.

Verification

  • npm test: 355 pass (48 new). linkColor clears 4.5:1 on all 39 presets' own grounds, on four blue grounds, and on a non-hex ground.
  • New e2e scenario links, reading computed colours off the page: a printed link wears the blue; the sentence's full stop does not; a 280-character link that wraps is painted on every row; switching to a light theme gives another colour that reads there and is still a blue.
  • npm run typecheck: clean. npm run lint: 0 errors. npm run e2e: 12 scenarios pass.
  • Looked at on the Pitch (black) theme and on Denim (navy).
  • Packaged and installed on this machine; exe timestamp polled (08:15:10 -> 08:40:50), app relaunched.

Notes

  • http and https only, the same links the click handler opens.
  • Unsigned. Version stays 0.1.0 (nothing released yet).

🤖 Generated with Claude Code

…adapts to the theme (#10)

xterm's link addon marks a link only under the pointer. Links are now painted
with a decoration per row: the link colour as the foreground and a faint
underline. The colour is blue, moved only as far as the theme's ground needs to
reach 4.5:1, so it holds on every preset and on a custom background. Scrollback
is painted once; the live screen is repainted each pass, so a row a TUI rewrote
never keeps a stale run.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Maxaubert
Maxaubert merged commit 6fc583d into main Sep 19, 2026
1 check passed
@Maxaubert
Maxaubert deleted the feat/10-highlight-links branch September 19, 2026 06:52
Maxaubert added a commit that referenced this pull request Sep 25, 2026
…2e harness (#71) (#72)

Settings: the colour editor saves the whole setup into Custom and is a theme
pick (#8, #29); ThemeSwitchAsk registers once (#22); a hex field commits only
a changed draft (#26); the dictation key is never a key that types or a chord
the terminal owns, and a press elsewhere ends the capture (#27); the editor
takes the focus, traps Tab and hears Escape, the pencil is its own button
(#28); a finished download reads fresh state before picking the model (#30).

Release and CI: release.yml tags the built commit (#11); core-release runs
from main only (#34), waits for terminal-gate by name and its success (#38),
and opens an issue when a core change cannot be released; core-version also
requires the core version above the base's (#39).

Harness: a time limit per scenario and closeApp (#35), profiles removed after
each scenario (#36), the poll's first verdict awaited instead of 6 s (#37).

Core 0.15.3, app 0.18.3. New reviewSettings e2e and unit tests.


Claude-Session: https://claude.ai/code/session_01LJbePcRzre7AusNzPNS2Bk

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
github-actions Bot pushed a commit that referenced this pull request Sep 25, 2026
…2e harness (#71) (#72)

Settings: the colour editor saves the whole setup into Custom and is a theme
pick (#8, #29); ThemeSwitchAsk registers once (#22); a hex field commits only
a changed draft (#26); the dictation key is never a key that types or a chord
the terminal owns, and a press elsewhere ends the capture (#27); the editor
takes the focus, traps Tab and hears Escape, the pencil is its own button
(#28); a finished download reads fresh state before picking the model (#30).

Release and CI: release.yml tags the built commit (#11); core-release runs
from main only (#34), waits for terminal-gate by name and its success (#38),
and opens an issue when a core change cannot be released; core-version also
requires the core version above the base's (#39).

Harness: a time limit per scenario and closeApp (#35), profiles removed after
each scenario (#36), the poll's first verdict awaited instead of 6 s (#37).

Core 0.15.3, app 0.18.3. New reviewSettings e2e and unit tests.


Claude-Session: https://claude.ai/code/session_01LJbePcRzre7AusNzPNS2Bk

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

Links in the terminal are always highlighted, in a colour that adapts to the theme

1 participant