From f9267351c56fa7fcc4d00ec61b42e5d92dcc93fa Mon Sep 17 00:00:00 2001 From: Anthony Kim Date: Sat, 27 Sep 2025 16:38:09 -0700 Subject: [PATCH] Do not adjust A sequence wrongly after clear, don't hard code in terminal sticky scroll for clear --- .../capabilities/commandDetectionCapability.ts | 14 ++++++++++---- .../browser/terminalStickyScrollOverlay.ts | 18 ------------------ 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index 70d698873f8..7a279bbee07 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -37,6 +37,9 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe get hasRichCommandDetection() { return this._hasRichCommandDetection; } private _promptType: string | undefined; get promptType(): string | undefined { return this._promptType; } + private _viewportCleared: boolean = false; + get viewportCleared(): boolean { return this._viewportCleared; } + set viewportCleared(value: boolean) { this._viewportCleared = value; } private _ptyHeuristicsHooks: ICommandDetectionHeuristicsHooks; private readonly _ptyHeuristics: MandatoryMutableDisposable; @@ -290,15 +293,15 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe handlePromptStart(options?: IHandleCommandOptions): void { // Adjust the last command's finished marker when needed. The standard position for the // finished marker `D` to appear is at the same position as the following prompt started - // `A`. + // `A`. Skip adjustment if viewport was recently cleared as previous marker positions + // are no longer valid. const lastCommand = this.commands.at(-1); - if (lastCommand?.endMarker && lastCommand?.executedMarker && lastCommand.endMarker.line === lastCommand.executedMarker.line) { + if (!this._viewportCleared && lastCommand?.endMarker && lastCommand?.executedMarker && lastCommand.endMarker.line === lastCommand.executedMarker.line) { this._logService.debug('CommandDetectionCapability#handlePromptStart adjusted commandFinished', `${lastCommand.endMarker.line} -> ${lastCommand.executedMarker.line + 1}`); lastCommand.endMarker = cloneMarker(this._terminal, lastCommand.executedMarker, 1); } - this._currentCommand.promptStartMarker = options?.marker || (lastCommand?.endMarker ? cloneMarker(this._terminal, lastCommand.endMarker) : this._terminal.registerMarker(0)); - + this._currentCommand.promptStartMarker = options?.marker || (!this._viewportCleared && lastCommand?.endMarker ? cloneMarker(this._terminal, lastCommand.endMarker) : this._terminal.registerMarker(0)); this._logService.debug('CommandDetectionCapability#handlePromptStart', this._terminal.buffer.active.cursorX, this._currentCommand.promptStartMarker?.line); } @@ -342,6 +345,8 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe this._currentCommand.commandStartX = this._terminal.buffer.active.cursorX; this._onCommandStartChanged.fire(); this._logService.debug('CommandDetectionCapability#handleCommandStart', this._currentCommand.commandStartX, this._currentCommand.commandStartMarker?.line); + // Reset the viewport cleared flag here, after we've handled the command start + this._viewportCleared = false; return; } this._ptyHeuristics.value.handleCommandStart(options); @@ -505,6 +510,7 @@ class UnixPtyHeuristics extends Disposable { this._register(_terminal.parser.registerCsiHandler({ final: 'J' }, params => { if (params.length >= 1 && (params[0] === 2 || params[0] === 3)) { _hooks.clearCommandsInViewport(); + this._capability.viewportCleared = true; } // We don't want to override xterm.js' default behavior, just augment it return false; diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index 8c073b4b7d5..0a789193617 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -244,12 +244,6 @@ export class TerminalStickyScrollOverlay extends Disposable { return; } - // Do not show sticky scroll after `clear` command - if (command.command && this._isClearCommand(command.command)) { - this._setVisible(false); - return; - } - // If the marker doesn't exist or it was trimmed from scrollback const marker = command.marker; if (!marker || marker.line === -1) { @@ -528,18 +522,6 @@ export class TerminalStickyScrollOverlay extends Disposable { }; } - private _isClearCommand(command: string): boolean { - const trimmedCommand = command.trim().toLowerCase(); - - const clearCommands = [ - 'clear', // Unix/Linux/macOS bash/zsh - 'cls', // Windows cmd.exe - 'clear-host', // PowerShell - 'reset' - ]; - - return clearCommands.includes(trimmedCommand); - } } function lineStartsWith(line: IBufferLine | undefined, text: string): boolean {