Skip to content

Commit

Permalink
Implement Terminal.creationOptions API
Browse files Browse the repository at this point in the history
Fixes #63052
  • Loading branch information
Tyriar committed Nov 5, 2019
1 parent 5d3c599 commit 1d60909
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { window, Pseudoterminal, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget, Disposable } from 'vscode';
import { doesNotThrow, equal, ok, deepEqual } from 'assert';
import { doesNotThrow, equal, ok, deepEqual, throws } from 'assert';

suite('window namespace tests', () => {
suiteSetup(async () => {
Expand Down Expand Up @@ -84,6 +84,30 @@ suite('window namespace tests', () => {
}
});

test('creationOptions should be set and readonly for TerminalOptions terminals', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
}
terminal.dispose();
disposables.push(window.onDidCloseTerminal(() => done()));
}));
const options = {
name: 'foo',
hideFromUser: true
};
const terminal = window.createTerminal(options);
try {
equal(terminal.name, 'foo');
deepEqual(terminal.creationOptions, options);
throws(() => (<any>terminal.creationOptions).name = 'bad', 'creationOptions should be readonly at runtime');
} catch (e) {
done(e);
}
});

test('onDidOpenTerminal should fire when a terminal is created', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
Expand Down Expand Up @@ -369,6 +393,33 @@ suite('window namespace tests', () => {
};
const terminal = window.createTerminal({ name: 'foo', pty });
});

test('creationOptions should be set and readonly for ExtensionTerminalOptions terminals', (done) => {
disposables.push(window.onDidOpenTerminal(term => {
try {
equal(terminal, term);
} catch (e) {
done(e);
}
terminal.dispose();
disposables.push(window.onDidCloseTerminal(() => done()));
}));
const writeEmitter = new EventEmitter<string>();
const pty: Pseudoterminal = {
onDidWrite: writeEmitter.event,
open: () => { },
close: () => { }
};
const options = { name: 'foo', pty };
const terminal = window.createTerminal(options);
try {
equal(terminal.name, 'foo');
deepEqual(terminal.creationOptions, options);
throws(() => (<any>terminal.creationOptions).name = 'bad', 'creationOptions should be readonly at runtime');
} catch (e) {
done(e);
}
});
});
});
});
7 changes: 7 additions & 0 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,13 @@ declare module 'vscode' {
}

export interface Terminal {
/**
* The object used to initialize the terminal, this is useful for things like detecting the
* shell type of shells not launched by the extension or detecting what folder the shell was
* launched in.
*/
readonly creationOptions: Readonly<TerminalOptions | ExtensionTerminalOptions>;

/**
* The current dimensions of the terminal. This will be `undefined` immediately after the
* terminal is created as the dimensions are not known until shortly after the terminal is
Expand Down
11 changes: 9 additions & 2 deletions src/vs/workbench/api/browser/mainThreadTerminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,18 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
}

private _onTerminalOpened(terminalInstance: ITerminalInstance): void {
const shellLaunchConfigDto: IShellLaunchConfigDto = {
name: terminalInstance.shellLaunchConfig.name,
executable: terminalInstance.shellLaunchConfig.executable,
args: terminalInstance.shellLaunchConfig.args,
cwd: terminalInstance.shellLaunchConfig.cwd,
env: terminalInstance.shellLaunchConfig.env
};
if (terminalInstance.title) {
this._proxy.$acceptTerminalOpened(terminalInstance.id, terminalInstance.title);
this._proxy.$acceptTerminalOpened(terminalInstance.id, terminalInstance.title, shellLaunchConfigDto);
} else {
terminalInstance.waitForTitle().then(title => {
this._proxy.$acceptTerminalOpened(terminalInstance.id, title);
this._proxy.$acceptTerminalOpened(terminalInstance.id, title, shellLaunchConfigDto);
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/common/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,7 @@ export interface ITerminalDimensionsDto {

export interface ExtHostTerminalServiceShape {
$acceptTerminalClosed(id: number): void;
$acceptTerminalOpened(id: number, name: string): void;
$acceptTerminalOpened(id: number, name: string, shellLaunchConfig: IShellLaunchConfigDto): void;
$acceptActiveTerminalChanged(id: number | null): void;
$acceptTerminalProcessId(id: number, processId: number): void;
$acceptTerminalProcessData(id: number, data: string): void;
Expand Down
19 changes: 16 additions & 3 deletions src/vs/workbench/api/common/extHostTerminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi

constructor(
proxy: MainThreadTerminalServiceShape,
private readonly _creationOptions: vscode.TerminalOptions | vscode.ExtensionTerminalOptions,
private _name?: string,
id?: number
) {
super(proxy, id);
this._creationOptions = Object.freeze(this._creationOptions);
this._pidPromise = new Promise<number>(c => this._pidPromiseComplete = c);
}

Expand Down Expand Up @@ -162,6 +164,10 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi
return this._pidPromise;
}

public get creationOptions(): Readonly<vscode.TerminalOptions | vscode.ExtensionTerminalOptions> {
return this._creationOptions;
}

public sendText(text: string, addNewLine: boolean = true): void {
this._checkDisposed();
this._queueApiRequest(this._proxy.$sendText, [text, addNewLine]);
Expand Down Expand Up @@ -310,7 +316,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
public abstract $acceptWorkspacePermissionsChanged(isAllowed: boolean): void;

public createExtensionTerminal(options: vscode.ExtensionTerminalOptions): vscode.Terminal {
const terminal = new ExtHostTerminal(this._proxy, options.name);
const terminal = new ExtHostTerminal(this._proxy, options, options.name);
const p = new ExtHostPseudoterminal(options.pty);
terminal.createExtensionTerminal().then(id => this._setupExtHostProcessListeners(id, p));
this._terminals.push(terminal);
Expand Down Expand Up @@ -390,7 +396,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
}
}

public $acceptTerminalOpened(id: number, name: string): void {
public $acceptTerminalOpened(id: number, name: string, shellLaunchConfigDto: IShellLaunchConfigDto): void {
const index = this._getTerminalObjectIndexById(this._terminals, id);
if (index !== null) {
// The terminal has already been created (via createTerminal*), only fire the event
Expand All @@ -399,7 +405,14 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
return;
}

const terminal = new ExtHostTerminal(this._proxy, name, id);
const creationOptions: vscode.TerminalOptions = {
name: shellLaunchConfigDto.name,
shellPath: shellLaunchConfigDto.executable,
shellArgs: shellLaunchConfigDto.args,
cwd: typeof shellLaunchConfigDto.cwd === 'string' ? shellLaunchConfigDto.cwd : URI.revive(shellLaunchConfigDto.cwd),
env: shellLaunchConfigDto.env
};
const terminal = new ExtHostTerminal(this._proxy, creationOptions, name, id);
this._terminals.push(terminal);
this._onDidOpenTerminal.fire(terminal);
terminal.isOpen = true;
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/api/node/extHostTerminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
}

public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
const terminal = new ExtHostTerminal(this._proxy, name);
const terminal = new ExtHostTerminal(this._proxy, { name, shellPath, shellArgs }, name);
terminal.create(shellPath, shellArgs);
this._terminals.push(terminal);
return terminal;
}

public createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal {
const terminal = new ExtHostTerminal(this._proxy, options.name);
const terminal = new ExtHostTerminal(this._proxy, options, options.name);
terminal.create(options.shellPath, options.shellArgs, options.cwd, options.env, /*options.waitOnExit*/ undefined, options.strictEnv, options.hideFromUser);
this._terminals.push(terminal);
return terminal;
Expand Down

0 comments on commit 1d60909

Please sign in to comment.