diff --git a/src/vs/platform/terminal/common/environmentVariable.ts b/src/vs/platform/terminal/common/environmentVariable.ts index deb35d491cd87..fe8b083bffbb5 100644 --- a/src/vs/platform/terminal/common/environmentVariable.ts +++ b/src/vs/platform/terminal/common/environmentVariable.ts @@ -3,6 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { IProcessEnvironment } from 'vs/base/common/platform'; + export enum EnvironmentVariableMutatorType { Replace = 1, Append = 2, @@ -12,8 +14,47 @@ export interface IEnvironmentVariableMutator { readonly value: string; readonly type: EnvironmentVariableMutatorType; } + +export interface IEnvironmentVariableCollection { + readonly map: ReadonlyMap; +} + /** [variable, mutator] */ export type ISerializableEnvironmentVariableCollection = [string, IEnvironmentVariableMutator][]; /** [extension, collection] */ export type ISerializableEnvironmentVariableCollections = [string, ISerializableEnvironmentVariableCollection][]; + +export interface IExtensionOwnedEnvironmentVariableMutator extends IEnvironmentVariableMutator { + readonly extensionIdentifier: string; +} + +export interface IMergedEnvironmentVariableCollectionDiff { + added: ReadonlyMap; + changed: ReadonlyMap; + removed: ReadonlyMap; +} + +type VariableResolver = (str: string) => Promise; + +/** + * Represents an environment variable collection that results from merging several collections + * together. + */ +export interface IMergedEnvironmentVariableCollection { + readonly collections: ReadonlyMap; + readonly map: ReadonlyMap; + + /** + * Applies this collection to a process environment. + * @param variableResolver An optional function to use to resolve variables within the + * environment values. + */ + applyToProcessEnvironment(env: IProcessEnvironment, variableResolver?: VariableResolver): Promise; + + /** + * Generates a diff of this collection against another. Returns undefined if the collections are + * the same. + */ + diff(other: IMergedEnvironmentVariableCollection): IMergedEnvironmentVariableCollectionDiff | undefined; +} diff --git a/src/vs/workbench/contrib/terminal/common/environmentVariableCollection.ts b/src/vs/platform/terminal/common/environmentVariableCollection.ts similarity index 97% rename from src/vs/workbench/contrib/terminal/common/environmentVariableCollection.ts rename to src/vs/platform/terminal/common/environmentVariableCollection.ts index 3aa772dff65fd..8b58c64a53d45 100644 --- a/src/vs/workbench/contrib/terminal/common/environmentVariableCollection.ts +++ b/src/vs/platform/terminal/common/environmentVariableCollection.ts @@ -4,8 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { IProcessEnvironment, isWindows } from 'vs/base/common/platform'; -import { EnvironmentVariableMutatorType, IEnvironmentVariableCollection, IExtensionOwnedEnvironmentVariableMutator, IMergedEnvironmentVariableCollection, IMergedEnvironmentVariableCollectionDiff } from 'vs/workbench/contrib/terminal/common/environmentVariable'; -import { VariableResolver } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; +import { EnvironmentVariableMutatorType, IEnvironmentVariableCollection, IExtensionOwnedEnvironmentVariableMutator, IMergedEnvironmentVariableCollection, IMergedEnvironmentVariableCollectionDiff } from 'vs/platform/terminal/common/environmentVariable'; + +type VariableResolver = (str: string) => Promise; export class MergedEnvironmentVariableCollection implements IMergedEnvironmentVariableCollection { readonly map: Map = new Map(); diff --git a/src/vs/workbench/contrib/terminal/common/environmentVariableShared.ts b/src/vs/platform/terminal/common/environmentVariableShared.ts similarity index 94% rename from src/vs/workbench/contrib/terminal/common/environmentVariableShared.ts rename to src/vs/platform/terminal/common/environmentVariableShared.ts index 9295b2af99e84..7587473953766 100644 --- a/src/vs/workbench/contrib/terminal/common/environmentVariableShared.ts +++ b/src/vs/platform/terminal/common/environmentVariableShared.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IEnvironmentVariableCollection, IEnvironmentVariableMutator, ISerializableEnvironmentVariableCollection, ISerializableEnvironmentVariableCollections } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { IEnvironmentVariableCollection, IEnvironmentVariableMutator, ISerializableEnvironmentVariableCollection, ISerializableEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariable'; // This file is shared between the renderer and extension host diff --git a/src/vs/platform/terminal/node/terminalEnvironment.ts b/src/vs/platform/terminal/node/terminalEnvironment.ts index ba2ce5d131481..da34d75f863bf 100644 --- a/src/vs/platform/terminal/node/terminalEnvironment.ts +++ b/src/vs/platform/terminal/node/terminalEnvironment.ts @@ -7,7 +7,7 @@ import * as os from 'os'; import { FileAccess } from 'vs/base/common/network'; import { getCaseInsensitive } from 'vs/base/common/objects'; import * as path from 'vs/base/common/path'; -import { IProcessEnvironment, isWindows } from 'vs/base/common/platform'; +import { IProcessEnvironment, isMacintosh, isWindows } from 'vs/base/common/platform'; import * as process from 'vs/base/common/process'; import { format } from 'vs/base/common/strings'; import { isString } from 'vs/base/common/types'; @@ -15,6 +15,9 @@ import * as pfs from 'vs/base/node/pfs'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { IShellLaunchConfig, ITerminalEnvironment, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal'; +import { EnvironmentVariableMutatorType } from 'vs/platform/terminal/common/environmentVariable'; +import { deserializeEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariableShared'; +import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection'; export function getWindowsBuildNumber(): number { const osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release()); @@ -104,7 +107,7 @@ export interface IShellIntegrationConfigInjection { */ export function getShellIntegrationInjection( shellLaunchConfig: IShellLaunchConfig, - options: Pick, + options: ITerminalProcessOptions, env: ITerminalEnvironment | undefined, logService: ILogService, productService: IProductService @@ -151,6 +154,7 @@ export function getShellIntegrationInjection( newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Bash); } else if (areZshBashLoginArgs(originalArgs)) { envMixin['VSCODE_SHELL_LOGIN'] = '1'; + addEnvMixinPathPrefix(options, envMixin); newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Bash); } if (!newArgs) { @@ -166,6 +170,7 @@ export function getShellIntegrationInjection( const oldDataDirs = env?.XDG_DATA_DIRS ?? '/usr/local/share:/usr/share'; const newDataDir = path.join(appRoot, 'out/vs/workbench/contrib/xdg_data'); envMixin['XDG_DATA_DIRS'] = `${oldDataDirs}:${newDataDir}`; + addEnvMixinPathPrefix(options, envMixin); return { newArgs: undefined, envMixin }; } case 'pwsh': { @@ -186,6 +191,7 @@ export function getShellIntegrationInjection( newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Zsh); } else if (areZshBashLoginArgs(originalArgs)) { newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.ZshLogin); + addEnvMixinPathPrefix(options, envMixin); } else if (originalArgs === shellIntegrationArgs.get(ShellIntegrationExecutable.Zsh) || originalArgs === shellIntegrationArgs.get(ShellIntegrationExecutable.ZshLogin)) { newArgs = originalArgs; } @@ -230,6 +236,39 @@ export function getShellIntegrationInjection( return undefined; } +/** + * On macOS the profile calls path_helper which adds a bunch of standard bin directories to the + * beginning of the PATH. This causes significant problems for the environment variable + * collection API as the custom paths added to the end will now be somewhere in the middle of + * the PATH. To combat this, VSCODE_PATH_PREFIX is used to re-apply any prefix after the profile + * has run. This will cause duplication in the PATH but should fix the issue. + * + * See #99878 for more information. + */ +function addEnvMixinPathPrefix(options: ITerminalProcessOptions, envMixin: IProcessEnvironment): void { + if (isMacintosh && options.environmentVariableCollections) { + // Deserialize and merge + const deserialized = deserializeEnvironmentVariableCollections(options.environmentVariableCollections); + const merged = new MergedEnvironmentVariableCollection(deserialized); + + // Get all prepend PATH entries + const pathEntry = merged.map.get('PATH'); + const prependToPath: string[] = []; + if (pathEntry) { + for (const mutator of pathEntry) { + if (mutator.type === EnvironmentVariableMutatorType.Prepend) { + prependToPath.push(mutator.value); + } + } + } + + // Add to the environment mixin to be applied in the shell integration script + if (prependToPath.length > 0) { + envMixin['VSCODE_PATH_PREFIX'] = prependToPath.join(''); + } + } +} + enum ShellIntegrationExecutable { WindowsPwsh = 'windows-pwsh', WindowsPwshLogin = 'windows-pwsh-login', diff --git a/src/vs/platform/terminal/node/terminalProcess.ts b/src/vs/platform/terminal/node/terminalProcess.ts index abf6f7f9ef7c9..51da75ead8cc9 100644 --- a/src/vs/platform/terminal/node/terminalProcess.ts +++ b/src/vs/platform/terminal/node/terminalProcess.ts @@ -202,7 +202,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess let injection: IShellIntegrationConfigInjection | undefined; if (this._options.shellIntegration.enabled) { - injection = getShellIntegrationInjection(this.shellLaunchConfig, { shellIntegration: this._options.shellIntegration, windowsEnableConpty: this._options.windowsEnableConpty }, this._ptyOptions.env, this._logService, this._productService); + injection = getShellIntegrationInjection(this.shellLaunchConfig, this._options, this._ptyOptions.env, this._logService, this._productService); if (injection) { this._onDidChangeProperty.fire({ type: ProcessPropertyType.UsedShellIntegrationInjection, value: true }); if (injection.envMixin) { diff --git a/src/vs/platform/terminal/test/node/terminalEnvironment.test.ts b/src/vs/platform/terminal/test/node/terminalEnvironment.test.ts index 50242fb83da4c..dd74ad4dfd0a6 100644 --- a/src/vs/platform/terminal/test/node/terminalEnvironment.test.ts +++ b/src/vs/platform/terminal/test/node/terminalEnvironment.test.ts @@ -11,9 +11,9 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal'; import { getShellIntegrationInjection, IShellIntegrationConfigInjection } from 'vs/platform/terminal/node/terminalEnvironment'; -const enabledProcessOptions: Pick = { shellIntegration: { enabled: true }, windowsEnableConpty: true }; -const disabledProcessOptions: Pick = { shellIntegration: { enabled: false }, windowsEnableConpty: true }; -const winptyProcessOptions: Pick = { shellIntegration: { enabled: true }, windowsEnableConpty: false }; +const enabledProcessOptions: ITerminalProcessOptions = { shellIntegration: { enabled: true }, windowsEnableConpty: true, environmentVariableCollections: undefined }; +const disabledProcessOptions: ITerminalProcessOptions = { shellIntegration: { enabled: false }, windowsEnableConpty: true, environmentVariableCollections: undefined }; +const winptyProcessOptions: ITerminalProcessOptions = { shellIntegration: { enabled: true }, windowsEnableConpty: false, environmentVariableCollections: undefined }; const pwshExe = process.platform === 'win32' ? 'pwsh.exe' : 'pwsh'; const repoRoot = process.platform === 'win32' ? process.cwd()[0].toLowerCase() + process.cwd().substring(1) : process.cwd(); const logService = new NullLogService(); diff --git a/src/vs/server/node/remoteTerminalChannel.ts b/src/vs/server/node/remoteTerminalChannel.ts index 1b122f6c8fca0..753ca363fff15 100644 --- a/src/vs/server/node/remoteTerminalChannel.ts +++ b/src/vs/server/node/remoteTerminalChannel.ts @@ -20,9 +20,9 @@ import { IGetTerminalLayoutInfoArgs, ISetTerminalLayoutInfoArgs } from 'vs/platf import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { createURITransformer } from 'vs/workbench/api/node/uriTransformer'; import { CLIServerBase, ICommandsExecuter } from 'vs/workbench/api/node/extHostCLIServer'; -import { IEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable'; -import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection'; -import { deserializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared'; +import { IEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; +import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection'; +import { deserializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared'; import { ICreateTerminalProcessArguments, ICreateTerminalProcessResult, IWorkspaceFolderData } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/common/variableResolver'; diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 023613fe87c6c..3a37103ba8608 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -14,8 +14,8 @@ import { IProcessProperty, IShellLaunchConfig, IShellLaunchConfigDto, ProcessPro import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; import { ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalGroupService, ITerminalInstance, ITerminalLink, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy'; -import { IEnvironmentVariableService, ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable'; -import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared'; +import { IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared'; import { IStartExtensionTerminalRequest, ITerminalProcessExtHostProxy, ITerminalProfileResolverService, ITerminalProfileService, ITerminalQuickFixService } from 'vs/workbench/contrib/terminal/common/terminal'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { withNullAsUndefined } from 'vs/base/common/types'; @@ -26,6 +26,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities'; import { ITerminalOutputMatch, ITerminalOutputMatcher, ITerminalQuickFix, ITerminalQuickFixOptions } from 'vs/platform/terminal/common/xterm/terminalQuickFix'; import { TerminalQuickFixType } from 'vs/workbench/api/common/extHostTypes'; +import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; @extHostNamedCustomer(MainContext.MainThreadTerminalService) diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 8c789248827af..579752c1e9b1b 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -55,7 +55,7 @@ import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange'; import { OutputChannelUpdateMode } from 'vs/workbench/services/output/common/output'; import { InputValidationType } from 'vs/workbench/contrib/scm/common/scm'; import { IWorkspaceSymbol } from 'vs/workbench/contrib/search/common/search'; -import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; import { CoverageDetails, ExtensionRunTestsRequest, ICallProfileRunHandler, IFileCoverage, ISerializedTestResults, ITestItem, ITestMessage, ITestRunProfile, ITestRunTask, ResolvedTestRunRequest, IStartControllerTests, TestResultState, TestsDiffOp } from 'vs/workbench/contrib/testing/common/testTypes'; import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor } from 'vs/workbench/contrib/timeline/common/timeline'; import { TypeHierarchyItem } from 'vs/workbench/contrib/typeHierarchy/common/typeHierarchy'; diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 7737164a7ce75..5d86b3c222964 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -14,10 +14,10 @@ import { Disposable as VSCodeDisposable, EnvironmentVariableMutatorType, Termina import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { localize } from 'vs/nls'; import { NotSupportedError } from 'vs/base/common/errors'; -import { serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared'; +import { serializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { generateUuid } from 'vs/base/common/uuid'; -import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; import { ICreateContributedTerminalProfileOptions, IProcessReadyEvent, IShellLaunchConfigDto, ITerminalChildProcess, ITerminalLaunchError, ITerminalProfile, TerminalIcon, TerminalLocation, IProcessProperty, ProcessPropertyType, IProcessPropertyMap } from 'vs/platform/terminal/common/terminal'; import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; import { ThemeColor } from 'vs/platform/theme/common/themeService'; diff --git a/src/vs/workbench/contrib/terminal/browser/environmentVariableInfo.ts b/src/vs/workbench/contrib/terminal/browser/environmentVariableInfo.ts index 4b2b0bdc42668..8b7a734bf1685 100644 --- a/src/vs/workbench/contrib/terminal/browser/environmentVariableInfo.ts +++ b/src/vs/workbench/contrib/terminal/browser/environmentVariableInfo.ts @@ -3,13 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { EnvironmentVariableMutatorType, IEnvironmentVariableInfo, IMergedEnvironmentVariableCollection, IMergedEnvironmentVariableCollectionDiff } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { localize } from 'vs/nls'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { Codicon } from 'vs/base/common/codicons'; import { IHoverAction } from 'vs/workbench/services/hover/browser/hover'; +import { EnvironmentVariableMutatorType, IMergedEnvironmentVariableCollection, IMergedEnvironmentVariableCollectionDiff } from 'vs/platform/terminal/common/environmentVariable'; export class EnvironmentVariableInfoStale implements IEnvironmentVariableInfo { readonly requiresAction = true; diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh index cb466f5abb897..7671b840c5ed8 100755 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh @@ -31,6 +31,12 @@ if [ "$VSCODE_INJECTION" == "1" ]; then . ~/.profile fi builtin unset VSCODE_SHELL_LOGIN + + # Apply any explicit path prefix (see #99878) + if [ -n "$VSCODE_PATH_PREFIX" ]; then + export PATH=$VSCODE_PATH_PREFIX$PATH + builtin unset VSCODE_PATH_PREFIX + fi fi builtin unset VSCODE_INJECTION fi diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-profile.zsh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-profile.zsh index 6803fd9782f15..5a45b076b2256 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-profile.zsh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-profile.zsh @@ -7,4 +7,10 @@ if [[ $options[norcs] = off && -o "login" && -f $USER_ZDOTDIR/.zprofile ]]; the ZDOTDIR=$USER_ZDOTDIR . $USER_ZDOTDIR/.zprofile ZDOTDIR=$VSCODE_ZDOTDIR + + # Apply any explicit path prefix (see #99878) + if (( ${+VSCODE_PATH_PREFIX} )); then + export PATH=$VSCODE_PATH_PREFIX$PATH + fi + builtin unset VSCODE_PATH_PREFIX fi diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.fish b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.fish index 565fdf7bb87af..1e96dd9680160 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.fish +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.fish @@ -22,6 +22,12 @@ or exit set --global VSCODE_SHELL_INTEGRATION 1 +# Apply any explicit path prefix (see #99878) +if status --is-login; and set -q VSCODE_PATH_PREFIX + fish_add_path -p $VSCODE_PATH_PREFIX +end +set -e VSCODE_PATH_PREFIX + # Helper function function __vsc_esc -d "Emit escape sequences for VS Code shell integration" builtin printf "\e]633;%s\a" (string join ";" $argv) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 784ae0effd89b..bac68672ec003 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -75,8 +75,8 @@ import { ITerminalQuickFixAddon, TerminalQuickFixAddon } from 'vs/workbench/cont import { LineDataEventAddon } from 'vs/workbench/contrib/terminal/browser/xterm/lineDataEventAddon'; import { NavigationModeAddon } from 'vs/workbench/contrib/terminal/browser/xterm/navigationModeAddon'; import { XtermTerminal } from 'vs/workbench/contrib/terminal/browser/xterm/xtermTerminal'; -import { IEnvironmentVariableCollection, IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable'; -import { deserializeEnvironmentVariableCollections } from 'vs/workbench/contrib/terminal/common/environmentVariableShared'; +import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { deserializeEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariableShared'; import { getCommandHistory, getDirectoryHistory } from 'vs/workbench/contrib/terminal/common/history'; import { DEFAULT_COMMANDS_TO_SKIP_SHELL, INavigationMode, ITerminalProcessManager, ITerminalProfileResolverService, ProcessState, TerminalCommandId, TERMINAL_CREATION_COMMANDS, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; @@ -91,6 +91,7 @@ import { IAudioCueService, AudioCue } from 'vs/platform/audioCues/browser/audioC import { ITerminalQuickFixOptions } from 'vs/platform/terminal/common/xterm/terminalQuickFix'; import { FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files'; import { preparePathForShell } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; +import { IEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; const enum Constants { /** diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 40cb5d651de07..2a8783e26d072 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -25,9 +25,9 @@ import { TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { EnvironmentVariableInfoChangesActive, EnvironmentVariableInfoStale } from 'vs/workbench/contrib/terminal/browser/environmentVariableInfo'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { IEnvironmentVariableCollection, IEnvironmentVariableInfo, IEnvironmentVariableService, IMergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable'; -import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection'; -import { serializeEnvironmentVariableCollections } from 'vs/workbench/contrib/terminal/common/environmentVariableShared'; +import { IEnvironmentVariableInfo, IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection'; +import { serializeEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariableShared'; import { IBeforeProcessDataEvent, ITerminalBackend, ITerminalConfigHelper, ITerminalProcessManager, ITerminalProfileResolverService, ProcessState } from 'vs/workbench/contrib/terminal/common/terminal'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; @@ -38,6 +38,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA import { TaskSettingId } from 'vs/workbench/contrib/tasks/common/tasks'; import Severity from 'vs/base/common/severity'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IEnvironmentVariableCollection, IMergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; const enum ProcessConstants { /** diff --git a/src/vs/workbench/contrib/terminal/common/environmentVariable.ts b/src/vs/workbench/contrib/terminal/common/environmentVariable.ts index 00a87326b6ebd..284bdb04240d7 100644 --- a/src/vs/workbench/contrib/terminal/common/environmentVariable.ts +++ b/src/vs/workbench/contrib/terminal/common/environmentVariable.ts @@ -5,63 +5,11 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { Event } from 'vs/base/common/event'; -import { IProcessEnvironment } from 'vs/base/common/platform'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; -import { VariableResolver } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; +import { IEnvironmentVariableCollection, IMergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; export const IEnvironmentVariableService = createDecorator('environmentVariableService'); -export enum EnvironmentVariableMutatorType { - Replace = 1, - Append = 2, - Prepend = 3 -} - -export interface IEnvironmentVariableMutator { - readonly value: string; - readonly type: EnvironmentVariableMutatorType; -} - -export interface IExtensionOwnedEnvironmentVariableMutator extends IEnvironmentVariableMutator { - readonly extensionIdentifier: string; -} - -export interface IEnvironmentVariableCollection { - readonly map: ReadonlyMap; -} - -export interface IEnvironmentVariableCollectionWithPersistence extends IEnvironmentVariableCollection { - readonly persistent: boolean; -} - -export interface IMergedEnvironmentVariableCollectionDiff { - added: ReadonlyMap; - changed: ReadonlyMap; - removed: ReadonlyMap; -} - -/** - * Represents an environment variable collection that results from merging several collections - * together. - */ -export interface IMergedEnvironmentVariableCollection { - readonly collections: ReadonlyMap; - readonly map: ReadonlyMap; - - /** - * Applies this collection to a process environment. - * @param variableResolver An optional function to use to resolve variables within the - * environment values. - */ - applyToProcessEnvironment(env: IProcessEnvironment, variableResolver?: VariableResolver): Promise; - - /** - * Generates a diff of this connection against another. Returns undefined if the collections are - * the same. - */ - diff(other: IMergedEnvironmentVariableCollection): IMergedEnvironmentVariableCollectionDiff | undefined; -} - /** * Tracks and persists environment variable collections as defined by extensions. */ @@ -97,11 +45,9 @@ export interface IEnvironmentVariableService { delete(extensionIdentifier: string): void; } -/** [variable, mutator] */ -export type ISerializableEnvironmentVariableCollection = [string, IEnvironmentVariableMutator][]; - -/** [extension, collection] */ -export type ISerializableEnvironmentVariableCollections = [string, ISerializableEnvironmentVariableCollection][]; +export interface IEnvironmentVariableCollectionWithPersistence extends IEnvironmentVariableCollection { + readonly persistent: boolean; +} export interface IEnvironmentVariableInfo { readonly requiresAction: boolean; diff --git a/src/vs/workbench/contrib/terminal/common/environmentVariableService.ts b/src/vs/workbench/contrib/terminal/common/environmentVariableService.ts index 8a7eb1c7c0b01..9f68db1d984f0 100644 --- a/src/vs/workbench/contrib/terminal/common/environmentVariableService.ts +++ b/src/vs/workbench/contrib/terminal/common/environmentVariableService.ts @@ -7,10 +7,11 @@ import { Event, Emitter } from 'vs/base/common/event'; import { debounce, throttle } from 'vs/base/common/decorators'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection'; -import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared'; -import { IEnvironmentVariableCollectionWithPersistence, IEnvironmentVariableService, IMergedEnvironmentVariableCollection, ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection'; +import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared'; +import { IEnvironmentVariableCollectionWithPersistence, IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { TerminalStorageKeys } from 'vs/workbench/contrib/terminal/common/terminalStorageKeys'; +import { IMergedEnvironmentVariableCollection, ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; interface ISerializableExtensionEnvironmentVariableCollection { extensionIdentifier: string; diff --git a/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts b/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts index 9223124be8f3a..05bcb2a800c7b 100644 --- a/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts +++ b/src/vs/workbench/contrib/terminal/common/remoteTerminalChannel.ts @@ -11,18 +11,19 @@ import { IWorkbenchConfigurationService } from 'vs/workbench/services/configurat import { ILogService } from 'vs/platform/log/common/log'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared'; +import { serializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { SideBySideEditor, EditorResourceAccessor } from 'vs/workbench/common/editor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { Schemas } from 'vs/base/common/network'; import { ILabelService } from 'vs/platform/label/common/label'; -import { IEnvironmentVariableService, ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { IProcessDataEvent, IRequestResolveVariablesEvent, IShellLaunchConfigDto, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, IProcessProperty, ProcessPropertyType, IProcessPropertyMap, TitleEventSource, ISerializedTerminalState, IPtyHostController, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal'; import { IGetTerminalLayoutInfoArgs, IProcessDetails, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform'; import { ICompleteTerminalConfiguration } from 'vs/workbench/contrib/terminal/common/terminal'; import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; export const REMOTE_TERMINAL_CHANNEL_NAME = 'remoteterminal'; diff --git a/src/vs/workbench/contrib/terminal/test/common/environmentVariableCollection.test.ts b/src/vs/workbench/contrib/terminal/test/common/environmentVariableCollection.test.ts index 40c086a7dcce8..3ecd9b962e7cd 100644 --- a/src/vs/workbench/contrib/terminal/test/common/environmentVariableCollection.test.ts +++ b/src/vs/workbench/contrib/terminal/test/common/environmentVariableCollection.test.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import { deepStrictEqual, strictEqual } from 'assert'; -import { EnvironmentVariableMutatorType } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { EnvironmentVariableMutatorType } from 'vs/platform/terminal/common/environmentVariable'; import { IProcessEnvironment, isWindows } from 'vs/base/common/platform'; -import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection'; -import { deserializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared'; +import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection'; +import { deserializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared'; suite('EnvironmentVariable - MergedEnvironmentVariableCollection', () => { suite('ctor', () => { diff --git a/src/vs/workbench/contrib/terminal/test/common/environmentVariableService.test.ts b/src/vs/workbench/contrib/terminal/test/common/environmentVariableService.test.ts index dd391ea487d68..e3ac05202f80d 100644 --- a/src/vs/workbench/contrib/terminal/test/common/environmentVariableService.test.ts +++ b/src/vs/workbench/contrib/terminal/test/common/environmentVariableService.test.ts @@ -6,7 +6,7 @@ import { deepStrictEqual } from 'assert'; import { TestExtensionService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; import { EnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariableService'; -import { EnvironmentVariableMutatorType, IEnvironmentVariableMutator } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { EnvironmentVariableMutatorType, IEnvironmentVariableMutator } from 'vs/platform/terminal/common/environmentVariable'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; diff --git a/src/vs/workbench/contrib/terminal/test/common/environmentVariableShared.test.ts b/src/vs/workbench/contrib/terminal/test/common/environmentVariableShared.test.ts index 1f4e518c58ddc..cb96b0b8bb61d 100644 --- a/src/vs/workbench/contrib/terminal/test/common/environmentVariableShared.test.ts +++ b/src/vs/workbench/contrib/terminal/test/common/environmentVariableShared.test.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { deepStrictEqual } from 'assert'; -import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared'; -import { EnvironmentVariableMutatorType, IEnvironmentVariableMutator } from 'vs/workbench/contrib/terminal/common/environmentVariable'; +import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared'; +import { EnvironmentVariableMutatorType, IEnvironmentVariableMutator } from 'vs/platform/terminal/common/environmentVariable'; suite('EnvironmentVariable - deserializeEnvironmentVariableCollection', () => { test('should construct correctly with 3 arguments', () => {