mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-25 15:35:43 +01:00
Apply ext env changes to new terminals
This commit is contained in:
@@ -48,13 +48,15 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
|
||||
this._updateVariableResolver();
|
||||
this._registerListeners();
|
||||
|
||||
const c = this.getEnvironmentVariableCollection({ identifier: { value: 'test' } } as any, true);
|
||||
setTimeout(() => {
|
||||
this._logService.info('get and set');
|
||||
const c = this.getEnvironmentVariableCollection({ identifier: { value: 'test' } } as any, true);
|
||||
c.prepend('a', 'b');
|
||||
c.replace('c', 'd');
|
||||
c.append('e', 'f');
|
||||
}, 2000);
|
||||
setTimeout(() => {
|
||||
c.prepend('a', 'late addition');
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
|
||||
|
||||
@@ -23,6 +23,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { IEnvironmentVariableService, IEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||
|
||||
/** The amount of time to consider terminal errors to be related to the launch */
|
||||
const LAUNCHING_DURATION = 500;
|
||||
@@ -59,6 +60,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
||||
private _latency: number = -1;
|
||||
private _latencyLastMeasured: number = 0;
|
||||
private _initialCwd: string | undefined;
|
||||
private _extEnvironmentVariableCollection: IEnvironmentVariableCollection | undefined;
|
||||
|
||||
private readonly _onProcessReady = this._register(new Emitter<void>());
|
||||
public get onProcessReady(): Event<void> { return this._onProcessReady.event; }
|
||||
@@ -87,7 +89,8 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
||||
@IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService,
|
||||
@IProductService private readonly _productService: IProductService,
|
||||
@ITerminalInstanceService private readonly _terminalInstanceService: ITerminalInstanceService,
|
||||
@IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService
|
||||
@IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService,
|
||||
@IEnvironmentVariableService private readonly _environmentVariableService: IEnvironmentVariableService
|
||||
) {
|
||||
super();
|
||||
this.ptyProcessReady = new Promise<void>(c => {
|
||||
@@ -230,6 +233,15 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
||||
const baseEnv = this._configHelper.config.inheritEnv ? processEnv : await this._terminalInstanceService.getMainProcessParentEnv();
|
||||
const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.detectLocale, baseEnv);
|
||||
|
||||
// Fetch any extension environment additions and apply them
|
||||
this._extEnvironmentVariableCollection = this._environmentVariableService.mergedCollection;
|
||||
this._environmentVariableService.onDidChangeCollections((newCollection) => {
|
||||
const newAdditions = this._extEnvironmentVariableCollection!.getNewAdditions(newCollection);
|
||||
// TODO: React to event
|
||||
console.log('new env additions!', newAdditions);
|
||||
});
|
||||
this._extEnvironmentVariableCollection.applyToProcessEnvironment(env);
|
||||
|
||||
const useConpty = this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled;
|
||||
return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, useConpty);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
|
||||
export const IEnvironmentVariableService = createDecorator<IEnvironmentVariableService>('environmentVariableService');
|
||||
|
||||
@@ -20,7 +22,17 @@ export interface IEnvironmentVariableMutator {
|
||||
|
||||
export interface IEnvironmentVariableCollection {
|
||||
readonly entries: ReadonlyMap<string, IEnvironmentVariableMutator>;
|
||||
equals(other: IEnvironmentVariableCollection): boolean;
|
||||
// TODO: Remove equals?
|
||||
// equals(other: IEnvironmentVariableCollection): boolean;
|
||||
|
||||
/**
|
||||
* Get's additions when compared to another collection. This only gets additions rather than
|
||||
* doing a full diff because we can only reliably add entries to an environment, not remove
|
||||
* them.
|
||||
*/
|
||||
getNewAdditions(other: IEnvironmentVariableCollection): ReadonlyMap<string, IEnvironmentVariableMutator> | undefined;
|
||||
|
||||
applyToProcessEnvironment(env: IProcessEnvironment): void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,6 +46,8 @@ export interface IEnvironmentVariableService {
|
||||
*/
|
||||
readonly mergedCollection: IEnvironmentVariableCollection;
|
||||
|
||||
onDidChangeCollections: Event<IEnvironmentVariableCollection>;
|
||||
|
||||
set(extensionIdentifier: string, collection: IEnvironmentVariableCollection): void;
|
||||
delete(extensionIdentifier: string): void;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { IEnvironmentVariableService, IEnvironmentVariableCollection, IEnvironmentVariableMutator, EnvironmentVariableMutatorType } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { debounce } from 'vs/base/common/decorators';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
|
||||
export class EnvironmentVariableCollection implements IEnvironmentVariableCollection {
|
||||
readonly entries: Map<string, IEnvironmentVariableMutator>;
|
||||
@@ -26,19 +27,47 @@ export class EnvironmentVariableCollection implements IEnvironmentVariableCollec
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
// TODO: Remove? Does diff do the job?
|
||||
// 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;
|
||||
// }
|
||||
|
||||
// TODO: Consider doing a full diff, just marking the environment as stale with no action available?
|
||||
getNewAdditions(other: IEnvironmentVariableCollection): ReadonlyMap<string, IEnvironmentVariableMutator> | undefined {
|
||||
const result = new Map<string, IEnvironmentVariableMutator>();
|
||||
other.entries.forEach((newMutator, variable) => {
|
||||
const currentMutator = this.entries.get(variable);
|
||||
if (currentMutator?.type !== newMutator.type || currentMutator.value !== newMutator.value) {
|
||||
result.set(variable, newMutator);
|
||||
}
|
||||
});
|
||||
return result.size === 0 ? undefined : result;
|
||||
}
|
||||
|
||||
applyToProcessEnvironment(env: IProcessEnvironment): void {
|
||||
this.entries.forEach((mutator, variable) => {
|
||||
switch (mutator.type) {
|
||||
case EnvironmentVariableMutatorType.Append:
|
||||
env[variable] = (env[variable] || '') + mutator.value;
|
||||
break;
|
||||
case EnvironmentVariableMutatorType.Prepend:
|
||||
env[variable] = mutator.value + (env[variable] || '');
|
||||
break;
|
||||
case EnvironmentVariableMutatorType.Replace:
|
||||
env[variable] = mutator.value;
|
||||
break;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +81,8 @@ export class EnvironmentVariableService implements IEnvironmentVariableService {
|
||||
private _mergedCollection: IEnvironmentVariableCollection = new EnvironmentVariableCollection();
|
||||
|
||||
// TODO: Generate a summary of changes inside the terminal component as it needs to be done per-terminal compared to what it started with
|
||||
private readonly _onDidChangeCollections = new Emitter<void>();
|
||||
get onDidChangeCollections(): Event<void> { return this._onDidChangeCollections.event; }
|
||||
private readonly _onDidChangeCollections = new Emitter<IEnvironmentVariableCollection>();
|
||||
get onDidChangeCollections(): Event<IEnvironmentVariableCollection> { return this._onDidChangeCollections.event; }
|
||||
|
||||
constructor() {
|
||||
// TODO: Load in persisted collections
|
||||
@@ -78,7 +107,7 @@ export class EnvironmentVariableService implements IEnvironmentVariableService {
|
||||
|
||||
@debounce(1000)
|
||||
private _notifyCollectionUpdates(): void {
|
||||
this._onDidChangeCollections.fire();
|
||||
this._onDidChangeCollections.fire(this._mergedCollection);
|
||||
}
|
||||
|
||||
private _resolveMergedCollection(): IEnvironmentVariableCollection {
|
||||
|
||||
Reference in New Issue
Block a user