mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-17 23:35:54 +01:00
fix reading configuration from workspace folders (#299302)
* fix reading configuration from workspace folders * feedback
This commit is contained in:
committed by
GitHub
parent
bcd6b6b1df
commit
5ee6f4f532
@@ -2015,6 +2015,7 @@ export default tseslint.config(
|
||||
'vs/editor/contrib/*/~',
|
||||
'vs/workbench/~',
|
||||
'vs/workbench/services/*/~',
|
||||
'vs/sessions/services/*/~',
|
||||
{
|
||||
'when': 'test',
|
||||
'pattern': 'vs/workbench/contrib/*/~'
|
||||
|
||||
@@ -352,14 +352,15 @@ export class SessionsMain extends Disposable {
|
||||
logService: ILogService,
|
||||
policyService: IPolicyService
|
||||
): Promise<{ configurationService: ConfigurationService; workspaceContextService: SessionsWorkspaceContextService }> {
|
||||
const configurationService = new ConfigurationService(userDataProfileService.currentProfile.settingsResource, fileService, policyService, logService);
|
||||
const workspaceContextService = new SessionsWorkspaceContextService(workspaceIdentifier, uriIdentityService);
|
||||
const configurationService = new ConfigurationService(userDataProfileService, workspaceContextService, uriIdentityService, fileService, policyService, logService);
|
||||
try {
|
||||
await configurationService.initialize();
|
||||
} catch (error) {
|
||||
onUnexpectedError(error);
|
||||
}
|
||||
|
||||
const workspaceContextService = new SessionsWorkspaceContextService(workspaceIdentifier, uriIdentityService, configurationService);
|
||||
workspaceContextService.setConfigurationService(configurationService);
|
||||
return { configurationService, workspaceContextService };
|
||||
}
|
||||
|
||||
|
||||
@@ -3,25 +3,375 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event } from '../../../../base/common/event.js';
|
||||
import { Extensions, IConfigurationRegistry } from '../../../../platform/configuration/common/configurationRegistry.js';
|
||||
import { ConfigurationService as BaseConfigurationService } from '../../../../platform/configuration/common/configurationService.js';
|
||||
import { onUnexpectedError } from '../../../../base/common/errors.js';
|
||||
import { Emitter, Event } from '../../../../base/common/event.js';
|
||||
import { Disposable, DisposableMap } from '../../../../base/common/lifecycle.js';
|
||||
import { ResourceMap } from '../../../../base/common/map.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { Queue } from '../../../../base/common/async.js';
|
||||
import { VSBuffer } from '../../../../base/common/buffer.js';
|
||||
import { JSONPath, ParseError, parse } from '../../../../base/common/json.js';
|
||||
import { applyEdits, setProperty } from '../../../../base/common/jsonEdit.js';
|
||||
import { Edit, FormattingOptions } from '../../../../base/common/jsonFormatter.js';
|
||||
import { equals } from '../../../../base/common/objects.js';
|
||||
import { distinct, equals as arrayEquals } from '../../../../base/common/arrays.js';
|
||||
import { OS, OperatingSystem } from '../../../../base/common/platform.js';
|
||||
import { IConfigurationChange, IConfigurationChangeEvent, IConfigurationData, IConfigurationOverrides, IConfigurationUpdateOptions, IConfigurationUpdateOverrides, IConfigurationValue, ConfigurationTarget, isConfigurationOverrides, isConfigurationUpdateOverrides } from '../../../../platform/configuration/common/configuration.js';
|
||||
import { ConfigurationChangeEvent, ConfigurationModel } from '../../../../platform/configuration/common/configurationModels.js';
|
||||
import { DefaultConfiguration, IPolicyConfiguration, NullPolicyConfiguration, PolicyConfiguration } from '../../../../platform/configuration/common/configurations.js';
|
||||
import { Extensions, IConfigurationRegistry, keyFromOverrideIdentifiers } from '../../../../platform/configuration/common/configurationRegistry.js';
|
||||
import { IFileService, FileOperationError, FileOperationResult } from '../../../../platform/files/common/files.js';
|
||||
import { ILogService } from '../../../../platform/log/common/log.js';
|
||||
import { IPolicyService, NullPolicyService } from '../../../../platform/policy/common/policy.js';
|
||||
import { Registry } from '../../../../platform/registry/common/platform.js';
|
||||
import { APPLICATION_SCOPES, APPLY_ALL_PROFILES_SETTING, IWorkbenchConfigurationService, RestrictedSettings } from '../../../../workbench/services/configuration/common/configuration.js';
|
||||
import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';
|
||||
import { IWorkspaceContextService, IWorkspaceFoldersChangeEvent, IWorkspaceFolder, WorkbenchState, Workspace } from '../../../../platform/workspace/common/workspace.js';
|
||||
import { FolderConfiguration, UserConfiguration } from '../../../../workbench/services/configuration/browser/configuration.js';
|
||||
import { APPLICATION_SCOPES, APPLY_ALL_PROFILES_SETTING, FOLDER_CONFIG_FOLDER_NAME, FOLDER_SETTINGS_PATH, IWorkbenchConfigurationService, RestrictedSettings } from '../../../../workbench/services/configuration/common/configuration.js';
|
||||
import { Configuration } from '../../../../workbench/services/configuration/common/configurationModels.js';
|
||||
import { IUserDataProfileService } from '../../../../workbench/services/userDataProfile/common/userDataProfile.js';
|
||||
|
||||
// Import to register contributions
|
||||
// Import to register configuration contributions
|
||||
import '../../../../workbench/services/configuration/browser/configurationService.js';
|
||||
|
||||
export class ConfigurationService extends BaseConfigurationService implements IWorkbenchConfigurationService {
|
||||
readonly restrictedSettings: RestrictedSettings = { default: [] };
|
||||
export class ConfigurationService extends Disposable implements IWorkbenchConfigurationService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private _configuration: Configuration;
|
||||
private readonly defaultConfiguration: DefaultConfiguration;
|
||||
private readonly policyConfiguration: IPolicyConfiguration;
|
||||
private readonly userConfiguration: UserConfiguration;
|
||||
private readonly cachedFolderConfigs = this._register(new DisposableMap<URI, FolderConfiguration>(new ResourceMap()));
|
||||
|
||||
private readonly _onDidChangeConfiguration = this._register(new Emitter<IConfigurationChangeEvent>());
|
||||
readonly onDidChangeConfiguration = this._onDidChangeConfiguration.event;
|
||||
|
||||
readonly onDidChangeRestrictedSettings = Event.None;
|
||||
readonly restrictedSettings: RestrictedSettings = { default: [] };
|
||||
|
||||
private readonly configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
|
||||
|
||||
private readonly settingsResource: URI;
|
||||
private readonly configurationEditing: ConfigurationEditing;
|
||||
|
||||
constructor(
|
||||
userDataProfileService: IUserDataProfileService,
|
||||
private readonly workspaceService: IWorkspaceContextService,
|
||||
private readonly uriIdentityService: IUriIdentityService,
|
||||
private readonly fileService: IFileService,
|
||||
policyService: IPolicyService,
|
||||
private readonly logService: ILogService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this.settingsResource = userDataProfileService.currentProfile.settingsResource;
|
||||
this.defaultConfiguration = this._register(new DefaultConfiguration(logService));
|
||||
this.policyConfiguration = policyService instanceof NullPolicyService ? new NullPolicyConfiguration() : this._register(new PolicyConfiguration(this.defaultConfiguration, policyService, logService));
|
||||
this.userConfiguration = this._register(new UserConfiguration(userDataProfileService.currentProfile.settingsResource, userDataProfileService.currentProfile.tasksResource, userDataProfileService.currentProfile.mcpResource, {}, fileService, uriIdentityService, logService));
|
||||
this.configurationEditing = new ConfigurationEditing(fileService, this);
|
||||
|
||||
this._configuration = new Configuration(
|
||||
ConfigurationModel.createEmptyModel(logService),
|
||||
ConfigurationModel.createEmptyModel(logService),
|
||||
ConfigurationModel.createEmptyModel(logService),
|
||||
ConfigurationModel.createEmptyModel(logService),
|
||||
ConfigurationModel.createEmptyModel(logService),
|
||||
ConfigurationModel.createEmptyModel(logService),
|
||||
new ResourceMap(),
|
||||
ConfigurationModel.createEmptyModel(logService),
|
||||
new ResourceMap<ConfigurationModel>(),
|
||||
this.workspaceService.getWorkspace() as Workspace,
|
||||
this.logService
|
||||
);
|
||||
|
||||
this._register(this.defaultConfiguration.onDidChangeConfiguration(({ defaults, properties }) => this.onDefaultConfigurationChanged(defaults, properties)));
|
||||
this._register(this.policyConfiguration.onDidChangeConfiguration(configurationModel => this.onPolicyConfigurationChanged(configurationModel)));
|
||||
this._register(this.userConfiguration.onDidChangeConfiguration(userConfiguration => this.onUserConfigurationChanged(userConfiguration)));
|
||||
this._register(this.workspaceService.onWillChangeWorkspaceFolders(e => e.join(this.loadFolderConfigurations(e.changes.added))));
|
||||
this._register(this.workspaceService.onDidChangeWorkspaceFolders(e => this.onWorkspaceFoldersChanged(e)));
|
||||
}
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
const [defaultModel, policyModel, userModel] = await Promise.all([
|
||||
this.defaultConfiguration.initialize(),
|
||||
this.policyConfiguration.initialize(),
|
||||
this.userConfiguration.initialize()
|
||||
]);
|
||||
const workspace = this.workspaceService.getWorkspace() as Workspace;
|
||||
this._configuration = new Configuration(
|
||||
defaultModel,
|
||||
policyModel,
|
||||
ConfigurationModel.createEmptyModel(this.logService),
|
||||
userModel,
|
||||
ConfigurationModel.createEmptyModel(this.logService),
|
||||
ConfigurationModel.createEmptyModel(this.logService),
|
||||
new ResourceMap(),
|
||||
ConfigurationModel.createEmptyModel(this.logService),
|
||||
new ResourceMap<ConfigurationModel>(),
|
||||
workspace,
|
||||
this.logService
|
||||
);
|
||||
await this.loadFolderConfigurations(workspace.folders);
|
||||
}
|
||||
|
||||
// #region IWorkbenchConfigurationService
|
||||
|
||||
getConfigurationData(): IConfigurationData {
|
||||
return this._configuration.toData();
|
||||
}
|
||||
|
||||
getValue<T>(): T;
|
||||
getValue<T>(section: string): T;
|
||||
getValue<T>(overrides: IConfigurationOverrides): T;
|
||||
getValue<T>(section: string, overrides: IConfigurationOverrides): T;
|
||||
getValue(arg1?: unknown, arg2?: unknown): unknown {
|
||||
const section = typeof arg1 === 'string' ? arg1 : undefined;
|
||||
const overrides = isConfigurationOverrides(arg1) ? arg1 : isConfigurationOverrides(arg2) ? arg2 : undefined;
|
||||
return this._configuration.getValue(section, overrides);
|
||||
}
|
||||
|
||||
updateValue(key: string, value: unknown): Promise<void>;
|
||||
updateValue(key: string, value: unknown, overrides: IConfigurationOverrides | IConfigurationUpdateOverrides): Promise<void>;
|
||||
updateValue(key: string, value: unknown, target: ConfigurationTarget): Promise<void>;
|
||||
updateValue(key: string, value: unknown, overrides: IConfigurationOverrides | IConfigurationUpdateOverrides, target: ConfigurationTarget, options?: IConfigurationUpdateOptions): Promise<void>;
|
||||
async updateValue(key: string, value: unknown, arg3?: unknown, arg4?: unknown, _options?: IConfigurationUpdateOptions): Promise<void> {
|
||||
const overrides: IConfigurationUpdateOverrides | undefined = isConfigurationUpdateOverrides(arg3) ? arg3
|
||||
: isConfigurationOverrides(arg3) ? { resource: arg3.resource, overrideIdentifiers: arg3.overrideIdentifier ? [arg3.overrideIdentifier] : undefined } : undefined;
|
||||
const target: ConfigurationTarget | undefined = (overrides ? arg4 : arg3) as ConfigurationTarget | undefined;
|
||||
|
||||
if (overrides?.overrideIdentifiers) {
|
||||
overrides.overrideIdentifiers = distinct(overrides.overrideIdentifiers);
|
||||
overrides.overrideIdentifiers = overrides.overrideIdentifiers.length ? overrides.overrideIdentifiers : undefined;
|
||||
}
|
||||
|
||||
const inspect = this.inspect(key, { resource: overrides?.resource, overrideIdentifier: overrides?.overrideIdentifiers ? overrides.overrideIdentifiers[0] : undefined });
|
||||
if (inspect.policyValue !== undefined) {
|
||||
throw new Error(`Unable to write ${key} because it is configured in system policy.`);
|
||||
}
|
||||
|
||||
// Remove the setting, if the value is same as default value
|
||||
if (equals(value, inspect.defaultValue)) {
|
||||
value = undefined;
|
||||
}
|
||||
|
||||
if (overrides?.overrideIdentifiers?.length && overrides.overrideIdentifiers.length > 1) {
|
||||
const overrideIdentifiers = overrides.overrideIdentifiers.sort();
|
||||
const existingOverrides = this._configuration.localUserConfiguration.overrides.find(override => arrayEquals([...override.identifiers].sort(), overrideIdentifiers));
|
||||
if (existingOverrides) {
|
||||
overrides.overrideIdentifiers = existingOverrides.identifiers;
|
||||
}
|
||||
}
|
||||
|
||||
const path = overrides?.overrideIdentifiers?.length ? [keyFromOverrideIdentifiers(overrides.overrideIdentifiers), key] : [key];
|
||||
|
||||
const settingsResource = this.getSettingsResource(target, overrides?.resource ?? undefined);
|
||||
await this.configurationEditing.write(settingsResource, path, value);
|
||||
await this.reloadConfiguration();
|
||||
}
|
||||
|
||||
private getSettingsResource(target: ConfigurationTarget | undefined, resource: URI | undefined): URI {
|
||||
if (target === ConfigurationTarget.WORKSPACE_FOLDER || target === ConfigurationTarget.WORKSPACE) {
|
||||
if (resource) {
|
||||
const folder = this.workspaceService.getWorkspaceFolder(resource);
|
||||
if (folder) {
|
||||
return this.uriIdentityService.extUri.joinPath(folder.uri, FOLDER_SETTINGS_PATH);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.settingsResource;
|
||||
}
|
||||
|
||||
inspect<T>(key: string, overrides?: IConfigurationOverrides): IConfigurationValue<T> {
|
||||
return this._configuration.inspect<T>(key, overrides);
|
||||
}
|
||||
|
||||
keys(): { default: string[]; policy: string[]; user: string[]; workspace: string[]; workspaceFolder: string[] } {
|
||||
return this._configuration.keys();
|
||||
}
|
||||
|
||||
async reloadConfiguration(_target?: ConfigurationTarget | IWorkspaceFolder): Promise<void> {
|
||||
const userModel = await this.userConfiguration.initialize();
|
||||
const previousData = this._configuration.toData();
|
||||
const change = this._configuration.compareAndUpdateLocalUserConfiguration(userModel);
|
||||
|
||||
// Reload folder configurations
|
||||
for (const folder of this.workspaceService.getWorkspace().folders) {
|
||||
const folderConfiguration = this.cachedFolderConfigs.get(folder.uri);
|
||||
if (folderConfiguration) {
|
||||
const folderModel = await folderConfiguration.loadConfiguration();
|
||||
const folderChange = this._configuration.compareAndUpdateFolderConfiguration(folder.uri, folderModel);
|
||||
change.keys.push(...folderChange.keys);
|
||||
change.overrides.push(...folderChange.overrides);
|
||||
}
|
||||
}
|
||||
|
||||
this.triggerConfigurationChange(change, previousData, ConfigurationTarget.USER);
|
||||
}
|
||||
|
||||
hasCachedConfigurationDefaultsOverrides(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
async whenRemoteConfigurationLoaded(): Promise<void> { }
|
||||
|
||||
isSettingAppliedForAllProfiles(key: string): boolean {
|
||||
const scope = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties()[key]?.scope;
|
||||
const scope = this.configurationRegistry.getConfigurationProperties()[key]?.scope;
|
||||
if (scope && APPLICATION_SCOPES.includes(scope)) {
|
||||
return true;
|
||||
}
|
||||
const allProfilesSettings = this.getValue<string[]>(APPLY_ALL_PROFILES_SETTING) ?? [];
|
||||
return Array.isArray(allProfilesSettings) && allProfilesSettings.includes(key);
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Configuration change handlers
|
||||
|
||||
private onDefaultConfigurationChanged(defaults: ConfigurationModel, properties?: string[]): void {
|
||||
const previousData = this._configuration.toData();
|
||||
const change = this._configuration.compareAndUpdateDefaultConfiguration(defaults, properties);
|
||||
this._configuration.updateLocalUserConfiguration(this.userConfiguration.reparse());
|
||||
for (const folder of this.workspaceService.getWorkspace().folders) {
|
||||
const folderConfiguration = this.cachedFolderConfigs.get(folder.uri);
|
||||
if (folderConfiguration) {
|
||||
this._configuration.updateFolderConfiguration(folder.uri, folderConfiguration.reparse());
|
||||
}
|
||||
}
|
||||
this.triggerConfigurationChange(change, previousData, ConfigurationTarget.DEFAULT);
|
||||
}
|
||||
|
||||
private onPolicyConfigurationChanged(policyConfiguration: ConfigurationModel): void {
|
||||
const previousData = this._configuration.toData();
|
||||
const change = this._configuration.compareAndUpdatePolicyConfiguration(policyConfiguration);
|
||||
this.triggerConfigurationChange(change, previousData, ConfigurationTarget.DEFAULT);
|
||||
}
|
||||
|
||||
private onUserConfigurationChanged(userConfiguration: ConfigurationModel): void {
|
||||
const previousData = this._configuration.toData();
|
||||
const change = this._configuration.compareAndUpdateLocalUserConfiguration(userConfiguration);
|
||||
this.triggerConfigurationChange(change, previousData, ConfigurationTarget.USER);
|
||||
}
|
||||
|
||||
private onWorkspaceFoldersChanged(e: IWorkspaceFoldersChangeEvent): void {
|
||||
// Remove configurations for removed folders
|
||||
const previousData = this._configuration.toData();
|
||||
const keys: string[] = [];
|
||||
const overrides: [string, string[]][] = [];
|
||||
for (const folder of e.removed) {
|
||||
const change = this._configuration.compareAndDeleteFolderConfiguration(folder.uri);
|
||||
keys.push(...change.keys);
|
||||
overrides.push(...change.overrides);
|
||||
this.cachedFolderConfigs.deleteAndDispose(folder.uri);
|
||||
}
|
||||
if (keys.length || overrides.length) {
|
||||
this.triggerConfigurationChange({ keys, overrides }, previousData, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
}
|
||||
}
|
||||
|
||||
private onWorkspaceFolderConfigurationChanged(folder: IWorkspaceFolder): void {
|
||||
const folderConfiguration = this.cachedFolderConfigs.get(folder.uri);
|
||||
if (folderConfiguration) {
|
||||
folderConfiguration.loadConfiguration().then(configurationModel => {
|
||||
const previousData = this._configuration.toData();
|
||||
const change = this._configuration.compareAndUpdateFolderConfiguration(folder.uri, configurationModel);
|
||||
this.triggerConfigurationChange(change, previousData, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
}, onUnexpectedError);
|
||||
}
|
||||
}
|
||||
|
||||
private async loadFolderConfigurations(folders: readonly IWorkspaceFolder[]): Promise<void> {
|
||||
for (const folder of folders) {
|
||||
let folderConfiguration = this.cachedFolderConfigs.get(folder.uri);
|
||||
if (!folderConfiguration) {
|
||||
folderConfiguration = new FolderConfiguration(false, folder, FOLDER_CONFIG_FOLDER_NAME, WorkbenchState.WORKSPACE, true, this.fileService, this.uriIdentityService, this.logService, { needsCaching: () => false, read: async () => '', write: async () => { }, remove: async () => { } });
|
||||
folderConfiguration.addRelated(folderConfiguration.onDidChange(() => this.onWorkspaceFolderConfigurationChanged(folder)));
|
||||
this.cachedFolderConfigs.set(folder.uri, folderConfiguration);
|
||||
}
|
||||
const configurationModel = await folderConfiguration.loadConfiguration();
|
||||
this._configuration.updateFolderConfiguration(folder.uri, configurationModel);
|
||||
}
|
||||
}
|
||||
|
||||
private triggerConfigurationChange(change: IConfigurationChange, previousData: IConfigurationData, target: ConfigurationTarget): void {
|
||||
if (change.keys.length) {
|
||||
const workspace = this.workspaceService.getWorkspace() as Workspace;
|
||||
const event = new ConfigurationChangeEvent(change, { data: previousData, workspace }, this._configuration, workspace, this.logService);
|
||||
event.source = target;
|
||||
this._onDidChangeConfiguration.fire(event);
|
||||
}
|
||||
}
|
||||
|
||||
// #endregion
|
||||
}
|
||||
|
||||
class ConfigurationEditing {
|
||||
|
||||
private readonly queue = new Queue<void>();
|
||||
|
||||
constructor(
|
||||
private readonly fileService: IFileService,
|
||||
private readonly configurationService: ConfigurationService,
|
||||
) { }
|
||||
|
||||
write(settingsResource: URI, path: JSONPath, value: unknown): Promise<void> {
|
||||
return this.queue.queue(() => this.doWriteConfiguration(settingsResource, path, value));
|
||||
}
|
||||
|
||||
private async doWriteConfiguration(settingsResource: URI, path: JSONPath, value: unknown): Promise<void> {
|
||||
let content: string;
|
||||
try {
|
||||
const fileContent = await this.fileService.readFile(settingsResource);
|
||||
content = fileContent.value.toString();
|
||||
} catch (error) {
|
||||
if ((error as FileOperationError).fileOperationResult === FileOperationResult.FILE_NOT_FOUND) {
|
||||
content = '{}';
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
const parseErrors: ParseError[] = [];
|
||||
parse(content, parseErrors, { allowTrailingComma: true, allowEmptyContent: true });
|
||||
if (parseErrors.length > 0) {
|
||||
throw new Error('Unable to write into the settings file. Please open the file to correct errors/warnings in the file and try again.');
|
||||
}
|
||||
|
||||
const edits = this.getEdits(content, path, value);
|
||||
content = applyEdits(content, edits);
|
||||
|
||||
await this.fileService.writeFile(settingsResource, VSBuffer.fromString(content));
|
||||
}
|
||||
|
||||
private getEdits(content: string, path: JSONPath, value: unknown): Edit[] {
|
||||
const { tabSize, insertSpaces, eol } = this.formattingOptions;
|
||||
|
||||
if (!path.length) {
|
||||
const newContent = JSON.stringify(value, null, insertSpaces ? ' '.repeat(tabSize) : '\t');
|
||||
return [{
|
||||
content: newContent,
|
||||
length: content.length,
|
||||
offset: 0
|
||||
}];
|
||||
}
|
||||
|
||||
return setProperty(content, path, value, { tabSize, insertSpaces, eol });
|
||||
}
|
||||
|
||||
private _formattingOptions: Required<FormattingOptions> | undefined;
|
||||
private get formattingOptions(): Required<FormattingOptions> {
|
||||
if (!this._formattingOptions) {
|
||||
let eol = OS === OperatingSystem.Linux || OS === OperatingSystem.Macintosh ? '\n' : '\r\n';
|
||||
const configuredEol = this.configurationService.getValue<string>('files.eol', { overrideIdentifier: 'jsonc' });
|
||||
if (configuredEol && typeof configuredEol === 'string' && configuredEol !== 'auto') {
|
||||
eol = configuredEol;
|
||||
}
|
||||
this._formattingOptions = {
|
||||
eol,
|
||||
insertSpaces: !!this.configurationService.getValue('editor.insertSpaces', { overrideIdentifier: 'jsonc' }),
|
||||
tabSize: this.configurationService.getValue('editor.tabSize', { overrideIdentifier: 'jsonc' })
|
||||
};
|
||||
}
|
||||
return this._formattingOptions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import assert from 'assert';
|
||||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { Registry } from '../../../../../platform/registry/common/platform.js';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from '../../../../../platform/configuration/common/configurationRegistry.js';
|
||||
import { ConfigurationTarget } from '../../../../../platform/configuration/common/configuration.js';
|
||||
import { FileService } from '../../../../../platform/files/common/fileService.js';
|
||||
import { NullLogService } from '../../../../../platform/log/common/log.js';
|
||||
import { NullPolicyService } from '../../../../../platform/policy/common/policy.js';
|
||||
import { VSBuffer } from '../../../../../base/common/buffer.js';
|
||||
import { UriIdentityService } from '../../../../../platform/uriIdentity/common/uriIdentityService.js';
|
||||
import { InMemoryFileSystemProvider } from '../../../../../platform/files/common/inMemoryFilesystemProvider.js';
|
||||
import { joinPath } from '../../../../../base/common/resources.js';
|
||||
import { Schemas } from '../../../../../base/common/network.js';
|
||||
import { UserDataProfilesService } from '../../../../../platform/userDataProfile/common/userDataProfile.js';
|
||||
import { UserDataProfileService } from '../../../../../workbench/services/userDataProfile/common/userDataProfileService.js';
|
||||
import { FileUserDataProvider } from '../../../../../platform/userData/common/fileUserDataProvider.js';
|
||||
import { TestEnvironmentService } from '../../../../../workbench/test/browser/workbenchTestServices.js';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
|
||||
import { runWithFakedTimers } from '../../../../../base/test/common/timeTravelScheduler.js';
|
||||
import { ConfigurationService } from '../../browser/configurationService.js';
|
||||
import { SessionsWorkspaceContextService } from '../../../workspace/browser/workspaceContextService.js';
|
||||
import { getWorkspaceIdentifier } from '../../../../../workbench/services/workspaces/browser/workspaces.js';
|
||||
import { Event } from '../../../../../base/common/event.js';
|
||||
import { IUserDataProfileService } from '../../../../../workbench/services/userDataProfile/common/userDataProfile.js';
|
||||
|
||||
const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' });
|
||||
|
||||
suite('Sessions ConfigurationService', () => {
|
||||
|
||||
let testObject: ConfigurationService;
|
||||
let workspaceService: SessionsWorkspaceContextService;
|
||||
let fileService: FileService;
|
||||
let userDataProfileService: IUserDataProfileService;
|
||||
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
|
||||
const disposables = ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
suiteSetup(() => {
|
||||
configurationRegistry.registerConfiguration({
|
||||
'id': '_test_sessions',
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'sessionsConfigurationService.testSetting': {
|
||||
'type': 'string',
|
||||
'default': 'defaultValue',
|
||||
scope: ConfigurationScope.RESOURCE
|
||||
},
|
||||
'sessionsConfigurationService.machineSetting': {
|
||||
'type': 'string',
|
||||
'default': 'defaultValue',
|
||||
scope: ConfigurationScope.MACHINE
|
||||
},
|
||||
'sessionsConfigurationService.applicationSetting': {
|
||||
'type': 'string',
|
||||
'default': 'defaultValue',
|
||||
scope: ConfigurationScope.APPLICATION
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
setup(async () => {
|
||||
const logService = new NullLogService();
|
||||
fileService = disposables.add(new FileService(logService));
|
||||
const fileSystemProvider = disposables.add(new InMemoryFileSystemProvider());
|
||||
disposables.add(fileService.registerProvider(ROOT.scheme, fileSystemProvider));
|
||||
|
||||
const environmentService = TestEnvironmentService;
|
||||
const uriIdentityService = disposables.add(new UriIdentityService(fileService));
|
||||
const userDataProfilesService = disposables.add(new UserDataProfilesService(environmentService, fileService, uriIdentityService, logService));
|
||||
disposables.add(fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, logService))));
|
||||
userDataProfileService = disposables.add(new UserDataProfileService(userDataProfilesService.defaultProfile));
|
||||
|
||||
const configResource = joinPath(ROOT, 'agent-sessions.code-workspace');
|
||||
await fileService.writeFile(configResource, VSBuffer.fromString(JSON.stringify({ folders: [] })));
|
||||
|
||||
workspaceService = disposables.add(new SessionsWorkspaceContextService(getWorkspaceIdentifier(configResource), uriIdentityService));
|
||||
testObject = disposables.add(new ConfigurationService(userDataProfileService, workspaceService, uriIdentityService, fileService, new NullPolicyService(), logService));
|
||||
await testObject.initialize();
|
||||
});
|
||||
|
||||
// #region Reading
|
||||
|
||||
test('defaults', () => {
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.machineSetting'), 'defaultValue');
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.applicationSetting'), 'defaultValue');
|
||||
});
|
||||
|
||||
test('user settings override defaults', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));
|
||||
await testObject.reloadConfiguration();
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'userValue');
|
||||
}));
|
||||
|
||||
test('workspace folder settings override user settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'myFolder');
|
||||
await fileService.createFolder(folder);
|
||||
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));
|
||||
await testObject.reloadConfiguration();
|
||||
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
|
||||
}));
|
||||
|
||||
test('folder settings are read when folders are added', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'addedFolder');
|
||||
await fileService.createFolder(folder);
|
||||
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
|
||||
}));
|
||||
|
||||
test('folder settings are removed when folders are removed', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'removedFolder');
|
||||
await fileService.createFolder(folder);
|
||||
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
|
||||
await workspaceService.removeFolders([folder]);
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'defaultValue');
|
||||
}));
|
||||
|
||||
test('configuration change event is fired when folders with settings are removed', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'removedFolder2');
|
||||
await fileService.createFolder(folder);
|
||||
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
|
||||
|
||||
const promise = Event.toPromise(testObject.onDidChangeConfiguration);
|
||||
await workspaceService.removeFolders([folder]);
|
||||
const event = await promise;
|
||||
assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'defaultValue');
|
||||
}));
|
||||
|
||||
test('configuration change event is fired on user settings change', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const promise = Event.toPromise(testObject.onDidChangeConfiguration);
|
||||
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));
|
||||
await testObject.reloadConfiguration();
|
||||
const event = await promise;
|
||||
assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));
|
||||
}));
|
||||
|
||||
test('inspect returns correct values per layer', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'inspectFolder');
|
||||
await fileService.createFolder(folder);
|
||||
await fileService.writeFile(userDataProfileService.currentProfile.settingsResource, VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "userValue" }'));
|
||||
await testObject.reloadConfiguration();
|
||||
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
|
||||
const inspection = testObject.inspect('sessionsConfigurationService.testSetting', { resource: folder });
|
||||
assert.strictEqual(inspection.defaultValue, 'defaultValue');
|
||||
assert.strictEqual(inspection.userValue, 'userValue');
|
||||
assert.strictEqual(inspection.workspaceFolderValue, 'folderValue');
|
||||
}));
|
||||
|
||||
test('application settings are not read from workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'appFolder');
|
||||
await fileService.createFolder(folder);
|
||||
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.applicationSetting": "folderValue" }'));
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.applicationSetting', { resource: folder }), 'defaultValue');
|
||||
}));
|
||||
|
||||
test('machine settings are not read from workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'machineFolder');
|
||||
await fileService.createFolder(folder);
|
||||
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.machineSetting": "folderValue" }'));
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.machineSetting', { resource: folder }), 'defaultValue');
|
||||
}));
|
||||
|
||||
test('folder settings change fires configuration change event', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'changeFolder');
|
||||
await fileService.createFolder(folder);
|
||||
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "initialValue" }'));
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'initialValue');
|
||||
|
||||
const promise = Event.toPromise(testObject.onDidChangeConfiguration);
|
||||
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "updatedValue" }'));
|
||||
const event = await promise;
|
||||
assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'updatedValue');
|
||||
}));
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Writing
|
||||
|
||||
test('updateValue writes to user settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'writtenValue');
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'writtenValue');
|
||||
}));
|
||||
|
||||
test('updateValue persists to settings file', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'persistedValue');
|
||||
|
||||
const content = (await fileService.readFile(userDataProfileService.currentProfile.settingsResource)).value.toString();
|
||||
assert.ok(content.includes('"sessionsConfigurationService.testSetting"'));
|
||||
assert.ok(content.includes('persistedValue'));
|
||||
}));
|
||||
|
||||
test('updateValue fires change event', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const promise = Event.toPromise(testObject.onDidChangeConfiguration);
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'eventValue');
|
||||
const event = await promise;
|
||||
assert.ok(event.affectsConfiguration('sessionsConfigurationService.testSetting'));
|
||||
}));
|
||||
|
||||
test('updateValue removes setting when value equals default', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'nonDefault');
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'nonDefault');
|
||||
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'defaultValue');
|
||||
const content = (await fileService.readFile(userDataProfileService.currentProfile.settingsResource)).value.toString();
|
||||
assert.ok(!content.includes('sessionsConfigurationService.testSetting'));
|
||||
}));
|
||||
|
||||
test('updateValue can update multiple settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'value1');
|
||||
await testObject.updateValue('sessionsConfigurationService.machineSetting', 'value2');
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'value1');
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.machineSetting'), 'value2');
|
||||
}));
|
||||
|
||||
test('updateValue with language override', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'langValue', { overrideIdentifier: 'jsonc' });
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { overrideIdentifier: 'jsonc' }), 'langValue');
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');
|
||||
}));
|
||||
|
||||
test('updateValue is reflected in inspect', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'inspectedValue');
|
||||
const inspection = testObject.inspect('sessionsConfigurationService.testSetting');
|
||||
assert.strictEqual(inspection.defaultValue, 'defaultValue');
|
||||
assert.strictEqual(inspection.userValue, 'inspectedValue');
|
||||
}));
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Workspace Folder - Read and Write
|
||||
|
||||
test('read setting from workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'readFolder');
|
||||
await fileService.createFolder(folder);
|
||||
await fileService.writeFile(joinPath(folder, '.vscode', 'settings.json'), VSBuffer.fromString('{ "sessionsConfigurationService.testSetting": "folderValue" }'));
|
||||
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');
|
||||
}));
|
||||
|
||||
test('write setting to workspace folder', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'writeFolder');
|
||||
await fileService.createFolder(folder);
|
||||
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'writtenFolderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'writtenFolderValue');
|
||||
}));
|
||||
|
||||
test('write setting to workspace folder persists to folder settings file', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'persistFolder');
|
||||
await fileService.createFolder(folder);
|
||||
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'persistedFolderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
|
||||
const content = (await fileService.readFile(joinPath(folder, '.vscode', 'settings.json'))).value.toString();
|
||||
assert.ok(content.includes('"sessionsConfigurationService.testSetting"'));
|
||||
assert.ok(content.includes('persistedFolderValue'));
|
||||
}));
|
||||
|
||||
test('write setting to workspace folder does not affect user settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'isolateFolder');
|
||||
await fileService.createFolder(folder);
|
||||
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderOnly', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderOnly');
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'defaultValue');
|
||||
}));
|
||||
|
||||
test('workspace folder setting overrides user setting for resource', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'overrideFolder');
|
||||
await fileService.createFolder(folder);
|
||||
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'userValue');
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting'), 'userValue');
|
||||
}));
|
||||
|
||||
test('inspect shows workspace folder value after write', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'inspectWriteFolder');
|
||||
await fileService.createFolder(folder);
|
||||
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'userVal');
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderVal', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
|
||||
const inspection = testObject.inspect('sessionsConfigurationService.testSetting', { resource: folder });
|
||||
assert.strictEqual(inspection.defaultValue, 'defaultValue');
|
||||
assert.strictEqual(inspection.userValue, 'userVal');
|
||||
assert.strictEqual(inspection.workspaceFolderValue, 'folderVal');
|
||||
}));
|
||||
|
||||
test('removing folder clears its written settings', () => runWithFakedTimers<void>({ useFakeTimers: true }, async () => {
|
||||
const folder = joinPath(ROOT, 'clearFolder');
|
||||
await fileService.createFolder(folder);
|
||||
|
||||
await workspaceService.addFolders([{ uri: folder }]);
|
||||
await testObject.updateValue('sessionsConfigurationService.testSetting', 'folderValue', { resource: folder }, ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'folderValue');
|
||||
|
||||
await workspaceService.removeFolders([folder]);
|
||||
assert.strictEqual(testObject.getValue('sessionsConfigurationService.testSetting', { resource: folder }), 'defaultValue');
|
||||
}));
|
||||
|
||||
// #endregion
|
||||
});
|
||||
@@ -35,7 +35,6 @@ export class SessionsWorkspaceContextService extends Disposable implements IWork
|
||||
constructor(
|
||||
workspaceIdentifier: IWorkspaceIdentifier,
|
||||
private readonly uriIdentityService: IUriIdentityService,
|
||||
private readonly configurationService: IConfigurationService,
|
||||
) {
|
||||
super();
|
||||
this.workspace = new Workspace(workspaceIdentifier.id, [], false, workspaceIdentifier.configPath, uri => uriIdentityService.extUri.ignorePathCasing(uri));
|
||||
@@ -53,8 +52,13 @@ export class SessionsWorkspaceContextService extends Disposable implements IWork
|
||||
return WorkbenchState.WORKSPACE;
|
||||
}
|
||||
|
||||
private _configurationService: IConfigurationService | undefined;
|
||||
setConfigurationService(configurationService: IConfigurationService) {
|
||||
this._configurationService = configurationService;
|
||||
}
|
||||
|
||||
hasWorkspaceData(): boolean {
|
||||
return this.configurationService.getValue('sessions.workspace.sendWorkspaceDataToExtHost') === true;
|
||||
return this._configurationService?.getValue('sessions.workspace.sendWorkspaceDataToExtHost') === true;
|
||||
}
|
||||
|
||||
getWorkspaceFolder(resource: URI): IWorkspaceFolder | null {
|
||||
@@ -159,7 +163,8 @@ export class SessionsWorkspaceContextService extends Disposable implements IWork
|
||||
|
||||
// Update workspace
|
||||
const workspaceIdentifier = getWorkspaceIdentifier(this.workspace.configuration!);
|
||||
this.workspace = new Workspace(workspaceIdentifier.id, newFolders, false, workspaceIdentifier.configPath, uri => this.uriIdentityService.extUri.ignorePathCasing(uri));
|
||||
const workspace = new Workspace(workspaceIdentifier.id, newFolders, false, workspaceIdentifier.configPath, uri => this.uriIdentityService.extUri.ignorePathCasing(uri));
|
||||
this.workspace.update(workspace);
|
||||
|
||||
// Fire did change event
|
||||
this._onDidChangeWorkspaceFolders.fire(changes);
|
||||
|
||||
@@ -363,7 +363,7 @@ export class SettingsTargetsWidget extends Widget {
|
||||
private async update(): Promise<void> {
|
||||
this.settingsSwitcherBar.domNode.classList.toggle('empty-workbench', this.contextService.getWorkbenchState() === WorkbenchState.EMPTY);
|
||||
this.userRemoteSettings.enabled = !!(this.options.enableRemoteSettings && this.environmentService.remoteAuthority);
|
||||
this.workspaceSettings.enabled = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY;
|
||||
this.workspaceSettings.enabled = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY && !this.environmentService.isSessionsWindow;
|
||||
this.folderSettings.action.enabled = this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE && this.contextService.getWorkspace().folders.length > 0;
|
||||
|
||||
this.workspaceSettings.tooltip = localize('workspaceSettings', "Workspace");
|
||||
|
||||
Reference in New Issue
Block a user