private evaluateSingleVariable()

in src/vs/workbench/services/configurationResolver/common/variableResolver.ts [126:272]


	private evaluateSingleVariable(match: string, variable: string, folderUri: uri | undefined, commandValueMapping: IStringDictionary<string> | undefined): string {

		// try to separate variable arguments from variable name
		let argument: string | undefined;
		const parts = variable.split(':');
		if (parts.length > 1) {
			variable = parts[0];
			argument = parts[1];
		}

		// common error handling for all variables that require an open editor
		const getFilePath = (): string => {

			const filePath = this._context.getFilePath();
			if (filePath) {
				return filePath;
			}
			throw new Error(localize('canNotResolveFile', "'{0}' can not be resolved. Please open an editor.", match));
		};

		// common error handling for all variables that require an open folder and accept a folder name argument
		const getFolderUri = (withArg = true): uri => {

			if (withArg && argument) {
				const folder = this._context.getFolderUri(argument);
				if (folder) {
					return folder;
				}
				throw new Error(localize('canNotFindFolder', "'{0}' can not be resolved. No such folder '{1}'.", match, argument));
			}

			if (folderUri) {
				return folderUri;
			}

			if (this._context.getWorkspaceFolderCount() > 1) {
				throw new Error(localize('canNotResolveWorkspaceFolderMultiRoot', "'{0}' can not be resolved in a multi folder workspace. Scope this variable using ':' and a workspace folder name.", match));
			}
			throw new Error(localize('canNotResolveWorkspaceFolder', "'{0}' can not be resolved. Please open a folder.", match));
		};


		switch (variable) {

			case 'env':
				if (argument) {
					if (isWindows) {
						argument = argument.toLowerCase();
					}
					const env = this._envVariables[argument];
					if (types.isString(env)) {
						return env;
					}
					// For `env` we should do the same as a normal shell does - evaluates missing envs to an empty string #46436
					return '';
				}
				throw new Error(localize('missingEnvVarName', "'{0}' can not be resolved because no environment variable name is given.", match));

			case 'config':
				if (argument) {
					const config = this._context.getConfigurationValue(getFolderUri(false), argument);
					if (types.isUndefinedOrNull(config)) {
						throw new Error(localize('configNotFound', "'{0}' can not be resolved because setting '{1}' not found.", match, argument));
					}
					if (types.isObject(config)) {
						throw new Error(localize('configNoString', "'{0}' can not be resolved because '{1}' is a structured value.", match, argument));
					}
					return config;
				}
				throw new Error(localize('missingConfigName', "'{0}' can not be resolved because no settings name is given.", match));

			case 'command':
				return this.resolveFromMap(match, argument, commandValueMapping, 'command');

			case 'input':
				return this.resolveFromMap(match, argument, commandValueMapping, 'input');

			default: {

				switch (variable) {
					case 'workspaceRoot':
					case 'workspaceFolder':
						return normalizeDriveLetter(getFolderUri().fsPath);

					case 'cwd':
						return (folderUri ? normalizeDriveLetter(getFolderUri().fsPath) : process.cwd());

					case 'workspaceRootFolderName':
					case 'workspaceFolderBasename':
						return paths.basename(getFolderUri().fsPath);

					case 'lineNumber':
						const lineNumber = this._context.getLineNumber();
						if (lineNumber) {
							return lineNumber;
						}
						throw new Error(localize('canNotResolveLineNumber', "'{0}' can not be resolved. Make sure to have a line selected in the active editor.", match));

					case 'selectedText':
						const selectedText = this._context.getSelectedText();
						if (selectedText) {
							return selectedText;
						}
						throw new Error(localize('canNotResolveSelectedText', "'{0}' can not be resolved. Make sure to have some text selected in the active editor.", match));

					case 'file':
						return getFilePath();

					case 'relativeFile':
						if (folderUri) {
							return paths.normalize(paths.relative(getFolderUri().fsPath, getFilePath()));
						}
						return getFilePath();

					case 'relativeFileDirname':
						let dirname = paths.dirname(getFilePath());
						if (folderUri) {
							return paths.normalize(paths.relative(getFolderUri().fsPath, dirname));
						}
						return dirname;

					case 'fileDirname':
						return paths.dirname(getFilePath());

					case 'fileExtname':
						return paths.extname(getFilePath());

					case 'fileBasename':
						return paths.basename(getFilePath());

					case 'fileBasenameNoExtension':
						const basename = paths.basename(getFilePath());
						return (basename.slice(0, basename.length - paths.extname(basename).length));

					case 'execPath':
						const ep = this._context.getExecPath();
						if (ep) {
							return ep;
						}
						return match;

					default:
						return match;
				}
			}
		}
	}