提交 ed9e7241 编写于 作者: D Daniel Imms

Move single ext collection updates across

上级 8ee60554
...@@ -13,6 +13,8 @@ import { ITerminalInstanceService, ITerminalService, ITerminalInstance, ITermina ...@@ -13,6 +13,8 @@ import { ITerminalInstanceService, ITerminalService, ITerminalInstance, ITermina
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TerminalDataBufferer } from 'vs/workbench/contrib/terminal/common/terminalDataBuffering'; import { TerminalDataBufferer } from 'vs/workbench/contrib/terminal/common/terminalDataBuffering';
import { IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { EnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableService';
@extHostNamedCustomer(MainContext.MainThreadTerminalService) @extHostNamedCustomer(MainContext.MainThreadTerminalService)
export class MainThreadTerminalService implements MainThreadTerminalServiceShape { export class MainThreadTerminalService implements MainThreadTerminalServiceShape {
...@@ -29,8 +31,9 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape ...@@ -29,8 +31,9 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
extHostContext: IExtHostContext, extHostContext: IExtHostContext,
@ITerminalService private readonly _terminalService: ITerminalService, @ITerminalService private readonly _terminalService: ITerminalService,
@ITerminalInstanceService readonly terminalInstanceService: ITerminalInstanceService, @ITerminalInstanceService readonly terminalInstanceService: ITerminalInstanceService,
@IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService, @IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService,
@IInstantiationService private readonly _instantiationService: IInstantiationService, @IInstantiationService private readonly _instantiationService: IInstantiationService,
@IEnvironmentVariableService private readonly _environmentVariableService: IEnvironmentVariableService,
) { ) {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService); this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService);
this._remoteAuthority = extHostContext.remoteAuthority; this._remoteAuthority = extHostContext.remoteAuthority;
...@@ -347,9 +350,13 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape ...@@ -347,9 +350,13 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
return terminal; return terminal;
} }
$updateEnvironmentVariableCollections(collections: IEnvironmentVariableCollectionDto[]): void { $setEnvironmentVariableCollection(extensionIdentifier: string, collection: IEnvironmentVariableCollectionDto | undefined): void {
// TODO: Pass on to env var service if (collection) {
throw new Error('Method not implemented.'); const translatedCollection = new EnvironmentVariableCollection(collection.variables, collection.values, collection.types);
this._environmentVariableService.set(extensionIdentifier, translatedCollection);
} else {
this._environmentVariableService.delete(extensionIdentifier);
}
} }
} }
......
...@@ -428,7 +428,6 @@ export interface TerminalLaunchConfig { ...@@ -428,7 +428,6 @@ export interface TerminalLaunchConfig {
} }
export interface IEnvironmentVariableCollectionDto { export interface IEnvironmentVariableCollectionDto {
extensionIdentifier: string;
variables: string[]; variables: string[];
values: string[]; values: string[];
types: EnvironmentVariableMutatorType[]; types: EnvironmentVariableMutatorType[];
...@@ -444,7 +443,7 @@ export interface MainThreadTerminalServiceShape extends IDisposable { ...@@ -444,7 +443,7 @@ export interface MainThreadTerminalServiceShape extends IDisposable {
$stopSendingDataEvents(): void; $stopSendingDataEvents(): void;
$startHandlingLinks(): void; $startHandlingLinks(): void;
$stopHandlingLinks(): void; $stopHandlingLinks(): void;
$updateEnvironmentVariableCollections(collections: IEnvironmentVariableCollectionDto[]): void; $setEnvironmentVariableCollection(extensionIdentifier: string, collection: IEnvironmentVariableCollectionDto | undefined): void;
// Process // Process
$sendProcessTitle(terminalId: number, title: string): void; $sendProcessTitle(terminalId: number, title: string): void;
......
...@@ -14,7 +14,7 @@ import { timeout } from 'vs/base/common/async'; ...@@ -14,7 +14,7 @@ import { timeout } from 'vs/base/common/async';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { TerminalDataBufferer } from 'vs/workbench/contrib/terminal/common/terminalDataBuffering'; import { TerminalDataBufferer } from 'vs/workbench/contrib/terminal/common/terminalDataBuffering';
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Disposable as VSCodeDisposable } from './extHostTypes'; import { Disposable as VSCodeDisposable, EnvironmentVariableMutatorType } from './extHostTypes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
export interface IExtHostTerminalService extends ExtHostTerminalServiceShape { export interface IExtHostTerminalService extends ExtHostTerminalServiceShape {
...@@ -640,6 +640,62 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ ...@@ -640,6 +640,62 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
} }
} }
export class EnvironmentVariableMutator implements vscode.EnvironmentVariableMutator {
constructor(
public value: string,
public type: vscode.EnvironmentVariableMutatorType
) { }
}
export class EnvironmentVariableCollection implements vscode.EnvironmentVariableCollection {
private _entries: Map<string, EnvironmentVariableMutator> = new Map();
protected readonly _onDidChangeCollection: Emitter<void> = new Emitter<void>();
get onDidChangeCollection(): Event<void> { return this._onDidChangeCollection && this._onDidChangeCollection.event; }
get size(): number {
return this._entries.size;
}
replace(variable: string, value: string): void {
this._entries.set(variable, new EnvironmentVariableMutator(value, EnvironmentVariableMutatorType.Replace));
this._onDidChangeCollection.fire();
}
append(variable: string, value: string): void {
this._entries.set(variable, new EnvironmentVariableMutator(value, EnvironmentVariableMutatorType.Append));
this._onDidChangeCollection.fire();
}
prepend(variable: string, value: string): void {
this._entries.set(variable, new EnvironmentVariableMutator(value, EnvironmentVariableMutatorType.Prepend));
this._onDidChangeCollection.fire();
}
get(variable: string): EnvironmentVariableMutator | undefined {
return this._entries.get(variable);
}
forEach(callback: (variable: string, mutator: vscode.EnvironmentVariableMutator, collection: vscode.EnvironmentVariableCollection) => any, thisArg?: any): void {
this._entries.forEach((value, key) => callback(key, value, this));
}
delete(variable: string): void {
this._entries.delete(variable);
this._onDidChangeCollection.fire();
}
clear(): void {
this._entries.clear();
this._onDidChangeCollection.fire();
}
dispose(): void {
this._entries.clear();
this._onDidChangeCollection.fire();
}
}
export class WorkerExtHostTerminalService extends BaseExtHostTerminalService { export class WorkerExtHostTerminalService extends BaseExtHostTerminalService {
public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal { public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
throw new Error('Not implemented'); throw new Error('Not implemented');
......
...@@ -20,67 +20,12 @@ import { ExtHostVariableResolverService } from 'vs/workbench/api/common/extHostD ...@@ -20,67 +20,12 @@ import { ExtHostVariableResolverService } from 'vs/workbench/api/common/extHostD
import { ExtHostDocumentsAndEditors, IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { ExtHostDocumentsAndEditors, IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal';
import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment';
import { BaseExtHostTerminalService, ExtHostTerminal } from 'vs/workbench/api/common/extHostTerminalService'; import { BaseExtHostTerminalService, ExtHostTerminal, EnvironmentVariableCollection } from 'vs/workbench/api/common/extHostTerminalService';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { EnvironmentVariableMutatorType } from 'vs/workbench/api/common/extHostTypes'; import { EnvironmentVariableMutatorType } from 'vs/workbench/api/common/extHostTypes';
import { Emitter, Event } from 'vs/base/common/event';
import { debounce } from 'vs/base/common/decorators';
import { dispose } from 'vs/base/common/lifecycle'; import { dispose } from 'vs/base/common/lifecycle';
class EnvironmentVariableMutator implements vscode.EnvironmentVariableMutator {
constructor(
public value: string,
public type: vscode.EnvironmentVariableMutatorType
) { }
}
class EnvironmentVariableCollection implements vscode.EnvironmentVariableCollection {
private _entries: Map<string, EnvironmentVariableMutator> = new Map();
protected readonly _onDidChangeCollection: Emitter<void> = new Emitter<void>();
get onDidChangeCollection(): Event<void> { return this._onDidChangeCollection && this._onDidChangeCollection.event; }
replace(variable: string, value: string): void {
this._entries.set(variable, new EnvironmentVariableMutator(value, EnvironmentVariableMutatorType.Replace));
this._onDidChangeCollection.fire();
}
append(variable: string, value: string): void {
this._entries.set(variable, new EnvironmentVariableMutator(value, EnvironmentVariableMutatorType.Append));
this._onDidChangeCollection.fire();
}
prepend(variable: string, value: string): void {
this._entries.set(variable, new EnvironmentVariableMutator(value, EnvironmentVariableMutatorType.Prepend));
this._onDidChangeCollection.fire();
}
get(variable: string): EnvironmentVariableMutator | undefined {
return this._entries.get(variable);
}
forEach(callback: (variable: string, mutator: vscode.EnvironmentVariableMutator, collection: vscode.EnvironmentVariableCollection) => any, thisArg?: any): void {
this._entries.forEach((value, key) => callback(key, value, this));
}
delete(variable: string): void {
this._entries.delete(variable);
this._onDidChangeCollection.fire();
}
clear(): void {
this._entries.clear();
this._onDidChangeCollection.fire();
}
dispose(): void {
this._entries.clear();
this._onDidChangeCollection.fire();
}
}
export class ExtHostTerminalService extends BaseExtHostTerminalService { export class ExtHostTerminalService extends BaseExtHostTerminalService {
private _variableResolver: ExtHostVariableResolverService | undefined; private _variableResolver: ExtHostVariableResolverService | undefined;
...@@ -287,21 +232,19 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { ...@@ -287,21 +232,19 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
} else { } else {
collection = new EnvironmentVariableCollection(); collection = new EnvironmentVariableCollection();
} }
collection.onDidChangeCollection(() => this._updateEnvironmentVariableCollections()); collection.onDidChangeCollection(() => this._syncEnvironmentVariableCollection(extension.identifier.value, collection));
this._environmentVariableCollection.set(extension.identifier.value, collection); this._environmentVariableCollection.set(extension.identifier.value, collection);
return collection; return collection;
} }
@debounce(1000) private _syncEnvironmentVariableCollection(extensionIdentifier: string, collection: EnvironmentVariableCollection): void {
private _updateEnvironmentVariableCollections(): void { this._proxy.$setEnvironmentVariableCollection(extensionIdentifier, this._serializeEnvironmentVariableCollection(collection));
const collections: IEnvironmentVariableCollectionDto[] = [];
this._environmentVariableCollection.forEach((collection, extensionIdenfitier) => {
collections.push(this._serializeEnvironmentVariableCollection(extensionIdenfitier, collection));
});
this._proxy.$updateEnvironmentVariableCollections(collections);
} }
private _serializeEnvironmentVariableCollection(extensionIdentifier: string, collection: vscode.EnvironmentVariableCollection): IEnvironmentVariableCollectionDto { private _serializeEnvironmentVariableCollection(collection: EnvironmentVariableCollection): IEnvironmentVariableCollectionDto | undefined {
if (collection.size === 0) {
return undefined;
}
const variables: string[] = []; const variables: string[] = [];
const values: string[] = []; const values: string[] = [];
const types: EnvironmentVariableMutatorType[] = []; const types: EnvironmentVariableMutatorType[] = [];
...@@ -311,7 +254,6 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { ...@@ -311,7 +254,6 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
types.push(mutator.type); types.push(mutator.type);
}); });
return { return {
extensionIdentifier,
variables, variables,
values, values,
types types
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { EnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariableService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
registerSingleton(IEnvironmentVariableService, EnvironmentVariableService, true);
...@@ -19,13 +19,16 @@ export interface IEnvironmentVariableMutator { ...@@ -19,13 +19,16 @@ export interface IEnvironmentVariableMutator {
} }
export interface IEnvironmentVariableCollection { export interface IEnvironmentVariableCollection {
readonly entries: Map<string, IEnvironmentVariableMutator>; readonly entries: ReadonlyMap<string, IEnvironmentVariableMutator>;
equals(other: IEnvironmentVariableCollection): boolean;
} }
/** /**
* Tracks and persists environment variable collections as defined by extensions. * Tracks and persists environment variable collections as defined by extensions.
*/ */
export interface IEnvironmentVariableService { export interface IEnvironmentVariableService {
_serviceBrand: undefined;
/** /**
* Gets a single collection constructed by merging all collections into one. * Gets a single collection constructed by merging all collections into one.
*/ */
......
...@@ -3,15 +3,41 @@ ...@@ -3,15 +3,41 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { IEnvironmentVariableService, IEnvironmentVariableCollection, IEnvironmentVariableMutator } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { IEnvironmentVariableService, IEnvironmentVariableCollection, IEnvironmentVariableMutator, EnvironmentVariableMutatorType } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { Event, Emitter } from 'vs/base/common/event';
export class EnvironmentVariableCollection implements IEnvironmentVariableCollection { export class EnvironmentVariableCollection implements IEnvironmentVariableCollection {
readonly entries: Map<string, IEnvironmentVariableMutator>; readonly entries: Map<string, IEnvironmentVariableMutator>;
constructor( constructor(
// TODO: Init entries via ctor if specified variables?: string[],
values?: string[],
types?: EnvironmentVariableMutatorType[]
) { ) {
this.entries = new Map(); this.entries = new Map();
if (variables && values && types) {
if (variables.length !== values.length || variables.length !== types.length) {
throw new Error('Cannot create environment collection from arrays of differing length');
}
for (let i = 0; i < variables.length; i++) {
this.entries.set(variables[i], { value: values[i], type: types[i] });
}
}
}
// TODO: Implement diff method?
equals(other: IEnvironmentVariableCollection): boolean {
if (this.entries.size !== other.entries.size) {
return false;
}
let result = true;
this.entries.forEach((mutator, variable) => {
const otherMutator = other.entries.get(variable);
if (otherMutator !== mutator) {
result = false;
}
});
return result;
} }
} }
...@@ -19,14 +45,21 @@ export class EnvironmentVariableCollection implements IEnvironmentVariableCollec ...@@ -19,14 +45,21 @@ export class EnvironmentVariableCollection implements IEnvironmentVariableCollec
* Tracks and persists environment variable collections as defined by extensions. * Tracks and persists environment variable collections as defined by extensions.
*/ */
export class EnvironmentVariableService implements IEnvironmentVariableService { export class EnvironmentVariableService implements IEnvironmentVariableService {
_serviceBrand: undefined;
/** /**
* The merged collection, this is set to undefined when it needs to be resolved again and is * The merged collection, this is set to undefined when it needs to be resolved again and is
* evaluated lazily as needed. * evaluated lazily as needed.
*/ */
private _mergedCollection: IEnvironmentVariableCollection | undefined; private _mergedCollection: IEnvironmentVariableCollection = new EnvironmentVariableCollection();
private _collections: Map<string, IEnvironmentVariableCollection> = new Map(); private _collections: Map<string, IEnvironmentVariableCollection> = new Map();
// TODO: Debounce notifying of terminals about onDidChangeCollections
// TODO: Generate a summary of changes inside the terminal component as it needs to be done per-terminal compared to what it started with
protected readonly _onDidChangeCollections = new Emitter<void>();
public get onDidChangeCollections(): Event<void> { return this._onDidChangeCollections.event; }
// TODO: Load in persisted collections // TODO: Load in persisted collections
// TODO: Fire an event when collections have changed that the terminal component can listen to // TODO: Fire an event when collections have changed that the terminal component can listen to
...@@ -39,12 +72,10 @@ export class EnvironmentVariableService implements IEnvironmentVariableService { ...@@ -39,12 +72,10 @@ export class EnvironmentVariableService implements IEnvironmentVariableService {
set(extensionIdentifier: string, collection: IEnvironmentVariableCollection): void { set(extensionIdentifier: string, collection: IEnvironmentVariableCollection): void {
this._collections.set(extensionIdentifier, collection); this._collections.set(extensionIdentifier, collection);
this._mergedCollection = undefined;
} }
delete(extensionIdentifier: string): void { delete(extensionIdentifier: string): void {
this._collections.delete(extensionIdentifier); this._collections.delete(extensionIdentifier);
this._mergedCollection = undefined;
} }
private _resolveMergedCollection(): IEnvironmentVariableCollection { private _resolveMergedCollection(): IEnvironmentVariableCollection {
......
...@@ -207,6 +207,7 @@ import 'vs/workbench/contrib/output/browser/output.contribution'; ...@@ -207,6 +207,7 @@ import 'vs/workbench/contrib/output/browser/output.contribution';
import 'vs/workbench/contrib/output/browser/outputView'; import 'vs/workbench/contrib/output/browser/outputView';
// Terminal // Terminal
import 'vs/workbench/contrib/terminal/browser/environmentVariable.contribution';
import 'vs/workbench/contrib/terminal/browser/terminal.contribution'; import 'vs/workbench/contrib/terminal/browser/terminal.contribution';
import 'vs/workbench/contrib/terminal/browser/terminalView'; import 'vs/workbench/contrib/terminal/browser/terminalView';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册