From 258ac38b0f95457f818a081c589e029a051c3de7 Mon Sep 17 00:00:00 2001 From: Philip Langer Date: Thu, 1 Sep 2022 18:44:43 +0200 Subject: [PATCH] vscode: Support TerminalOptions.hideFromUser * Add TerminalOptions.hideFromUser in theia.d.ts * Add TerminalWidget.hiddenFromUser * Fix cwd for created terminals with undefined cwd (default: workspace) If TerminalOptions.hideFromUser is set to true, the TerminalWidget will be hidden from any user-facing terminal lists until it is first explicitly shown to the user (see TerminalWidget.hiddenFromUser). As we don't open TerminalWidgets by default on `TerminalService.newTerminal` and as we don't have a global terminal view (in contrast to VS Code), we only need to hide it in the `TerminalQuickOpenService` really. Contributed on behalf of STMicroelectronics. Fixes https://github.com/eclipse-theia/theia/issues/11144 Change-Id: Ic1fdf2d5515d5b2fa8feb58b72218b93eeabda4d --- packages/plugin-ext/src/main/browser/terminal-main.ts | 3 ++- packages/plugin/src/theia.d.ts | 9 +++++++++ packages/terminal/src/browser/base/terminal-widget.ts | 8 ++++++++ .../terminal/src/browser/terminal-quick-open-service.ts | 4 ++-- packages/terminal/src/browser/terminal-widget-impl.ts | 9 +++++++++ 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/plugin-ext/src/main/browser/terminal-main.ts b/packages/plugin-ext/src/main/browser/terminal-main.ts index aafec73f4ae7f..a38f173475bf0 100644 --- a/packages/plugin-ext/src/main/browser/terminal-main.ts +++ b/packages/plugin-ext/src/main/browser/terminal-main.ts @@ -123,12 +123,13 @@ export class TerminalServiceMainImpl implements TerminalServiceMain, Disposable title: options.name, shellPath: options.shellPath, shellArgs: options.shellArgs, - cwd: new URI(options.cwd), + cwd: options.cwd ? new URI(options.cwd) : undefined, env: options.env, strictEnv: options.strictEnv, destroyTermOnClose: true, useServerTitle: false, attributes: options.attributes, + hideFromUser: options.hideFromUser, isPseudoTerminal }); if (options.message) { diff --git a/packages/plugin/src/theia.d.ts b/packages/plugin/src/theia.d.ts index 976fc4ee18b30..d7a4a35162849 100644 --- a/packages/plugin/src/theia.d.ts +++ b/packages/plugin/src/theia.d.ts @@ -3006,6 +3006,15 @@ export module '@theia/plugin' { */ strictEnv?: boolean; + /** + * When enabled the terminal will run the process as normal but not be surfaced to the user + * until `Terminal.show` is called. The typical usage for this is when you need to run + * something that may need interactivity but only want to tell the user about it when + * interaction is needed. Note that the terminals will still be exposed to all extensions + * as normal. + */ + hideFromUser?: boolean; + /** * A message to write to the terminal on first launch. Note that this is not sent to the * process, but rather written directly to the terminal. This supports escape sequences such diff --git a/packages/terminal/src/browser/base/terminal-widget.ts b/packages/terminal/src/browser/base/terminal-widget.ts index ac4a6eb04143f..d283f1aa06c81 100644 --- a/packages/terminal/src/browser/base/terminal-widget.ts +++ b/packages/terminal/src/browser/base/terminal-widget.ts @@ -51,6 +51,9 @@ export abstract class TerminalWidget extends BaseWidget { abstract readonly exitStatus: TerminalExitStatus | undefined; + /** Terminal widget can be hidden from users until explicitly shown once. */ + abstract readonly hiddenFromUser: boolean; + /** The last CWD assigned to the terminal, useful when attempting getCwdURI on a task terminal fails */ lastCwd: URI; @@ -202,4 +205,9 @@ export interface TerminalWidgetOptions { * Terminal kind that indicates whether a terminal is created by a user or by some extension for a user */ readonly kind?: 'user' | string; + + /** + * When enabled the terminal will run the process as normal but not be surfaced to the user until `Terminal.show` is called. + */ + readonly hideFromUser?: boolean; } diff --git a/packages/terminal/src/browser/terminal-quick-open-service.ts b/packages/terminal/src/browser/terminal-quick-open-service.ts index cb8d6e5cf1792..5f1e0e6378b6f 100644 --- a/packages/terminal/src/browser/terminal-quick-open-service.ts +++ b/packages/terminal/src/browser/terminal-quick-open-service.ts @@ -51,8 +51,8 @@ export class TerminalQuickOpenService implements QuickAccessProvider { async getPicks(filter: string, token: CancellationToken): Promise { const items: QuickPickItem[] = []; - // Get the sorted list of currently opened terminal widgets - const widgets: TerminalWidget[] = this.terminalService.all + // Get the sorted list of currently opened terminal widgets that aren't hidden from users + const widgets: TerminalWidget[] = this.terminalService.all.filter(widget => !widget.hiddenFromUser) .sort((a: TerminalWidget, b: TerminalWidget) => this.compareItems(a, b)); for (const widget of widgets) { diff --git a/packages/terminal/src/browser/terminal-widget-impl.ts b/packages/terminal/src/browser/terminal-widget-impl.ts index 9bd70ae74304b..742001aa970fa 100644 --- a/packages/terminal/src/browser/terminal-widget-impl.ts +++ b/packages/terminal/src/browser/terminal-widget-impl.ts @@ -64,6 +64,7 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget protected hoverMessage: HTMLDivElement; protected lastTouchEnd: TouchEvent | undefined; protected isAttachedCloseListener: boolean = false; + protected shown = false; override lastCwd = new URI(); @inject(WorkspaceService) protected readonly workspaceService: WorkspaceService; @@ -349,6 +350,13 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget return this.lastTouchEnd; } + get hiddenFromUser(): boolean { + if (this.shown) { + return false; + } + return this.options.hideFromUser ?? false; + } + onDispose(onDispose: () => void): void { this.toDispose.push(Disposable.create(onDispose)); } @@ -461,6 +469,7 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget protected override onAfterShow(msg: Message): void { super.onAfterShow(msg); this.update(); + this.shown = true; } protected override onAfterAttach(msg: Message): void { Widget.attach(this.searchBox, this.node);