diff --git a/src/browser/Linkifier2.ts b/src/browser/Linkifier2.ts index a82994c5..4dc36056 100644 --- a/src/browser/Linkifier2.ts +++ b/src/browser/Linkifier2.ts @@ -309,19 +309,27 @@ export class Linkifier2 extends Disposable implements ILinkifier2 { } }); - // Add listener for rerendering + // Listen to viewport changes to re-render the link under the cursor (only when the line the + // link is on changes) if (this._renderService) { this._linkCacheDisposables.push(this._renderService.onRenderedViewportChange(e => { + // Sanity check, this shouldn't happen in practice as this listener would be disposed + if (!this._currentLink) { + return; + } // When start is 0 a scroll most likely occurred, make sure links above the fold also get // cleared. const start = e.start === 0 ? 0 : e.start + 1 + this._bufferService.buffer.ydisp; - const oldEvent = this._currentLink ? this._lastMouseEvent : undefined; - this._clearCurrentLink(start, e.end + 1 + this._bufferService.buffer.ydisp); - if (oldEvent && this._element) { - // re-eval previously active link after changes - const position = this._positionFromMouseEvent(oldEvent, this._element, this._mouseService!); - if (position) { - this._askForLink(position, false); + const end = this._bufferService.buffer.ydisp + 1 + e.end; + // Only clear the link if the viewport change happened on this line + if (this._currentLink.link.range.start.y >= start && this._currentLink.link.range.end.y <= end) { + this._clearCurrentLink(start, end); + if (this._lastMouseEvent && this._element) { + // re-eval previously active link after changes + const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element, this._mouseService!); + if (position) { + this._askForLink(position, false); + } } } }));