diff --git a/extensions/rust/package.json b/extensions/rust/package.json index 4436da8bcafc5..58ee4e84987ac 100644 --- a/extensions/rust/package.json +++ b/extensions/rust/package.json @@ -9,16 +9,16 @@ "update-grammar": "node ../../build/npm/update-grammar.js zargony/atom-language-rust grammars/rust.cson ./syntaxes/rust.tmLanguage.json" }, "contributes": { - "languages": [{ - "id": "rust", - "extensions": [".rs"], - "aliases": ["Rust", "rust"], - "configuration": "./language-configuration.json" - }], - "grammars": [{ - "language": "rust", - "path": "./syntaxes/rust.tmLanguage.json", - "scopeName":"source.rust" - }] + "colors": [ + { + "id": "rub.addedResourceForeground", + "description": "%colors.added%", + "defaults": { + "light": "#587c0c", + "dark": "#81b88b", + "highContrast": "#1b5225" + } + } + ] } } \ No newline at end of file diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 1a0b67210d646..aafd80bf811a3 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -4,12 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as platform from 'vs/platform/registry/common/platform'; -import { IJSONSchema } from 'vs/base/common/jsonSchema'; +import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import { Color, RGBA } from 'vs/base/common/color'; import { ITheme } from 'vs/platform/theme/common/themeService'; +import { Event, Emitter } from 'vs/base/common/event'; import * as nls from 'vs/nls'; import { Extensions as JSONExtensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; +import { RunOnceScheduler } from 'vs/base/common/async'; // ------ API types @@ -46,14 +48,21 @@ export const Extensions = { export interface IColorRegistry { + readonly onDidChangeSchema: Event; + /** * Register a color to the registry. - * @param id The color id as used in theme descrition files + * @param id The color id as used in theme description files * @param defaults The default values * @description the description */ registerColor(id: string, defaults: ColorDefaults, description: string): ColorIdentifier; + /** + * Register a color to the registry. + */ + deregisterColor(id: string); + /** * Get all color contributions */ @@ -65,12 +74,12 @@ export interface IColorRegistry { resolveDefaultColor(id: ColorIdentifier, theme: ITheme): Color | null; /** - * JSON schema for an object to assign color values to one of the color contrbutions. + * JSON schema for an object to assign color values to one of the color contributions. */ getColorSchema(): IJSONSchema; /** - * JSON schema to for a reference to a color contrbution. + * JSON schema to for a reference to a color contribution. */ getColorReferenceSchema(): IJSONSchema; @@ -79,9 +88,13 @@ export interface IColorRegistry { class ColorRegistry implements IColorRegistry { + + private readonly _onDidChangeSchema = new Emitter(); + readonly onDidChangeSchema: Event = this._onDidChangeSchema.event; + private colorsById: { [key: string]: ColorContribution }; - private colorSchema: IJSONSchema = { type: 'object', properties: {} }; - private colorReferenceSchema: IJSONSchema = { type: 'string', enum: [], enumDescriptions: [] }; + private colorSchema: IJSONSchema & { properties: IJSONSchemaMap } = { type: 'object', properties: {} }; + private colorReferenceSchema: IJSONSchema & { enum: string[], enumDescriptions: string[] } = { type: 'string', enum: [], enumDescriptions: [] }; constructor() { this.colorsById = {}; @@ -94,12 +107,26 @@ class ColorRegistry implements IColorRegistry { if (deprecationMessage) { propertySchema.deprecationMessage = deprecationMessage; } - this.colorSchema.properties![id] = propertySchema; - this.colorReferenceSchema.enum!.push(id); - this.colorReferenceSchema.enumDescriptions!.push(description); + this.colorSchema.properties[id] = propertySchema; + this.colorReferenceSchema.enum.push(id); + this.colorReferenceSchema.enumDescriptions.push(description); + + this._onDidChangeSchema.fire(); return id; } + + public deregisterColor(id: string): void { + delete this.colorsById[id]; + delete this.colorSchema.properties[id]; + const index = this.colorReferenceSchema.enum.indexOf(id); + if (index !== -1) { + this.colorReferenceSchema.enum.splice(index, 1); + this.colorReferenceSchema.enumDescriptions.splice(index, 1); + } + this._onDidChangeSchema.fire(); + } + public getColors(): ColorContribution[] { return Object.keys(this.colorsById).map(id => this.colorsById[id]); } @@ -449,6 +476,13 @@ export const workbenchColorsSchemaId = 'vscode://schemas/workbench-colors'; let schemaRegistry = platform.Registry.as(JSONExtensions.JSONContribution); schemaRegistry.registerSchema(workbenchColorsSchemaId, colorRegistry.getColorSchema()); +const delayer = new RunOnceScheduler(() => schemaRegistry.notifySchemaChanged(workbenchColorsSchemaId), 200); +colorRegistry.onDidChangeSchema(() => { + if (!delayer.isScheduled()) { + delayer.schedule(); + } +}); + // setTimeout(_ => console.log(colorRegistry.toString()), 5000); diff --git a/src/vs/workbench/services/themes/common/colorExtensionPoint.ts b/src/vs/workbench/services/themes/common/colorExtensionPoint.ts index e903d072150fc..b810fdfd67f93 100644 --- a/src/vs/workbench/services/themes/common/colorExtensionPoint.ts +++ b/src/vs/workbench/services/themes/common/colorExtensionPoint.ts @@ -5,8 +5,9 @@ import * as nls from 'vs/nls'; import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { registerColor, getColorRegistry } from 'vs/platform/theme/common/colorRegistry'; +import { IColorRegistry, Extensions as ColorRegistryExtensions } from 'vs/platform/theme/common/colorRegistry'; import { Color } from 'vs/base/common/color'; +import { Registry } from 'vs/platform/registry/common/platform'; interface IColorExtensionPoint { id: string; @@ -14,11 +15,14 @@ interface IColorExtensionPoint { defaults: { light: string, dark: string, highContrast: string }; } -const colorReferenceSchema = getColorRegistry().getColorReferenceSchema(); +const colorRegistry: IColorRegistry = Registry.as(ColorRegistryExtensions.ColorContribution); + +const colorReferenceSchema = colorRegistry.getColorReferenceSchema(); const colorIdPattern = '^\\w+[.\\w+]*$'; const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint({ extensionPoint: 'colors', + isDynamic: true, jsonSchema: { description: nls.localize('contributes.color', 'Contributes extension defined themable colors'), type: 'array', @@ -72,8 +76,8 @@ const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint { - for (const extension of extensions) { + configurationExtPoint.setHandler((extensions, delta) => { + for (const extension of delta.added) { const extensionValue = extension.value; const collector = extension.collector; @@ -93,30 +97,36 @@ export class ColorExtensionPoint { return Color.red; }; - extensionValue.forEach(extension => { - if (typeof extension.id !== 'string' || extension.id.length === 0) { + for (const colorContribution of extensionValue) { + if (typeof colorContribution.id !== 'string' || colorContribution.id.length === 0) { collector.error(nls.localize('invalid.id', "'configuration.colors.id' must be defined and can not be empty")); return; } - if (!extension.id.match(colorIdPattern)) { + if (!colorContribution.id.match(colorIdPattern)) { collector.error(nls.localize('invalid.id.format', "'configuration.colors.id' must follow the word[.word]*")); return; } - if (typeof extension.description !== 'string' || extension.id.length === 0) { + if (typeof colorContribution.description !== 'string' || colorContribution.id.length === 0) { collector.error(nls.localize('invalid.description', "'configuration.colors.description' must be defined and can not be empty")); return; } - let defaults = extension.defaults; + let defaults = colorContribution.defaults; if (!defaults || typeof defaults !== 'object' || typeof defaults.light !== 'string' || typeof defaults.dark !== 'string' || typeof defaults.highContrast !== 'string') { collector.error(nls.localize('invalid.defaults', "'configuration.colors.defaults' must be defined and must contain 'light', 'dark' and 'highContrast'")); return; } - registerColor(extension.id, { + colorRegistry.registerColor(colorContribution.id, { light: parseColorValue(defaults.light, 'configuration.colors.defaults.light'), dark: parseColorValue(defaults.dark, 'configuration.colors.defaults.dark'), hc: parseColorValue(defaults.highContrast, 'configuration.colors.defaults.highContrast') - }, extension.description); - }); + }, colorContribution.description); + } + } + for (const extension of delta.removed) { + const extensionValue = extension.value; + for (const colorContribution of extensionValue) { + colorRegistry.deregisterColor(colorContribution.id); + } } }); }