From 6350f21dfe5614d722def7e259103e846ef5bf2c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:07:28 -0800 Subject: [PATCH 1/4] Reveal link source while navigating detected links Part of #206127 --- .../terminal/browser/media/terminal.css | 5 + .../contrib/terminal/browser/terminal.ts | 6 +- .../browser/xterm/markNavigationAddon.ts | 97 +++++++++++++++++-- .../browser/terminal.links.contribution.ts | 2 +- .../links/browser/terminalLinkQuickpick.ts | 46 ++++++++- 5 files changed, 145 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/terminal.css b/src/vs/workbench/contrib/terminal/browser/media/terminal.css index 488815cf258..e30f5dd92d9 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/terminal.css +++ b/src/vs/workbench/contrib/terminal/browser/media/terminal.css @@ -474,6 +474,11 @@ pointer-events: none; } +.terminal-range-highlight { + outline: 1px solid var(--vscode-focusBorder); + pointer-events: none; +} + .terminal-command-guide { left: 0; border: 1.5px solid #ffffff; diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 9a1bd1ab1b7..d8d7ebeb111 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -23,7 +23,7 @@ import { ITerminalStatusList } from 'vs/workbench/contrib/terminal/browser/termi import { XtermTerminal } from 'vs/workbench/contrib/terminal/browser/xterm/xtermTerminal'; import { IRegisterContributedProfileArgs, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfiguration, ITerminalFont, ITerminalProcessExtHostProxy, ITerminalProcessInfo } from 'vs/workbench/contrib/terminal/common/terminal'; import { ISimpleSelectedSuggestion } from 'vs/workbench/services/suggest/browser/simpleSuggestWidget'; -import type { IMarker, ITheme, Terminal as RawXtermTerminal } from '@xterm/xterm'; +import type { IMarker, ITheme, Terminal as RawXtermTerminal, IBufferRange } from '@xterm/xterm'; import { ScrollPosition } from 'vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { GroupIdentifier } from 'vs/workbench/common/editor'; @@ -118,8 +118,12 @@ export interface IMarkTracker { scrollToLine(line: number, position: ScrollPosition): void; revealCommand(command: ITerminalCommand, position?: ScrollPosition): void; + revealRange(range: IBufferRange): void; registerTemporaryDecoration(marker: IMarker, endMarker: IMarker | undefined, showOutline: boolean): void; showCommandGuide(command: ITerminalCommand | undefined): void; + + saveScrollState(): void; + restoreScrollState(): void; } export interface ITerminalGroup { diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts index 499e1d2f57d..bb6907c4e78 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts @@ -7,7 +7,7 @@ import { coalesce } from 'vs/base/common/arrays'; import { Disposable, DisposableStore, MutableDisposable, dispose } from 'vs/base/common/lifecycle'; import { IMarkTracker } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ITerminalCapabilityStore, ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; -import type { Terminal, IMarker, ITerminalAddon, IDecoration } from '@xterm/xterm'; +import type { Terminal, IMarker, ITerminalAddon, IDecoration, IBufferRange } from '@xterm/xterm'; import { timeout } from 'vs/base/common/async'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { TERMINAL_OVERVIEW_RULER_CURSOR_FOREGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; @@ -24,6 +24,11 @@ export const enum ScrollPosition { Middle } +interface IScrollToMarkerOptions { + hideDecoration?: boolean; + bufferRange?: IBufferRange; +} + export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITerminalAddon { private _currentMarker: IMarker | Boundary = Boundary.Bottom; private _selectionStart: IMarker | Boundary | null = null; @@ -219,7 +224,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe } } - private _scrollToMarker(start: IMarker | number, position: ScrollPosition, end?: IMarker | number, hideDecoration?: boolean): void { + private _scrollToMarker(start: IMarker | number, position: ScrollPosition, end?: IMarker | number, options?: IScrollToMarkerOptions): void { if (!this._terminal) { return; } @@ -227,8 +232,12 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe const line = this.getTargetScrollLine(toLineIndex(start), position); this._terminal.scrollToLine(line); } - if (!hideDecoration) { - this.registerTemporaryDecoration(start, end, true); + if (!options?.hideDecoration) { + if (options?.bufferRange) { + this._highlightBufferRange(options.bufferRange); + } else { + this.registerTemporaryDecoration(start, end, true); + } } } @@ -260,6 +269,16 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe ); } + revealRange(range: IBufferRange): void { + // TODO: Allow room for sticky scroll + this._scrollToMarker( + range.start.y - 1, + ScrollPosition.Middle, + range.end.y - 1, + { bufferRange: range } + ); + } + showCommandGuide(command: ITerminalCommand | undefined): void { if (!this._terminal) { return; @@ -314,6 +333,72 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe } } + + private _scrollState: { viewportY: number } | undefined; + + saveScrollState(): void { + this._scrollState = { viewportY: this._terminal?.buffer.active.viewportY ?? 0 }; + } + + restoreScrollState(): void { + if (this._scrollState && this._terminal) { + this._terminal.scrollToLine(this._scrollState.viewportY); + this._scrollState = undefined; + } + } + + private _highlightBufferRange(range: IBufferRange): void { + if (!this._terminal) { + return; + } + + // TODO: Save original scroll point + + this._resetNavigationDecorations(); + const startLine = range.start.y; + const decorationCount = range.end.y - range.start.y + 1; + for (let i = 0; i < decorationCount; i++) { + const decoration = this._terminal.registerDecoration({ + marker: this._createMarkerForOffset(startLine - 1, i), + x: range.start.x - 1, + width: (range.end.x - 1) - (range.start.x - 1) + 1, + overviewRulerOptions: undefined + }); + if (decoration) { + this._navigationDecorations?.push(decoration); + let renderedElement: HTMLElement | undefined; + + decoration.onRender(element => { + if (!renderedElement) { + renderedElement = element; + // if (i === 0) { + // element.classList.add('top'); + // } + // if (i === decorationCount - 1) { + // element.classList.add('bottom'); + // } + element.classList.add('terminal-range-highlight'); + } + if (this._terminal?.element) { + // element.style.marginLeft = `-${getWindow(this._terminal.element).getComputedStyle(this._terminal.element).paddingLeft}`; + } + }); + // TODO: Scroll may be under sticky scroll + + // TODO: This is not efficient for a large decorationCount + decoration.onDispose(() => { this._navigationDecorations = this._navigationDecorations?.filter(d => d !== decoration); }); + // Number picked to align with symbol highlight in the editor + // if (showOutline) { + // timeout(350).then(() => { + // if (renderedElement) { + // renderedElement.classList.remove('terminal-scroll-highlight-outline'); + // } + // }); + // } + } + } + } + registerTemporaryDecoration(marker: IMarker | number, endMarker: IMarker | number | undefined, showOutline: boolean): void { if (!this._terminal) { return; @@ -373,7 +458,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe } getTargetScrollLine(line: number, position: ScrollPosition): number { - // Middle is treated at 1/4 of the viewport's size because context below is almost always + // Middle is treated as 1/4 of the viewport's size because context below is almost always // more important than context above in the terminal. if (this._terminal && position === ScrollPosition.Middle) { return Math.max(line - Math.floor(this._terminal.rows / 4), 0); @@ -397,7 +482,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe return; } const endMarker = endMarkerId ? detectionCapability.getMark(endMarkerId) : startMarker; - this._scrollToMarker(startMarker, ScrollPosition.Top, endMarker, !highlight); + this._scrollToMarker(startMarker, ScrollPosition.Top, endMarker, { hideDecoration: !highlight }); } selectToPreviousMark(): void { diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminal.links.contribution.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminal.links.contribution.ts index 0327aa48168..2a0269486a3 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminal.links.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminal.links.contribution.ts @@ -83,7 +83,7 @@ class TerminalLinkContribution extends DisposableStore implements ITerminalContr }); } const links = await this._getLinks(); - return await this._terminalLinkQuickpick.show(links); + return await this._terminalLinkQuickpick.show(this._instance, links); } private async _getLinks(): Promise<{ viewport: IDetectedLinks; all: Promise }> { diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts index 2c042949a9d..f496f89cbfc 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts @@ -8,7 +8,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { localize } from 'vs/nls'; import { QuickPickItem, IQuickInputService, IQuickPickItem, QuickInputHideReason } from 'vs/platform/quickinput/common/quickInput'; import { IDetectedLinks } from 'vs/workbench/contrib/terminalContrib/links/browser/terminalLinkManager'; -import { TerminalLinkQuickPickEvent } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { TerminalLinkQuickPickEvent, type IDetachedTerminalInstance, type ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; import type { ILink } from '@xterm/xterm'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; @@ -30,6 +30,8 @@ export class TerminalLinkQuickpick extends DisposableStore { private readonly _editorSequencer = new Sequencer(); private readonly _editorViewState: EditorViewState; + private _instance: ITerminalInstance | IDetachedTerminalInstance | undefined; + private readonly _onDidRequestMoreLinks = this.add(new Emitter()); readonly onDidRequestMoreLinks = this._onDidRequestMoreLinks.event; @@ -45,7 +47,9 @@ export class TerminalLinkQuickpick extends DisposableStore { this._editorViewState = new EditorViewState(_editorService); } - async show(links: { viewport: IDetectedLinks; all: Promise }): Promise { + async show(instance: ITerminalInstance | IDetachedTerminalInstance, links: { viewport: IDetectedLinks; all: Promise }): Promise { + this._instance = instance; + // Get raw link picks const wordPicks = links.viewport.wordLinks ? await this._generatePicks(links.viewport.wordLinks) : undefined; const filePicks = links.viewport.fileLinks ? await this._generatePicks(links.viewport.fileLinks) : undefined; @@ -122,6 +126,18 @@ export class TerminalLinkQuickpick extends DisposableStore { return new Promise(r => { disposables.add(pick.onDidHide(({ reason }) => { + + // Restore terminal scroll state + if (this._terminalScrollStateSaved) { + const markTracker = this._instance?.xterm?.markTracker; + if (markTracker) { + markTracker.restoreScrollState(); + // TODO: This name isn't great + markTracker.clearMarker(); + this._terminalScrollStateSaved = false; + } + } + // Restore view state upon cancellation if we changed it // but only when the picker was closed via explicit user // gesture and not e.g. when focus was lost because that @@ -208,11 +224,18 @@ export class TerminalLinkQuickpick extends DisposableStore { } private _previewItem(item: ITerminalLinkQuickPickItem | IQuickPickItem) { - if (!item || !('link' in item) || !item.link || !('uri' in item.link) || !item.link.uri) { + if (!item || !('link' in item) || !item.link) { return; } + // Any link can be previewed in the termninal const link = item.link; + this._previewItemInTerminal(link); + + if (!('uri' in link) || !link.uri) { + return; + } + if (link.type !== TerminalBuiltinLinkType.LocalFile) { return; } @@ -223,6 +246,10 @@ export class TerminalLinkQuickpick extends DisposableStore { return; } + this._previewItemInEditor(link); + } + + private _previewItemInEditor(link: TerminalLink) { const linkSuffix = link.parsedLink ? link.parsedLink.suffix : getLinkSuffix(link.text); const selection = linkSuffix?.row === undefined ? undefined : { startLineNumber: linkSuffix.row ?? 1, @@ -245,6 +272,19 @@ export class TerminalLinkQuickpick extends DisposableStore { } }); } + + private _terminalScrollStateSaved: boolean = false; + private _previewItemInTerminal(link: ILink) { + const xterm = this._instance?.xterm; + if (!xterm) { + return; + } + if (!this._terminalScrollStateSaved) { + xterm.markTracker.saveScrollState(); + this._terminalScrollStateSaved = true; + } + xterm.markTracker.revealRange(link.range); + } } export interface ITerminalLinkQuickPickItem extends IQuickPickItem { From c9e61431bae75f54303d2c00b83c6ed6b8ff2f3c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 26 Feb 2024 11:17:28 -0800 Subject: [PATCH 2/4] Show all links if resolved within 500ms Fixes #206280 --- .../links/browser/terminalLinkQuickpick.ts | 76 ++++++++++--------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts index f496f89cbfc..544612bcb53 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts @@ -14,7 +14,7 @@ import { DisposableStore } from 'vs/base/common/lifecycle'; import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { AccessibleViewProviderId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; import type { TerminalLink } from 'vs/workbench/contrib/terminalContrib/links/browser/terminalLink'; -import { Sequencer } from 'vs/base/common/async'; +import { Sequencer, timeout } from 'vs/base/common/async'; import { EditorViewState } from 'vs/workbench/browser/quickaccess'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; @@ -50,11 +50,17 @@ export class TerminalLinkQuickpick extends DisposableStore { async show(instance: ITerminalInstance | IDetachedTerminalInstance, links: { viewport: IDetectedLinks; all: Promise }): Promise { this._instance = instance; + // Allow all links a small amount of time to elapse to finish, if this is not done in this + // time they will be loaded upon the first filter. + const result = await Promise.race([links.all, timeout(500)]); + const usingAllLinks = typeof result === 'object'; + const resolvedLinks = usingAllLinks ? result : links.viewport; + // Get raw link picks - const wordPicks = links.viewport.wordLinks ? await this._generatePicks(links.viewport.wordLinks) : undefined; - const filePicks = links.viewport.fileLinks ? await this._generatePicks(links.viewport.fileLinks) : undefined; - const folderPicks = links.viewport.folderLinks ? await this._generatePicks(links.viewport.folderLinks) : undefined; - const webPicks = links.viewport.webLinks ? await this._generatePicks(links.viewport.webLinks) : undefined; + const wordPicks = resolvedLinks.wordLinks ? await this._generatePicks(resolvedLinks.wordLinks) : undefined; + const filePicks = resolvedLinks.fileLinks ? await this._generatePicks(resolvedLinks.fileLinks) : undefined; + const folderPicks = resolvedLinks.folderLinks ? await this._generatePicks(resolvedLinks.folderLinks) : undefined; + const webPicks = resolvedLinks.webLinks ? await this._generatePicks(resolvedLinks.webLinks) : undefined; const picks: LinkQuickPickItem[] = []; if (webPicks) { @@ -88,36 +94,38 @@ export class TerminalLinkQuickpick extends DisposableStore { // ASAP with only the viewport entries. let accepted = false; const disposables = new DisposableStore(); - disposables.add(Event.once(pick.onDidChangeValue)(async () => { - const allLinks = await links.all; - if (accepted) { - return; - } - const wordIgnoreLinks = [...(allLinks.fileLinks ?? []), ...(allLinks.folderLinks ?? []), ...(allLinks.webLinks ?? [])]; + if (!usingAllLinks) { + disposables.add(Event.once(pick.onDidChangeValue)(async () => { + const allLinks = await links.all; + if (accepted) { + return; + } + const wordIgnoreLinks = [...(allLinks.fileLinks ?? []), ...(allLinks.folderLinks ?? []), ...(allLinks.webLinks ?? [])]; - const wordPicks = allLinks.wordLinks ? await this._generatePicks(allLinks.wordLinks, wordIgnoreLinks) : undefined; - const filePicks = allLinks.fileLinks ? await this._generatePicks(allLinks.fileLinks) : undefined; - const folderPicks = allLinks.folderLinks ? await this._generatePicks(allLinks.folderLinks) : undefined; - const webPicks = allLinks.webLinks ? await this._generatePicks(allLinks.webLinks) : undefined; - const picks: LinkQuickPickItem[] = []; - if (webPicks) { - picks.push({ type: 'separator', label: localize('terminal.integrated.urlLinks', "Url") }); - picks.push(...webPicks); - } - if (filePicks) { - picks.push({ type: 'separator', label: localize('terminal.integrated.localFileLinks', "File") }); - picks.push(...filePicks); - } - if (folderPicks) { - picks.push({ type: 'separator', label: localize('terminal.integrated.localFolderLinks', "Folder") }); - picks.push(...folderPicks); - } - if (wordPicks) { - picks.push({ type: 'separator', label: localize('terminal.integrated.searchLinks', "Workspace Search") }); - picks.push(...wordPicks); - } - pick.items = picks; - })); + const wordPicks = allLinks.wordLinks ? await this._generatePicks(allLinks.wordLinks, wordIgnoreLinks) : undefined; + const filePicks = allLinks.fileLinks ? await this._generatePicks(allLinks.fileLinks) : undefined; + const folderPicks = allLinks.folderLinks ? await this._generatePicks(allLinks.folderLinks) : undefined; + const webPicks = allLinks.webLinks ? await this._generatePicks(allLinks.webLinks) : undefined; + const picks: LinkQuickPickItem[] = []; + if (webPicks) { + picks.push({ type: 'separator', label: localize('terminal.integrated.urlLinks', "Url") }); + picks.push(...webPicks); + } + if (filePicks) { + picks.push({ type: 'separator', label: localize('terminal.integrated.localFileLinks', "File") }); + picks.push(...filePicks); + } + if (folderPicks) { + picks.push({ type: 'separator', label: localize('terminal.integrated.localFolderLinks', "Folder") }); + picks.push(...folderPicks); + } + if (wordPicks) { + picks.push({ type: 'separator', label: localize('terminal.integrated.searchLinks', "Workspace Search") }); + picks.push(...wordPicks); + } + pick.items = picks; + })); + } disposables.add(pick.onDidChangeActive(async () => { const [item] = pick.activeItems; From d4b102e34470574cf8c6eedb7bb6895268674ba5 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 26 Feb 2024 11:28:42 -0800 Subject: [PATCH 3/4] Always scroll when sticky scroll is enabled --- .../browser/xterm/markNavigationAddon.ts | 36 ++++++------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts index bb6907c4e78..aae4ac6f275 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts @@ -13,6 +13,8 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; import { TERMINAL_OVERVIEW_RULER_CURSOR_FOREGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { getWindow } from 'vs/base/browser/dom'; import { ICurrentPartialCommand } from 'vs/platform/terminal/common/capabilities/commandDetection/terminalCommand'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { TerminalSettingId } from 'vs/platform/terminal/common/terminal'; enum Boundary { Top, @@ -26,6 +28,8 @@ export const enum ScrollPosition { interface IScrollToMarkerOptions { hideDecoration?: boolean; + /** Scroll even if the line is within the viewport */ + forceScroll?: boolean; bufferRange?: IBufferRange; } @@ -48,6 +52,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe constructor( private readonly _capabilities: ITerminalCapabilityStore, + @IConfigurationService private readonly _configurationService: IConfigurationService, @IThemeService private readonly _themeService: IThemeService ) { super(); @@ -228,7 +233,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe if (!this._terminal) { return; } - if (!this._isMarkerInViewport(this._terminal, start)) { + if (!this._isMarkerInViewport(this._terminal, start) || options?.forceScroll) { const line = this.getTargetScrollLine(toLineIndex(start), position); this._terminal.scrollToLine(line); } @@ -270,12 +275,15 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe } revealRange(range: IBufferRange): void { - // TODO: Allow room for sticky scroll this._scrollToMarker( range.start.y - 1, ScrollPosition.Middle, range.end.y - 1, - { bufferRange: range } + { + bufferRange: range, + // Ensure scroll shows the line when sticky scroll is enabled + forceScroll: !!this._configurationService.getValue(TerminalSettingId.StickyScrollEnabled) + } ); } @@ -352,8 +360,6 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe return; } - // TODO: Save original scroll point - this._resetNavigationDecorations(); const startLine = range.start.y; const decorationCount = range.end.y - range.start.y + 1; @@ -371,30 +377,10 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe decoration.onRender(element => { if (!renderedElement) { renderedElement = element; - // if (i === 0) { - // element.classList.add('top'); - // } - // if (i === decorationCount - 1) { - // element.classList.add('bottom'); - // } element.classList.add('terminal-range-highlight'); } - if (this._terminal?.element) { - // element.style.marginLeft = `-${getWindow(this._terminal.element).getComputedStyle(this._terminal.element).paddingLeft}`; - } }); - // TODO: Scroll may be under sticky scroll - - // TODO: This is not efficient for a large decorationCount decoration.onDispose(() => { this._navigationDecorations = this._navigationDecorations?.filter(d => d !== decoration); }); - // Number picked to align with symbol highlight in the editor - // if (showOutline) { - // timeout(350).then(() => { - // if (renderedElement) { - // renderedElement.classList.remove('terminal-scroll-highlight-outline'); - // } - // }); - // } } } } From f9377b87afb68830547acf13a81119b6e07f1b5b Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 26 Feb 2024 11:29:51 -0800 Subject: [PATCH 4/4] clearMarker -> clear --- src/vs/workbench/contrib/terminal/browser/terminal.ts | 2 +- .../contrib/terminal/browser/xterm/markNavigationAddon.ts | 2 +- .../terminalContrib/links/browser/terminalLinkQuickpick.ts | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index d8d7ebeb111..db2791f9bda 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -113,7 +113,7 @@ export interface IMarkTracker { selectToNextMark(): void; selectToPreviousLine(): void; selectToNextLine(): void; - clearMarker(): void; + clear(): void; scrollToClosestMarker(startMarkerId: string, endMarkerId?: string, highlight?: boolean | undefined): void; scrollToLine(line: number, position: ScrollPosition): void; diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts index aae4ac6f275..9a2fbf8e6d7 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/markNavigationAddon.ts @@ -101,7 +101,7 @@ export class MarkNavigationAddon extends Disposable implements IMarkTracker, ITe return undefined; } - clearMarker(): void { + clear(): void { // Clear the current marker so successive focus/selection actions are performed from the // bottom of the buffer this._currentMarker = Boundary.Bottom; diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts index 544612bcb53..e3bd74aec3b 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkQuickpick.ts @@ -140,8 +140,7 @@ export class TerminalLinkQuickpick extends DisposableStore { const markTracker = this._instance?.xterm?.markTracker; if (markTracker) { markTracker.restoreScrollState(); - // TODO: This name isn't great - markTracker.clearMarker(); + markTracker.clear(); this._terminalScrollStateSaved = false; } }