Fix implicit-link boundaries and link cursor flicker - #650
Conversation
|
The issue with the "at" is that it sounds like it might be a valid file reference, and I can imagine other strings that we could argue whether they should be part of it or not. I wonder if we do need a different way of detecting these links. |
migueldeicaza
left a comment
There was a problem hiding this comment.
Thank you for taking the time to send these along - they look wonderful.
I am still mulling over the regex change, and whether we should do something to make this configurable instead or extend the probing infrastructure - perhaps we should validate the existence (it would only work for local mode)
|
|
||
| func linkCursor(at position: Position, hasCommandModifier: Bool) -> NSCursor | ||
| { | ||
| guard let match = terminal.linkMatch(at: .buffer(position), mode: .explicitAndImplicit), |
There was a problem hiding this comment.
This needs to use withTerminal, as we are now multi-threaded. I am
|
|
||
| func linkCursor(at position: Position, hasCommandModifier: Bool) -> NSCursor | ||
| { | ||
| guard let match = terminal.linkMatch(at: .buffer(position), mode: .explicitAndImplicit), |
There was a problem hiding this comment.
Additionally, the same call always uses .explicitAndImplicit. With the default .hoverWithModifier mode, it runs the full implicit-link regex even when Command is not pressed. When Command is pressed, updateHoverLink performs the lookup first, and linkCursor immediately performs it again. Use implicitLinkCouldBeVisible to select the mode, or reuse the result from updateHoverLink.
385ba70 to
1aade1e
Compare
|
Addressed the review feedback and force-pushed the rebased branch:
I agree that filesystem/session-specific validation belongs behind a configurable host resolver or policy rather than in the generic regex. Local probing would not be authoritative for remote/container/tmux sessions, so I left that for a separate API discussion. Validation: focused link suites and the full |
migueldeicaza
left a comment
There was a problem hiding this comment.
Thank you for the follow up! One small little detail.
| let hasCommandModifier = commandActive || event.modifierFlags.contains(.command) | ||
| linkCursor(at: hit, hasCommandModifier: hasCommandModifier).set() | ||
| } | ||
|
|
There was a problem hiding this comment.
AppKit calls cursorUpdate(with:) when the pointer enters a cursor rectangle.
resetCursorRects() defines one rectangle for the entire view. Moving from normal text to a link therefore updates the underline but not the cursor. Pressing or releasing Command while stationary also leaves a stale cursor. Update the cursor from mouseMoved and flagsChanged, or invalidate the cursor rectangles when link state changes. The new test calls linkCursor directly, so it does not test this event-routing behavior.
Summary
Terminal emulators pad every row with blank cells. Treating those cells as part of a link makes the hover underline and click target extend to the right edge. Separately, SwiftTerm's unconditional I-beam in
cursorUpdate(with:)competed with host link-hover handling and caused rapid cursor flicker.The application-specific
atpath boundary has been removed. A host-provided link resolver/policy would be a better follow-up for cases that need filesystem- or session-specific validation, since SwiftTerm may display remote filesystems where local probing is not authoritative.Tests
swift test --filter GhosttyImplicitLinkDetectionTestsswift test --filter MacDefaultLinkTestsswift test(986 tests passed)