plans/osc8-toansi-hyperlinks.md
ToAnsi()When Driver.ToAnsi() is called (e.g., for print mode in clet --help or mdv --print), the resulting ANSI string includes SGR styling (underline, color) for links but does NOT include OSC 8 hyperlink sequences. This means links are visually styled but not clickable in terminals that support OSC 8.
The codebase already has all the pieces:
Cell-level URL storage: IOutputBuffer.GetCellUrl(col, row) returns the URL associated with a cell. OutputBufferImpl stores these in a _urlMap dictionary keyed by Point(col, row).
URL assignment during draw: Both Link view and Markdown view set Driver.CurrentUrl before drawing cells. The OutputBufferImpl.AddStr/AddRune methods call SetCellUrl when CurrentUrl is non-null.
OSC 8 utilities: EscSeqUtils.OSC_StartHyperlink(url) and EscSeqUtils.OSC_EndHyperlink() already exist.
Real-time rendering already works: OutputBase.Write(IOutputBuffer) already queries buffer.GetCellUrl(col, row) and emits OSC 8 sequences during live terminal output.
ToAnsi() does NOT emit OSC 8: BuildAnsiForRegion (called by ToAnsi) only handles SGR attribute changes and graphemes — it has no URL tracking.
Modify BuildAnsiForRegion in OutputBase.cs to track the current URL state and emit OSC 8 open/close sequences when the URL changes between cells.
In BuildAnsiForRegion, add a string? lastUrl = null tracker. For each cell:
buffer.GetCellUrl(col, row) to get the cell's URLlastUrl:
lastUrl was non-null, emit EscSeqUtils.OSC_EndHyperlink() to close the previous linkEscSeqUtils.OSC_StartHyperlink(url) to open the new linklastUrllastUrl is non-null, emit EscSeqUtils.OSC_EndHyperlink()Terminal.Gui/Drivers/Output/OutputBase.cs — BuildAnsiForRegion methodTests in Tests/UnitTestsParallelizable/Drivers/Output/OutputBaseTests.cs:
ToAnsi_CellsWithUrl_EmitsOsc8Sequences: Create a buffer, set CurrentUrl, write text, verify ToAnsi() output contains OSC 8 start/end sequences.
ToAnsi_CellsWithDifferentUrls_EmitsCorrectTransitions: Verify that transitioning between different URLs properly closes the first and opens the second.
ToAnsi_CellsWithUrl_ThenNoUrl_ClosesHyperlink: Verify that when URL cells are followed by non-URL cells, the hyperlink is properly closed.
ToAnsi_LegacyConsole_NoOsc8: Verify that legacy console mode does not emit OSC 8.
LinkTests.Link_Renders_With_OSC8_Hyperlink test already verifies OSC 8 in live renderingToAnsi() output specificallyMarkdownViewTests to ensure no regressions