Skip to content

Fixes #4814 - Adds 'Link' View providing OSC 8 Hyperlink Support#4815

Merged
tig merged 33 commits intogui-cs:v2_developfrom
tig:pr-4741-link
Mar 9, 2026
Merged

Fixes #4814 - Adds 'Link' View providing OSC 8 Hyperlink Support#4815
tig merged 33 commits intogui-cs:v2_developfrom
tig:pr-4741-link

Conversation

@tig
Copy link
Copy Markdown
Collaborator

@tig tig commented Mar 9, 2026

Fixes

NOTE: This is a new PR based on the awesome work @ccoulioufr did. His branch was his own v2_develop fork and that made it tricky for me to update. So I created this new PR instead. I also created #4814 to track.

Summary

Adds a new Link view and driver-level OSC 8 hyperlink infrastructure to Terminal.Gui.

New Link View (Terminal.Gui/Views/Link.cs)

  • Displays a clickable hyperlink with three independent properties: Text (display), Title (HotKey), and Url (target)
  • When Text is empty, Url is shown as display text (auto-sized via Dim.Auto(DimAutoStyle.Text))
  • URL validation at draw time: invalid URLs render with VisualRole.Disabled style; valid URLs emit OSC 8 sequences
  • OpenUrl() opens URLs cross-platform (cmd /c start on Windows, open on macOS, xdg-open on Linux)
  • Copy() copies the URL to the system clipboard
  • CWP events: UrlChanging (cancellable) and UrlChanged for the Url property
  • HotKey proxy: when CanFocus is false, HotKey passes focus to the next peer view (like Label)
  • Implements IDesignable for the TUI designer

Driver-Level OSC 8 Infrastructure

  • IDriver.CurrentUrl / IOutputBuffer.CurrentUrl — new property to tag subsequently drawn cells with a URL
  • OutputBufferImpl — sparse Dictionary<Point, string> URL map stores per-cell URLs only when set
  • OutputBase.Write() — tracks URL state across cell runs, emitting OSC 8 start/end escape sequences; closes open hyperlinks at row boundaries; skips OSC 8 on legacy consoles
  • Osc8UrlLinker.WrapOsc8() — wraps detected plain-text URLs in output with OSC 8 sequences

UICatalog Scenario (Examples/UICatalog/Scenarios/Links.cs)

  • Interactive demo with editable Title, Text, and URL fields driving a live Link instance
  • Copy button and status bar hover indicator

Tests (Tests/UnitTestsParallelizable/Views/LinkTests.cs)

  • Comprehensive test coverage: construction defaults, Text/Title/Url independence, CWP event lifecycle, URL validation, OnDrawingText with valid/invalid URLs, Copy(), IDesignable, and HotKey proxy behavior

Test Plan

  • dotnet build succeeds
  • dotnet test --project Tests/UnitTestsParallelizable passes
  • Manual testing with the Links UICatalog scenario in Windows Terminal
  • Verify OSC 8 hyperlinks are clickable in a supporting terminal
  • Verify graceful fallback on legacy consoles (no OSC 8 emitted)

ccoulioufr and others added 30 commits February 22, 2026 02:34
en doc translation

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
url doc fix

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Update Url property validation to retain previous value on invalid input.
- Added static Link.OpenUrl for platform-specific URL opening; removed OpenUrl from UICatalogRunnable.
- Link now handles mouse clicks and keyboard activation, opening URLs directly.
- Improved drawing: shows Url if Text is empty, disables link if Url is invalid, always clears Driver.CurrentUrl.
- Copy() now copies Text, not Url.
- SetUrl validates URLs; invalid URLs revert to DEFAULT_URL.
- IDesignable.EnableForDesign sets default Title and Text.
- Refactored Links scenario UI for clarity and usability; status bar now shows Link's Text.
- Updated all tests for new Link API and behaviors; improved test clarity.
- Minor code style improvements and use of System.Diagnostics for process launching.
- IDesignable.EnableForDesign now sets Title and Url, not Text.
- Copy() now copies Url to clipboard instead of Text.
- Text, Title, and Url are now independent; setting one does not affect the others.
- TextFormatter displays Url if Text is empty; otherwise uses Text.
- DimAuto sizing uses Text width if set, otherwise Url, including wide chars.
- Url property now accepts any string (no URI validation).
- Setting the same Url does not fire change events.
- UrlChanging event can cancel Url changes.
- Rendering tests ensure invalid URLs do not produce OSC 8 hyperlinks and are styled as disabled.
- Tests updated and expanded to cover all new behaviors and edge cases.
- Minor test code cleanups and clarifications.
tig and others added 2 commits March 6, 2026 14:08
Add comprehensive XML docs for the Link class covering the three
independent text properties (Text, Title, Url), OSC 8 hyperlink
rendering, draw-time URL validation, CWP event pattern, HotKey-to-next-peer
behavior, and Dim.Auto sizing. Enhance docs for all public members.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolved conflict in OutputBase.cs: kept _lastUrl hyperlink tracking
from Link branch, adopted IsLegacyConsole branching and readonly
modifier from v2_develop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tig tig changed the title Adds 'Link' View providing OSC 8 Hyperlink Support Fixes #4814 - Adds 'Link' View providing OSC 8 Hyperlink Support Mar 9, 2026
@tig tig merged commit ce3fb45 into gui-cs:v2_develop Mar 9, 2026
10 of 11 checks passed
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.

Add OSC 8 Hyperlink Support

2 participants