diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index ccb32e5246d..ef8b3ba3d96 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri'; import { FindReplaceState } from 'vs/editor/contrib/find/findState'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource, TerminalShellType, IExtensionTerminalProfile, TerminalLocation, ProcessPropertyType, IProcessPropertyMap } from 'vs/platform/terminal/common/terminal'; -import { ICommandTracker, INavigationMode, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalFont, ITerminalBackend, ITerminalProcessExtHostProxy, IRegisterContributedProfileArgs, IShellIntegration, ITerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ICommandTracker, INavigationMode, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalFont, ITerminalBackend, ITerminalProcessExtHostProxy, IRegisterContributedProfileArgs, IShellIntegration } from 'vs/workbench/contrib/terminal/common/terminal'; import { ITerminalStatusList } from 'vs/workbench/contrib/terminal/browser/terminalStatusList'; import { Orientation } from 'vs/base/browser/ui/splitview/splitview'; import { IEditableData } from 'vs/workbench/common/views'; @@ -17,6 +17,7 @@ import { DeserializedTerminalEditorInput } from 'vs/workbench/contrib/terminal/b import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput'; import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn'; import { IKeyMods } from 'vs/platform/quickinput/common/quickInput'; +import { ITerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/capabilities/capabilities'; export const ITerminalService = createDecorator('terminalService'); export const ITerminalEditorService = createDecorator('terminalEditorService'); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 3318fcab31c..04dd56184e3 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1175,7 +1175,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { protected _createProcessManager(): TerminalProcessManager { const processManager = this._instantiationService.createInstance(TerminalProcessManager, this._instanceId, this._configHelper); - this.capabilities.addCapabilityStore(processManager.capabilities); + this.capabilities.add(processManager.capabilities); processManager.onProcessReady(async (e) => { this._onProcessIdReady.fire(this); this._initialCwd = await this.getInitialCwd(); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index bd0be54f574..fbe8a148f51 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -29,6 +29,7 @@ import { IProcessEnvironment, isMacintosh, isWindows, OperatingSystem, OS } from import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/capabilities/terminalCapabilityStore'; +import { NaiveCwdDetectionCapability } from 'vs/workbench/contrib/terminal/common/capabilities/naiveCwdDetectionCapability'; /** The amount of time to consider terminal errors to be related to the launch */ const LAUNCHING_DURATION = 500; @@ -103,11 +104,6 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce private readonly _onProcessExit = this._register(new Emitter()); readonly onProcessExit = this._onProcessExit.event; - private readonly _onCapabilityDisabled = new Emitter(); - readonly onCapabilityDisabled = this._onCapabilityDisabled.event; - private readonly _onCapabilityEnabled = new Emitter(); - readonly onCapabilityEnabled = this._onCapabilityEnabled.event; - get persistentProcessId(): number | undefined { return this._process?.id; } get shouldPersist(): boolean { return this._process ? this._process.shouldPersist : false; } get hasWrittenData(): boolean { return this._hasWrittenData; } @@ -296,7 +292,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce // Add any capabilities inherit to the backend if (this.os === OperatingSystem.Linux || this.os === OperatingSystem.Macintosh) { - this.capabilities.addCapability(TerminalCapability.NaiveCwdDetection); + this.capabilities.add(TerminalCapability.NaiveCwdDetection, new NaiveCwdDetectionCapability()); } this._dataFilter.newProcess(this._process, reset); diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/shellIntegrationAddon.ts b/src/vs/workbench/contrib/terminal/browser/xterm/shellIntegrationAddon.ts index 65dc638b52a..f55feb3825a 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/shellIntegrationAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/shellIntegrationAddon.ts @@ -9,6 +9,7 @@ import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { TerminalCapability } from 'vs/platform/terminal/common/terminal'; import { TerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/capabilities/terminalCapabilityStore'; +import { CommandDetectionCapability } from 'vs/workbench/contrib/terminal/common/capabilities/commandDetectionCapability'; /** * Shell integration is a feature that enhances the terminal's understanding of what's happening @@ -104,7 +105,7 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati type = ShellIntegrationInteraction.CommandFinished; break; case ShellIntegrationOscPt.EnableShellIntegration: - this.capabilities.addCapability(TerminalCapability.CommandDetection); + this.capabilities.add(TerminalCapability.CommandDetection, new CommandDetectionCapability()); return true; default: return false; diff --git a/src/vs/workbench/contrib/terminal/common/capabilities/capabilities.d.ts b/src/vs/workbench/contrib/terminal/common/capabilities/capabilities.d.ts new file mode 100644 index 00000000000..83cf5aa8b09 --- /dev/null +++ b/src/vs/workbench/contrib/terminal/common/capabilities/capabilities.d.ts @@ -0,0 +1,53 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from 'vs/base/common/event'; +import { TerminalCapability } from 'vs/platform/terminal/common/terminal'; +import { CommandDetectionCapability } from 'vs/workbench/contrib/terminal/common/capabilities/commandDetectionCapability'; +import { CwdDetectionCapability } from 'vs/workbench/contrib/terminal/common/capabilities/cwdDetectionCapability'; +import { NaiveCwdDetectionCapability } from 'vs/workbench/contrib/terminal/common/capabilities/naiveCwdDetectionCapability'; +import { PartialCommandDetectionCapability } from 'vs/workbench/contrib/terminal/common/capabilities/partialCommandDetectionCapability'; + +/** + * An object that keeps track of additional capabilities and their implementations for features that + * are not available for all terminals. + */ +export interface ITerminalCapabilityStore { + /** + * An iterable of all capabilities in the store. + */ + readonly items: IterableIterator; + + /** + * Fired when a capability is added. + */ + readonly onDidAddCapability: Event; + + /** + * Fired when a capability is removed. + */ + readonly onDidRemoveCapability: Event; + + /** + * Gets whether the capability exists in the store. + */ + has(capability: TerminalCapability): boolean; + + /** + * Gets the implementation of a capability if it has been added to the store. + */ + get(capability: T): ITerminalCapabilityImplMap[T] | undefined; +} + +/** + * Maps capability types to their implementation, enabling strongly typed fetching of + * implementations. + */ +export interface ITerminalCapabilityImplMap { + [TerminalCapability.CwdDetection]: InstanceType; + [TerminalCapability.CommandDetection]: InstanceType; + [TerminalCapability.NaiveCwdDetection]: InstanceType; + [TerminalCapability.PartialCommandDetection]: InstanceType; +} diff --git a/src/vs/workbench/contrib/terminal/common/capabilities/commandDetectionCapability.ts b/src/vs/workbench/contrib/terminal/common/capabilities/commandDetectionCapability.ts new file mode 100644 index 00000000000..24781f20aa8 --- /dev/null +++ b/src/vs/workbench/contrib/terminal/common/capabilities/commandDetectionCapability.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { TerminalCapability } from 'vs/platform/terminal/common/terminal'; + +export class CommandDetectionCapability { + readonly type = TerminalCapability.CommandDetection; + + // TODO: Encapsulate the functionality the capability brings here +} diff --git a/src/vs/workbench/contrib/terminal/common/capabilities/cwdDetectionCapability.ts b/src/vs/workbench/contrib/terminal/common/capabilities/cwdDetectionCapability.ts new file mode 100644 index 00000000000..496485d1416 --- /dev/null +++ b/src/vs/workbench/contrib/terminal/common/capabilities/cwdDetectionCapability.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { TerminalCapability } from 'vs/platform/terminal/common/terminal'; + +export class CwdDetectionCapability { + readonly type = TerminalCapability.CwdDetection; + + // TODO: Encapsulate the functionality the capability brings here +} diff --git a/src/vs/workbench/contrib/terminal/common/capabilities/naiveCwdDetectionCapability.ts b/src/vs/workbench/contrib/terminal/common/capabilities/naiveCwdDetectionCapability.ts new file mode 100644 index 00000000000..2a1c0bd0c4c --- /dev/null +++ b/src/vs/workbench/contrib/terminal/common/capabilities/naiveCwdDetectionCapability.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { TerminalCapability } from 'vs/platform/terminal/common/terminal'; + +export class NaiveCwdDetectionCapability { + readonly type = TerminalCapability.NaiveCwdDetection; + + // TODO: Encapsulate the functionality the capability brings here +} diff --git a/src/vs/workbench/contrib/terminal/common/capabilities/partialCommandDetectionCapability.ts b/src/vs/workbench/contrib/terminal/common/capabilities/partialCommandDetectionCapability.ts new file mode 100644 index 00000000000..66b6476c6a9 --- /dev/null +++ b/src/vs/workbench/contrib/terminal/common/capabilities/partialCommandDetectionCapability.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { TerminalCapability } from 'vs/platform/terminal/common/terminal'; + +export class PartialCommandDetectionCapability { + readonly type = TerminalCapability.CwdDetection; + + // TODO: Encapsulate the functionality the capability brings here +} diff --git a/src/vs/workbench/contrib/terminal/common/capabilities/terminalCapabilityStore.ts b/src/vs/workbench/contrib/terminal/common/capabilities/terminalCapabilityStore.ts index d28906eedae..14dd644ba17 100644 --- a/src/vs/workbench/contrib/terminal/common/capabilities/terminalCapabilityStore.ts +++ b/src/vs/workbench/contrib/terminal/common/capabilities/terminalCapabilityStore.ts @@ -6,32 +6,40 @@ import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { TerminalCapability } from 'vs/platform/terminal/common/terminal'; -import { ITerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalCapabilityImplMap, ITerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/capabilities/capabilities'; export class TerminalCapabilityStore extends Disposable implements ITerminalCapabilityStore { - readonly items: TerminalCapability[] = []; + private _map: Map = new Map(); private readonly _onDidRemoveCapability = this._register(new Emitter()); readonly onDidRemoveCapability = this._onDidRemoveCapability.event; private readonly _onDidAddCapability = this._register(new Emitter()); readonly onDidAddCapability = this._onDidAddCapability.event; - addCapability(capability: TerminalCapability) { - this.items.push(capability); + get items(): IterableIterator { + return this._map.keys(); + } + + add(capability: T, impl: ITerminalCapabilityImplMap[T]) { + this._map.set(capability, impl); this._onDidAddCapability.fire(capability); } - removeCapability(capability: TerminalCapability) { - const index = this.items.indexOf(capability); - if (index === -1) { + get(capability: T): ITerminalCapabilityImplMap[T] | undefined { + // HACK: This isn't totally safe since the Map key and value are not connected + return this._map.get(capability) as ITerminalCapabilityImplMap[T] | undefined; + } + + remove(capability: TerminalCapability) { + if (!this._map.has(capability)) { return; } - this.items.splice(index, 1); + this._map.delete(capability); this._onDidRemoveCapability.fire(capability); } has(capability: TerminalCapability) { - return this.items.includes(capability); + return this._map.has(capability); } } @@ -43,18 +51,40 @@ export class TerminalCapabilityStoreMultiplexer extends Disposable implements IT private readonly _onDidAddCapability = this._register(new Emitter()); readonly onDidAddCapability = this._onDidAddCapability.event; - get items(): readonly TerminalCapability[] { - return this._stores.reduce((p, c) => { - p.push(...c.items); - return p; - }, []); + get items(): IterableIterator { + return this._items(); } - has(capability: TerminalCapability) { - return this.items.includes(capability); + private *_items(): IterableIterator { + for (const store of this._stores) { + for (const c of store.items) { + yield c; + } + } } - addCapabilityStore(store: ITerminalCapabilityStore) { + has(capability: TerminalCapability): boolean { + for (const store of this._stores) { + for (const c of store.items) { + if (c === capability) { + return true; + } + } + } + return false; + } + + get(capability: T): ITerminalCapabilityImplMap[T] | undefined { + for (const store of this._stores) { + const c = store.get(capability); + if (c) { + return c; + } + } + return undefined; + } + + add(store: ITerminalCapabilityStore) { this._stores.push(store); for (const capability of store.items) { this._onDidAddCapability.fire(capability); diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index a84a8276956..2fc6bc76d02 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -8,12 +8,13 @@ import { Event } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform'; import { IExtensionPointDescriptor } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, TerminalLocationString, IProcessProperty, TitleEventSource, ProcessPropertyType, IFixedTerminalDimensions, IExtensionTerminalProfile, ICreateContributedTerminalProfileOptions, IProcessPropertyMap, ITerminalEnvironment, TerminalCommand, TerminalCapability } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, TerminalLocationString, IProcessProperty, TitleEventSource, ProcessPropertyType, IFixedTerminalDimensions, IExtensionTerminalProfile, ICreateContributedTerminalProfileOptions, IProcessPropertyMap, ITerminalEnvironment, TerminalCommand } from 'vs/platform/terminal/common/terminal'; import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { URI } from 'vs/base/common/uri'; import { IProcessDetails } from 'vs/platform/terminal/common/terminalProcess'; import { Registry } from 'vs/platform/registry/common/platform'; +import { ITerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/capabilities/capabilities'; export const TERMINAL_VIEW_ID = 'terminal'; @@ -403,18 +404,6 @@ export interface ITerminalProcessManager extends IDisposable { updateProperty(property: T, value: IProcessPropertyMap[T]): void; } -export interface ITerminalCapabilityStore { - readonly items: readonly TerminalCapability[]; - readonly onDidRemoveCapability: Event; - readonly onDidAddCapability: Event; - has(capability: TerminalCapability): boolean; -} - -export interface ITerminalCapabilityStoreController { - addCapability(capability: TerminalCapability): void; - removeCapability(capability: TerminalCapability): void; -} - export const enum ProcessState { // The process has not been initialized yet. Uninitialized = 1, diff --git a/src/vs/workbench/contrib/terminal/test/browser/terminalInstance.test.ts b/src/vs/workbench/contrib/terminal/test/browser/terminalInstance.test.ts index b4833a3c525..11e10d31475 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/terminalInstance.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/terminalInstance.test.ts @@ -22,7 +22,7 @@ import { TerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/ca function createInstance(partial?: Partial): Pick { const capabilities = new TerminalCapabilityStore(); if (!isWindows) { - capabilities.addCapability(TerminalCapability.NaiveCwdDetection); + capabilities.add(TerminalCapability.NaiveCwdDetection, null!); } return { shellLaunchConfig: {}, @@ -169,7 +169,7 @@ suite('Workbench - TerminalInstance', () => { instantiationService.stub(IWorkspaceContextService, new TestContextService()); capabilities = new TerminalCapabilityStore(); if (!isWindows) { - capabilities.addCapability(TerminalCapability.NaiveCwdDetection); + capabilities.add(TerminalCapability.NaiveCwdDetection, null!); } const ROOT_1_URI = getUri(ROOT_1); diff --git a/src/vs/workbench/contrib/terminal/test/common/capabilities/terminalCapabilityStore.test.ts b/src/vs/workbench/contrib/terminal/test/common/capabilities/terminalCapabilityStore.test.ts index eef4165cdc6..f6ac406206f 100644 --- a/src/vs/workbench/contrib/terminal/test/common/capabilities/terminalCapabilityStore.test.ts +++ b/src/vs/workbench/contrib/terminal/test/common/capabilities/terminalCapabilityStore.test.ts @@ -24,31 +24,31 @@ suite('TerminalCapabilityStore', () => { test('should fire events when capabilities are added', () => { assertEvents(addEvents, []); - store.addCapability(TerminalCapability.CwdDetection); + store.add(TerminalCapability.CwdDetection, null!); assertEvents(addEvents, [TerminalCapability.CwdDetection]); }); test('should fire events when capabilities are removed', async () => { assertEvents(removeEvents, []); - store.addCapability(TerminalCapability.CwdDetection); + store.add(TerminalCapability.CwdDetection, null!); assertEvents(removeEvents, []); - store.removeCapability(TerminalCapability.CwdDetection); + store.remove(TerminalCapability.CwdDetection); assertEvents(removeEvents, [TerminalCapability.CwdDetection]); }); test('has should return whether a capability is present', () => { deepStrictEqual(store.has(TerminalCapability.CwdDetection), false); - store.addCapability(TerminalCapability.CwdDetection); + store.add(TerminalCapability.CwdDetection, null!); deepStrictEqual(store.has(TerminalCapability.CwdDetection), true); - store.removeCapability(TerminalCapability.CwdDetection); + store.remove(TerminalCapability.CwdDetection); deepStrictEqual(store.has(TerminalCapability.CwdDetection), false); }); test('items should reflect current state', () => { - deepStrictEqual(store.items, []); - store.addCapability(TerminalCapability.CwdDetection); - deepStrictEqual(store.items, [TerminalCapability.CwdDetection]); - store.addCapability(TerminalCapability.NaiveCwdDetection); - deepStrictEqual(store.items, [TerminalCapability.CwdDetection, TerminalCapability.NaiveCwdDetection]); - store.removeCapability(TerminalCapability.CwdDetection); - deepStrictEqual(store.items, [TerminalCapability.NaiveCwdDetection]); + deepStrictEqual(Array.from(store.items), []); + store.add(TerminalCapability.CwdDetection, null!); + deepStrictEqual(Array.from(store.items), [TerminalCapability.CwdDetection]); + store.add(TerminalCapability.NaiveCwdDetection, null!); + deepStrictEqual(Array.from(store.items), [TerminalCapability.CwdDetection, TerminalCapability.NaiveCwdDetection]); + store.remove(TerminalCapability.CwdDetection); + deepStrictEqual(Array.from(store.items), [TerminalCapability.NaiveCwdDetection]); }); }); @@ -73,52 +73,52 @@ suite('TerminalCapabilityStoreMultiplexer', () => { test('should fire events when capabilities are enabled', async () => { assertEvents(addEvents, []); - multiplexer.addCapabilityStore(store1); - multiplexer.addCapabilityStore(store2); - store1.addCapability(TerminalCapability.CwdDetection); + multiplexer.add(store1); + multiplexer.add(store2); + store1.add(TerminalCapability.CwdDetection, null!); assertEvents(addEvents, [TerminalCapability.CwdDetection]); - store2.addCapability(TerminalCapability.NaiveCwdDetection); + store2.add(TerminalCapability.NaiveCwdDetection, null!); assertEvents(addEvents, [TerminalCapability.NaiveCwdDetection]); }); test('should fire events when capabilities are disabled', async () => { assertEvents(removeEvents, []); - multiplexer.addCapabilityStore(store1); - multiplexer.addCapabilityStore(store2); - store1.addCapability(TerminalCapability.CwdDetection); - store2.addCapability(TerminalCapability.NaiveCwdDetection); + multiplexer.add(store1); + multiplexer.add(store2); + store1.add(TerminalCapability.CwdDetection, null!); + store2.add(TerminalCapability.NaiveCwdDetection, null!); assertEvents(removeEvents, []); - store1.removeCapability(TerminalCapability.CwdDetection); + store1.remove(TerminalCapability.CwdDetection); assertEvents(removeEvents, [TerminalCapability.CwdDetection]); - store2.removeCapability(TerminalCapability.NaiveCwdDetection); + store2.remove(TerminalCapability.NaiveCwdDetection); assertEvents(removeEvents, [TerminalCapability.NaiveCwdDetection]); }); test('should fire events when stores are added', async () => { assertEvents(addEvents, []); - store1.addCapability(TerminalCapability.CwdDetection); + store1.add(TerminalCapability.CwdDetection, null!); assertEvents(addEvents, []); - store2.addCapability(TerminalCapability.NaiveCwdDetection); - multiplexer.addCapabilityStore(store1); - multiplexer.addCapabilityStore(store2); + store2.add(TerminalCapability.NaiveCwdDetection, null!); + multiplexer.add(store1); + multiplexer.add(store2); assertEvents(addEvents, [TerminalCapability.CwdDetection, TerminalCapability.NaiveCwdDetection]); }); test('items should return items from all stores', () => { - deepStrictEqual(multiplexer.items, []); - multiplexer.addCapabilityStore(store1); - multiplexer.addCapabilityStore(store2); - store1.addCapability(TerminalCapability.CwdDetection); - deepStrictEqual(multiplexer.items, [TerminalCapability.CwdDetection]); - store1.addCapability(TerminalCapability.CommandDetection); - store2.addCapability(TerminalCapability.NaiveCwdDetection); - deepStrictEqual(multiplexer.items, [TerminalCapability.CwdDetection, TerminalCapability.CommandDetection, TerminalCapability.NaiveCwdDetection]); - store2.removeCapability(TerminalCapability.NaiveCwdDetection); - deepStrictEqual(multiplexer.items, [TerminalCapability.CwdDetection, TerminalCapability.CommandDetection]); + deepStrictEqual(Array.from(multiplexer.items).sort(), [].sort()); + multiplexer.add(store1); + multiplexer.add(store2); + store1.add(TerminalCapability.CwdDetection, null!); + deepStrictEqual(Array.from(multiplexer.items).sort(), [TerminalCapability.CwdDetection].sort()); + store1.add(TerminalCapability.CommandDetection, null!); + store2.add(TerminalCapability.NaiveCwdDetection, null!); + deepStrictEqual(Array.from(multiplexer.items).sort(), [TerminalCapability.CwdDetection, TerminalCapability.CommandDetection, TerminalCapability.NaiveCwdDetection].sort()); + store2.remove(TerminalCapability.NaiveCwdDetection); + deepStrictEqual(Array.from(multiplexer.items).sort(), [TerminalCapability.CwdDetection, TerminalCapability.CommandDetection].sort()); }); test('has should return whether a capability is present', () => { deepStrictEqual(multiplexer.has(TerminalCapability.CwdDetection), false); - multiplexer.addCapabilityStore(store1); - store1.addCapability(TerminalCapability.CwdDetection); + multiplexer.add(store1); + store1.add(TerminalCapability.CwdDetection, null!); deepStrictEqual(multiplexer.has(TerminalCapability.CwdDetection), true); - store1.removeCapability(TerminalCapability.CwdDetection); + store1.remove(TerminalCapability.CwdDetection); deepStrictEqual(multiplexer.has(TerminalCapability.CwdDetection), false); }); });