Skip to content

Commit 3fa7cc6

Browse files
committed
Improve cls/clear SI behavior on Windows
1 parent 8aa6274 commit 3fa7cc6

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
171171
get isCommandStorageDisabled() { return that.__isCommandStorageDisabled; }
172172
get commandMarkers() { return that._commandMarkers; }
173173
set commandMarkers(value) { that._commandMarkers = value; }
174-
get clearCommandsInViewport() { return that._clearCommandsInViewport; }
174+
get clearCommandsInViewport() { return that._clearCommandsInViewport.bind(that); }
175175
},
176176
this._logService
177177
);
@@ -504,7 +504,8 @@ const enum AdjustCommandStartMarkerConstants {
504504
class WindowsPtyHeuristics extends Disposable {
505505

506506
private _onCursorMoveListener = this._register(new MutableDisposable());
507-
private _windowsPromptPollingInProcess: boolean = false;
507+
508+
private _recentlyPerformedCsiJ = false;
508509

509510
constructor(
510511
private readonly _terminal: Terminal,
@@ -514,11 +515,27 @@ class WindowsPtyHeuristics extends Disposable {
514515
) {
515516
super();
516517

518+
this._register(_terminal.parser.registerCsiHandler({ final: 'J' }, params => {
519+
if (params.length >= 1 && (params[0] === 2 || params[0] === 3)) {
520+
this._recentlyPerformedCsiJ = true;
521+
this._hooks.clearCommandsInViewport();
522+
}
523+
// We don't want to override xterm.js' default behavior, just augment it
524+
return false;
525+
}));
526+
517527
this._register(this._capability.onBeforeCommandFinished(command => {
518-
// For a Windows backend we cannot listen to CSI J, instead we assume running clear or
519-
// cls will clear all commands in the viewport. This is not perfect but it's right most
520-
// of the time.
528+
if (this._recentlyPerformedCsiJ) {
529+
this._recentlyPerformedCsiJ = false;
530+
return;
531+
}
532+
533+
// For older Windows backends we cannot listen to CSI J, instead we assume running clear
534+
// or cls will clear all commands in the viewport. This is not perfect but it's right
535+
// most of the time.
521536
if (command.command.trim().toLowerCase() === 'clear' || command.command.trim().toLowerCase() === 'cls') {
537+
this._tryAdjustCommandStartMarkerScheduler?.cancel();
538+
this._tryAdjustCommandStartMarkerScheduler = undefined;
522539
this._hooks.clearCommandsInViewport();
523540
this._capability.currentCommand.isInvalid = true;
524541
this._hooks.onCurrentCommandInvalidatedEmitter.fire({ reason: CommandInvalidationReason.Windows });
@@ -580,10 +597,6 @@ class WindowsPtyHeuristics extends Disposable {
580597
private _tryAdjustCommandStartMarkerPollCount: number = 0;
581598

582599
async handleCommandStart() {
583-
584-
if (this._windowsPromptPollingInProcess) {
585-
this._windowsPromptPollingInProcess = false;
586-
}
587600
this._capability.currentCommand.commandStartX = this._terminal.buffer.active.cursorX;
588601

589602
// On Windows track all cursor movements after the command start sequence

0 commit comments

Comments
 (0)