Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support VSCode API: EnvironmentVariableMutator.option #4169

Merged
merged 3 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,16 @@ describe('ext host terminal test', () => {

it('EnvironmentVariableCollection#append', () => {
collection.append('FOO', 'BAR');
const serialized = [['FOO', { value: 'BAR', type: 2 /** EnvironmentVariableMutatorType.Append */ }]];
const serialized = [
[
'FOO',
{
value: 'BAR',
type: 2 /** EnvironmentVariableMutatorType.Append */,
options: { applyAtProcessCreation: true },
},
],
];

expect(mocksyncEnvironmentVariableCollection).toHaveBeenCalled();
expect(mocksyncEnvironmentVariableCollection).toHaveBeenCalledWith(mockExtension.id, collection);
Expand All @@ -266,7 +275,16 @@ describe('ext host terminal test', () => {

it('EnvironmentVariableCollection#replace', () => {
collection.replace('FOO', 'BAR2');
const serialized = [['FOO', { value: 'BAR2', type: 1 /** EnvironmentVariableMutatorType.Replace */ }]];
const serialized = [
[
'FOO',
{
value: 'BAR2',
type: 1 /** EnvironmentVariableMutatorType.Replace */,
options: { applyAtProcessCreation: true },
},
],
];

expect(mocksyncEnvironmentVariableCollection).toHaveBeenCalled();
expect(mocksyncEnvironmentVariableCollection).toHaveBeenCalledWith(mockExtension.id, collection);
Expand All @@ -275,7 +293,16 @@ describe('ext host terminal test', () => {

it('EnvironmentVariableCollection#prepend', () => {
collection.prepend('FOO', 'BAR3');
const serialized = [['FOO', { value: 'BAR3', type: 3 /** EnvironmentVariableMutatorType.Prepend */ }]];
const serialized = [
[
'FOO',
{
value: 'BAR3',
type: 3 /** EnvironmentVariableMutatorType.Prepend */,
options: { applyAtProcessCreation: true },
},
],
];

expect(mocksyncEnvironmentVariableCollection).toHaveBeenCalled();
expect(mocksyncEnvironmentVariableCollection).toHaveBeenCalledWith(mockExtension.id, collection);
Expand All @@ -284,7 +311,7 @@ describe('ext host terminal test', () => {

it('EnvironmentVariableCollection#get', () => {
const value = collection.get('FOO');
expect(value).toEqual({ value: 'BAR3', type: 3 });
expect(value).toEqual({ value: 'BAR3', type: 3, options: { applyAtProcessCreation: true } });
});

it('EnvironmentVariableCollection#forEach', async () => {
Expand Down
24 changes: 18 additions & 6 deletions packages/extension/src/hosted/api/vscode/ext.host.terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,16 +596,28 @@ export class EnvironmentVariableCollection implements vscode.EnvironmentVariable
}
}

replace(variable: string, value: string): void {
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Replace });
replace(variable: string, value: string, options?: vscode.EnvironmentVariableMutatorOptions): void {
this._setIfDiffers(variable, {
value,
type: EnvironmentVariableMutatorType.Replace,
options: options ?? { applyAtProcessCreation: true },
});
}

append(variable: string, value: string): void {
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Append });
append(variable: string, value: string, options?: vscode.EnvironmentVariableMutatorOptions): void {
this._setIfDiffers(variable, {
value,
type: EnvironmentVariableMutatorType.Append,
options: options ?? { applyAtProcessCreation: true },
});
}

prepend(variable: string, value: string): void {
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Prepend });
prepend(variable: string, value: string, options?: vscode.EnvironmentVariableMutatorOptions): void {
this._setIfDiffers(variable, {
value,
type: EnvironmentVariableMutatorType.Prepend,
options: options ?? { applyAtProcessCreation: true },
});
}

get(variable: string): vscode.EnvironmentVariableMutator | undefined {
Expand Down
6 changes: 6 additions & 0 deletions packages/terminal-next/src/common/environmentVariable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,14 @@ export enum EnvironmentVariableMutatorType {
Prepend = 3,
}

export interface EnvironmentVariableMutatorOptions {
applyAtProcessCreation?: boolean;
}

export interface EnvironmentVariableMutator {
readonly value: string;
readonly type: EnvironmentVariableMutatorType;
readonly options: EnvironmentVariableMutatorOptions;
}

export interface ExtensionOwnedEnvironmentVariableMutator extends EnvironmentVariableMutator {
Expand Down Expand Up @@ -145,6 +150,7 @@ export type SerializableEnvironmentVariableCollection = [string, EnvironmentVari
export interface IEnvironmentVariableMutator {
readonly value: string;
readonly type: EnvironmentVariableMutatorType;
readonly options: EnvironmentVariableMutatorOptions;
}

/** [variable, mutator] */
Expand Down
25 changes: 14 additions & 11 deletions packages/terminal-next/src/common/environmentVariableCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export class MergedEnvironmentVariableCollection implements IMergedEnvironmentVa
extensionIdentifier,
value: mutator.value,
type: mutator.type,
options: mutator.options,
});

next = it.next();
Expand All @@ -63,17 +64,19 @@ export class MergedEnvironmentVariableCollection implements IMergedEnvironmentVa
const actualVariable =
os === OperatingSystem.Windows ? lowerToActualVariableNames![variable.toLowerCase()] || variable : variable;
mutators.forEach(async (mutator) => {
const value = variableResolver ? await variableResolver(mutator.value) : mutator.value;
switch (mutator.type) {
case EnvironmentVariableMutatorType.Append:
env[actualVariable] = (env[actualVariable] || '') + value;
break;
case EnvironmentVariableMutatorType.Prepend:
env[actualVariable] = value + (env[actualVariable] || '');
break;
case EnvironmentVariableMutatorType.Replace:
env[actualVariable] = value;
break;
if (mutator.options?.applyAtProcessCreation ?? true) {
const value = variableResolver ? await variableResolver(mutator.value) : mutator.value;
switch (mutator.type) {
case EnvironmentVariableMutatorType.Append:
env[actualVariable] = (env[actualVariable] || '') + value;
break;
case EnvironmentVariableMutatorType.Prepend:
env[actualVariable] = value + (env[actualVariable] || '');
break;
case EnvironmentVariableMutatorType.Replace:
env[actualVariable] = value;
break;
}
}
});
});
Expand Down
86 changes: 57 additions & 29 deletions packages/types/vscode/typings/vscode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3062,6 +3062,24 @@ declare module 'vscode' {
Prepend = 3,
}

/**
* Options applied to the mutator.
*/
export interface EnvironmentVariableMutatorOptions {
/**
* Apply to the environment just before the process is created. Defaults to true
*/
applyAtProcessCreation?: boolean;

/**
* Apply to the environment in the shell integration script. Note that this _will not_ apply
* the mutator if shell integration is disabled or not working for some reason. Defaults to
* false.
* @stubbed
*/
applyAtShellIntegration?: boolean;
}

/**
* A type of mutation and its value to be applied to an environment variable.
*/
Expand All @@ -3075,6 +3093,10 @@ declare module 'vscode' {
* The value to use for the variable.
*/
readonly value: string;
/**
* Options applied to the mutator.
*/
readonly options: EnvironmentVariableMutatorOptions;
}

/**
Expand All @@ -3091,37 +3113,43 @@ declare module 'vscode' {
persistent: boolean;

/**
* Replace an environment variable with a value.
*
* Note that an extension can only make a single change to any one variable, so this will
* overwrite any previous calls to replace, append or prepend.
*
* @param variable The variable to replace.
* @param value The value to replace the variable with.
*/
replace(variable: string, value: string): void;
* Replace an environment variable with a value.
*
* Note that an extension can only make a single change to any one variable, so this will
* overwrite any previous calls to replace, append or prepend.
*
* @param variable The variable to replace.
* @param value The value to replace the variable with.
* @param options Options applied to the mutator, when no options are provided this will
* default to `{ applyAtProcessCreation: true }`.
*/
replace(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void;

/**
* Append a value to an environment variable.
*
* Note that an extension can only make a single change to any one variable, so this will
* overwrite any previous calls to replace, append or prepend.
*
* @param variable The variable to append to.
* @param value The value to append to the variable.
*/
append(variable: string, value: string): void;
/**
* Append a value to an environment variable.
*
* Note that an extension can only make a single change to any one variable, so this will
* overwrite any previous calls to replace, append or prepend.
*
* @param variable The variable to append to.
* @param value The value to append to the variable.
* @param options Options applied to the mutator, when no options are provided this will
* default to `{ applyAtProcessCreation: true }`.
*/
append(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void;

/**
* Prepend a value to an environment variable.
*
* Note that an extension can only make a single change to any one variable, so this will
* overwrite any previous calls to replace, append or prepend.
*
* @param variable The variable to prepend.
* @param value The value to prepend to the variable.
*/
prepend(variable: string, value: string): void;
/**
* Prepend a value to an environment variable.
*
* Note that an extension can only make a single change to any one variable, so this will
* overwrite any previous calls to replace, append or prepend.
*
* @param variable The variable to prepend.
* @param value The value to prepend to the variable.
* @param options Options applied to the mutator, when no options are provided this will
* default to `{ applyAtProcessCreation: true }`.
*/
prepend(variable: string, value: string, options?: EnvironmentVariableMutatorOptions): void;

/**
* Gets the mutator that this collection applies to a variable, if any.
Expand Down
Loading