diff --git a/package-lock.json b/package-lock.json index e7712beb..1777b7d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,14 +68,14 @@ } }, "vscode-json-languageservice": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.0.12.tgz", - "integrity": "sha512-XSgRVY/vsPqOa//ZwLD5DWx1wzTQGgeZfsOlVqFlLya10dpimSnd27kbuL45hzxh4B+MvmHZtZeWQKjSYnNF0A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.1.0.tgz", + "integrity": "sha512-ybmyI9sn3nGJS8LgLR+YPk6M0LH8A7hp14ZGYDeNgrNVqkbZRN6K+JthHkhCR0MmA0RluwDtOJlAeqRFUEiK2A==", "dev": true, "requires": { "jsonc-parser": "2.0.0-next.1", "vscode-languageserver-types": "3.6.1", - "vscode-nls": "3.2.1", + "vscode-nls": "3.2.2", "vscode-uri": "1.0.3" } }, @@ -86,9 +86,9 @@ "dev": true }, "vscode-nls": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.1.tgz", - "integrity": "sha512-5D0USR9x2bXMS9f8NFQWNb7oA1FWveqeNAVaGNFaJJvDF7G7qmSGZMRng+YvD4XnGgbJvXQnCIh8eXbo6Kcz8w==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-3.2.2.tgz", + "integrity": "sha512-/Ur1+tgazwd51+ncRyoy0UIu4dvMdVXS9XMUULQlZIBoNGEwOhwEx9x+hHWoUjldMrOQ32t2CGKo0u6D4R6/hg==", "dev": true }, "vscode-uri": { diff --git a/package.json b/package.json index 1a74ca60..6e328d7b 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "requirejs": "^2.3.5", "typescript": "2.7.2", "uglify-js": "^3.3.14", - "vscode-json-languageservice": "3.0.12", + "vscode-json-languageservice": "3.1.0", "vscode-languageserver-types": "3.6.1" } } diff --git a/src/jsonMode.ts b/src/jsonMode.ts index 30605489..39d8f7df 100644 --- a/src/jsonMode.ts +++ b/src/jsonMode.ts @@ -35,6 +35,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): void { disposables.push(new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults)); disposables.push(monaco.languages.setTokensProvider(languageId, createTokenizationSupport(true))); disposables.push(monaco.languages.setLanguageConfiguration(languageId, richEditConfiguration)); + disposables.push(monaco.languages.registerColorProvider(languageId, new languageFeatures.DocumentColorAdapter(worker))); } diff --git a/src/jsonWorker.ts b/src/jsonWorker.ts index e9ff0545..bbe0cf8e 100644 --- a/src/jsonWorker.ts +++ b/src/jsonWorker.ts @@ -18,7 +18,7 @@ class PromiseAdapter implements jsonService.Thenable { this.wrapped = new monaco.Promise(executor); } public then(onfulfilled?: (value: T) => TResult | jsonService.Thenable, onrejected?: (reason: any) => void): jsonService.Thenable { - let thenable : jsonService.Thenable = this.wrapped; + let thenable: jsonService.Thenable = this.wrapped; return thenable.then(onfulfilled, onrejected); } public getWrapped(): monaco.Thenable { @@ -28,7 +28,7 @@ class PromiseAdapter implements jsonService.Thenable { this.wrapped.cancel(); } public static resolve(v: T | Thenable): jsonService.Thenable { - return > monaco.Promise.as(v); + return >monaco.Promise.as(v); } public static reject(v: T): jsonService.Thenable { return monaco.Promise.wrapError(v); @@ -88,6 +88,18 @@ export class JSONWorker { let symbols = this._languageService.findDocumentSymbols(document, jsonDocument); return Promise.as(symbols); } + findDocumentColors(uri: string): Thenable { + let document = this._getTextDocument(uri); + let stylesheet = this._languageService.parseJSONDocument(document); + let colorSymbols = this._languageService.findDocumentColors(document, stylesheet); + return Promise.as(colorSymbols); + } + getColorPresentations(uri: string, color: jsonService.Color, range: ls.Range): Thenable { + let document = this._getTextDocument(uri); + let stylesheet = this._languageService.parseJSONDocument(document); + let colorPresentations = this._languageService.getColorPresentations(document, stylesheet, color, range); + return Promise.as(colorPresentations); + } private _getTextDocument(uri: string): ls.TextDocument { let models = this._ctx.getMirrorModels(); for (let model of models) { diff --git a/src/languageFeatures.ts b/src/languageFeatures.ts index 67ad7400..3b8b3e22 100644 --- a/src/languageFeatures.ts +++ b/src/languageFeatures.ts @@ -12,6 +12,7 @@ import * as ls from 'vscode-languageserver-types'; import Uri = monaco.Uri; import Position = monaco.Position; import Range = monaco.Range; +import IRange = monaco.IRange; import Thenable = monaco.Thenable; import Promise = monaco.Promise; import CancellationToken = monaco.CancellationToken; @@ -149,13 +150,12 @@ function fromPosition(position: Position): ls.Position { return { character: position.column - 1, line: position.lineNumber - 1 }; } -function fromRange(range: Range): ls.Range { +function fromRange(range: IRange): ls.Range { if (!range) { return void 0; } - return { start: fromPosition(range.getStartPosition()), end: fromPosition(range.getEndPosition()) }; + return { start: { line: range.startLineNumber - 1, character: range.startColumn - 1 }, end: { line: range.endLineNumber - 1, character: range.endColumn - 1 } }; } - function toRange(range: ls.Range): Range { if (!range) { return void 0; @@ -486,6 +486,48 @@ export class DocumentRangeFormattingEditProvider implements monaco.languages.Doc } } +export class DocumentColorAdapter implements monaco.languages.DocumentColorProvider { + + constructor(private _worker: WorkerAccessor) { + } + + public provideDocumentColors(model: monaco.editor.IReadOnlyModel, token: CancellationToken): Thenable { + const resource = model.uri; + + return wireCancellationToken(token, this._worker(resource).then(worker => worker.findDocumentColors(resource.toString())).then(infos => { + if (!infos) { + return; + } + return infos.map(item => ({ + color: item.color, + range: toRange(item.range) + })); + })); + } + + public provideColorPresentations(model: monaco.editor.IReadOnlyModel, info: monaco.languages.IColorInformation, token: CancellationToken): Thenable { + const resource = model.uri; + + return wireCancellationToken(token, this._worker(resource).then(worker => worker.getColorPresentations(resource.toString(), info.color, fromRange(info.range))).then(presentations => { + if (!presentations) { + return; + } + return presentations.map(presentation => { + let item: monaco.languages.IColorPresentation = { + label: presentation.label, + }; + if (presentation.textEdit) { + item.textEdit = toTextEdit(presentation.textEdit) + } + if (presentation.additionalTextEdits) { + item.additionalTextEdits = presentation.additionalTextEdits.map(toTextEdit) + } + return item; + }); + })); + } +} + /** * Hook a cancellation token to a WinJS Promise */