Skip to content

Commit

Permalink
fix: improve terminal marker placements on windows
Browse files Browse the repository at this point in the history
Signed-off-by: Chapman Pendery <cpendery@microsoft.com>
  • Loading branch information
cpendery committed Mar 29, 2024
1 parent 9d98da3 commit f47baf3
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ export interface ICommandDetectionCapability {
getCwdForLine(line: number): string | undefined;
getCommandForLine(line: number): ITerminalCommand | ICurrentPartialCommand | undefined;
handlePromptStart(options?: IHandleCommandOptions): void;
handleInput(): void;
handleContinuationStart(): void;
handleContinuationEnd(): void;
handleRightPromptStart(): void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,16 @@ export interface ICurrentPartialCommand {
*/
isInvalid?: boolean;

/**
* Whether the command start marker has been adjusted on Windows.
*/
isAdjusted?: boolean;

/**
* Whether the command start marker adjustment has been attempt on new terminal input.
*/
isInputAdjusted?: boolean;

getPromptRowCount(): number;
getCommandRowCount(): number;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
};
this._register(this._terminal.onResize(e => this._handleResize(e)));
this._register(this._terminal.onCursorMove(() => this._handleCursorMove()));
this._register(this._terminal.onData(() => this.handleInput()));
}

private _handleResize(e: { cols: number; rows: number }) {
Expand Down Expand Up @@ -233,6 +234,10 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
return undefined;
}

handleInput(): void {
this._ptyHeuristics.value.handleInput();
}

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
Expand Down Expand Up @@ -447,6 +452,8 @@ class UnixPtyHeuristics extends Disposable {
}));
}

handleInput() { }

async handleCommandStart(options?: IHandleCommandOptions) {
this._hooks.commitCommandFinished();

Expand Down Expand Up @@ -600,6 +607,19 @@ class WindowsPtyHeuristics extends Disposable {
}
}

handleInput() {
if (this._capability.currentCommand.isAdjusted === true || this._capability.currentCommand.isInputAdjusted === true) {
return;
}
this._capability.currentCommand.isInputAdjusted = true;
this._logService.debug('CommandDetectionCapability#handleInput attempting start marker adjustment');

this._tryAdjustCommandStartMarkerScannedLineCount = 0;
this._tryAdjustCommandStartMarkerPollCount = 0;
this._tryAdjustCommandStartMarkerScheduler = new RunOnceScheduler(() => this._tryAdjustCommandStartMarker(this._terminal.registerMarker(0)!), AdjustCommandStartMarkerConstants.Interval);
this._tryAdjustCommandStartMarkerScheduler.schedule();
}

async handleCommandStart() {
this._capability.currentCommand.commandStartX = this._terminal.buffer.active.cursorX;

Expand Down Expand Up @@ -661,21 +681,24 @@ class WindowsPtyHeuristics extends Disposable {
if (prompt) {
const adjustedPrompt = typeof prompt === 'string' ? prompt : prompt.prompt;
this._capability.currentCommand.commandStartMarker = this._terminal.registerMarker(0)!;
if (typeof prompt === 'object' && prompt.likelySingleLine) {
this._logService.debug('CommandDetectionCapability#_tryAdjustCommandStartMarker adjusted promptStart', `${this._capability.currentCommand.promptStartMarker?.line} -> ${this._capability.currentCommand.commandStartMarker.line}`);
this._capability.currentCommand.promptStartMarker?.dispose();
this._capability.currentCommand.promptStartMarker = cloneMarker(this._terminal, this._capability.currentCommand.commandStartMarker);
// Adjust the last command if it's not in the same position as the following
// prompt start marker
const lastCommand = this._capability.commands.at(-1);
if (lastCommand && this._capability.currentCommand.commandStartMarker.line !== lastCommand.endMarker?.line) {
lastCommand.endMarker?.dispose();
lastCommand.endMarker = cloneMarker(this._terminal, this._capability.currentCommand.commandStartMarker);
}

// Adjust the prompt start marker to the command start marker
this._logService.debug('CommandDetectionCapability#_tryAdjustCommandStartMarker adjusted promptStart', `${this._capability.currentCommand.promptStartMarker?.line} -> ${this._capability.currentCommand.commandStartMarker.line}`);
this._capability.currentCommand.promptStartMarker?.dispose();
this._capability.currentCommand.promptStartMarker = cloneMarker(this._terminal, this._capability.currentCommand.commandStartMarker);

// Adjust the last command if it's not in the same position as the following
// prompt start marker
const lastCommand = this._capability.commands.at(-1);
if (lastCommand && this._capability.currentCommand.commandStartMarker.line !== lastCommand.endMarker?.line) {
lastCommand.endMarker?.dispose();
lastCommand.endMarker = cloneMarker(this._terminal, this._capability.currentCommand.commandStartMarker);
}

// use the regex to set the position as it's possible input has occurred
this._capability.currentCommand.commandStartX = adjustedPrompt.length;
this._logService.debug('CommandDetectionCapability#_tryAdjustCommandStartMarker adjusted commandStart', `${start.line} -> ${this._capability.currentCommand.commandStartMarker.line}:${this._capability.currentCommand.commandStartX}`);
this._capability.currentCommand.isAdjusted = true;
this._flushPendingHandleCommandStartTask();
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
if (this.os === OperatingSystem.Linux || this.os === OperatingSystem.Macintosh) {
this.capabilities.add(TerminalCapability.NaiveCwdDetection, new NaiveCwdDetectionCapability(this._process));
}

this._dataFilter.newProcess(this._process, reset);

if (this._processListeners) {
Expand Down

0 comments on commit f47baf3

Please sign in to comment.