With WorkspaceConfiguration.update(...) you can specify that the setting needs to be written to the ConfigurationTarget.Workspace. This updates the Workspace .code-workspace file if Multi Root or it updates the WorkspaceFolder .vscode/settings.json if opened a single folder.
Now I want to get the current setting from the Workspace (.code-workspace or .vscode/settings.json).
What is the ConfigurationScope I need to set in the call to workspace.getConfiguration?
What is the URI I need to use? The TextDocument and WorkspaceFolder will always get me the value from .vscode/settings.json
I found the method WorkspaceConfiguration.inspect. It shows the unmerged parts of the setting.
In my extension I have setup a configuration setting with "scope": "resource"
"configuration": {
"title": "Test Config",
"properties": {
"extension.someconfig": {
"type": "string",
"scope": "resource",
"description": "some test configuration setting",
"default": "default-value"
}
}
}
Defined a value for the Global/User level: "extension.someconfig": "user-value"
Setup a command to log a few things depending on the current file. I don't log the language parts of inspect because I don't use them (and where do you define them).
let uri = vscode.window.activeTextEditor.document.uri;
let config = vscode.workspace.getConfiguration('extension', uri);
console.log('---------');
console.log('someconfig:', config.get('someconfig'));
let inspect = config.inspect('someconfig');
console.log('inspect.key:', inspect.key);
console.log('inspect.defaultValue:', inspect.defaultValue);
console.log('inspect.globalValue:', inspect.globalValue);
console.log('inspect.workspaceValue:', inspect.workspaceValue);
console.log('inspect.workspaceFolderValue:', inspect.workspaceFolderValue);
I have setup a test MR Workspace:
testconfig
+ project1
| + .vscode
| | + settings.json // "extension.someconfig": "project1-value"
| + main.py
+ project2
| + .vscode
| | + settings.json // "extension.someconfig": "project2-value"
| + main.py
+ project3
| + .vscode
| | + settings.json // "extension.someconfig": "project3-value"
| + main.py
+ testconfig.code-workspace // "extension.someconfig": "workspace-value"
When I log the setting for a non-scoped getConfiguration:
let config = vscode.workspace.getConfiguration('extension');
All 3 main.py files give:
someconfig: workspace-value
inspect.key: extension.someconfig
inspect.defaultValue: default-value
inspect.globalValue: user-value
inspect.workspaceValue: workspace-value
inspect.workspaceFolderValue: undefined
When using the scoped getConfiguration:
let config = vscode.workspace.getConfiguration('extension', uri);
Common for all 3 main.py files:
inspect.key: extension.someconfig
inspect.defaultValue: default-value
inspect.globalValue: user-value
inspect.workspaceValue: workspace-value
--------- project1/main.py:
someconfig: project1-value
inspect.workspaceFolderValue: project1-value
--------- project2/main.py:
someconfig: project2-value
inspect.workspaceFolderValue: project2-value
--------- project3/main.py:
someconfig: project3-value
inspect.workspaceFolderValue: project3-value
When scoped to the WorkspaceFolder
let uri = vscode.window.activeTextEditor.document.uri;
let workspaceFolder = vscode.workspace.getWorkspaceFolder(uri);
let config = vscode.workspace.getConfiguration('extension', workspaceFolder);
The results are the same as for file scoped.
When the merged setting is determined the workspaceFolderValue is undefined for the non-scoped getConfiguration call.
The inspect call uses the same scope as the getConfiguration call that returned the WorkspaceConfiguration
I'll try to explain my limited understanding of what is going on here (as a relative rookie to extension coding).
Say I have these two commands:
const codeWorkspaceConfigs = vscode.workspace.getConfiguration('launch'); // no scope argument
const launchConfigs = vscode.workspace.getConfiguration('launch', workSpace.uri);
with no scope argument I get the launch settings from that *.code-workspace file only. Even if the <someName>.code-workspace file is in some weird unrelated place from the project's code. So that I believe is the short answer to your question. But it is more interesting.
Say I do have a 'launch.json ' file in a workspaceFolder, then on calling the second workspaced-scope getConfiguration() I get only that workspaceFolder's launch.json settings. Whether there is a code-workspace with launch settings or not.
But if there is a .code-workspace but no workspaceFolder launch.json then the second workspaced-scoped call gets me the .code-workspace settings!
As it should, since now there are no local settings anymore to override the more global .code-workspace settings.
Initially I misunderstand that ConfigurationScope parameter.
ConfigurationScope: Uri | TextDocument | WorkspaceFolder | {languageId: string, uri: Uri}
I thought that the WorkspaceFolder would get the settings actually listed in that WorksapceFolder's .vscode/settings.json but then why would there be a TextDocument or Uri option (where there wouldn't necessarily be any settings. But you are limiting the scope to those settings that apply to that document or uri - and that is the result of local settings overriding global settings, for example.
const codeWorkspaceConfigs = vscode.workspace.getConfiguration('launch'); // no scope argument
for me with this non-scoped version I get the .code-workspace settings only. While ConfigurationScope is an optional parameter to the getConfiguration() command I don't see any place that tells you what will happen (what the scope might be) if it is omitted. Maybe that is obvious to others, but it isn't to me.
To get a specific setting from .code-workspace this works for me:
let settings = vscode.workspace.getConfiguration().get('commandAlias.category');
and that setting is in both .code-workspace and in user settings.json. And it doesn't seem to matter what file is active at the time the configuration is retrieved.

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With