From 757c5f54c90bfde5406d0436df3229cb8e5d12bc Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Wed, 22 Jun 2022 00:51:33 -0500 Subject: [PATCH] Proposal TerminalExitStatus --- src/vs/platform/terminal/common/terminal.ts | 5 +++ .../api/browser/mainThreadTerminalService.ts | 2 +- .../workbench/api/common/extHost.api.impl.ts | 1 + .../workbench/api/common/extHost.protocol.ts | 4 +-- .../api/common/extHostTerminalService.ts | 10 +++--- src/vs/workbench/api/common/extHostTypes.ts | 5 +++ .../contrib/terminal/browser/terminal.ts | 11 +++--- .../terminal/browser/terminalInstance.ts | 10 +++--- .../terminal/browser/terminalQuickAccess.ts | 5 +-- .../terminal/browser/terminalService.ts | 2 +- .../common/extensionsApiProposals.ts | 1 + .../vscode.proposed.terminalExitReason.d.ts | 35 +++++++++++++++++++ 12 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 src/vscode-dts/vscode.proposed.terminalExitReason.d.ts diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index fd5f4734492..e3e5042e131 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -790,3 +790,8 @@ export interface IShellIntegration { capabilities: ITerminalCapabilityStore; deserialize(serialized: ISerializedCommandDetectionCapability): void; } + +export enum TerminalExitReason { + Unknown = 0, + Shutdown = 1 +} diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index b280f677abe..f6421747044 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -253,7 +253,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } private _onTerminalDisposed(terminalInstance: ITerminalInstance): void { - this._proxy.$acceptTerminalClosed(terminalInstance.instanceId, terminalInstance.exitCode); + this._proxy.$acceptTerminalClosed(terminalInstance.instanceId, terminalInstance.exitCode, terminalInstance.exitReason); } private _onTerminalOpened(terminalInstance: ITerminalInstance): void { diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index b438fb90ead..93c514d238f 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1273,6 +1273,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I TaskPanelKind: extHostTypes.TaskPanelKind, TaskRevealKind: extHostTypes.TaskRevealKind, TaskScope: extHostTypes.TaskScope, + TerminalExitReason: extHostTypes.TerminalExitReason, TerminalLink: extHostTypes.TerminalLink, TerminalLocation: extHostTypes.TerminalLocation, TerminalProfile: extHostTypes.TerminalProfile, diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 5af7bb15f92..6b6fd263b04 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -40,7 +40,7 @@ import * as quickInput from 'vs/platform/quickinput/common/quickInput'; import { IRemoteConnectionData, TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; -import { ICreateContributedTerminalProfileOptions, IProcessProperty, IShellLaunchConfigDto, ITerminalEnvironment, ITerminalLaunchError, ITerminalProfile, TerminalLocation } from 'vs/platform/terminal/common/terminal'; +import { ICreateContributedTerminalProfileOptions, IProcessProperty, IShellLaunchConfigDto, ITerminalEnvironment, ITerminalLaunchError, ITerminalProfile, TerminalExitReason, TerminalLocation } from 'vs/platform/terminal/common/terminal'; import { ThemeColor, ThemeIcon } from 'vs/platform/theme/common/themeService'; import { ProvidedPortAttributes, TunnelCreationOptions, TunnelOptions, TunnelPrivacyId, TunnelProviderFeatures } from 'vs/platform/tunnel/common/tunnel'; import { WorkspaceTrustRequestOptions } from 'vs/platform/workspace/common/workspaceTrust'; @@ -1817,7 +1817,7 @@ export interface ITerminalDimensionsDto { } export interface ExtHostTerminalServiceShape { - $acceptTerminalClosed(id: number, exitCode: number | undefined): void; + $acceptTerminalClosed(id: number, exitCode: number | undefined, exitReason: TerminalExitReason | undefined): void; $acceptTerminalOpened(id: number, extHostTerminalId: string | undefined, name: string, shellLaunchConfig: IShellLaunchConfigDto): void; $acceptActiveTerminalChanged(id: number | null): void; $acceptTerminalProcessId(id: number, processId: number): void; diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index f27f16dca52..05631f9eaef 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -10,7 +10,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { URI } from 'vs/base/common/uri'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle'; -import { Disposable as VSCodeDisposable, EnvironmentVariableMutatorType } from './extHostTypes'; +import { Disposable as VSCodeDisposable, EnvironmentVariableMutatorType, TerminalExitReason } from './extHostTypes'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { localize } from 'vs/nls'; import { NotSupportedError } from 'vs/base/common/errors'; @@ -203,8 +203,8 @@ export class ExtHostTerminal { this._name = name; } - public setExitCode(code: number | undefined) { - this._exitStatus = Object.freeze({ code }); + public setExitCode(code: number | undefined, reason: TerminalExitReason | undefined) { + this._exitStatus = Object.freeze({ code, reason }); } public setDimensions(cols: number, rows: number): boolean { @@ -500,11 +500,11 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I } } - public async $acceptTerminalClosed(id: number, exitCode: number | undefined): Promise { + public async $acceptTerminalClosed(id: number, exitCode: number | undefined, exitReason: TerminalExitReason | undefined): Promise { const index = this._getTerminalObjectIndexById(this._terminals, id); if (index !== null) { const terminal = this._terminals.splice(index, 1)[0]; - terminal.setExitCode(exitCode); + terminal.setExitCode(exitCode, exitReason); this._onDidCloseTerminal.fire(terminal.value); } } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index ce30f68d26e..745e7761ceb 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -1854,6 +1854,11 @@ export enum SourceControlInputBoxValidationType { Information = 2 } +export enum TerminalExitReason { + Unknown = 0, + Shutdown = 1 +} + export class TerminalLink implements vscode.TerminalLink { constructor( public startIndex: number, diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index ddaf6f211db..ea2e9200ecc 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -11,7 +11,7 @@ import { FindReplaceState } from 'vs/editor/contrib/find/browser/findState'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IKeyMods } from 'vs/platform/quickinput/common/quickInput'; import { ITerminalCapabilityStore, ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities'; -import { IExtensionTerminalProfile, IProcessPropertyMap, IShellIntegration, IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, ProcessPropertyType, TerminalIcon, TerminalLocation, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal'; +import { IExtensionTerminalProfile, IProcessPropertyMap, IShellIntegration, IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, ProcessPropertyType, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { IGenericMarkProperties } from 'vs/platform/terminal/common/terminalProcess'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; @@ -567,6 +567,8 @@ export interface ITerminalInstance { readonly exitCode: number | undefined; + readonly exitReason: TerminalExitReason | undefined; + readonly areLinksReady: boolean; /** @@ -651,12 +653,9 @@ export interface ITerminalInstance { /** * Dispose the terminal instance, removing it from the panel/service and freeing up resources. * - * @param immediate Whether the kill should be immediate or not. Immediate should only be used - * when VS Code is shutting down or in cases where the terminal dispose was user initiated. - * The immediate===false exists to cover an edge case where the final output of the terminal can - * get cut off. If immediate kill any terminal processes immediately. + * @param isShutdown Whether the kill was triggered by lifecycle shutdown */ - dispose(immediate?: boolean): void; + dispose(isShutdown?: boolean): void; /** * Inform the process that the terminal is now detached. diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 4401c00feeb..1d6005c587e 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -46,7 +46,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; import { TerminalCapabilityStoreMultiplexer } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore'; -import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessPropertyMap, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, PosixShellType, ProcessPropertyType, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalSettingId, TerminalShellType, TitleEventSource, WindowsShellType } from 'vs/platform/terminal/common/terminal'; import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment'; import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry'; import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platform/theme/common/themeService'; @@ -170,6 +170,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _isVisible: boolean; private _isDisposed: boolean; private _exitCode: number | undefined; + private _exitReason: TerminalExitReason | undefined; private _skipTerminalCommands: string[]; private _shellType: TerminalShellType; private _title: string = ''; @@ -275,6 +276,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { get areLinksReady(): boolean { return this._areLinksReady; } get initialDataEvents(): string[] | undefined { return this._initialDataEvents; } get exitCode(): number | undefined { return this._exitCode; } + get exitReason(): TerminalExitReason | undefined { return this._exitReason; } get hadFocusOnExit(): boolean { return this._hadFocusOnExit; } get isTitleSetByProcess(): boolean { return !!this._messageTitleDisposable; } get shellLaunchConfig(): IShellLaunchConfig { return this._shellLaunchConfig; } @@ -1305,8 +1307,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { return confirmation.confirmed; } - - override dispose(immediate?: boolean): void { + override dispose(isShutdown?: boolean): void { if (this._isDisposed) { return; } @@ -1345,7 +1346,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._pressAnyKeyToCloseListener = undefined; } - this._processManager.dispose(immediate); + this._exitReason = isShutdown ? TerminalExitReason.Shutdown : TerminalExitReason.Unknown; + this._processManager.dispose(); // Process manager dispose/shutdown doesn't fire process exit, trigger with undefined if it // hasn't happened yet this._onProcessExit(undefined); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts b/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts index af7953a3268..11af476412f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalQuickAccess.ts @@ -7,7 +7,7 @@ import { localize } from 'vs/nls'; import { IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { IPickerQuickAccessItem, PickerQuickAccessProvider, TriggerAction } from 'vs/platform/quickinput/browser/pickerQuickAccess'; import { matchesFuzzy } from 'vs/base/common/filters'; -import { ITerminalEditorService, ITerminalGroupService, ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import { IThemeService, ThemeIcon } from 'vs/platform/theme/common/themeService'; @@ -24,6 +24,7 @@ export class TerminalQuickAccessProvider extends PickerQuickAccessProvider