Skip to content

Expose API for variable substitution in contributed configuration #46471

Open
@rozzzly

Description

@rozzzly

So now we have a bunch of variable substitutions we can use in .vscode/tasks.json

${workspaceFolder} - the path of the folder opened in VS Code
${workspaceFolderBasename} - the name of the folder opened in VS Code without any slashes (/)
${file} - the current opened file
${relativeFile} - the current opened file relative to workspaceFolder
${fileBasename} - the current opened file's basename
${fileBasenameNoExtension} - the current opened file's basename with no file extension
${fileDirname} - the current opened file's dirname
${fileExtname} - the current opened file's extension
${cwd} - the task runner's current working directory on startup
${lineNumber} - the current selected line number in the active file
${env:Name} - the `Name` variable from the environment
${config:Name} - example: ${config:editor.fontSize}
${command:CommandID} - example: ${command:explorer.newFolder}

But what if an extension wants to give the user the ability to use substitution for the configuration points it contributes, the extension developer has to implement that all themselves. While it is totally possible to support all of these substitutions, even inlined commands, from an extension the developer has to reinvent the wheel and maintain compatibility with future/past versions of VSCode.

It would be great if there was a way for an extension to make use of the existing variable substitution logic. Unfortunately, this is pretty deeply embedded into vscode and not something made readily accessible to extension developers.

I'm sure that there will be demand for custom substitutions and for limiting what kind of substitutions are allowed.

Really rough, but this is how something like this could look.

./package.json

"contributes": {
  "substitutions": {
    "prompt-debug.colorOfSky": {
      "description": "..."
    }
    "prompt-debug.binaryPath": {
      "description": "..."
    }
  },
  "configuration": {
    "properties": {
      "prompt-debug.autoResolveScript": {
        "description": "A javascript or typescript file which is exports a function named 'autoResolve' that resolves a file path to run.",
        "title": "Auto Resolve Script",
        "type": "string",
        "required": false,
		"substitutions": false, // substitutions disabled (default)
        "substitutions": "*", // allow all registered substitutions
		"substitutions": [
		  "*", // allow all registered substitutions
		  "-command:*" // exclude commands from substitutions
		  "command:explorer.newFolder" // with the exception of the newFolder command
		],
        "substitutions": [
    	  "substitution:prompt-debug.*" // allow all of the substitutions prompt-debug contributes
		  "-substitution:prompt-debug.binaryPath" // with the exception of binaryPath 
		]
	}
}

./src/extension.ts

export function activate(context: vscode.ExtensionContext) {
  vscode.substitutions.registerSubstitution('prompt-debug.colorOfSky', () => (Math.random() > 0.5) ? 'blue' : 'grey');
  vscode.substitutions.registerSubstitution('prompt-debug.binaryPath', async () => {
    const binaryPath = await someAsycStuff();
	if (binaryPath) return binaryPath;
    else return '/usr/bin/derp';
  });
}

Obviously vscode.workspace.getConfiguration().get('prompt-debug.autoResolveScript'); would have to be async because substitutions with commands can take a while to evaluate.. I have a few good ideas, but I'm tired of typing so we can bikeshed later if anyone is actually interested in this.. lol

Metadata

Metadata

Assignees

No one assigned

    Labels

    apifeature-requestRequest for new features or functionality

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions