mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
Re #34366. Extensions define color formats.
This commit is contained in:
parent
ff8c917a87
commit
d069e922ef
|
@ -6,7 +6,7 @@
|
|||
|
||||
import * as path from 'path';
|
||||
|
||||
import { languages, window, commands, ExtensionContext, TextDocument, ColorRange, ColorFormat, Color } from 'vscode';
|
||||
import { languages, window, commands, ExtensionContext, TextDocument, ColorInformation, ColorPresentation, Color, TextEdit as CodeTextEdit } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, TextEdit } from 'vscode-languageclient';
|
||||
|
||||
import { ConfigurationFeature } from 'vscode-languageclient/lib/proposed';
|
||||
|
@ -60,38 +60,45 @@ export function activate(context: ExtensionContext) {
|
|||
client.onReady().then(_ => {
|
||||
// register color provider
|
||||
context.subscriptions.push(languages.registerColorProvider(documentSelector, {
|
||||
provideDocumentColors(document: TextDocument): Thenable<ColorRange[]> {
|
||||
provideDocumentColors(document: TextDocument): Thenable<ColorInformation[]> {
|
||||
let params = client.code2ProtocolConverter.asDocumentSymbolParams(document);
|
||||
return client.sendRequest(DocumentColorRequest.type, params).then(symbols => {
|
||||
return symbols.map(symbol => {
|
||||
let range = client.protocol2CodeConverter.asRange(symbol.range);
|
||||
let color = new Color(symbol.color.red * 255, symbol.color.green * 255, symbol.color.blue * 255, symbol.color.alpha);
|
||||
return new ColorRange(range, color);
|
||||
return new ColorInformation(range, color);
|
||||
});
|
||||
});
|
||||
},
|
||||
resolveDocumentColor(color: Color, colorFormat: ColorFormat): Thenable<string> | string {
|
||||
switch (colorFormat) {
|
||||
case ColorFormat.RGB:
|
||||
if (color.alpha === 1) {
|
||||
return `rgb(${Math.round(color.red * 255)}, ${Math.round(color.green * 255)}, ${Math.round(color.blue * 255)})`;
|
||||
} else {
|
||||
return `rgba(${Math.round(color.red * 255)}, ${Math.round(color.green * 255)}, ${Math.round(color.blue * 255)}, ${color.alpha})`;
|
||||
}
|
||||
case ColorFormat.HEX:
|
||||
if (color.alpha === 1) {
|
||||
return `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}`;
|
||||
} else {
|
||||
return `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}${_toTwoDigitHex(Math.round(color.alpha * 255))}`;
|
||||
}
|
||||
case ColorFormat.HSL:
|
||||
const hsl = convert.rgb.hsl(Math.round(color.red * 255), Math.round(color.green * 255), Math.round(color.blue * 255));
|
||||
if (color.alpha === 1) {
|
||||
return `hsl(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%)`;
|
||||
} else {
|
||||
return `hsla(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%, ${color.alpha})`;
|
||||
}
|
||||
provideColorPresentations(colorInfo: ColorInformation): ColorPresentation[] | Thenable<ColorPresentation[]> {
|
||||
let result: ColorPresentation[] = [];
|
||||
let color = colorInfo.color;
|
||||
let label;
|
||||
if (color.alpha === 1) {
|
||||
label = `rgb(${Math.round(color.red * 255)}, ${Math.round(color.green * 255)}, ${Math.round(color.blue * 255)})`;
|
||||
} else {
|
||||
label = `rgba(${Math.round(color.red * 255)}, ${Math.round(color.green * 255)}, ${Math.round(color.blue * 255)}, ${color.alpha})`;
|
||||
}
|
||||
|
||||
result.push({ label: label, textEdit: new CodeTextEdit(colorInfo.range, label) });
|
||||
|
||||
if (color.alpha === 1) {
|
||||
label = `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}`;
|
||||
} else {
|
||||
label = `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}${_toTwoDigitHex(Math.round(color.alpha * 255))}`;
|
||||
}
|
||||
|
||||
result.push({ label: label, textEdit: new CodeTextEdit(colorInfo.range, label) });
|
||||
|
||||
const hsl = convert.rgb.hsl(Math.round(color.red * 255), Math.round(color.green * 255), Math.round(color.blue * 255));
|
||||
if (color.alpha === 1) {
|
||||
label = `hsl(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%)`;
|
||||
} else {
|
||||
label = `hsla(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%, ${color.alpha})`;
|
||||
}
|
||||
|
||||
result.push({ label: label, textEdit: new CodeTextEdit(colorInfo.range, label) });
|
||||
return result;
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import * as path from 'path';
|
||||
|
||||
import { languages, ExtensionContext, IndentAction, Position, TextDocument, Color, ColorRange, ColorFormat } from 'vscode';
|
||||
import { languages, ExtensionContext, IndentAction, Position, TextDocument, Color, ColorInformation, ColorPresentation, TextEdit } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, TextDocumentPositionParams } from 'vscode-languageclient';
|
||||
import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared';
|
||||
import { activateTagClosing } from './tagClosing';
|
||||
|
@ -77,38 +77,45 @@ export function activate(context: ExtensionContext) {
|
|||
toDispose.push(disposable);
|
||||
client.onReady().then(() => {
|
||||
disposable = languages.registerColorProvider(documentSelector, {
|
||||
provideDocumentColors(document: TextDocument): Thenable<ColorRange[]> {
|
||||
provideDocumentColors(document: TextDocument): Thenable<ColorInformation[]> {
|
||||
let params = client.code2ProtocolConverter.asDocumentSymbolParams(document);
|
||||
return client.sendRequest(DocumentColorRequest.type, params).then(symbols => {
|
||||
return symbols.map(symbol => {
|
||||
let range = client.protocol2CodeConverter.asRange(symbol.range);
|
||||
let color = new Color(symbol.color.red * 255, symbol.color.green * 255, symbol.color.blue * 255, symbol.color.alpha);
|
||||
return new ColorRange(range, color);
|
||||
return new ColorInformation(range, color);
|
||||
});
|
||||
});
|
||||
},
|
||||
resolveDocumentColor(color: Color, colorFormat: ColorFormat): Thenable<string> | string {
|
||||
switch (colorFormat) {
|
||||
case ColorFormat.RGB:
|
||||
if (color.alpha === 1) {
|
||||
return `rgb(${Math.round(color.red * 255)}, ${Math.round(color.green * 255)}, ${Math.round(color.blue * 255)})`;
|
||||
} else {
|
||||
return `rgba(${Math.round(color.red * 255)}, ${Math.round(color.green * 255)}, ${Math.round(color.blue * 255)}, ${color.alpha})`;
|
||||
}
|
||||
case ColorFormat.HEX:
|
||||
if (color.alpha === 1) {
|
||||
return `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}`;
|
||||
} else {
|
||||
return `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}${_toTwoDigitHex(Math.round(color.alpha * 255))}`;
|
||||
}
|
||||
case ColorFormat.HSL:
|
||||
const hsl = convert.rgb.hsl(Math.round(color.red * 255), Math.round(color.green * 255), Math.round(color.blue * 255));
|
||||
if (color.alpha === 1) {
|
||||
return `hsl(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%)`;
|
||||
} else {
|
||||
return `hsla(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%, ${color.alpha})`;
|
||||
}
|
||||
provideColorPresentations(colorInfo: ColorInformation): ColorPresentation[] | Thenable<ColorPresentation[]> {
|
||||
let result: ColorPresentation[] = [];
|
||||
let color = colorInfo.color;
|
||||
let label;
|
||||
if (color.alpha === 1) {
|
||||
label = `rgb(${Math.round(color.red * 255)}, ${Math.round(color.green * 255)}, ${Math.round(color.blue * 255)})`;
|
||||
} else {
|
||||
label = `rgba(${Math.round(color.red * 255)}, ${Math.round(color.green * 255)}, ${Math.round(color.blue * 255)}, ${color.alpha})`;
|
||||
}
|
||||
|
||||
result.push({ label: label, textEdit: new TextEdit(colorInfo.range, label) });
|
||||
|
||||
if (color.alpha === 1) {
|
||||
label = `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}`;
|
||||
} else {
|
||||
label = `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}${_toTwoDigitHex(Math.round(color.alpha * 255))}`;
|
||||
}
|
||||
|
||||
result.push({ label: label, textEdit: new TextEdit(colorInfo.range, label) });
|
||||
|
||||
const hsl = convert.rgb.hsl(Math.round(color.red * 255), Math.round(color.green * 255), Math.round(color.blue * 255));
|
||||
if (color.alpha === 1) {
|
||||
label = `hsl(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%)`;
|
||||
} else {
|
||||
label = `hsla(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%, ${color.alpha})`;
|
||||
}
|
||||
|
||||
result.push({ label: label, textEdit: new TextEdit(colorInfo.range, label) });
|
||||
return result;
|
||||
}
|
||||
});
|
||||
toDispose.push(disposable);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import * as path from 'path';
|
||||
|
||||
import { workspace, languages, ExtensionContext, extensions, Uri, TextDocument, ColorRange, Color, ColorFormat } from 'vscode';
|
||||
import { workspace, languages, ExtensionContext, extensions, Uri, TextDocument, ColorInformation, Color, ColorPresentation, TextEdit } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification } from 'vscode-languageclient';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import { ConfigurationFeature } from 'vscode-languageclient/lib/proposed';
|
||||
|
@ -122,22 +122,29 @@ export function activate(context: ExtensionContext) {
|
|||
};
|
||||
// register color provider
|
||||
context.subscriptions.push(languages.registerColorProvider(documentSelector, {
|
||||
provideDocumentColors(document: TextDocument): Thenable<ColorRange[]> {
|
||||
provideDocumentColors(document: TextDocument): Thenable<ColorInformation[]> {
|
||||
let params = client.code2ProtocolConverter.asDocumentSymbolParams(document);
|
||||
return client.sendRequest(DocumentColorRequest.type, params).then(symbols => {
|
||||
return symbols.map(symbol => {
|
||||
let range = client.protocol2CodeConverter.asRange(symbol.range);
|
||||
let color = new Color(symbol.color.red * 255, symbol.color.green * 255, symbol.color.blue * 255, symbol.color.alpha);
|
||||
return new ColorRange(range, color);
|
||||
return new ColorInformation(range, color);
|
||||
});
|
||||
});
|
||||
},
|
||||
resolveDocumentColor(color: Color, colorFormat: ColorFormat): Thenable<string> | string {
|
||||
provideColorPresentations(colorInfo: ColorInformation): ColorPresentation[] | Thenable<ColorPresentation[]> {
|
||||
let result: ColorPresentation[] = [];
|
||||
let color = colorInfo.color;
|
||||
let label;
|
||||
|
||||
if (color.alpha === 1) {
|
||||
return `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}`;
|
||||
label = `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}`;
|
||||
} else {
|
||||
return `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}${_toTwoDigitHex(Math.round(color.alpha * 255))}`;
|
||||
label = `#${_toTwoDigitHex(Math.round(color.red * 255))}${_toTwoDigitHex(Math.round(color.green * 255))}${_toTwoDigitHex(Math.round(color.blue * 255))}${_toTwoDigitHex(Math.round(color.alpha * 255))}`;
|
||||
}
|
||||
|
||||
result.push({ label: label, textEdit: new TextEdit(colorInfo.range, label) });
|
||||
return result;
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -680,28 +680,31 @@ export interface IColor {
|
|||
}
|
||||
|
||||
/**
|
||||
* Represents a color format
|
||||
* String representations for a color
|
||||
*/
|
||||
export enum ColorFormat {
|
||||
RGB = 0,
|
||||
HEX = 1,
|
||||
HSL = 2
|
||||
}
|
||||
|
||||
/**
|
||||
* A color formatter.
|
||||
* @internal
|
||||
*/
|
||||
export interface IColorFormatter {
|
||||
readonly supportsTransparency: boolean;
|
||||
readonly colorFormat: ColorFormat;
|
||||
format(color: Color): string;
|
||||
export interface IColorPresentation {
|
||||
/**
|
||||
* The label of this color presentation. It will be shown on the color
|
||||
* picker header. By default this is also the text that is inserted when selecting
|
||||
* this color presentation.
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* An [edit](#TextEdit) which is applied to a document when selecting
|
||||
* this presentation for the color.
|
||||
*/
|
||||
textEdit?: TextEdit;
|
||||
/**
|
||||
* An optional array of additional [text edits](#TextEdit) that are applied when
|
||||
* selecting this color presentation.
|
||||
*/
|
||||
additionalTextEdits?: TextEdit[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A color range is a range in a text model which represents a color.
|
||||
*/
|
||||
export interface IColorRange {
|
||||
export interface IColorInformation {
|
||||
|
||||
/**
|
||||
* The range within the model.
|
||||
|
@ -721,11 +724,11 @@ export interface DocumentColorProvider {
|
|||
/**
|
||||
* Provides the color ranges for a specific model.
|
||||
*/
|
||||
provideColorRanges(model: editorCommon.IReadOnlyModel, token: CancellationToken): IColorRange[] | Thenable<IColorRange[]>;
|
||||
provideDocumentColors(model: editorCommon.IReadOnlyModel, token: CancellationToken): IColorInformation[] | Thenable<IColorInformation[]>;
|
||||
/**
|
||||
* Provide the string representation for a color.
|
||||
* Provide the string representations for a color.
|
||||
*/
|
||||
resolveColor(color: IColor, colorFormat: ColorFormat, token: CancellationToken): string | Thenable<string>;
|
||||
provideColorPresentations(colorInfo: IColorInformation, token: CancellationToken): IColorPresentation[] | Thenable<IColorPresentation[]>;
|
||||
}
|
||||
|
||||
export interface IResourceEdit {
|
||||
|
|
|
@ -149,10 +149,10 @@ export class ColorDetector implements IEditorContribution {
|
|||
private updateDecorations(colorDatas: IColorData[]): void {
|
||||
const decorations = colorDatas.map(c => ({
|
||||
range: {
|
||||
startLineNumber: c.colorRange.range.startLineNumber,
|
||||
startColumn: c.colorRange.range.startColumn,
|
||||
endLineNumber: c.colorRange.range.endLineNumber,
|
||||
endColumn: c.colorRange.range.endColumn
|
||||
startLineNumber: c.colorInfo.range.startLineNumber,
|
||||
startColumn: c.colorInfo.range.startColumn,
|
||||
endLineNumber: c.colorInfo.range.endLineNumber,
|
||||
endColumn: c.colorInfo.range.endColumn
|
||||
},
|
||||
options: {}
|
||||
}));
|
||||
|
@ -163,12 +163,12 @@ export class ColorDetector implements IEditorContribution {
|
|||
this._decorationsIds.forEach((id, i) => this._colorDatas.set(id, colorDatas[i]));
|
||||
}
|
||||
|
||||
private updateColorDecorators(colorInfos: IColorData[]): void {
|
||||
private updateColorDecorators(colorData: IColorData[]): void {
|
||||
let decorations = [];
|
||||
let newDecorationsTypes: { [key: string]: boolean } = {};
|
||||
|
||||
for (let i = 0; i < colorInfos.length && decorations.length < MAX_DECORATORS; i++) {
|
||||
const { red, green, blue, alpha } = colorInfos[i].colorRange.color;
|
||||
for (let i = 0; i < colorData.length && decorations.length < MAX_DECORATORS; i++) {
|
||||
const { red, green, blue, alpha } = colorData[i].colorInfo.color;
|
||||
const rgba = new RGBA(Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255), alpha);
|
||||
let subKey = hash(rgba).toString(16);
|
||||
let color = `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`;
|
||||
|
@ -195,10 +195,10 @@ export class ColorDetector implements IEditorContribution {
|
|||
newDecorationsTypes[key] = true;
|
||||
decorations.push({
|
||||
range: {
|
||||
startLineNumber: colorInfos[i].colorRange.range.startLineNumber,
|
||||
startColumn: colorInfos[i].colorRange.range.startColumn,
|
||||
endLineNumber: colorInfos[i].colorRange.range.endLineNumber,
|
||||
endColumn: colorInfos[i].colorRange.range.endColumn
|
||||
startLineNumber: colorData[i].colorInfo.range.startLineNumber,
|
||||
startColumn: colorData[i].colorInfo.range.startColumn,
|
||||
endLineNumber: colorData[i].colorInfo.range.endLineNumber,
|
||||
endColumn: colorData[i].colorInfo.range.endColumn
|
||||
},
|
||||
options: this._codeEditorService.resolveDecorationOptions(key, true)
|
||||
});
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
import Event, { Emitter } from 'vs/base/common/event';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { IColorFormatter } from 'vs/editor/common/modes';
|
||||
import { HexFormatter, HSLFormatter, RGBFormatter } from '../common/colorFormatter';
|
||||
import { IColorPresentation } from 'vs/editor/common/modes';
|
||||
|
||||
export class ColorPickerModel {
|
||||
|
||||
|
@ -26,9 +25,21 @@ export class ColorPickerModel {
|
|||
this._onDidChangeColor.fire(color);
|
||||
}
|
||||
|
||||
get formatter(): IColorFormatter { return this.formatters[this.formatterIndex]; }
|
||||
get presentation(): IColorPresentation { return this.colorPresentations[this.presentationIndex]; }
|
||||
|
||||
readonly formatters: IColorFormatter[];
|
||||
private _colorPresentations: IColorPresentation[];
|
||||
|
||||
get colorPresentations(): IColorPresentation[] {
|
||||
return this._colorPresentations;
|
||||
}
|
||||
|
||||
set colorPresentations(colorPresentations: IColorPresentation[]) {
|
||||
this._colorPresentations = colorPresentations;
|
||||
if (this.presentationIndex > colorPresentations.length - 1) {
|
||||
this.presentationIndex = 0;
|
||||
}
|
||||
this._onDidChangePresentation.fire(this.presentation);
|
||||
}
|
||||
|
||||
private _onColorFlushed = new Emitter<Color>();
|
||||
readonly onColorFlushed: Event<Color> = this._onColorFlushed.event;
|
||||
|
@ -36,29 +47,26 @@ export class ColorPickerModel {
|
|||
private _onDidChangeColor = new Emitter<Color>();
|
||||
readonly onDidChangeColor: Event<Color> = this._onDidChangeColor.event;
|
||||
|
||||
private _onDidChangeFormatter = new Emitter<IColorFormatter>();
|
||||
readonly onDidChangeFormatter: Event<IColorFormatter> = this._onDidChangeFormatter.event;
|
||||
private _onDidChangePresentation = new Emitter<IColorPresentation>();
|
||||
readonly onDidChangePresentation: Event<IColorPresentation> = this._onDidChangePresentation.event;
|
||||
|
||||
constructor(color: Color, private formatterIndex: number) {
|
||||
constructor(color: Color, availableColorPresentations: IColorPresentation[], private presentationIndex: number) {
|
||||
this.originalColor = color;
|
||||
this._color = color;
|
||||
this.formatters = [
|
||||
new RGBFormatter(),
|
||||
new HexFormatter(),
|
||||
new HSLFormatter()
|
||||
];
|
||||
this._colorPresentations = availableColorPresentations;
|
||||
}
|
||||
|
||||
selectNextColorFormat(): void {
|
||||
this.formatterIndex = (this.formatterIndex + 1) % this.formatters.length;
|
||||
selectNextColorPresentation(): void {
|
||||
this.presentationIndex = (this.presentationIndex + 1) % this.colorPresentations.length;
|
||||
this.flushColor();
|
||||
this._onDidChangeFormatter.fire(this.formatter);
|
||||
this._onDidChangePresentation.fire(this.presentation);
|
||||
}
|
||||
|
||||
guessColorFormat(color: Color, originalText: string): void {
|
||||
for (let i = 0; i < this.formatters.length; i++) {
|
||||
if (originalText === this.formatters[i].format(color)) {
|
||||
this.formatterIndex = i;
|
||||
guessColorPresentation(color: Color, originalText: string): void {
|
||||
for (let i = 0; i < this.colorPresentations.length; i++) {
|
||||
if (originalText === this.colorPresentations[i].label) {
|
||||
this.presentationIndex = i;
|
||||
this._onDidChangePresentation.fire(this.presentation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,24 +38,25 @@ export class ColorPickerHeader extends Disposable {
|
|||
this.backgroundColor = theme.getColor(editorHoverBackground) || Color.white;
|
||||
}));
|
||||
|
||||
this._register(dom.addDisposableListener(this.pickedColorNode, dom.EventType.CLICK, () => this.model.selectNextColorFormat()));
|
||||
this._register(dom.addDisposableListener(this.pickedColorNode, dom.EventType.CLICK, () => this.model.selectNextColorPresentation()));
|
||||
this._register(dom.addDisposableListener(colorBox, dom.EventType.CLICK, () => {
|
||||
this.model.color = this.model.originalColor;
|
||||
this.model.flushColor();
|
||||
}));
|
||||
this._register(model.onDidChangeColor(this.onDidChangeColor, this));
|
||||
this._register(model.onDidChangeFormatter(this.onDidChangeFormatter, this));
|
||||
this.onDidChangeColor(this.model.color);
|
||||
this._register(model.onDidChangePresentation(this.onDidChangePresentation, this));
|
||||
this.pickedColorNode.style.backgroundColor = Color.Format.CSS.format(model.color);
|
||||
dom.toggleClass(this.pickedColorNode, 'light', model.color.rgba.a < 0.5 ? this.backgroundColor.isLighter() : model.color.isLighter());
|
||||
}
|
||||
|
||||
private onDidChangeColor(color: Color): void {
|
||||
this.pickedColorNode.style.backgroundColor = Color.Format.CSS.format(color);
|
||||
dom.toggleClass(this.pickedColorNode, 'light', color.rgba.a < 0.5 ? this.backgroundColor.isLighter() : color.isLighter());
|
||||
this.onDidChangeFormatter();
|
||||
this.onDidChangePresentation();
|
||||
}
|
||||
|
||||
private onDidChangeFormatter(): void {
|
||||
this.pickedColorNode.textContent = this.model.formatter.format(this.model.color);
|
||||
private onDidChangePresentation(): void {
|
||||
this.pickedColorNode.textContent = this.model.presentation.label;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,22 +4,22 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ColorProviderRegistry, DocumentColorProvider, IColorRange, IColor, ColorFormat } from 'vs/editor/common/modes';
|
||||
import { ColorProviderRegistry, DocumentColorProvider, IColorInformation, IColorPresentation } from 'vs/editor/common/modes';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { IReadOnlyModel } from 'vs/editor/common/editorCommon';
|
||||
|
||||
export interface IColorData {
|
||||
colorRange: IColorRange;
|
||||
colorInfo: IColorInformation;
|
||||
provider: DocumentColorProvider;
|
||||
}
|
||||
|
||||
export function getColors(model: IReadOnlyModel): TPromise<IColorData[]> {
|
||||
const colors: IColorData[] = [];
|
||||
const providers = ColorProviderRegistry.ordered(model).reverse();
|
||||
const promises = providers.map(provider => asWinJsPromise(token => provider.provideColorRanges(model, token)).then(result => {
|
||||
const promises = providers.map(provider => asWinJsPromise(token => provider.provideDocumentColors(model, token)).then(result => {
|
||||
if (Array.isArray(result)) {
|
||||
for (let colorRange of result) {
|
||||
colors.push({ colorRange, provider });
|
||||
for (let colorInfo of result) {
|
||||
colors.push({ colorInfo, provider });
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
@ -27,6 +27,6 @@ export function getColors(model: IReadOnlyModel): TPromise<IColorData[]> {
|
|||
return TPromise.join(promises).then(() => colors);
|
||||
}
|
||||
|
||||
export function resolveColor(color: IColor, colorFormat: ColorFormat, provider: DocumentColorProvider): TPromise<string> {
|
||||
return asWinJsPromise(token => provider.resolveColor(color, colorFormat, token));
|
||||
export function getColorPresentations(colorInfo: IColorInformation, provider: DocumentColorProvider): TPromise<IColorPresentation[]> {
|
||||
return asWinJsPromise(token => provider.provideColorPresentations(colorInfo, token));
|
||||
}
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IColorFormatter, ColorFormat } from 'vs/editor/common/modes';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
|
||||
function normalize(value: number, min: number, max: number): number {
|
||||
return value * (max - min) + min;
|
||||
}
|
||||
|
||||
export class RGBFormatter implements IColorFormatter {
|
||||
readonly supportsTransparency: boolean = true;
|
||||
readonly colorFormat: ColorFormat = ColorFormat.RGB;
|
||||
|
||||
format(color: Color): string {
|
||||
const rgb = color.rgba;
|
||||
if (rgb.a === 1) {
|
||||
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
|
||||
} else {
|
||||
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${rgb.a})`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class HexFormatter implements IColorFormatter {
|
||||
readonly supportsTransparency: boolean = false;
|
||||
readonly colorFormat: ColorFormat = ColorFormat.HEX;
|
||||
|
||||
_toTwoDigitHex(n: number): string {
|
||||
const r = n.toString(16);
|
||||
return r.length !== 2 ? '0' + r : r;
|
||||
}
|
||||
|
||||
format(color: Color): string {
|
||||
const rgb = color.rgba;
|
||||
if (rgb.a === 1) {
|
||||
return `#${this._toTwoDigitHex(rgb.r).toUpperCase()}${this._toTwoDigitHex(rgb.g).toUpperCase()}${this._toTwoDigitHex(rgb.b).toUpperCase()}`;
|
||||
} else {
|
||||
return `#${this._toTwoDigitHex(rgb.r).toUpperCase()}${this._toTwoDigitHex(rgb.g).toUpperCase()}${this._toTwoDigitHex(rgb.b).toUpperCase()}${this._toTwoDigitHex(Math.round(rgb.a * 255)).toUpperCase()}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class HSLFormatter implements IColorFormatter {
|
||||
readonly supportsTransparency: boolean = true;
|
||||
readonly colorFormat: ColorFormat = ColorFormat.HSL;
|
||||
|
||||
format(color: Color): string {
|
||||
const hsla = color.hsla;
|
||||
if (hsla.a === 1) {
|
||||
return `hsl(${hsla.h}, ${normalize(hsla.s, 0, 100).toFixed(0)}%, ${normalize(hsla.l, 0, 100).toFixed(0)}%)`;
|
||||
} else {
|
||||
return `hsla(${hsla.h}, ${normalize(hsla.s, 0, 100).toFixed(0)}%, ${normalize(hsla.l, 0, 100).toFixed(0)}%, ${hsla.a})`;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { Color, RGBA, HSLA } from 'vs/base/common/color';
|
||||
import { RGBFormatter, HexFormatter, HSLFormatter } from 'vs/editor/contrib/colorPicker/common/colorFormatter';
|
||||
|
||||
suite('ColorFormatter', () => {
|
||||
test('documentation', () => {
|
||||
const color = new Color(new RGBA(255, 127, 0));
|
||||
|
||||
const rgb = new RGBFormatter();
|
||||
assert.equal(rgb.format(color), 'rgb(255, 127, 0)');
|
||||
|
||||
const hex = new HexFormatter();
|
||||
assert.equal(hex.format(color), '#FF7F00');
|
||||
|
||||
const hsl = new HSLFormatter();
|
||||
assert.equal(hsl.format(color), 'hsl(30, 100%, 50%)');
|
||||
});
|
||||
|
||||
test('bug#32323', () => {
|
||||
const color = new Color(new HSLA(121, 0.45, 0.29, 0.61));
|
||||
const rgba = color.rgba;
|
||||
const color2 = new Color(new RGBA(rgba.r, rgba.g, rgba.b, rgba.a));
|
||||
const hsla = new HSLFormatter();
|
||||
assert.equal(hsla.format(color2), 'hsla(121, 45%, 29%, 0.61)');
|
||||
});
|
||||
});
|
|
@ -22,7 +22,7 @@ import { ColorPickerWidget } from 'vs/editor/contrib/colorPicker/browser/colorPi
|
|||
import { ColorDetector } from 'vs/editor/contrib/colorPicker/browser/colorDetector';
|
||||
import { Color, RGBA } from 'vs/base/common/color';
|
||||
import { IDisposable, empty as EmptyDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { resolveColor } from 'vs/editor/contrib/colorPicker/common/color';
|
||||
import { getColorPresentations } from 'vs/editor/contrib/colorPicker/common/color';
|
||||
const $ = dom.$;
|
||||
|
||||
class ColorHover {
|
||||
|
@ -96,7 +96,7 @@ class ModesContentComputer implements IHoverComputer<HoverPart[]> {
|
|||
if (!didFindColor && colorData) {
|
||||
didFindColor = true;
|
||||
|
||||
const { color } = colorData.colorRange;
|
||||
const { color } = colorData.colorInfo;
|
||||
return new ColorHover(d.range, color, colorData.provider);
|
||||
} else {
|
||||
if (isEmptyMarkdownString(d.options.hoverMessage)) {
|
||||
|
@ -294,6 +294,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
|||
highlightRange = messages[0].range,
|
||||
fragment = document.createDocumentFragment();
|
||||
|
||||
let containColorPicker = false;
|
||||
messages.forEach((msg) => {
|
||||
if (!msg.range) {
|
||||
return;
|
||||
|
@ -310,46 +311,88 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
|||
fragment.appendChild($('div.hover-row', null, renderedContents));
|
||||
});
|
||||
} else {
|
||||
containColorPicker = true;
|
||||
|
||||
const { red, green, blue, alpha } = msg.color;
|
||||
const rgba = new RGBA(red * 255, green * 255, blue * 255, alpha);
|
||||
const color = new Color(rgba);
|
||||
|
||||
const model = new ColorPickerModel(color, 0);
|
||||
const originalText = this._editor.getModel().getValueInRange(msg.range);
|
||||
model.guessColorFormat(color, originalText);
|
||||
const widget = new ColorPickerWidget(fragment, model, this._editor.getConfiguration().pixelRatio);
|
||||
|
||||
const editorModel = this._editor.getModel();
|
||||
let range = new Range(msg.range.startLineNumber, msg.range.startColumn, msg.range.endLineNumber, msg.range.endColumn);
|
||||
let colorInfo = { range: msg.range, color: msg.color };
|
||||
|
||||
const updateEditorModel = () => {
|
||||
const color = {
|
||||
red: model.color.rgba.r / 255,
|
||||
green: model.color.rgba.g / 255,
|
||||
blue: model.color.rgba.b / 255,
|
||||
alpha: model.color.rgba.a
|
||||
};
|
||||
resolveColor(color, model.formatter.colorFormat, msg.provider).then(text => {
|
||||
editorModel.pushEditOperations([], [{ identifier: null, range, text, forceMoveMarkers: false }], () => []);
|
||||
// create blank olor picker model and widget first to ensure it's positioned correctly.
|
||||
const model = new ColorPickerModel(color, [], 0);
|
||||
const widget = new ColorPickerWidget(fragment, model, this._editor.getConfiguration().pixelRatio);
|
||||
|
||||
getColorPresentations(colorInfo, msg.provider).then(colorPresentations => {
|
||||
model.colorPresentations = colorPresentations;
|
||||
const originalText = this._editor.getModel().getValueInRange(msg.range);
|
||||
model.guessColorPresentation(color, originalText);
|
||||
|
||||
const updateEditorModel = () => {
|
||||
let textEdits;
|
||||
let newRange;
|
||||
if (model.presentation.textEdit) {
|
||||
textEdits = [model.presentation.textEdit];
|
||||
console.log('insert text');
|
||||
newRange = new Range(
|
||||
model.presentation.textEdit.range.startLineNumber,
|
||||
model.presentation.textEdit.range.startColumn,
|
||||
model.presentation.textEdit.range.endLineNumber,
|
||||
model.presentation.textEdit.range.endColumn
|
||||
);
|
||||
newRange = newRange.setEndPosition(newRange.endLineNumber, newRange.startColumn + model.presentation.textEdit.text.length);
|
||||
} else {
|
||||
textEdits = [{ identifier: null, range, text: model.presentation.label, forceMoveMarkers: false }];
|
||||
newRange = range.setEndPosition(range.endLineNumber, range.startColumn + model.presentation.label.length);
|
||||
}
|
||||
|
||||
editorModel.pushEditOperations([], textEdits, () => []);
|
||||
|
||||
if (model.presentation.additionalTextEdits) {
|
||||
textEdits = [...model.presentation.additionalTextEdits];
|
||||
editorModel.pushEditOperations([], textEdits, () => []);
|
||||
this.hide();
|
||||
}
|
||||
this._editor.pushUndoStop();
|
||||
range = range.setEndPosition(range.endLineNumber, range.startColumn + text.length);
|
||||
range = newRange;
|
||||
};
|
||||
|
||||
const updateColorPresentations = (color: Color) => {
|
||||
return getColorPresentations({
|
||||
range: range,
|
||||
color: {
|
||||
red: color.rgba.r / 255,
|
||||
green: color.rgba.g / 255,
|
||||
blue: color.rgba.b / 255,
|
||||
alpha: color.rgba.a
|
||||
}
|
||||
}, msg.provider).then((colorPresentations) => {
|
||||
model.colorPresentations = colorPresentations;
|
||||
});
|
||||
};
|
||||
|
||||
const colorListener = model.onColorFlushed((color: Color) => {
|
||||
updateColorPresentations(color).then(updateEditorModel);
|
||||
});
|
||||
};
|
||||
const colorChangeListener = model.onDidChangeColor(updateColorPresentations);
|
||||
|
||||
const colorListener = model.onColorFlushed(updateEditorModel);
|
||||
this._colorPicker = widget;
|
||||
this.showAt(new Position(renderRange.startLineNumber, renderColumn), this._shouldFocus);
|
||||
this.updateContents(fragment);
|
||||
this._colorPicker.layout();
|
||||
|
||||
this._colorPicker = widget;
|
||||
this.renderDisposable = combinedDisposable([colorListener, widget]);
|
||||
this.renderDisposable = combinedDisposable([colorListener, colorChangeListener, widget]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// show
|
||||
this.showAt(new Position(renderRange.startLineNumber, renderColumn), this._shouldFocus);
|
||||
|
||||
this.updateContents(fragment);
|
||||
|
||||
if (this._colorPicker) {
|
||||
this._colorPicker.layout();
|
||||
if (!containColorPicker) {
|
||||
this.showAt(new Position(renderRange.startLineNumber, renderColumn), this._shouldFocus);
|
||||
this.updateContents(fragment);
|
||||
}
|
||||
|
||||
this._isChangingDecorations = true;
|
||||
|
|
|
@ -738,7 +738,6 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages {
|
|||
DocumentHighlightKind: modes.DocumentHighlightKind,
|
||||
CompletionItemKind: CompletionItemKind,
|
||||
SymbolKind: modes.SymbolKind,
|
||||
IndentAction: IndentAction,
|
||||
ColorFormat: modes.ColorFormat
|
||||
IndentAction: IndentAction
|
||||
};
|
||||
}
|
||||
|
|
31
src/vs/monaco.d.ts
vendored
31
src/vs/monaco.d.ts
vendored
|
@ -4823,18 +4823,31 @@ declare module monaco.languages {
|
|||
}
|
||||
|
||||
/**
|
||||
* Represents a color format
|
||||
* String representations for a color
|
||||
*/
|
||||
export enum ColorFormat {
|
||||
RGB = 0,
|
||||
HEX = 1,
|
||||
HSL = 2,
|
||||
export interface IColorPresentation {
|
||||
/**
|
||||
* The label of this color presentation. It will be shown on the color
|
||||
* picker header. By default this is also the text that is inserted when selecting
|
||||
* this color presentation.
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* An [edit](#TextEdit) which is applied to a document when selecting
|
||||
* this presentation for the color.
|
||||
*/
|
||||
textEdit?: TextEdit;
|
||||
/**
|
||||
* An optional array of additional [text edits](#TextEdit) that are applied when
|
||||
* selecting this color presentation.
|
||||
*/
|
||||
additionalTextEdits?: TextEdit[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A color range is a range in a text model which represents a color.
|
||||
*/
|
||||
export interface IColorRange {
|
||||
export interface IColorInformation {
|
||||
/**
|
||||
* The range within the model.
|
||||
*/
|
||||
|
@ -4852,11 +4865,11 @@ declare module monaco.languages {
|
|||
/**
|
||||
* Provides the color ranges for a specific model.
|
||||
*/
|
||||
provideColorRanges(model: editor.IReadOnlyModel, token: CancellationToken): IColorRange[] | Thenable<IColorRange[]>;
|
||||
provideDocumentColors(model: editor.IReadOnlyModel, token: CancellationToken): IColorInformation[] | Thenable<IColorInformation[]>;
|
||||
/**
|
||||
* Provide the string representation for a color.
|
||||
* Provide the string representations for a color.
|
||||
*/
|
||||
resolveColor(color: IColor, colorFormat: ColorFormat, token: CancellationToken): string | Thenable<string>;
|
||||
provideColorPresentations(colorInfo: IColorInformation, token: CancellationToken): IColorPresentation[] | Thenable<IColorPresentation[]>;
|
||||
}
|
||||
|
||||
export interface IResourceEdit {
|
||||
|
|
39
src/vs/vscode.proposed.d.ts
vendored
39
src/vs/vscode.proposed.d.ts
vendored
|
@ -104,19 +104,10 @@ declare module 'vscode' {
|
|||
constructor(red: number, green: number, blue: number, alpha: number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a color format
|
||||
*/
|
||||
export enum ColorFormat {
|
||||
RGB = 0,
|
||||
HEX = 1,
|
||||
HSL = 2
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a color range from a document.
|
||||
*/
|
||||
export class ColorRange {
|
||||
export class ColorInformation {
|
||||
|
||||
/**
|
||||
* The range in the document where this color appers.
|
||||
|
@ -138,6 +129,26 @@ declare module 'vscode' {
|
|||
constructor(range: Range, color: Color);
|
||||
}
|
||||
|
||||
export class ColorPresentation {
|
||||
/**
|
||||
* The label of this color presentation. It will be shown on the color
|
||||
* picker header. By default this is also the text that is inserted when selecting
|
||||
* this color presentation.
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* An [edit](#TextEdit) which is applied to a document when selecting
|
||||
* this presentation for the color. When `falsy` the [label](#ColorPresentation.label)
|
||||
* is used.
|
||||
*/
|
||||
textEdit?: TextEdit;
|
||||
/**
|
||||
* An optional array of additional [text edits](#TextEdit) that are applied when
|
||||
* selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves.
|
||||
*/
|
||||
additionalTextEdits?: TextEdit[];
|
||||
}
|
||||
|
||||
/**
|
||||
* The document color provider defines the contract between extensions and feature of
|
||||
* picking and modifying colors in the editor.
|
||||
|
@ -148,14 +159,14 @@ declare module 'vscode' {
|
|||
*
|
||||
* @param document The document in which the command was invoked.
|
||||
* @param token A cancellation token.
|
||||
* @return An array of [color ranges](#ColorRange) or a thenable that resolves to such. The lack of a result
|
||||
* @return An array of [color informations](#ColorInformation) or a thenable that resolves to such. The lack of a result
|
||||
* can be signaled by returning `undefined`, `null`, or an empty array.
|
||||
*/
|
||||
provideDocumentColors(document: TextDocument, token: CancellationToken): ProviderResult<ColorRange[]>;
|
||||
provideDocumentColors(document: TextDocument, token: CancellationToken): ProviderResult<ColorInformation[]>;
|
||||
/**
|
||||
* Provide the string representation for a color.
|
||||
* Provide representations for a color.
|
||||
*/
|
||||
resolveDocumentColor(color: Color, colorFormat: ColorFormat): ProviderResult<string>;
|
||||
provideColorPresentations(colorInfo: ColorInformation, token: CancellationToken): ProviderResult<ColorPresentation[]>;
|
||||
}
|
||||
|
||||
export namespace languages {
|
||||
|
|
|
@ -286,7 +286,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
|
|||
$registerDocumentColorProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
|
||||
const proxy = this._proxy;
|
||||
this._registrations[handle] = modes.ColorProviderRegistry.register(selector, <modes.DocumentColorProvider>{
|
||||
provideColorRanges: (model, token) => {
|
||||
provideDocumentColors: (model, token) => {
|
||||
return wireCancellationToken(token, proxy.$provideDocumentColors(handle, model.uri))
|
||||
.then(documentColors => {
|
||||
return documentColors.map(documentColor => {
|
||||
|
@ -305,8 +305,12 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
|
|||
});
|
||||
});
|
||||
},
|
||||
resolveColor: (color, format, token) => {
|
||||
return wireCancellationToken(token, proxy.$resolveDocumentColor(handle, color, format));
|
||||
|
||||
provideColorPresentations: (colorInfo, token) => {
|
||||
return wireCancellationToken(token, proxy.$provideColorPresentations(handle, {
|
||||
color: [colorInfo.color.red, colorInfo.color.green, colorInfo.color.blue, colorInfo.color.alpha],
|
||||
range: colorInfo.range
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -551,8 +551,8 @@ export function createApiFactory(
|
|||
CancellationTokenSource: CancellationTokenSource,
|
||||
CodeLens: extHostTypes.CodeLens,
|
||||
Color: extHostTypes.Color,
|
||||
ColorFormat: extHostTypes.ColorFormat,
|
||||
ColorRange: extHostTypes.ColorRange,
|
||||
ColorPresentation: extHostTypes.ColorPresentation,
|
||||
ColorInformation: extHostTypes.ColorInformation,
|
||||
EndOfLine: extHostTypes.EndOfLine,
|
||||
CompletionItem: extHostTypes.CompletionItem,
|
||||
CompletionItemKind: extHostTypes.CompletionItemKind,
|
||||
|
|
|
@ -548,7 +548,7 @@ export interface ExtHostLanguageFeaturesShape {
|
|||
$provideDocumentLinks(handle: number, resource: URI): TPromise<modes.ILink[]>;
|
||||
$resolveDocumentLink(handle: number, link: modes.ILink): TPromise<modes.ILink>;
|
||||
$provideDocumentColors(handle: number, resource: URI): TPromise<IRawColorInfo[]>;
|
||||
$resolveDocumentColor(handle: number, color: modes.IColor, colorFormat: modes.ColorFormat): TPromise<string>;
|
||||
$provideColorPresentations(handle: number, colorInfo: IRawColorInfo): TPromise<modes.IColorPresentation[]>;
|
||||
}
|
||||
|
||||
export interface ExtHostQuickOpenShape {
|
||||
|
|
|
@ -729,8 +729,19 @@ class ColorProviderAdapter {
|
|||
});
|
||||
}
|
||||
|
||||
resolveColor(color: modes.IColor, colorFormat: modes.ColorFormat): TPromise<string> {
|
||||
return asWinJsPromise(token => this._provider.resolveDocumentColor(color, colorFormat));
|
||||
provideColorPresentations(rawColorInfo: IRawColorInfo): TPromise<modes.IColorPresentation[]> {
|
||||
let colorInfo: vscode.ColorInformation = {
|
||||
range: TypeConverters.toRange(rawColorInfo.range),
|
||||
color: {
|
||||
red: rawColorInfo.color[0],
|
||||
green: rawColorInfo.color[1],
|
||||
blue: rawColorInfo.color[2],
|
||||
alpha: rawColorInfo.color[3]
|
||||
}
|
||||
};
|
||||
return asWinJsPromise(token => this._provider.provideColorPresentations(colorInfo, token)).then(value => {
|
||||
return value.map(v => TypeConverters.ColorPresentation.from(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1042,8 +1053,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
|
|||
return this._withAdapter(handle, ColorProviderAdapter, adapter => adapter.provideColors(resource));
|
||||
}
|
||||
|
||||
$resolveDocumentColor(handle: number, color: modes.IColor, colorFormat: modes.ColorFormat): TPromise<string> {
|
||||
return this._withAdapter(handle, ColorProviderAdapter, adapter => adapter.resolveColor(color, colorFormat));
|
||||
$provideColorPresentations(handle: number, colorInfo: IRawColorInfo): TPromise<modes.IColorPresentation[]> {
|
||||
return this._withAdapter(handle, ColorProviderAdapter, adapter => adapter.provideColorPresentations(colorInfo));
|
||||
}
|
||||
|
||||
// --- configuration
|
||||
|
|
|
@ -448,6 +448,24 @@ export namespace DocumentLink {
|
|||
}
|
||||
}
|
||||
|
||||
export namespace ColorPresentation {
|
||||
export function to(colorPresentation: modes.IColorPresentation): vscode.ColorPresentation {
|
||||
return {
|
||||
label: colorPresentation.label,
|
||||
textEdit: colorPresentation.textEdit ? TextEdit.to(colorPresentation.textEdit) : undefined,
|
||||
additionalTextEdits: colorPresentation.additionalTextEdits ? colorPresentation.additionalTextEdits.map(value => TextEdit.to(value)) : undefined
|
||||
};
|
||||
}
|
||||
|
||||
export function from(colorPresentation: vscode.ColorPresentation): modes.IColorPresentation {
|
||||
return {
|
||||
label: colorPresentation.label,
|
||||
textEdit: colorPresentation.textEdit ? TextEdit.from(colorPresentation.textEdit) : undefined,
|
||||
additionalTextEdits: colorPresentation.additionalTextEdits ? colorPresentation.additionalTextEdits.map(value => TextEdit.from(value)) : undefined
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export namespace TextDocumentSaveReason {
|
||||
|
||||
export function to(reason: SaveReason): vscode.TextDocumentSaveReason {
|
||||
|
|
|
@ -1055,7 +1055,7 @@ export class Color {
|
|||
|
||||
export type IColorFormat = string | { opaque: string, transparent: string };
|
||||
|
||||
export class ColorRange {
|
||||
export class ColorInformation {
|
||||
range: Range;
|
||||
|
||||
color: Color;
|
||||
|
@ -1072,6 +1072,12 @@ export class ColorRange {
|
|||
}
|
||||
}
|
||||
|
||||
export class ColorPresentation {
|
||||
label: string;
|
||||
textEdit?: TextEdit;
|
||||
additionalTextEdits?: TextEdit[];
|
||||
}
|
||||
|
||||
export enum ColorFormat {
|
||||
RGB = 0,
|
||||
HEX = 1,
|
||||
|
|
Loading…
Reference in a new issue