🔗 feat(link-styling): add per-profile underline style and hover/active colours for OSC 8 hyperlinks - #650
🔗 feat(link-styling): add per-profile underline style and hover/active colours for OSC 8 hyperlinks#650kud wants to merge 2 commits into
Conversation
|
Still working on it. Draft: not ready to present it to reviewers, but gives information that I'm working on a feature. |
|
There are a number of underlines. In addition to the ones set by SGR control sequence, they are also used for annotations, semantic history, and OSC 8 hyperlinks. There could be others I'm forgetting. Customizing colors is simple enough but customizing the shapes is riskier - you could easily end up with ambiguous cases. I believe there's a special code path for semantic history on already-underlined text that shows a mixed sold/dash underline. |
6dc7d16 to
127ce9f
Compare
- Add KEY_LINK_HOVER_COLOR, KEY_LINK_ACTIVE_COLOR, and their "use custom colour" toggles plus KEY_LINK_UNDERLINE_STYLE to ITAddressBookMgr.h and wire them through iTermProfilePreferences.m (defaults, descriptions, presets) and iTermColorPresets.m - Introduce kColorMapLinkHover/kColorMapLinkActive in iTermColorMap.h/.m and resolve them in PTYSession.m's colour keyMap (honouring the use-custom toggles) and PTYSession.swift's light/dark-mode key list - Track an activeLinkRange in iTermTextDrawingHelper (new property, activeLinkRangeOnLine: accessor) driven from PTYTextView+ARC.m's Cmd+hover handler and reset on mouse-down/selection changes in PTYTextView.m; iTermAttributedStringBuilder.m now prefers the hover colour when drawing underlined link text - Extend the Metal rendering path (iTermMetalPerFrameState/Row/Configuration) to carry inActiveLinkRange through glyph colour keys and apply the configurable link underline style - Add IBOutlets and preference bindings for the new colour wells/checkboxes/popup in ProfilesColorsPreferencesViewController.m and the corresponding PreferencePanel.xib layout, plus regression tests in ModernTests/LinkColourMapAndActiveRangeTests.swift
127ce9f to
b767337
Compare
- Document new “Link hover” and “Link active” profile colors (Settings > Profiles > Colors), each with its own checkbox, off by default - Document new “Link style” setting for the underline drawn under OSC 8 hyperlinks: single, double, curly, dotted, or dashed
|
Thanks for this. The wiring through the color map, profile prefs, and presets looks clean, and keeping the default at dashed-single with the toggles off is the right call. A few things to flag before this is ready, the first of which is load-bearing: 1. The legacy (Core Text) renderer is missing two of the three featuresiTerm2 treats the GPU renderer and the legacy renderer as pixel-for-pixel equal. That is a hard invariant, not a best-effort target, so any divergence between them is a bug rather than a polish item. Right now only the Metal path implements the underline style and the active-link color:
The legacy path is reachable in normal use (Metal disabled, and the transparency/low-power fallbacks), so this is a visible divergence. Both properties need to be threaded into the Core Text attribute build so the two renderers match. 2.
|
Note
Rebased onto current master and reworked in response to the review below. Still draft: I haven't rebuilt it since the rebase, and the
PreferencePanel.xibmerge wants a pass in Interface Builder before this is ready.📄 Motivation
The OSC 8 hyperlink underline is currently hardcoded to a dashed single underline. With a handful of links that's fine. With output that is mostly links it turns into visual noise — this is my own terminal, running a tool that emits OSC 8 links in almost every line:
I'd like to be able to make that solid, or turn it off, per profile — and to give hovered and active links their own colours so the affordance survives without leaning on the underline.
🔍 Scope, and the ambiguity question
From the review:
That's fair, and it's the reason this PR touches exactly one branch. The style setting is applied only where the OSC 8 style is currently hardcoded:
DashedSinglebecomes the profile settingTwo things that follow from keeping it that narrow:
DashedSingleremains the default and the fallback when the stored value isn't a valid style, so an existing profile renders exactly as it does today. Nothing changes unless someone opts in.If you'd still rather not have shape customisation at all, I'm happy to cut the popup and land only the hover/active colours — say the word and I'll strip it.
📦 What's in it
KEY_LINK_HOVER_COLOR,KEY_LINK_ACTIVE_COLORand their "use custom colour" toggles, plusKEY_LINK_UNDERLINE_STYLE, wired throughiTermProfilePreferencesand the colour presetskColorMapLinkHover/kColorMapLinkActiveiniTermColorMap, resolved inPTYSession's colour key map and included in the light/dark key listactiveLinkRangeoniTermTextDrawingHelper, driven from the Cmd-hover handler inPTYTextView+ARC.mand cleared on mouse-down and selection changeModernTests/LinkColourMapAndActiveRangeTests.swift— coverage for the colour-map resolution and the range maths🧹 Since the last review
<connections>of the "Border around active pane" checkbox rather than to the view controller.NSButtonisn't KVC-compliant for_useLinkHoverColorand friends, so opening Profiles → Colors would have raisedNSUnknownKeyException. They now bind top8i-eM-oBc, alongside the existing_linkColoroutlet. The three new rows were also parented to the terminal-mode enclosure instead of the Regular pane — they lined up by coordinate coincidence — and are now siblings of the other colour controls, where they belong.submodules/iTerm2-shell-integrationpointer bumpMakefilechange that resigned frameworks on my machine and had no business being here✅ How to Validate
🛠️ Developer Checklist
LinkColourMapAndActiveRangeTests.swift) — not re-run since the rebase