Skip to content

Commit 3777aa2

Browse files
committed
Don't expose cwd as a string on shellIntegration/execution
Fixes microsoft#208638
1 parent e857eec commit 3777aa2

File tree

6 files changed

+30
-22
lines changed

6 files changed

+30
-22
lines changed

src/vs/platform/terminal/common/capabilities/commandDetection/terminalCommand.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ export class PartialTerminalCommand implements ICurrentPartialCommand {
263263
currentContinuationMarker?: IMarker;
264264
continuations?: { marker: IMarker; end: number }[];
265265

266+
cwd?: string;
266267
command?: string;
267268

268269
isTrusted?: boolean;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
281281

282282
handleCommandStart(options?: IHandleCommandOptions): void {
283283
this._handleCommandStartOptions = options;
284+
this._currentCommand.cwd = this._cwd;
284285
// Only update the column if the line has already been set
285286
this._currentCommand.commandStartMarker = options?.marker || this._currentCommand.commandStartMarker;
286287
if (this._currentCommand.commandStartMarker?.line === this._terminal.buffer.active.cursorY) {

src/vs/workbench/api/browser/mainThreadTerminalShellIntegration.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import { Event } from 'vs/base/common/event';
77
import { Disposable } from 'vs/base/common/lifecycle';
8+
import { URI } from 'vs/base/common/uri';
89
import { TerminalCapability, type ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
910
import { ExtHostContext, MainContext, type ExtHostTerminalShellIntegrationShape, type MainThreadTerminalShellIntegrationShape } from 'vs/workbench/api/common/extHost.protocol';
1011
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
@@ -43,8 +44,9 @@ export class MainThreadTerminalShellIntegration extends Disposable implements Ma
4344
if (e.data === currentCommand) {
4445
return;
4546
}
47+
// String paths are not exposed in the extension API
4648
currentCommand = e.data;
47-
this._proxy.$shellExecutionStart(e.instance.instanceId, e.data.command, e.data.cwd);
49+
this._proxy.$shellExecutionStart(e.instance.instanceId, e.data.command, this._convertCwdToUri(e.data.cwd));
4850
}));
4951

5052
// onDidEndTerminalShellExecution
@@ -56,7 +58,9 @@ export class MainThreadTerminalShellIntegration extends Disposable implements Ma
5658

5759
// onDidChangeTerminalShellIntegration via cwd
5860
const cwdChangeEvent = this._store.add(this._terminalService.createOnInstanceCapabilityEvent(TerminalCapability.CwdDetection, e => e.onDidChangeCwd));
59-
this._store.add(cwdChangeEvent.event(e => this._proxy.$cwdChange(e.instance.instanceId, e.data)));
61+
this._store.add(cwdChangeEvent.event(e => {
62+
this._proxy.$cwdChange(e.instance.instanceId, this._convertCwdToUri(e.data));
63+
}));
6064

6165
// Clean up after dispose
6266
this._store.add(this._terminalService.onDidDisposeInstance(e => this._proxy.$closeTerminal(e.instanceId)));
@@ -71,4 +75,8 @@ export class MainThreadTerminalShellIntegration extends Disposable implements Ma
7175
$executeCommand(terminalId: number, commandLine: string): void {
7276
this._terminalService.getInstanceFromId(terminalId)?.runCommand(commandLine, true);
7377
}
78+
79+
private _convertCwdToUri(cwd: string | undefined): URI | undefined {
80+
return cwd ? URI.file(cwd) : undefined;
81+
}
7482
}

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,10 +2268,10 @@ export interface ExtHostTerminalServiceShape {
22682268

22692269
export interface ExtHostTerminalShellIntegrationShape {
22702270
$shellIntegrationChange(instanceId: number): void;
2271-
$shellExecutionStart(instanceId: number, commandLine: string | undefined, cwd: UriComponents | string | undefined): void;
2271+
$shellExecutionStart(instanceId: number, commandLine: string | undefined, cwd: UriComponents | undefined): void;
22722272
$shellExecutionEnd(instanceId: number, commandLine: string | undefined, exitCode: number | undefined): void;
22732273
$shellExecutionData(instanceId: number, data: string): void;
2274-
$cwdChange(instanceId: number, cwd: UriComponents | string): void;
2274+
$cwdChange(instanceId: number, cwd: UriComponents | undefined): void;
22752275
$closeTerminal(instanceId: number): void;
22762276
}
22772277

src/vs/workbench/api/common/extHostTerminalShellIntegration.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export class ExtHostTerminalShellIntegration extends Disposable implements IExtH
103103
});
104104
}
105105

106-
public $shellExecutionStart(instanceId: number, commandLine: string, cwd: URI | string | undefined): void {
106+
public $shellExecutionStart(instanceId: number, commandLine: string, cwd: URI | undefined): void {
107107
// Force shellIntegration creation if it hasn't been created yet, this could when events
108108
// don't come through on startup
109109
if (!this._activeShellIntegrations.has(instanceId)) {
@@ -120,7 +120,7 @@ export class ExtHostTerminalShellIntegration extends Disposable implements IExtH
120120
this._activeShellIntegrations.get(instanceId)?.emitData(data);
121121
}
122122

123-
public $cwdChange(instanceId: number, cwd: string): void {
123+
public $cwdChange(instanceId: number, cwd: URI | undefined): void {
124124
this._activeShellIntegrations.get(instanceId)?.setCwd(cwd);
125125
}
126126

@@ -136,7 +136,7 @@ class InternalTerminalShellIntegration extends Disposable {
136136
get currentExecution(): InternalTerminalShellExecution | undefined { return this._currentExecution; }
137137

138138
private _ignoreNextExecution: boolean = false;
139-
private _cwd: URI | string | undefined;
139+
private _cwd: URI | undefined;
140140

141141
readonly store: DisposableStore = this._register(new DisposableStore());
142142

@@ -157,7 +157,7 @@ class InternalTerminalShellIntegration extends Disposable {
157157

158158
const that = this;
159159
this.value = {
160-
get cwd(): URI | string | undefined {
160+
get cwd(): URI | undefined {
161161
return that._cwd;
162162
},
163163
executeCommand(commandLine): vscode.TerminalShellExecution {
@@ -171,7 +171,7 @@ class InternalTerminalShellIntegration extends Disposable {
171171
};
172172
}
173173

174-
startShellExecution(commandLine: string, cwd: URI | string | undefined, fireEventInMicrotask?: boolean): InternalTerminalShellExecution {
174+
startShellExecution(commandLine: string, cwd: URI | undefined, fireEventInMicrotask?: boolean): InternalTerminalShellExecution {
175175
if (this._ignoreNextExecution && this._currentExecution) {
176176
this._ignoreNextExecution = false;
177177
} else {
@@ -201,12 +201,10 @@ class InternalTerminalShellIntegration extends Disposable {
201201
}
202202
}
203203

204-
setCwd(cwd: URI | string): void {
204+
setCwd(cwd: URI | undefined): void {
205205
let wasChanged = false;
206206
if (URI.isUri(this._cwd)) {
207-
if (this._cwd.toString() !== cwd.toString()) {
208-
wasChanged = true;
209-
}
207+
wasChanged = !URI.isUri(cwd) || this._cwd.toString() !== cwd.toString();
210208
} else if (this._cwd !== cwd) {
211209
wasChanged = true;
212210
}
@@ -227,18 +225,18 @@ class InternalTerminalShellExecution {
227225
constructor(
228226
readonly terminal: vscode.Terminal,
229227
private _commandLine: string | undefined,
230-
readonly cwd: URI | string | undefined,
228+
readonly cwd: URI | undefined,
231229
) {
232230
const that = this;
233231
this.value = {
234232
get terminal(): vscode.Terminal {
235-
return terminal;
233+
return that.terminal;
236234
},
237235
get commandLine(): string | undefined {
238236
return that._commandLine;
239237
},
240-
get cwd(): URI | string | undefined {
241-
return cwd;
238+
get cwd(): URI | undefined {
239+
return that.cwd;
242240
},
243241
createDataStream(): AsyncIterable<string> {
244242
return that._createDataStream();

src/vscode-dts/vscode.proposed.terminalShellIntegration.d.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ declare module 'vscode' {
3030

3131
/**
3232
* The working directory that was reported by the shell when this command executed. This
33-
* will be a {@link Uri} if the string reported by the shell can reliably be mapped to the
33+
* will be a {@link Uri} if the path reported by the shell can reliably be mapped to the
3434
* connected machine. This requires the shell integration to support working directory
3535
* reporting via the [`OSC 633 ; P`](https://code.visualstudio.com/docs/terminal/shell-integration#_vs-code-custom-sequences-osc-633-st)
3636
* or `OSC 1337 ; CurrentDir=<Cwd> ST` sequences.
3737
*/
38-
readonly cwd: Uri | string | undefined;
38+
readonly cwd: Uri | undefined;
3939

4040
/**
4141
* Creates a stream of raw data (including escape sequences) that is written to the
@@ -69,12 +69,12 @@ declare module 'vscode' {
6969
}
7070

7171
export interface TerminalShellIntegration {
72-
// TODO: Is this fine to share the TerminalShellIntegrationChangeEvent event?
72+
// TODO: Should this share TerminalShellIntegrationChangeEvent or have it's own TerminalShellIntegrationCwdChangeEvent?
7373
/**
74-
* The current working directory of the terminal. This will be a {@link Uri} if the string
74+
* The current working directory of the terminal. This will be a {@link Uri} if the path
7575
* reported by the shell can reliably be mapped to the connected machine.
7676
*/
77-
readonly cwd: Uri | string | undefined;
77+
readonly cwd: Uri | undefined;
7878

7979
/**
8080
* Execute a command, sending ^C as necessary to interrupt any running command if needed.

0 commit comments

Comments
 (0)