variables: allow resolving extensionDir (#146274)

* variables: allow resolving `extensionDir`

This allows us to fix https://github.com/microsoft/vscode-remote-release/issues/5516#issuecomment-911597917

It enables a new replacement in the format `${extensionDir:<id>}` which
will expand to the filesystem path where the extension is stored. This
involved churn, since now resolution is always synchronous (where before
the terminal took a synchronous-only path.)

Additionally, changes were needed to inject this information in the
variable resolver. As part of this I made the extension host resolver
(used by debug and tasks) its own extension host service.

* fixup! preserve object key order in resolution, add extensionDir support

* fixup! address pr comments

* fixup! address pr comments

* fixup! address pr comments

* config: fix config replacement only working for first variable per line

* fixup! fix unit tests
This commit is contained in:
Connor Peet
2022-04-07 08:06:31 -07:00
committed by GitHub
parent 0fba8139ce
commit 0de44f9786
30 changed files with 450 additions and 298 deletions
@@ -40,7 +40,7 @@ function registerVariableCompletions(pattern: string): vscode.Disposable {
provideCompletionItems(document, position, _token) {
const location = getLocation(document.getText(), document.offsetAt(position));
if (!location.isAtPropertyKey && location.previousNode && location.previousNode.type === 'string') {
const indexOf$ = document.lineAt(position.line).text.indexOf('$');
const indexOf$ = document.lineAt(position.line).text.lastIndexOf('$', position.character);
const startPosition = indexOf$ >= 0 ? new vscode.Position(position.line, indexOf$) : position;
return [
@@ -58,9 +58,11 @@ function registerVariableCompletions(pattern: string): vscode.Disposable {
{ label: 'fileBasenameNoExtension', detail: localize('fileBasenameNoExtension', "The current opened file's basename with no file extension") },
{ label: 'defaultBuildTask', detail: localize('defaultBuildTask', "The name of the default build task. If there is not a single default build task then a quick pick is shown to choose the build task.") },
{ label: 'pathSeparator', detail: localize('pathSeparator', "The character used by the operating system to separate components in file paths") },
{ label: 'extensionInstallFolder', detail: localize('extensionInstallFolder', "The path where an an extension is installed."), param: 'publisher.extension' },
].map(variable => ({
label: '${' + variable.label + '}',
label: `\${${variable.label}}`,
range: new vscode.Range(startPosition, position),
insertText: variable.param ? new vscode.SnippetString(`\${${variable.label}:`).appendPlaceholder(variable.param).appendText('}') : (`\${${variable.label}}`),
detail: variable.detail
}));
}