Skip to content

Commit

Permalink
implement 'registerColorProvider' Languages API
Browse files Browse the repository at this point in the history
Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
  • Loading branch information
akurinnoy committed Jan 4, 2019
1 parent 6a22655 commit 21738e4
Show file tree
Hide file tree
Showing 9 changed files with 394 additions and 5 deletions.
25 changes: 24 additions & 1 deletion packages/plugin-ext/src/api/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ export interface FormattingOptions {

export interface TextEdit {
range: Range;
text?: string;
text: string;
eol?: monaco.editor.EndOfLineSequence;
}

Expand Down Expand Up @@ -442,3 +442,26 @@ export class FoldingRangeKind {
static readonly Region = new FoldingRangeKind('region');
public constructor(public value: string) { }
}

export interface Color {
readonly red: number;
readonly green: number;
readonly blue: number;
readonly alpha: number;
}

export interface ColorPresentation {
label: string;
textEdit?: TextEdit;
additionalTextEdits?: TextEdit[];
}

export interface ColorInformation {
range: Range;
color: Color;
}

export interface DocumentColorProvider {
provideDocumentColors(model: monaco.editor.ITextModel): PromiseLike<ColorInformation[]>;
provideColorPresentations(model: monaco.editor.ITextModel, colorInfo: ColorInformation): PromiseLike<ColorPresentation[]>;
}
11 changes: 10 additions & 1 deletion packages/plugin-ext/src/api/plugin-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ import {
TextDocumentShowOptions,
WorkspaceRootsChangeEvent,
Location,
Breakpoint
Breakpoint,
ColorPresentation,
} from './model';
import { ExtPluginApi } from '../common/plugin-ext-api-contribution';
import { KeysToAnyValues, KeysToKeysToAnyValue } from '../common/types';
Expand Down Expand Up @@ -859,6 +860,8 @@ export interface LanguagesExt {
resource: UriComponents,
context: monaco.languages.FoldingContext
): PromiseLike<monaco.languages.FoldingRange[] | undefined>;
$provideDocumentColors(handle: number, resource: UriComponents): PromiseLike<RawColorInfo[]>;
$provideColorPresentations(handle: number, resource: UriComponents, colorInfo: RawColorInfo): PromiseLike<ColorPresentation[]>;
}

export interface LanguagesMain {
Expand All @@ -885,6 +888,7 @@ export interface LanguagesMain {
$registerOutlineSupport(handle: number, selector: SerializedDocumentFilter[]): void;
$registerWorkspaceSymbolProvider(handle: number): void;
$registerFoldingRangeProvider(handle: number, selector: SerializedDocumentFilter[]): void;
$registerDocumentColorProvider(handle: number, selector: SerializedDocumentFilter[]): void;
}

export interface WebviewPanelViewState {
Expand Down Expand Up @@ -1022,3 +1026,8 @@ export interface TasksMain {
$unregister(handle: number): void;
$terminateTask(id: number): void;
}

export interface RawColorInfo {
color: [number, number, number, number];
range: Range;
}
48 changes: 48 additions & 0 deletions packages/plugin-ext/src/main/browser/languages-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,54 @@ export class LanguagesMainImpl implements LanguagesMain {
};
}

$registerDocumentColorProvider(handle: number, selector: SerializedDocumentFilter[]): void {
const languageSelector = fromLanguageSelector(selector);
const colorProvider = this.createColorProvider(handle, languageSelector);
const disposable = new DisposableCollection();
for (const language of getLanguages()) {
if (this.matchLanguage(languageSelector, language)) {
disposable.push(monaco.languages.registerColorProvider(language, colorProvider));
}
}
this.disposables.set(handle, disposable);
}

createColorProvider(handle: number, selector: LanguageSelector | undefined): monaco.languages.DocumentColorProvider {
return {
provideDocumentColors: (model, token) => {
if (!this.matchModel(selector, MonacoModelIdentifier.fromModel(model))) {
return undefined!;
}
return this.proxy.$provideDocumentColors(handle, model.uri).then(documentColors =>
documentColors.map(documentColor => {
const [red, green, blue, alpha] = documentColor.color;
const color = {
red: red,
green: green,
blue: blue,
alpha: alpha
};

return {
color,
range: documentColor.range
};
})
);
},
provideColorPresentations: (model, colorInfo, token) =>
this.proxy.$provideColorPresentations(handle, model.uri, {
color: [
colorInfo.color.red,
colorInfo.color.green,
colorInfo.color.blue,
colorInfo.color.alpha
],
range: colorInfo.range
})
};
}

$registerQuickFixProvider(handle: number, selector: SerializedDocumentFilter[], codeActionKinds?: string[]): void {
const languageSelector = fromLanguageSelector(selector);
const quickFixProvider = this.createQuickFixProvider(handle, languageSelector, codeActionKinds);
Expand Down
26 changes: 23 additions & 3 deletions packages/plugin-ext/src/plugin/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import {
SerializedOnEnterRule,
SerializedIndentationRule,
Position,
Selection
Selection,
RawColorInfo,
} from '../api/plugin-api';
import { RPCProtocol } from '../api/rpc-protocol';
import * as theia from '@theia/plugin';
Expand All @@ -50,7 +51,8 @@ import {
CodeLensSymbol,
DocumentSymbol,
ReferenceContext,
Location
Location,
ColorPresentation,
} from '../api/model';
import { CompletionAdapter } from './languages/completion';
import { Diagnostics } from './languages/diagnostics';
Expand All @@ -72,6 +74,7 @@ import { ReferenceAdapter } from './languages/reference';
import { WorkspaceSymbolAdapter } from './languages/workspace-symbol';
import { SymbolInformation } from 'vscode-languageserver-types';
import { FoldingProviderAdapter } from './languages/folding';
import { ColorProviderAdapter } from './languages/color';

type Adapter = CompletionAdapter |
SignatureHelpAdapter |
Expand All @@ -90,7 +93,8 @@ type Adapter = CompletionAdapter |
LinkProviderAdapter |
ReferenceAdapter |
WorkspaceSymbolAdapter |
FoldingProviderAdapter;
FoldingProviderAdapter |
ColorProviderAdapter;

export class LanguagesExtImpl implements LanguagesExt {

Expand Down Expand Up @@ -439,6 +443,22 @@ export class LanguagesExtImpl implements LanguagesExt {
}
// ### Document Symbol Provider end

// ### Color Provider begin
registerColorProvider(selector: theia.DocumentSelector, provider: theia.DocumentColorProvider): theia.Disposable {
const callId = this.addNewAdapter(new ColorProviderAdapter(this.documents, provider));
this.proxy.$registerDocumentColorProvider(callId, this.transformDocumentSelector(selector));
return this.createDisposable(callId);
}

$provideDocumentColors(handle: number, resource: UriComponents): Promise<RawColorInfo[]> {
return this.withAdapter(handle, ColorProviderAdapter, adapter => adapter.provideColors(URI.revive(resource)));
}

$provideColorPresentations(handle: number, resource: UriComponents, colorInfo: RawColorInfo): Promise<ColorPresentation[]> {
return this.withAdapter(handle, ColorProviderAdapter, adapter => adapter.provideColorPresentations(URI.revive(resource), colorInfo));
}
// ### Color Provider end

// ### Folding Range Provider begin
registerFoldingRangeProvider(selector: theia.DocumentSelector, provider: theia.FoldingRangeProvider): theia.Disposable {
const callId = this.addNewAdapter(new FoldingProviderAdapter(provider, this.documents));
Expand Down
76 changes: 76 additions & 0 deletions packages/plugin-ext/src/plugin/languages/color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/********************************************************************************
* Copyright (C) 2018 Red Hat, Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import * as theia from '@theia/plugin';
import URI from 'vscode-uri/lib/umd';
import { DocumentsExtImpl } from '@theia/plugin-ext/src/plugin/documents';
import { createToken } from '../token-provider';
import * as Converter from '../type-converters';
import { RawColorInfo } from '@theia/plugin-ext/src/api/plugin-api';
import { ColorPresentation } from '../../api/model';

export class ColorProviderAdapter {

constructor(
private documents: DocumentsExtImpl,
private provider: theia.DocumentColorProvider
) { }

provideColors(resource: URI): Promise<RawColorInfo[]> {
const document = this.documents.getDocumentData(resource);
if (!document) {
return Promise.reject(new Error(`There are no document for ${resource}`));
}

const doc = document.document;

return Promise.resolve(
this.provider.provideDocumentColors(doc, createToken())
).then(colors => {
if (!Array.isArray(colors)) {
return [];
}

const colorInfos: RawColorInfo[] = colors.map(colorInfo => ({
color: Converter.fromColor(colorInfo.color),
range: Converter.fromRange(colorInfo.range)!
}));

return colorInfos;
});
}

provideColorPresentations(resource: URI, raw: RawColorInfo): Promise<ColorPresentation[]> {
const document = this.documents.getDocumentData(resource);
if (!document) {
return Promise.reject(new Error(`There are no document for ${resource}`));
}

const doc = document.document;
const range = Converter.toRange(raw.range);
const color = Converter.toColor(raw.color);
return Promise.resolve(
this.provider.provideColorPresentations(color, { document: doc, range: range }, createToken())
).then(value => {
if (!Array.isArray(value)) {
return [];
}

return value.map(Converter.fromColorPresentation);
});
}

}
9 changes: 9 additions & 0 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ import {
FunctionBreakpoint,
FoldingRange,
FoldingRangeKind,
Color,
ColorInformation,
ColorPresentation,
} from './types-impl';
import { SymbolKind } from '../api/model';
import { EditorsAndDocumentsExtImpl } from './editors-and-documents';
Expand Down Expand Up @@ -491,6 +494,9 @@ export function createAPIFactory(
registerDocumentSymbolProvider(selector: theia.DocumentSelector, provider: theia.DocumentSymbolProvider): theia.Disposable {
return languagesExt.registerDocumentSymbolProvider(selector, provider);
},
registerColorProvider(selector: theia.DocumentSelector, provider: theia.DocumentColorProvider): theia.Disposable {
return languagesExt.registerColorProvider(selector, provider);
},
registerFoldingRangeProvider(selector: theia.DocumentSelector, provider: theia.FoldingRangeProvider): theia.Disposable {
return languagesExt.registerFoldingRangeProvider(selector, provider);
},
Expand Down Expand Up @@ -649,6 +655,9 @@ export function createAPIFactory(
Breakpoint,
SourceBreakpoint,
FunctionBreakpoint,
Color,
ColorInformation,
ColorPresentation,
FoldingRange,
FoldingRangeKind,
};
Expand Down
16 changes: 16 additions & 0 deletions packages/plugin-ext/src/plugin/type-converters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -750,3 +750,19 @@ export function fromFoldingRangeKind(kind: theia.FoldingRangeKind | undefined):
}
return undefined;
}

export function fromColor(color: types.Color): [number, number, number, number] {
return [color.red, color.green, color.blue, color.alpha];
}

export function toColor(color: [number, number, number, number]): types.Color {
return new types.Color(color[0], color[1], color[2], color[3]);
}

export function fromColorPresentation(colorPresentation: theia.ColorPresentation): model.ColorPresentation {
return {
label: colorPresentation.label,
textEdit: colorPresentation.textEdit ? fromTextEdit(colorPresentation.textEdit) : undefined,
additionalTextEdits: colorPresentation.additionalTextEdits ? colorPresentation.additionalTextEdits.map(value => fromTextEdit(value)) : undefined
};
}
49 changes: 49 additions & 0 deletions packages/plugin-ext/src/plugin/types-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1719,6 +1719,55 @@ export class FunctionBreakpoint extends Breakpoint {
}
}

export class Color {
readonly red: number;
readonly green: number;
readonly blue: number;
readonly alpha: number;

constructor(red: number, green: number, blue: number, alpha: number) {
this.red = red;
this.green = green;
this.blue = blue;
this.alpha = alpha;
}
}

export class ColorInformation {
range: Range;
color: Color;

constructor(range: Range, color: Color) {
if (color && !(color instanceof Color)) {
throw illegalArgument('color');
}
if (!Range.isRange(range)) {
throw illegalArgument('range');
}
this.range = range;
this.color = color;
}
}

export class ColorPresentation {
label: string;
textEdit?: TextEdit;
additionalTextEdits?: TextEdit[];

constructor(label: string) {
if (!label || typeof label !== 'string') {
throw illegalArgument('label');
}
this.label = label;
}
}

export enum ColorFormat {
RGB = 0,
HEX = 1,
HSL = 2
}

export class FoldingRange {
start: number;
end: number;
Expand Down
Loading

0 comments on commit 21738e4

Please sign in to comment.