Skip to content

Commit 1f32a87

Browse files
committed
[vscode] Support env.onDidChangeShell event
contributed on behalf of STMicroelectronics Signed-off-by: Remi Schnekenburger <[email protected]> Address review comments - remove indirection from TerminalService - change shellPath as getter rather than property - use instanceof instead of is()
1 parent 178d74e commit 1f32a87

File tree

10 files changed

+54
-12
lines changed

10 files changed

+54
-12
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
## v1.44.0
88

99
- [task] prevent task widget title from being changed by task process [#13003](https://github.com/eclipse-theia/theia/pull/13003)
10-
- [vscode] Added Notebook CodeActionKind [#13093](https://github.com/eclipse-theia/theia/pull/13093) - contributed on behalf of STMicroelectronics
10+
- [vscode] added Notebook CodeActionKind [#13093](https://github.com/eclipse-theia/theia/pull/13093) - contributed on behalf of STMicroelectronics
11+
- [vscode] added support to env.ondidChangeShell event [#13097](https://github.com/eclipse-theia/theia/pull/13097) - contributed on behalf of STMicroelectronics
1112

1213
## v1.43.0 - 10/26/2023
1314

packages/plugin-ext/src/common/plugin-api-rpc.ts

+1
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ export interface TerminalServiceExt {
296296
$provideTerminalLinks(line: string, terminalId: string, token: theia.CancellationToken): Promise<ProvidedTerminalLink[]>;
297297
$handleTerminalLink(link: ProvidedTerminalLink): Promise<void>;
298298
getEnvironmentVariableCollection(extensionIdentifier: string): theia.GlobalEnvironmentVariableCollection;
299+
$setShell(shell: string): void;
299300
}
300301
export interface OutputChannelRegistryExt {
301302
createOutputChannel(name: string, pluginInfo: PluginInfo): theia.OutputChannel,

packages/plugin-ext/src/main/browser/terminal-main.ts

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { interfaces } from '@theia/core/shared/inversify';
1818
import { ApplicationShell, WidgetOpenerOptions } from '@theia/core/lib/browser';
1919
import { TerminalEditorLocationOptions, TerminalOptions } from '@theia/plugin';
2020
import { TerminalLocation, TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget';
21+
import { TerminalProfileService } from '@theia/terminal/lib/browser/terminal-profile-service';
2122
import { TerminalService } from '@theia/terminal/lib/browser/base/terminal-service';
2223
import { TerminalServiceMain, TerminalServiceExt, MAIN_RPC_CONTEXT } from '../../common/plugin-api-rpc';
2324
import { RPCProtocol } from '../../common/rpc-protocol';
@@ -36,6 +37,7 @@ import { HostedPluginSupport } from '../../hosted/browser/hosted-plugin';
3637
export class TerminalServiceMainImpl implements TerminalServiceMain, TerminalLinkProvider, Disposable {
3738

3839
private readonly terminals: TerminalService;
40+
private readonly terminalProfileService: TerminalProfileService;
3941
private readonly pluginTerminalRegistry: PluginTerminalRegistry;
4042
private readonly hostedPluginSupport: HostedPluginSupport;
4143
private readonly shell: ApplicationShell;
@@ -47,6 +49,7 @@ export class TerminalServiceMainImpl implements TerminalServiceMain, TerminalLin
4749

4850
constructor(rpc: RPCProtocol, container: interfaces.Container) {
4951
this.terminals = container.get(TerminalService);
52+
this.terminalProfileService = container.get(TerminalProfileService);
5053
this.pluginTerminalRegistry = container.get(PluginTerminalRegistry);
5154
this.hostedPluginSupport = container.get(HostedPluginSupport);
5255
this.shell = container.get(ApplicationShell);
@@ -64,6 +67,10 @@ export class TerminalServiceMainImpl implements TerminalServiceMain, TerminalLin
6467
this.pluginTerminalRegistry.startCallback = id => this.startProfile(id);
6568

6669
container.bind(TerminalLinkProvider).toDynamicValue(() => this);
70+
71+
this.toDispose.push(this.terminalProfileService.onDidChangeDefaultShell(shell => {
72+
this.extProxy.$setShell(shell);
73+
}));
6774
}
6875

6976
async startProfile(id: string): Promise<string> {

packages/plugin-ext/src/plugin/env.ts

-8
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ export abstract class EnvExtImpl {
2525
private queryParameters: QueryParameters;
2626
private lang: string;
2727
private applicationName: string;
28-
private defaultShell: string;
2928
private ui: theia.UIKind;
3029
private envMachineId: string;
3130
private envSessionId: string;
@@ -68,10 +67,6 @@ export abstract class EnvExtImpl {
6867
this.lang = lang;
6968
}
7069

71-
setShell(shell: string): void {
72-
this.defaultShell = shell;
73-
}
74-
7570
setUIKind(uiKind: theia.UIKind): void {
7671
this.ui = uiKind;
7772
}
@@ -112,9 +107,6 @@ export abstract class EnvExtImpl {
112107
get uriScheme(): string {
113108
return 'theia';
114109
}
115-
get shell(): string {
116-
return this.defaultShell;
117-
}
118110
get uiKind(): theia.UIKind {
119111
return this.ui;
120112
}

packages/plugin-ext/src/plugin/plugin-context.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,10 @@ export function createAPIFactory(
796796
get machineId(): string { return envExt.machineId; },
797797
get sessionId(): string { return envExt.sessionId; },
798798
get uriScheme(): string { return envExt.uriScheme; },
799-
get shell(): string { return envExt.shell; },
799+
get shell(): string { return terminalExt.defaultShell; },
800+
get onDidChangeShell(): theia.Event<string> {
801+
return terminalExt.onDidChangeShell;
802+
},
800803
get uiKind(): theia.UIKind { return envExt.uiKind; },
801804
clipboard,
802805
getEnvVariable(envVarName: string): PromiseLike<string | undefined> {

packages/plugin-ext/src/plugin/plugin-manager.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ export class PluginManagerExtImpl implements PluginManagerExt, PluginManager {
206206

207207
this.envExt.setQueryParameters(params.env.queryParams);
208208
this.envExt.setLanguage(params.env.language);
209-
this.envExt.setShell(params.env.shell);
209+
this.terminalService.$setShell(params.env.shell);
210210
this.envExt.setUIKind(params.env.uiKind);
211211
this.envExt.setApplicationName(params.env.appName);
212212
this.envExt.setAppHost(params.env.appHost);

packages/plugin-ext/src/plugin/terminal-ext.ts

+15
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
7171

7272
protected environmentVariableCollections: MultiKeyMap<string, EnvironmentVariableCollectionImpl> = new MultiKeyMap(2);
7373

74+
private shell: string;
75+
private readonly onDidChangeShellEmitter = new Emitter<string>();
76+
readonly onDidChangeShell: theia.Event<string> = this.onDidChangeShellEmitter.event;
77+
7478
constructor(rpc: RPCProtocol) {
7579
this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.TERMINAL_MAIN);
7680
}
@@ -79,6 +83,17 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
7983
return [...this._terminals.values()];
8084
}
8185

86+
get defaultShell(): string {
87+
return this.shell || '';
88+
}
89+
90+
async $setShell(shell: string): Promise<void> {
91+
if (this.shell !== shell) {
92+
this.shell = shell;
93+
this.onDidChangeShellEmitter.fire(shell);
94+
}
95+
}
96+
8297
createTerminal(
8398
nameOrOptions: TerminalOptions | PseudoTerminalOptions | ExtensionTerminalOptions | (string | undefined),
8499
shellPath?: string, shellArgs?: string[] | string

packages/plugin/src/theia.d.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -7720,6 +7720,12 @@ export module '@theia/plugin' {
77207720
*/
77217721
export const isTelemetryEnabled: boolean;
77227722

7723+
/**
7724+
* An {@link Event} which fires when the default shell changes. This fires with the new
7725+
* shell path.
7726+
*/
7727+
export const onDidChangeShell: Event<string>;
7728+
77237729
/**
77247730
* An {@link Event} which fires when the user enabled or disables telemetry.
77257731
* `true` if the user has enabled telemetry or `false` if the user has disabled telemetry.
@@ -7747,7 +7753,9 @@ export module '@theia/plugin' {
77477753
export const remoteName: string | undefined;
77487754

77497755
/**
7750-
* The detected default shell for the extension host.
7756+
* The detected default shell for the extension host, this is overridden by the
7757+
* `terminal.integrated.defaultProfile` setting for the extension host's platform. Note that in
7758+
* environments that do not support a shell the value is the empty string.
77517759
*/
77527760
export const shell: string;
77537761

packages/terminal/src/browser/shell-terminal-profile.ts

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ import { TerminalWidget, TerminalWidgetOptions } from './base/terminal-widget';
2020
import { TerminalProfile } from './terminal-profile-service';
2121

2222
export class ShellTerminalProfile implements TerminalProfile {
23+
24+
get shellPath(): string | undefined {
25+
return this.options.shellPath;
26+
}
27+
2328
constructor(protected readonly terminalService: TerminalService, protected readonly options: TerminalWidgetOptions) { }
2429

2530
async start(): Promise<TerminalWidget> {

packages/terminal/src/browser/terminal-profile-service.ts

+10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import { Emitter, Event } from '@theia/core';
1818
import { injectable } from '@theia/core/shared/inversify';
1919
import { TerminalWidget } from './base/terminal-widget';
20+
import { ShellTerminalProfile } from './shell-terminal-profile';
2021

2122
export const TerminalProfileService = Symbol('TerminalProfileService');
2223
export const ContributedTerminalProfileStore = Symbol('ContributedTerminalProfileStore');
@@ -36,6 +37,7 @@ export interface TerminalProfileService {
3637
getProfile(id: string): TerminalProfile | undefined
3738
readonly all: [string, TerminalProfile][];
3839
setDefaultProfile(id: string): void;
40+
readonly onDidChangeDefaultShell: Event<string>;
3941
readonly defaultProfile: TerminalProfile | undefined;
4042
}
4143

@@ -87,9 +89,11 @@ export class DefaultTerminalProfileService implements TerminalProfileService {
8789

8890
protected readonly onAddedEmitter: Emitter<string> = new Emitter();
8991
protected readonly onRemovedEmitter: Emitter<string> = new Emitter();
92+
protected readonly onDidChangeDefaultShellEmitter: Emitter<string> = new Emitter();
9093

9194
onAdded: Event<string> = this.onAddedEmitter.event;
9295
onRemoved: Event<string> = this.onRemovedEmitter.event;
96+
onDidChangeDefaultShell: Event<string> = this.onDidChangeDefaultShellEmitter.event;
9397

9498
constructor(...stores: TerminalProfileStore[]) {
9599
this.stores = stores;
@@ -144,6 +148,12 @@ export class DefaultTerminalProfileService implements TerminalProfileService {
144148
throw new Error(`Cannot set default to unknown profile '${id}' `);
145149
}
146150
this.defaultProfileIndex = this.order.indexOf(id);
151+
152+
if (profile instanceof ShellTerminalProfile && profile.shellPath) {
153+
this.onDidChangeDefaultShellEmitter.fire(profile.shellPath);
154+
} else {
155+
this.onDidChangeDefaultShellEmitter.fire('');
156+
}
147157
}
148158

149159
getProfile(id: string): TerminalProfile | undefined {

0 commit comments

Comments
 (0)