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