Skip to content

Conversation

@karan68
Copy link

@karan68 karan68 commented Jan 8, 2026

Summary

Fixed a framebuffer artifact where hyperlink underlines could linger on rows below the last rendered document line.
Implemented hyperlink detection, styling, and Ctrl/Cmd+click navigation.

What / Where

src/buffer/mod.rs

Added lightweight hyperlink detection and caching (HyperlinkCache, LinkRange) and line‑level URL scanning.
In TextBuffer::render, track the last framebuffer row that contains document content and, after rendering, explicitly clear all remaining rows in the textarea viewport (text + fg/bg + attributes) so the diff sees them as changed.
Applied per‑line hyperlink styling (BrightCyan + underline) over the exact URL span.
src/tui.rs

For textareas, added Ctrl/Cmd+click handling: map click → document offset, resolve find_link_at_offset, and open the URL via start/open/xdg-open.
src/framebuffer.rs

Kept diffing model intact; no partial “dirty region” tracking, just used the new back‑buffer clears so rows below the last rendered line no longer carry stale styled pixels.

Why

Before: when hyperlink layout shrank upward, rows below the last rendered document line were never written into the back buffer, so front/back matched and the diff skipped them, leaving old underline/color data on screen.

After: TextBuffer::render always clears rows from last_rendered_row + 1 to the bottom of the textarea viewport, guaranteeing those rows change in the back buffer and get fully cleared in the terminal.

Tests

Automated:
cargo test (all unit tests and doctests pass).
Manual:
Open a file with long hyperlinks near the bottom of the viewport, edit/shorten the document or reflow so content moves up, and confirm no stale underlines remain below the last line.
Verify hyperlinks render underlined + cyan and that Ctrl/Cmd+click opens the correct URL.

image

@karan68
Copy link
Author

karan68 commented Jan 8, 2026

@microsoft-github-policy-service agree

Comment on lines 151 to 161

// It's not guaranteed that Black is actually dark and BrightWhite light (vice versa for a light theme).
// Such is the case with macOS 26's "Clear Dark" theme (and probably a lot other themes).
// Its black is #35424C (l=0.3716; oof!) and bright white is #E5EFF5 (l=0.9464).
// If we have a color such as #43698A (l=0.5065), which is l>0.5 ("light") and need a contrasting color,
// we need that to be #E5EFF5, even though that's also l>0.5. With a midpoint of 0.659, we get that right.
let lightness = self.auto_colors.map(|c| c.as_oklab().lightness());
self.auto_color_threshold = (lightness[0] + lightness[1]) * 0.5;

// Ensure [0] is dark and [1] is light.
if lightness[0] > lightness[1] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you reverted a change from main (#728) somehow. Please be careful not to do that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, the merge conflict resolution strategy where you delete all incoming changes is not good or typically acceptable for a collaborative project.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @DHowett , it missed my check sorry , i have reverted back , could you please review it , if i have missed something

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.

3 participants