fix(renderer): add OSC 8 hyperlink id parameter and onChunks hook for link detection#736
fix(renderer): add OSC 8 hyperlink id parameter and onChunks hook for link detection#736mugnimaestra wants to merge 2 commits intoanomalyco:mainfrom
Conversation
@opentui/core
@opentui/react
@opentui/solid
@opentui/core-darwin-arm64
@opentui/core-darwin-x64
@opentui/core-linux-arm64
@opentui/core-linux-x64
@opentui/core-win32-arm64
@opentui/core-win32-x64
commit: |
|
@mugnimaestra the reason why I didn't do the "link detection" in |
8a06638 to
3d7d4a3
Compare
|
Thanks for the feedback @kommander! I've refactored the approach:
Usage in opencode: import { detectLinks } from "@opentui/core"
<code filetype="markdown" onChunks={detectLinks} ... />Tested in iTerm2 — OSC 8 hyperlinks now work correctly, including URLs that wrap across multiple terminal lines (thanks to the |
Add detectLinks from @opentui/core as onChunks callback on the markdown code renderable. This enables OSC 8 hyperlink sequences for URLs in tree-sitter rendered markdown, making Cmd/Ctrl+Click work correctly for wrapped links. Depends on anomalyco/opentui#736
|
Cool, I'll re-check shortly. |
2fa7fad to
257c8c3
Compare
opencode-issues-7.movI couldn't make the UI highlighting works, it seems the issues is quite complex so I refrain to do any further, but at least when cmd+click url that gets separated by newline now it still captures the full URL as expected |
257c8c3 to
060f78f
Compare
Add the id parameter to OSC 8 hyperlink escape sequences so terminals
can identify multi-row links as belonging to the same hyperlink.
The id is derived from the existing linkId in cell attributes:
\x1b]8;id={linkId};{url}\x1b\\
Links are kept open across row boundaries and closed naturally when
a cell with a different linkId is encountered or at end of frame.
Add onChunks callback to CodeRenderable that runs after treeSitterToTextChunks
produces chunks, before setStyledText. This lets consumers modify chunks
without hardcoding language-specific scope names in the core.
Export a detectLinks() helper that scans tree-sitter highlights for URL
scopes and sets chunk.link on matching chunks. Uses content.indexOf()
to handle concealed text offset mismatches where chunk text length
differs from original content byte positions.
Usage:
import { detectLinks } from "@opentui/core"
<code filetype="markdown" onChunks={detectLinks}>{content}</code>
060f78f to
71e8d29
Compare
Summary
Fixes hyperlinks not working correctly when they wrap across terminal lines, and adds opt-in link detection for tree-sitter rendered code blocks.
Closes #735
Changes
1.
fix(renderer): add id parameter to OSC 8 hyperlink sequencesThe renderer emitted OSC 8 without the
idparameter, so terminals could not identify wrapped link segments as the same hyperlink. Now emits:Links stay open across row boundaries and close naturally when a different link (or no link) is encountered.
2.
feat(code): add onChunks hook and detectLinks helperThe tree-sitter path (
CodeRenderable) never setlinkonTextChunkobjects, so OSC 8 was never emitted for code blocks.Following maintainer feedback, this uses hooks instead of hardcoded scope names:
onChunkscallback onCodeRenderable— runs aftertreeSitterToTextChunks, beforesetStyledTextdetectLinks()exported helper — scans highlights for URL scopes, setschunk.link = { url }on matchesUses
content.indexOf()to find chunk positions in original content, handling concealed markdown syntax where visible text length differs from source byte positions.Tests
detectLinksincluding concealed text edge caseKnown Limitation
Visual hover highlighting covers one row at a time for wrapped links. The OSC 8 spec defines
id-based cross-row grouping, but no terminal has been verified to implement it. Cmd/Ctrl+Click works correctly across all rows.