Skip to content

Commit

Permalink
Clean up and disable command detection in common protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyriar committed Jun 23, 2022
1 parent ccc0a72 commit 15ba463
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 23 deletions.
10 changes: 9 additions & 1 deletion src/vs/platform/terminal/common/capabilities/capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export interface ICommandDetectionCapability {
handleContinuationEnd(): void;
handleRightPromptStart(): void;
handleRightPromptEnd(): void;
handleCommandStart(): void;
handleCommandStart(options?: IHandleCommandStartOptions): void;
handleCommandExecuted(): void;
handleCommandFinished(exitCode: number | undefined): void;
/**
Expand All @@ -118,6 +118,14 @@ export interface ICommandDetectionCapability {
deserialize(serialized: ISerializedCommandDetectionCapability): void;
}

export interface IHandleCommandStartOptions {
/**
* Whether to allow an empty command to be registered. This should be used to support certain
* shell integration scripts/features where tracking the command line may not be possible.
*/
ignoreCommandLine?: boolean;
}

export interface INaiveCwdDetectionCapability {
readonly type: TerminalCapability.NaiveCwdDetection;
readonly onDidChangeCwd: Event<string>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { timeout } from 'vs/base/common/async';
import { debounce } from 'vs/base/common/decorators';
import { Emitter } from 'vs/base/common/event';
import { ILogService } from 'vs/platform/log/common/log';
import { ICommandDetectionCapability, TerminalCapability, ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
import { ICommandDetectionCapability, TerminalCapability, ITerminalCommand, IHandleCommandStartOptions } from 'vs/platform/terminal/common/capabilities/capabilities';
import { ISerializedCommand, ISerializedCommandDetectionCapability } from 'vs/platform/terminal/common/terminalProcess';
// Importing types is safe in any layer
// eslint-disable-next-line code-import-patterns
Expand Down Expand Up @@ -61,6 +61,8 @@ export class CommandDetectionCapability implements ICommandDetectionCapability {
private _commandMarkers: IMarker[] = [];
private _dimensions: ITerminalDimensions;
private __isCommandStorageDisabled: boolean = false;
private _handleCommandStartOptions?: IHandleCommandStartOptions;

get commands(): readonly ITerminalCommand[] { return this._commands; }
get executingCommand(): string | undefined { return this._currentCommand.command; }
// TODO: as is unsafe here and it duplicates behavor of executingCommand
Expand Down Expand Up @@ -300,7 +302,8 @@ export class CommandDetectionCapability implements ICommandDetectionCapability {
this._logService.debug('CommandDetectionCapability#handleRightPromptEnd', this._currentCommand.commandRightPromptEndX);
}

handleCommandStart(): void {
handleCommandStart(options?: IHandleCommandStartOptions): void {
this._handleCommandStartOptions = options;
// Only update the column if the line has already been set
if (this._currentCommand.commandStartMarker?.line === this._terminal.buffer.active.cursorY) {
this._currentCommand.commandStartX = this._terminal.buffer.active.cursorX;
Expand Down Expand Up @@ -419,13 +422,13 @@ export class CommandDetectionCapability implements ICommandDetectionCapability {
return;
}

if (command !== undefined && !command.startsWith('\\')) {
if ((command !== undefined && !command.startsWith('\\')) || this._handleCommandStartOptions?.ignoreCommandLine) {
const buffer = this._terminal.buffer.active;
const timestamp = Date.now();
const executedMarker = this._currentCommand.commandExecutedMarker;
const endMarker = this._currentCommand.commandFinishedMarker;
const newCommand: ITerminalCommand = {
command,
command: this._handleCommandStartOptions?.ignoreCommandLine ? '' : (command || ''),
marker: this._currentCommand.commandStartMarker,
endMarker,
executedMarker,
Expand All @@ -446,6 +449,7 @@ export class CommandDetectionCapability implements ICommandDetectionCapability {
}
this._currentCommand.previousCommandMarker = this._currentCommand.commandStartMarker;
this._currentCommand = {};
this._handleCommandStartOptions = undefined;
}

private _preHandleCommandFinishedWindows(): void {
Expand Down
25 changes: 7 additions & 18 deletions src/vs/platform/terminal/common/xterm/shellIntegrationAddon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,7 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
this.capabilities.add(TerminalCapability.PartialCommandDetection, new PartialCommandDetectionCapability(this._terminal));
this._register(xterm.parser.registerOscHandler(ShellIntegrationOscPs.VSCode, data => this._handleVSCodeSequence(data)));
this._commonProtocolDisposables.push(
xterm.parser.registerOscHandler(ShellIntegrationOscPs.FinalTerm, data => this._handleFinalTermSequence(data)),
xterm.parser.registerOscHandler(ShellIntegrationOscPs.ITerm, data => this._handleITermSequence(data)),
xterm.parser.registerOscHandler(7, data => {
console.log('OSC 7', data);
return false;
}),
xterm.parser.registerOscHandler(9, data => {
console.log('OSC 9', data);
return false;
})
xterm.parser.registerOscHandler(ShellIntegrationOscPs.FinalTerm, data => this._handleFinalTermSequence(data))
);
this._ensureCapabilitiesOrAddFailureTelemetry();
}
Expand All @@ -169,16 +160,19 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
return false;
}

// TODO: Disable final term sequences if VS Code sequences are encountered
// TODO: How to handle extraction of command with right prompt and continuations?
// Pass the sequence along to the capability
// It was considered to disable the common protocol in order to not confuse the VS Code
// shell integration if both happen for some reason. This doesn't work for powerlevel10k
// when instant prompt is enabled though. If this does end up being a problem we could pass
// a type flag through the capability calls
const [command, ...args] = data.split(';');
switch (command) {
case 'A':
this._createOrGetCommandDetection(this._terminal).handlePromptStart();
return true;
case 'B':
this._createOrGetCommandDetection(this._terminal).handleCommandStart();
// Ignore the command line for these sequences as it's unreliable for example in powerlevel10k
this._createOrGetCommandDetection(this._terminal).handleCommandStart({ ignoreCommandLine: true });
return true;
case 'C':
this._createOrGetCommandDetection(this._terminal).handleCommandExecuted();
Expand All @@ -192,11 +186,6 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
return false;
}

private _handleITermSequence(data: string): boolean {
this._logService.debug('Shell integration: OSC 1337', data);
return false;
}

private _handleVSCodeSequence(data: string): boolean {
const didHandle = this._doHandleVSCodeSequence(data);
if (!this._hasUpdatedTelemetry && didHandle) {
Expand Down

0 comments on commit 15ba463

Please sign in to comment.