Skip to content

Commit

Permalink
8349-support-vscode-settings-schemas: added support for workspace and…
Browse files Browse the repository at this point in the history
… folder schema uris

Signed-off-by: Dan Arad <dan.arad@sap.com>
  • Loading branch information
danarad05 authored and amiramw committed Jan 11, 2021
1 parent 4abaff2 commit 7e8992b
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 13 deletions.
47 changes: 44 additions & 3 deletions packages/core/src/browser/preferences/preference-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<PreferenceContribution>;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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()];
}
}

0 comments on commit 7e8992b

Please sign in to comment.