Skip to main content

settings-precedence

VS Code settings precedence rules and common pitfalls. Essential for any code that reads or writes settings. Covers getConfiguration scope, inspect() vs get(), and multi-workspace handling.

Quellinformationen

Repository
microsoft/vscode-python-environments
Letzte Quellaktivität
16. Februar 2026 um 02:32
Erkannte Sprache von SKILL.md
Englisch
Sterne
145
Forks
77

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
settings-precedence
description
VS Code settings precedence rules and common pitfalls. Essential for any code that reads or writes settings. Covers getConfiguration scope, inspect() vs get(), and multi-workspace handling.
argument-hint
Review settings handling in [file or component]
user-invocable
false
# VS Code Settings Precedence Settings precedence bugs corrupt user configurations. This skill documents the correct patterns. ## Precedence Order (Highest to Lowest) 1. **Workspace folder value** - Per-folder in multi-root workspace 2. **Workspace value** - `.vscode/settings.json` or `.code-workspace` 3. **User/global value** - User `settings.json` 4. **Default value** - From extension's `package.json` (⚠️ may come from other extensions!) ## Core Rules ### Rule 1: Always Pass Scope to getConfiguration() ```typescript // ❌ WRONG: Missing scope const config = vscode.workspace.getConfiguration('python-envs'); const value = config.get('pythonProjects'); // workspaceFolderValue will be UNDEFINED because VS Code doesn't know which folder! // ✅ RIGHT: Pass scope (workspace folder or document URI) const config = vscode.workspace.getConfiguration('python-envs', workspaceFolder); const value = config.get('pythonProjects'); ``` **When to pass scope:** - Reading per-resource settings (`scope: "resource"` in package.json) - Any multi-workspace scenario - When you need `workspaceFolderValue` from inspect() ### Rule 2: Use inspect() to Check Explicit Values ```typescript // ❌ WRONG: get() returns defaultValue even from other extensions! const config = vscode.workspace.getConfiguration('python'); if (config.get('useEnvironmentsExtension')) { // May return true from another extension's package.json default! } // ✅ RIGHT: Use inspect() and check explicit values only const config = vscode.workspace.getConfiguration('python', scope); const inspected = config.inspect('useEnvironmentsExtension'); const hasExplicitValue = inspected?.globalValue !== undefined || inspected?.workspaceValue !== undefined || inspected?.workspaceFolderValue !== undefined; if (hasExplicitValue) { // User explicitly set this value const effectiveValue = inspected?.workspaceFolderValue ?? inspected?.workspaceValue ?? inspected?.globalValue; } ``` ### Rule 3: Don't Overwrite User's Explicit Values ```typescript // ❌ WRONG: Unconditionally writing to settings await config.update('pythonPath', detectedPath, ConfigurationTarget.Workspace); // Overwrites user's explicit choice! // ✅ RIGHT: Check for existing explicit values first const inspected = config.inspect('pythonPath'); const hasUserValue = inspected?.workspaceValue !== undefined; if (!hasUserValue) { // Only set if user hasn't explicitly chosen await config.update('pythonPath', detectedPath, ConfigurationTarget.Workspace); } ``` ### Rule 4: Update at the Correct Scope ```typescript // Configuration targets (least to most specific) ConfigurationTarget.Global; // User settings.json ConfigurationTarget.Workspace; // .vscode/settings.json or .code-workspace ConfigurationTarget.WorkspaceFolder; // Per-folder in multi-root // To remove a setting, update with undefined await config.update('pythonPath', undefined, ConfigurationTarget.Workspace); ``` ## Multi-Root Workspace Handling ### The `workspace` Property For multi-root workspaces, `pythonProjects` settings need a `workspace` property: ```json { "python-envs.pythonProjects": [ { "path": ".", "workspace": "/path/to/workspace-folder", "envManager": "ms-python.python:venv" } ] } ``` Without the `workspace` property, settings get mixed up between folders. ### Getting the Right Workspace Folder ```typescript // ❌ WRONG: Always using first workspace folder const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; // ✅ RIGHT: Get folder for specific document/file const workspaceFolder = vscode.workspace.getWorkspaceFolder(documentUri) ?? vscode.workspace.workspaceFolders?.[0]; // When you have a path but not a URI const uri = vscode.Uri.file(filePath); const workspaceFolder = vscode.workspace.getWorkspaceFolder(uri); ``` ## Common Issues ### Issue: workspaceFolderValue is undefined **Cause:** Missing scope parameter in `getConfiguration()` ```typescript // This returns undefined for workspaceFolderValue! const config = vscode.workspace.getConfiguration('python-envs'); const inspected = config.inspect('pythonProjects'); console.log(inspected?.workspaceFolderValue); // undefined! // Fix: Pass scope const config = vscode.workspace.getConfiguration('python-envs', workspaceFolder.uri); const inspected = config.inspect('pythonProjects'); console.log(inspected?.workspaceFolderValue); // Now works! ``` ### Issue: defaultValue from other extensions **Cause:** Using `get()` instead of `inspect()` for boolean checks The `defaultValue` in `inspect()` may come from ANY extension's `package.json`, not just yours: ```typescript // Another extension might have in their package.json: // "python.useEnvironmentsExtension": { "default": true } // Your check will be wrong: config.get('python.useEnvironmentsExtension') // true from other extension! // Fix: Only check explicit values const inspected = config.inspect('python.useEnvironmentsExtension'); if (inspected?.globalValue === true || ...) { } ``` ### Issue: Settings overwritten on reload **Cause:** Not checking for existing values before writing ```typescript // During extension activation, this overwrites user's config! await config.update('defaultEnvManager', 'venv', ConfigurationTarget.Global); // Fix: Only write defaults if no value exists const current = config.inspect('defaultEnvManager'); if (current?.globalValue === undefined && current?.workspaceValue === undefined) { await config.update('defaultEnvManager', 'venv', ConfigurationTarget.Global); } ``` ### Issue: Settings mixed up in multi-root **Cause:** Not including workspace identifier in settings ```typescript // Without workspace identifier, can't tell which folder this belongs to { "python-envs.pythonProjects": [ { "path": ".", "envManager": "venv" } // Which workspace? ] } // Fix: Always include workspace when saving const project = { path: projectPath, workspace: workspaceFolder.uri.fsPath, envManager: selectedManager }; ``` ## Complete Example: Safe Settings Read/Write ```typescript import * as vscode from 'vscode'; async function getProjectConfig(projectUri: vscode.Uri): Promise<ProjectConfig | undefined> { const workspaceFolder = vscode.workspace.getWorkspaceFolder(projectUri); if (!workspaceFolder) { return undefined; } // Always pass scope! const config = vscode.workspace.getConfiguration('python-envs', workspaceFolder.uri); // Use inspect() to understand where values come from const inspected = config.inspect<ProjectConfig[]>('pythonProjects'); // Prefer most specific value const projects = inspected?.workspaceFolderValue ?? inspected?.workspaceValue ?? inspected?.globalValue ?? []; // Don't use defaultValue! // Find project matching the URI return projects.find((p) => path.resolve(workspaceFolder.uri.fsPath, p.path) === projectUri.fsPath); } async function saveProjectConfig(projectUri: vscode.Uri, projectConfig: ProjectConfig): Promise<void> { const workspaceFolder = vscode.workspace.getWorkspaceFolder(projectUri); if (!workspaceFolder) { return; } const config = vscode.workspace.getConfiguration('python-envs', workspaceFolder.uri); const inspected = config.inspect<ProjectConfig[]>('pythonProjects'); // Get existing projects (not including defaults!) const existingProjects = inspected?.workspaceFolderValue ?? inspected?.workspaceValue ?? []; // Ensure workspace property for multi-root const configToSave: ProjectConfig = { ...projectConfig, workspace: workspaceFolder.uri.fsPath, }; // Update or add const projectIndex = existingProjects.findIndex( (p) => path.resolve(workspaceFolder.uri.fsPath, p.path) === projectUri.fsPath, ); const updatedProjects = [...existingProjects]; if (projectIndex >= 0) { updatedProjects[projectIndex] = configToSave; } else { updatedProjects.push(configToSave); } // Write to workspace folder scope in multi-root const target = vscode.workspace.workspaceFolders?.length > 1 ? vscode.ConfigurationTarget.WorkspaceFolder : vscode.ConfigurationTarget.Workspace; await config.update('pythonProjects', updatedProjects, target); } ```
Auf GitHub ansehen