Skip to content

Commit

Permalink
introduce new variable ${fileWorkspaceFolder}; fixes #84162
Browse files Browse the repository at this point in the history
  • Loading branch information
weinand committed Nov 16, 2020
1 parent b04e9c8 commit 876d1f0
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 46 deletions.
18 changes: 15 additions & 3 deletions src/vs/workbench/api/common/extHostDebugService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export abstract class ExtHostDebugServiceBase implements IExtHostDebugService, E

constructor(
@IExtHostRpcService extHostRpcService: IExtHostRpcService,
@IExtHostWorkspace private _workspaceService: IExtHostWorkspace,
@IExtHostWorkspace protected _workspaceService: IExtHostWorkspace,
@IExtHostExtensionService private _extensionService: IExtHostExtensionService,
@IExtHostDocumentsAndEditors private _editorsService: IExtHostDocumentsAndEditors,
@IExtHostConfiguration protected _configurationService: IExtHostConfiguration,
Expand Down Expand Up @@ -930,7 +930,7 @@ export class ExtHostDebugConsole implements vscode.DebugConsole {

export class ExtHostVariableResolverService extends AbstractVariableResolverService {

constructor(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors | undefined, configurationService: ExtHostConfigProvider, env?: IProcessEnvironment) {
constructor(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors | undefined, configurationService: ExtHostConfigProvider, env?: IProcessEnvironment, workspaceService?: IExtHostWorkspace) {
super({
getFolderUri: (folderName: string): URI | undefined => {
const found = folders.filter(f => f.name === folderName);
Expand All @@ -957,6 +957,18 @@ export class ExtHostVariableResolverService extends AbstractVariableResolverServ
}
return undefined;
},
getWorkspaceFolderPathForFile: (): string | undefined => {
if (editorService && workspaceService) {
const activeEditor = editorService.activeEditor();
if (activeEditor) {
const ws = workspaceService.getWorkspaceFolder(activeEditor.document.uri);
if (ws) {
return path.normalize(ws.uri.fsPath);
}
}
}
return undefined;
},
getSelectedText: (): string | undefined => {
if (editorService) {
const activeEditor = editorService.activeEditor();
Expand All @@ -975,7 +987,7 @@ export class ExtHostVariableResolverService extends AbstractVariableResolverServ
}
return undefined;
}
}, undefined, env, !editorService);
}, undefined, env);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/node/extHostDebugService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase {
}

protected createVariableResolver(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider): AbstractVariableResolverService {
return new ExtHostVariableResolverService(folders, editorService, configurationService, process.env as env.IProcessEnvironment);
return new ExtHostVariableResolverService(folders, editorService, configurationService, process.env as env.IProcessEnvironment, this._workspaceService);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR
}
return this.labelService.getUriLabel(fileResource, { noPrefix: true });
},
getWorkspaceFolderPathForFile: (): string | undefined => {
const fileResource = EditorResourceAccessor.getOriginalUri(editorService.activeEditor, {
supportSideBySide: SideBySideEditor.PRIMARY,
filterByScheme: [Schemas.file, Schemas.userData, Schemas.vscodeRemote]
});
if (!fileResource) {
return undefined;
}
const wsFolder = workspaceContextService.getWorkspaceFolder(fileResource);
if (!wsFolder) {
return undefined;
}
return this.labelService.getUriLabel(wsFolder.uri, { noPrefix: true });
},
getSelectedText: (): string | undefined => {
const activeTextEditorControl = editorService.activeTextEditorControl;
if (isCodeEditor(activeTextEditorControl)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface IVariableResolveContext {
getConfigurationValue(folderUri: uri, section: string): string | undefined;
getExecPath(): string | undefined;
getFilePath(): string | undefined;
getWorkspaceFolderPathForFile?(): string | undefined;
getSelectedText(): string | undefined;
getLineNumber(): string | undefined;
}
Expand All @@ -39,7 +40,7 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe
protected _contributedVariables: Map<string, () => Promise<string | undefined>> = new Map();


constructor(_context: IVariableResolveContext, _labelService?: ILabelService, _envVariables?: IProcessEnvironment, private _ignoreEditorVariables = false) {
constructor(_context: IVariableResolveContext, _labelService?: ILabelService, _envVariables?: IProcessEnvironment) {
this._context = _context;
this._labelService = _labelService;
if (_envVariables) {
Expand Down Expand Up @@ -169,7 +170,20 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe
if (filePath) {
return filePath;
}
throw new Error(localize('canNotResolveFile', "'{0}' can not be resolved. Please open an editor.", match));
throw new Error(localize('canNotResolveFile', "Variable {0} can not be resolved. Please open an editor.", match));
};

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

const filePath = getFilePath(); // throws error if no editor open
if (this._context.getWorkspaceFolderPathForFile) {
const folderPath = this._context.getWorkspaceFolderPathForFile();
if (folderPath) {
return folderPath;
}
}
throw new Error(localize('canNotResolveFolderForFile', "Variable {0}: can not find workspace folder of '{1}'.", match, paths.basename(filePath)));
};

// common error handling for all variables that require an open folder and accept a folder name argument
Expand All @@ -180,17 +194,17 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe
if (folder) {
return folder;
}
throw new Error(localize('canNotFindFolder', "'{0}' can not be resolved. No such folder '{1}'.", match, argument));
throw new Error(localize('canNotFindFolder', "Variable {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('canNotResolveWorkspaceFolderMultiRoot', "Variable {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));
throw new Error(localize('canNotResolveWorkspaceFolder', "Variable {0} can not be resolved. Please open a folder.", match));
};


Expand All @@ -207,20 +221,20 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe
// For `env` we should do the same as a normal shell does - evaluates undefined 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));
throw new Error(localize('missingEnvVarName', "Variable {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));
throw new Error(localize('configNotFound', "Variable {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));
throw new Error(localize('configNoString', "Variable {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));
throw new Error(localize('missingConfigName', "Variable {0} can not be resolved because no settings name is given.", match));

case 'command':
return this.resolveFromMap(match, argument, commandValueMapping, 'command');
Expand All @@ -243,44 +257,32 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe
return paths.basename(this.fsPath(getFolderUri()));

case 'lineNumber':
if (this._ignoreEditorVariables) {
return match;
}
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));
throw new Error(localize('canNotResolveLineNumber', "Variable {0} can not be resolved. Make sure to have a line selected in the active editor.", match));

case 'selectedText':
if (this._ignoreEditorVariables) {
return match;
}
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));
throw new Error(localize('canNotResolveSelectedText', "Variable {0} can not be resolved. Make sure to have some text selected in the active editor.", match));

case 'file':
if (this._ignoreEditorVariables) {
return match;
}
return getFilePath();

case 'fileWorkspaceFolder':
return getFolderPathForFile();

case 'relativeFile':
if (this._ignoreEditorVariables) {
return match;
}
if (folderUri || argument) {
return paths.relative(this.fsPath(getFolderUri()), getFilePath());
}
return getFilePath();

case 'relativeFileDirname':
if (this._ignoreEditorVariables) {
return match;
}
const dirname = paths.dirname(getFilePath());
if (folderUri || argument) {
const relative = paths.relative(this.fsPath(getFolderUri()), dirname);
Expand All @@ -289,34 +291,19 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe
return dirname;

case 'fileDirname':
if (this._ignoreEditorVariables) {
return match;
}
return paths.dirname(getFilePath());

case 'fileExtname':
if (this._ignoreEditorVariables) {
return match;
}
return paths.extname(getFilePath());

case 'fileBasename':
if (this._ignoreEditorVariables) {
return match;
}
return paths.basename(getFilePath());

case 'fileBasenameNoExtension':
if (this._ignoreEditorVariables) {
return match;
}
const basename = paths.basename(getFilePath());
return (basename.slice(0, basename.length - paths.extname(basename).length));

case 'fileDirnameBasename':
if (this._ignoreEditorVariables) {
return match;
}
return paths.basename(paths.dirname(getFilePath()));

case 'execPath':
Expand Down Expand Up @@ -346,7 +333,7 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe
if (typeof v === 'string') {
return v;
}
throw new Error(localize('noValueForCommand', "'{0}' can not be resolved because the command has no value.", match));
throw new Error(localize('noValueForCommand', "Variable {0} can not be resolved because the command has no value.", match));
}
return match;
}
Expand Down

0 comments on commit 876d1f0

Please sign in to comment.