Skip to content

Commit

Permalink
make color contribution point dynamic
Browse files Browse the repository at this point in the history
  • Loading branch information
aeschli committed Jan 23, 2019
1 parent 6220dcd commit 6ded24b
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 32 deletions.
22 changes: 11 additions & 11 deletions extensions/rust/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
]
}
}
52 changes: 43 additions & 9 deletions src/vs/platform/theme/common/colorRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -46,14 +48,21 @@ export const Extensions = {

export interface IColorRegistry {

readonly onDidChangeSchema: Event<void>;

/**
* 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
*/
Expand All @@ -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;

Expand All @@ -79,9 +88,13 @@ export interface IColorRegistry {


class ColorRegistry implements IColorRegistry {

private readonly _onDidChangeSchema = new Emitter<void>();
readonly onDidChangeSchema: Event<void> = 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 = {};
Expand All @@ -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]);
}
Expand Down Expand Up @@ -449,6 +476,13 @@ export const workbenchColorsSchemaId = 'vscode://schemas/workbench-colors';
let schemaRegistry = platform.Registry.as<IJSONContributionRegistry>(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);


Expand Down
34 changes: 22 additions & 12 deletions src/vs/workbench/services/themes/common/colorExtensionPoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@

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;
description: string;
defaults: { light: string, dark: string, highContrast: string };
}

const colorReferenceSchema = getColorRegistry().getColorReferenceSchema();
const colorRegistry: IColorRegistry = Registry.as<IColorRegistry>(ColorRegistryExtensions.ColorContribution);

const colorReferenceSchema = colorRegistry.getColorReferenceSchema();
const colorIdPattern = '^\\w+[.\\w+]*$';

const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint<IColorExtensionPoint[]>({
extensionPoint: 'colors',
isDynamic: true,
jsonSchema: {
description: nls.localize('contributes.color', 'Contributes extension defined themable colors'),
type: 'array',
Expand Down Expand Up @@ -72,8 +76,8 @@ const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint<IColorEx
export class ColorExtensionPoint {

constructor() {
configurationExtPoint.setHandler((extensions) => {
for (const extension of extensions) {
configurationExtPoint.setHandler((extensions, delta) => {
for (const extension of delta.added) {
const extensionValue = <IColorExtensionPoint[]>extension.value;
const collector = extension.collector;

Expand All @@ -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 = <IColorExtensionPoint[]>extension.value;
for (const colorContribution of extensionValue) {
colorRegistry.deregisterColor(colorContribution.id);
}
}
});
}
Expand Down

0 comments on commit 6ded24b

Please sign in to comment.