From bd57b0320a5b57cf349d6543372b4334677ab356 Mon Sep 17 00:00:00 2001 From: Dan Arad Date: Wed, 18 Nov 2020 15:32:24 +0200 Subject: [PATCH] 8349-support-vscode-settings-schemas: added support for workspace and folder schema uris Signed-off-by: Dan Arad --- .../preferences/preference-contribution.ts | 47 +++++++++++++++++-- .../preferences-json-schema-contribution.ts | 45 ++++++++++++++---- 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/packages/core/src/browser/preferences/preference-contribution.ts b/packages/core/src/browser/preferences/preference-contribution.ts index 019a7a64a7817..566247a0a320c 100644 --- a/packages/core/src/browser/preferences/preference-contribution.ts +++ b/packages/core/src/browser/preferences/preference-contribution.ts @@ -106,6 +106,8 @@ export class PreferenceSchemaProvider extends PreferenceProvider { protected readonly preferences: { [name: string]: any } = {}; protected readonly combinedSchema: PreferenceDataSchema = { properties: {}, patternProperties: {} }; + protected readonly workspaceSchema: PreferenceDataSchema = { properties: {}, patternProperties: {} }; + protected readonly folderSchema: PreferenceDataSchema = { properties: {}, patternProperties: {} }; @inject(ContributionProvider) @named(PreferenceContribution) protected readonly preferenceContributions: ContributionProvider; @@ -187,9 +189,9 @@ export class PreferenceSchemaProvider extends PreferenceProvider { const overridden = this.overriddenPreferenceName(preferenceName); if (overridden) { delete this.overridePatternProperties.properties[`[${overridden.overrideIdentifier}]`]; - delete this.combinedSchema.properties[`[${overridden.overrideIdentifier}]`]; + this.removePropFromSchemas(`[${overridden.overrideIdentifier}]`); } else { - delete this.combinedSchema.properties[preferenceName]; + this.removePropFromSchemas(preferenceName); } const newValue = change.oldValue; const oldValue = change.newValue; @@ -229,7 +231,7 @@ export class PreferenceSchemaProvider extends PreferenceProvider { if (schemaProps.overridable) { this.overridePatternProperties.properties[preferenceName] = schemaProps; } - this.combinedSchema.properties[preferenceName] = schemaProps; + this.updateSchemaProps(preferenceName, schemaProps); const value = schemaProps.defaultValue = this.getDefaultValue(schemaProps, preferenceName); if (this.testOverrideValue(preferenceName, value)) { @@ -291,6 +293,18 @@ export class PreferenceSchemaProvider extends PreferenceProvider { return this.combinedSchema; } + getSchema(scope: PreferenceScope): PreferenceDataSchema { + switch (scope) { + case PreferenceScope.Default: + case PreferenceScope.User: + return this.combinedSchema; + case PreferenceScope.Workspace: + return this.workspaceSchema; + case PreferenceScope.Folder: + return this.folderSchema; + } + } + setSchema(schema: PreferenceSchema): Disposable { const changes = this.doSetSchema(schema); if (!changes.length) { @@ -375,4 +389,31 @@ export class PreferenceSchemaProvider extends PreferenceProvider { testOverrideValue(name: string, value: any): value is PreferenceSchemaProperties { return PreferenceSchemaProperties.is(value) && OVERRIDE_PROPERTY_PATTERN.test(name); } + + private updateSchemaProps(key: string, property: PreferenceDataProperty): void { + this.combinedSchema.properties[key] = property; + + switch (property.scope) { + case PreferenceScope.Workspace: + this.workspaceSchema.properties[key] = property; + break; + case PreferenceScope.Folder: + this.folderSchema.properties[key] = property; + break; + } + } + + private removePropFromSchemas(key: string): void { + const scope = this.combinedSchema.properties[key].scope; + + delete this.combinedSchema.properties[key]; + switch (scope) { + case PreferenceScope.Workspace: + delete this.workspaceSchema.properties[key]; + break; + case PreferenceScope.Folder: + delete this.folderSchema.properties[key]; + break; + } + } } diff --git a/packages/preferences/src/browser/preferences-json-schema-contribution.ts b/packages/preferences/src/browser/preferences-json-schema-contribution.ts index b25f2c0ab47b0..51b6300e45a31 100644 --- a/packages/preferences/src/browser/preferences-json-schema-contribution.ts +++ b/packages/preferences/src/browser/preferences-json-schema-contribution.ts @@ -20,10 +20,14 @@ import { InMemoryResources } from '@theia/core'; import { JsonSchemaRegisterContext, JsonSchemaContribution } from '@theia/core/lib/browser/json-schema-store'; import { PreferenceSchemaProvider } from '@theia/core/lib/browser/preferences/preference-contribution'; import { PreferenceConfigurations } from '@theia/core/lib/browser/preferences/preference-configurations'; -import { UserStorageUri } from '@theia/userstorage/lib/browser/user-storage-uri'; +import { PreferenceScope } from '@theia/core/lib/browser'; + +const PREFERENCE_URI_PREFIX = 'vscode://schemas/settings/'; +const USER_STORAGE_PREFIX = 'user_storage:/'; @injectable() export class PreferencesJsonSchemaContribution implements JsonSchemaContribution { + private serializeSchema = (scope: PreferenceScope) => JSON.stringify(this.schemaProvider.getSchema(scope)); @inject(PreferenceSchemaProvider) protected readonly schemaProvider: PreferenceSchemaProvider; @@ -35,18 +39,39 @@ export class PreferencesJsonSchemaContribution implements JsonSchemaContribution protected readonly preferenceConfigurations: PreferenceConfigurations; registerSchemas(context: JsonSchemaRegisterContext): void { - const serializeSchema = () => JSON.stringify(this.schemaProvider.getCombinedSchema()); - const uri = new URI('vscode://schemas/settings/user'); - this.inmemoryResources.add(uri, serializeSchema()); - const baseName = this.preferenceConfigurations.getConfigName() + '.json'; - const fileMatch = [baseName, UserStorageUri.resolve(baseName).toString()]; + this.registerSchema(PreferenceScope.Default, context); + this.registerSchema(PreferenceScope.User, context); + this.registerSchema(PreferenceScope.Workspace, context); + this.registerSchema(PreferenceScope.Folder, context); + + this.schemaProvider.onDidPreferenceSchemaChanged(() => this.updateInMemoryResources()); + } + + private registerSchema(scope: PreferenceScope, context: JsonSchemaRegisterContext): void { + const scopeStr = PreferenceScope[scope].toLowerCase(); + const uri = new URI(PREFERENCE_URI_PREFIX + scopeStr); + + this.inmemoryResources.add(uri, this.serializeSchema(scope)); + context.registerSchema({ - fileMatch, + fileMatch: this.getFileMatch(scopeStr), url: uri.toString() }); - this.schemaProvider.onDidPreferenceSchemaChanged(() => - this.inmemoryResources.update(uri, serializeSchema()) - ); } + private updateInMemoryResources(): void { + this.inmemoryResources.update(new URI(PREFERENCE_URI_PREFIX + PreferenceScope[PreferenceScope.Default].toLowerCase()), + this.serializeSchema(+PreferenceScope.Default)); + this.inmemoryResources.update(new URI(PREFERENCE_URI_PREFIX + PreferenceScope[PreferenceScope.User].toLowerCase()), + this.serializeSchema(+PreferenceScope.User)); + this.inmemoryResources.update(new URI(PREFERENCE_URI_PREFIX + PreferenceScope[PreferenceScope.Workspace].toLowerCase()), + this.serializeSchema(+PreferenceScope.Workspace)); + this.inmemoryResources.update(new URI(PREFERENCE_URI_PREFIX + PreferenceScope[PreferenceScope.Folder].toLowerCase()), + this.serializeSchema(+PreferenceScope.Folder)); + } + + private getFileMatch(scope: string): string[] { + const baseName = this.preferenceConfigurations.getConfigName() + '.json'; + return [baseName, new URI(USER_STORAGE_PREFIX + scope).resolve(baseName).toString()]; + } }