From 275cb2f0e847dc943f580a386d5e5236c4f5e548 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 28 Mar 2024 13:26:15 -0700 Subject: [PATCH] Convert and pass URI to shellIntegration Fixes #208368 --- .../commandDetection/terminalCommand.ts | 9 +++++++++ .../capabilities/commandDetectionCapability.ts | 2 ++ .../mainThreadTerminalShellIntegration.ts | 16 ++++++++++------ src/vs/workbench/api/common/extHost.protocol.ts | 2 +- .../common/extHostTerminalShellIntegration.ts | 6 +++--- ...vscode.proposed.terminalShellIntegration.d.ts | 1 + 6 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/vs/platform/terminal/common/capabilities/commandDetection/terminalCommand.ts b/src/vs/platform/terminal/common/capabilities/commandDetection/terminalCommand.ts index 1fffd61bfe02c..24687d0ac74aa 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetection/terminalCommand.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetection/terminalCommand.ts @@ -9,6 +9,7 @@ import { ITerminalOutputMatcher, ITerminalOutputMatch } from 'vs/platform/termin // Importing types is safe in any layer // eslint-disable-next-line local/code-import-patterns import type { IBuffer, IBufferLine, Terminal } from '@xterm/headless'; +import { URI } from 'vs/base/common/uri'; export interface ITerminalCommandProperties { command: string; @@ -201,6 +202,13 @@ export class TerminalCommand implements ITerminalCommand { getCommandRowCount(): number { return getCommandRowCount(this); } + + getCwdResource(): URI | undefined { + if (!this.cwd) { + return undefined; + } + return URI.file(this.cwd); + } } export interface ICurrentPartialCommand { @@ -263,6 +271,7 @@ export class PartialTerminalCommand implements ICurrentPartialCommand { currentContinuationMarker?: IMarker; continuations?: { marker: IMarker; end: number }[]; + cwd?: string; command?: string; isTrusted?: boolean; diff --git a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts index 9ad13a75baa13..8a578cd5a650c 100644 --- a/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts +++ b/src/vs/platform/terminal/common/capabilities/commandDetectionCapability.ts @@ -157,6 +157,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe } setCwd(value: string) { + console.log('setCwd', value); this._cwd = value; } @@ -281,6 +282,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe handleCommandStart(options?: IHandleCommandOptions): void { this._handleCommandStartOptions = options; + this._currentCommand.cwd = this._cwd; // Only update the column if the line has already been set this._currentCommand.commandStartMarker = options?.marker || this._currentCommand.commandStartMarker; if (this._currentCommand.commandStartMarker?.line === this._terminal.buffer.active.cursorY) { diff --git a/src/vs/workbench/api/browser/mainThreadTerminalShellIntegration.ts b/src/vs/workbench/api/browser/mainThreadTerminalShellIntegration.ts index ab771ec17d3ec..97057f0628b8f 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalShellIntegration.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalShellIntegration.ts @@ -5,6 +5,7 @@ import { Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; +import { URI } from 'vs/base/common/uri'; import { TerminalCapability, type ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities'; import { ExtHostContext, MainContext, type ExtHostTerminalShellIntegrationShape, type MainThreadTerminalShellIntegrationShape } from 'vs/workbench/api/common/extHost.protocol'; import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; @@ -38,17 +39,14 @@ export class MainThreadTerminalShellIntegration extends Disposable implements Ma const commandDetectionStartEvent = this._store.add(this._terminalService.createOnInstanceCapabilityEvent(TerminalCapability.CommandDetection, e => e.onCommandExecuted)); let currentCommand: ITerminalCommand | undefined; this._store.add(commandDetectionStartEvent.event(e => { - // String paths are not exposed in the extension API - if (typeof e.data.cwd === 'string') { - return; - } // Prevent duplicate events from being sent in case command detection double fires the // event if (e.data === currentCommand) { return; } + // String paths are not exposed in the extension API currentCommand = e.data; - this._proxy.$shellExecutionStart(e.instance.instanceId, e.data.command, e.data.cwd); + this._proxy.$shellExecutionStart(e.instance.instanceId, e.data.command, this._convertCwdToUri(e.data.cwd)); })); // onDidEndTerminalShellExecution @@ -60,7 +58,9 @@ export class MainThreadTerminalShellIntegration extends Disposable implements Ma // onDidChangeTerminalShellIntegration via cwd const cwdChangeEvent = this._store.add(this._terminalService.createOnInstanceCapabilityEvent(TerminalCapability.CwdDetection, e => e.onDidChangeCwd)); - this._store.add(cwdChangeEvent.event(e => this._proxy.$cwdChange(e.instance.instanceId, e.data))); + this._store.add(cwdChangeEvent.event(e => { + this._proxy.$cwdChange(e.instance.instanceId, this._convertCwdToUri(e.data)); + })); // Clean up after dispose this._store.add(this._terminalService.onDidDisposeInstance(e => this._proxy.$closeTerminal(e.instanceId))); @@ -75,4 +75,8 @@ export class MainThreadTerminalShellIntegration extends Disposable implements Ma $executeCommand(terminalId: number, commandLine: string): void { this._terminalService.getInstanceFromId(terminalId)?.runCommand(commandLine, true); } + + private _convertCwdToUri(cwd: string | undefined): URI | undefined { + return cwd ? URI.file(cwd) : undefined; + } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 7fb0d5693568c..0501cdf6c143e 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -2271,7 +2271,7 @@ export interface ExtHostTerminalShellIntegrationShape { $shellExecutionStart(instanceId: number, commandLine: string | undefined, cwd: UriComponents | undefined): void; $shellExecutionEnd(instanceId: number, commandLine: string | undefined, exitCode: number | undefined): void; $shellExecutionData(instanceId: number, data: string): void; - $cwdChange(instanceId: number, cwd: UriComponents | string): void; + $cwdChange(instanceId: number, cwd: UriComponents | undefined): void; $closeTerminal(instanceId: number): void; } diff --git a/src/vs/workbench/api/common/extHostTerminalShellIntegration.ts b/src/vs/workbench/api/common/extHostTerminalShellIntegration.ts index 302404ea86f64..10d7ccbe4abfc 100644 --- a/src/vs/workbench/api/common/extHostTerminalShellIntegration.ts +++ b/src/vs/workbench/api/common/extHostTerminalShellIntegration.ts @@ -120,7 +120,7 @@ export class ExtHostTerminalShellIntegration extends Disposable implements IExtH this._activeShellIntegrations.get(instanceId)?.emitData(data); } - public $cwdChange(instanceId: number, cwd: URI): void { + public $cwdChange(instanceId: number, cwd: URI | undefined): void { this._activeShellIntegrations.get(instanceId)?.setCwd(cwd); } @@ -230,13 +230,13 @@ class InternalTerminalShellExecution { const that = this; this.value = { get terminal(): vscode.Terminal { - return terminal; + return that.terminal; }, get commandLine(): string | undefined { return that._commandLine; }, get cwd(): URI | undefined { - return cwd; + return that.cwd; }, createDataStream(): AsyncIterable { return that._createDataStream(); diff --git a/src/vscode-dts/vscode.proposed.terminalShellIntegration.d.ts b/src/vscode-dts/vscode.proposed.terminalShellIntegration.d.ts index 15382de1e40ae..8d19e54747e23 100644 --- a/src/vscode-dts/vscode.proposed.terminalShellIntegration.d.ts +++ b/src/vscode-dts/vscode.proposed.terminalShellIntegration.d.ts @@ -69,6 +69,7 @@ declare module 'vscode' { } export interface TerminalShellIntegration { + // TODO: Should this share TerminalShellIntegrationChangeEvent or have it's own TerminalShellIntegrationCwdChangeEvent? /** * The current working directory of the terminal. This will be a {@link Uri} if the path * reported by the shell can reliably be mapped to the connected machine.