From 1a46d2339995b53f30a66d307b62d4d90594d6e0 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 7 Sep 2020 16:48:41 +0200 Subject: [PATCH] Use the global `monaco` only in the AMD case (see microsoft/monaco-editor#1974) --- src/monaco.d.ts => monaco.d.ts | 28 +-- package-lock.json | 24 +- package.json | 14 +- scripts/bundle.js | 12 +- scripts/dts.js | 41 ++++ src/fillers/monaco-editor-core-amd.ts | 12 + .../monaco-editor-core.ts} | 3 +- src/html.worker.ts | 1 - src/htmlMode.ts | 53 ++-- src/htmlWorker.ts | 15 +- src/languageFeatures.ts | 231 +++++++++--------- src/monaco.contribution.ts | 167 ++++++++++--- src/tsconfig.esm.json | 1 + src/tsconfig.json | 1 + src/workerManager.ts | 17 +- 15 files changed, 370 insertions(+), 250 deletions(-) rename src/monaco.d.ts => monaco.d.ts (89%) create mode 100644 scripts/dts.js create mode 100644 src/fillers/monaco-editor-core-amd.ts rename src/{typings/refs.d.ts => fillers/monaco-editor-core.ts} (82%) diff --git a/src/monaco.d.ts b/monaco.d.ts similarity index 89% rename from src/monaco.d.ts rename to monaco.d.ts index 031f5db..7792d75 100644 --- a/src/monaco.d.ts +++ b/monaco.d.ts @@ -3,7 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -declare module monaco.languages.html { +/// + +declare namespace monaco.languages.html { export interface HTMLFormatConfiguration { readonly tabSize: number; readonly insertSpaces: boolean; @@ -22,11 +24,9 @@ declare module monaco.languages.html { | 'force-aligned' | 'force-expand-multiline'; } - export interface CompletionConfiguration { [provider: string]: boolean; } - export interface Options { /** * If set, comments are tolerated. If set to false, syntax errors will be emitted for comments. @@ -37,76 +37,64 @@ declare module monaco.languages.html { */ readonly suggest?: CompletionConfiguration; } - export interface ModeConfiguration { /** * Defines whether the built-in completionItemProvider is enabled. */ readonly completionItems?: boolean; - /** * Defines whether the built-in hoverProvider is enabled. */ readonly hovers?: boolean; - /** * Defines whether the built-in documentSymbolProvider is enabled. */ readonly documentSymbols?: boolean; - /** * Defines whether the built-in definitions provider is enabled. */ readonly links?: boolean; - /** * Defines whether the built-in references provider is enabled. */ readonly documentHighlights?: boolean; - /** * Defines whether the built-in rename provider is enabled. */ readonly rename?: boolean; - /** * Defines whether the built-in color provider is enabled. */ readonly colors?: boolean; - /** * Defines whether the built-in foldingRange provider is enabled. */ readonly foldingRanges?: boolean; - /** * Defines whether the built-in diagnostic provider is enabled. */ readonly diagnostics?: boolean; - /** * Defines whether the built-in selection range provider is enabled. */ readonly selectionRanges?: boolean; - /** * Defines whether the built-in documentFormattingEdit provider is enabled. */ readonly documentFormattingEdits?: boolean; - /** * Defines whether the built-in documentRangeFormattingEdit provider is enabled. */ readonly documentRangeFormattingEdits?: boolean; } - export interface LanguageServiceDefaults { + readonly languageId: string; + readonly modeConfiguration: ModeConfiguration; readonly onDidChange: IEvent; readonly options: Options; setOptions(options: Options): void; } - - export var htmlDefaults: LanguageServiceDefaults; - export var handlebarDefaults: LanguageServiceDefaults; - export var razorDefaults: LanguageServiceDefaults; + export const htmlDefaults: LanguageServiceDefaults; + export const handlebarDefaults: LanguageServiceDefaults; + export const razorDefaults: LanguageServiceDefaults; } diff --git a/package-lock.json b/package-lock.json index b15747d..4e9a78f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -423,9 +423,9 @@ "dev": true }, "monaco-plugin-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/monaco-plugin-helpers/-/monaco-plugin-helpers-1.0.2.tgz", - "integrity": "sha512-7kUx8dtd5qVNVgUARBRhnM8oftPglYwlINfigC4yGUiuzqtIN22u1tly8umiOCIPR0eFiBLjt6aN23oZh2QJgg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/monaco-plugin-helpers/-/monaco-plugin-helpers-1.0.3.tgz", + "integrity": "sha512-6AYI3ONAy8ki74qG2JqtFrLdiJHQlgeO5l4Rwr0OMyIpGXhc94y5rZuFxOtgGkxgSrZfHSwOt/MulUNZ/mOQOw==", "dev": true, "requires": { "typescript": "^2.7.2" @@ -672,9 +672,9 @@ "dev": true }, "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -697,9 +697,9 @@ } }, "terser": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz", - "integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.3.0.tgz", + "integrity": "sha512-XTT3D3AwxC54KywJijmY2mxZ8nJiEjBHVYzq8l9OaYuRFWeQNBwvipuzzYEP4e+/AVcd1hqG/CqgsdIRyT45Fg==", "dev": true, "requires": { "commander": "^2.20.0", @@ -708,9 +708,9 @@ } }, "typescript": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", - "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", + "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", "dev": true }, "vscode-html-languageservice": { diff --git a/package.json b/package.json index de5ec4b..22c90a6 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,9 @@ "version": "2.7.0", "description": "HTML plugin for the Monaco Editor", "scripts": { - "compile": "mrmdir ./out && tsc -p ./src/tsconfig.json && tsc -p ./src/tsconfig.esm.json", + "compile": "mrmdir ./out && tsc -p ./src/tsconfig.json && tsc -p ./src/tsconfig.esm.json && node ./scripts/dts && prettier --write ./monaco.d.ts", "watch": "tsc -p ./src --watch", - "prepublishOnly": "mrmdir ./release && npm run compile && node ./scripts/release.js && node ./scripts/bundle && mcopy ./src/monaco.d.ts ./release/monaco.d.ts", + "prepublishOnly": "mrmdir ./release && npm run compile && node ./scripts/release.js && node ./scripts/bundle && mcopy ./monaco.d.ts ./release/monaco.d.ts && mcopy ./out/esm/monaco.contribution.d.ts ./release/esm/monaco.contribution.d.ts && mcopy ./out/esm/fillers/monaco-editor-core.d.ts ./release/esm/fillers/monaco-editor-core.d.ts", "install-service-next": "npm install vscode-html-languageservice@next -f -D && npm install vscode-languageserver-types@next -f -D", "install-service-local": "npm install ../vscode-html-languageservice -f -D && npm install ../vscode-languageserver-node/types -f -D", "prettier": "prettier --write ." @@ -19,16 +19,18 @@ "bugs": { "url": "https://github.com/Microsoft/monaco-editor/issues" }, + "module": "./release/esm/monaco.contribution.js", + "typings": "./release/esm/monaco.contribution.d.ts", "devDependencies": { - "husky": "^4.2.5", + "husky": "^4.3.0", "monaco-editor-core": "0.20.0", "monaco-languages": "^1.10.0", - "monaco-plugin-helpers": "^1.0.2", + "monaco-plugin-helpers": "^1.0.3", "prettier": "^2.1.1", "pretty-quick": "^3.0.0", "requirejs": "^2.3.6", - "typescript": "^3.7.5", - "terser": "^4.6.3", + "typescript": "^4.0.2", + "terser": "^5.3.0", "vscode-html-languageservice": "3.0.4-next.12", "vscode-languageserver-types": "3.15.0-next.9", "vscode-languageserver-textdocument": "^1.0.0-next.5" diff --git a/scripts/bundle.js b/scripts/bundle.js index 586eecf..44e6989 100644 --- a/scripts/bundle.js +++ b/scripts/bundle.js @@ -21,7 +21,7 @@ const BUNDLED_FILE_HEADER = [ ].join('\n'); bundleOne('monaco.contribution'); -bundleOne('htmlMode'); +bundleOne('htmlMode', ['vs/language/html/monaco.contribution']); bundleOne('htmlWorker'); function bundleOne(moduleId, exclude) { @@ -32,7 +32,9 @@ function bundleOne(moduleId, exclude) { out: 'release/dev/' + moduleId + '.js', exclude: exclude, paths: { - 'vs/language/html': REPO_ROOT + '/out/amd' + 'vs/language/html': REPO_ROOT + '/out/amd', + 'vs/language/html/fillers/monaco-editor-core': + REPO_ROOT + '/out/amd/fillers/monaco-editor-core-amd' }, optimize: 'none', packages: [ @@ -72,7 +74,7 @@ function bundleOne(moduleId, exclude) { } ] }, - function (buildResponse) { + async function (buildResponse) { const devFilePath = path.join( REPO_ROOT, 'release/dev/' + moduleId + '.js' @@ -84,12 +86,12 @@ function bundleOne(moduleId, exclude) { const fileContents = fs.readFileSync(devFilePath).toString(); console.log(); console.log(`Minifying ${devFilePath}...`); - const result = terser.minify(fileContents, { + const result = await terser.minify(fileContents, { output: { comments: 'some' } }); - console.log(`Done.`); + console.log(`Done minifying ${devFilePath}.`); try { fs.mkdirSync(path.join(REPO_ROOT, 'release/min')); } catch (err) {} diff --git a/scripts/dts.js b/scripts/dts.js new file mode 100644 index 0000000..64f17a4 --- /dev/null +++ b/scripts/dts.js @@ -0,0 +1,41 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const path = require('path'); +const fs = require('fs'); + +const REPO_ROOT = path.join(__dirname, '../'); +const SRC_PATH = path.join(REPO_ROOT, 'out/amd/monaco.contribution.d.ts'); +const DST_PATH = path.join(REPO_ROOT, 'monaco.d.ts'); + +const lines = fs + .readFileSync(SRC_PATH) + .toString() + .split(/\r\n|\r|\n/); +let result = [ + `/*---------------------------------------------------------------------------------------------`, + ` * Copyright (c) Microsoft Corporation. All rights reserved.`, + ` * Licensed under the MIT License. See License.txt in the project root for license information.`, + ` *--------------------------------------------------------------------------------------------*/`, + ``, + `/// `, + ``, + `declare namespace monaco.languages.html {` +]; +for (let line of lines) { + if (/^import/.test(line)) { + continue; + } + line = line.replace(/ /g, '\t'); + line = line.replace(/export declare/g, 'export'); + if (line.length > 0) { + line = `\t${line}`; + result.push(line); + } +} +result.push(`}`); +result.push(``); + +fs.writeFileSync(DST_PATH, result.join('\n')); diff --git a/src/fillers/monaco-editor-core-amd.ts b/src/fillers/monaco-editor-core-amd.ts new file mode 100644 index 0000000..59874ef --- /dev/null +++ b/src/fillers/monaco-editor-core-amd.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// Resolves with the global monaco API + +declare var define; + +define([], function () { + return (self).monaco; +}); diff --git a/src/typings/refs.d.ts b/src/fillers/monaco-editor-core.ts similarity index 82% rename from src/typings/refs.d.ts rename to src/fillers/monaco-editor-core.ts index 3927c21..cd996aa 100644 --- a/src/typings/refs.d.ts +++ b/src/fillers/monaco-editor-core.ts @@ -2,4 +2,5 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -/// + +export * from 'monaco-editor-core'; diff --git a/src/html.worker.ts b/src/html.worker.ts index 565bec3..3251956 100644 --- a/src/html.worker.ts +++ b/src/html.worker.ts @@ -2,7 +2,6 @@ * 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 worker from 'monaco-editor-core/esm/vs/editor/editor.worker'; import { HTMLWorker } from './htmlWorker'; diff --git a/src/htmlMode.ts b/src/htmlMode.ts index dfd4981..c30f12b 100644 --- a/src/htmlMode.ts +++ b/src/htmlMode.ts @@ -2,17 +2,14 @@ * 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 { WorkerManager } from './workerManager'; -import { HTMLWorker } from './htmlWorker'; -import { LanguageServiceDefaultsImpl } from './monaco.contribution'; +import type { HTMLWorker } from './htmlWorker'; +import { LanguageServiceDefaults } from './monaco.contribution'; import * as languageFeatures from './languageFeatures'; +import { Uri, IDisposable, languages } from './fillers/monaco-editor-core'; -import Uri = monaco.Uri; -import IDisposable = monaco.IDisposable; - -export function setupMode1(defaults: LanguageServiceDefaultsImpl): void { +export function setupMode1(defaults: LanguageServiceDefaults): void { const client = new WorkerManager(defaults); const worker: languageFeatures.WorkerAccessor = ( @@ -24,47 +21,47 @@ export function setupMode1(defaults: LanguageServiceDefaultsImpl): void { let languageId = defaults.languageId; // all modes - monaco.languages.registerCompletionItemProvider( + languages.registerCompletionItemProvider( languageId, new languageFeatures.CompletionAdapter(worker) ); - monaco.languages.registerHoverProvider( + languages.registerHoverProvider( languageId, new languageFeatures.HoverAdapter(worker) ); - monaco.languages.registerDocumentHighlightProvider( + languages.registerDocumentHighlightProvider( languageId, new languageFeatures.DocumentHighlightAdapter(worker) ); - monaco.languages.registerLinkProvider( + languages.registerLinkProvider( languageId, new languageFeatures.DocumentLinkAdapter(worker) ); - monaco.languages.registerFoldingRangeProvider( + languages.registerFoldingRangeProvider( languageId, new languageFeatures.FoldingRangeAdapter(worker) ); - monaco.languages.registerDocumentSymbolProvider( + languages.registerDocumentSymbolProvider( languageId, new languageFeatures.DocumentSymbolAdapter(worker) ); - monaco.languages.registerSelectionRangeProvider( + languages.registerSelectionRangeProvider( languageId, new languageFeatures.SelectionRangeAdapter(worker) ); - monaco.languages.registerRenameProvider( + languages.registerRenameProvider( languageId, new languageFeatures.RenameAdapter(worker) ); // only html if (languageId === 'html') { - monaco.languages.registerDocumentFormattingEditProvider( + languages.registerDocumentFormattingEditProvider( languageId, new languageFeatures.DocumentFormattingEditProvider(worker) ); - monaco.languages.registerDocumentRangeFormattingEditProvider( + languages.registerDocumentRangeFormattingEditProvider( languageId, new languageFeatures.DocumentRangeFormattingEditProvider(worker) ); @@ -72,7 +69,7 @@ export function setupMode1(defaults: LanguageServiceDefaultsImpl): void { } } -export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { +export function setupMode(defaults: LanguageServiceDefaults): IDisposable { const disposables: IDisposable[] = []; const providers: IDisposable[] = []; @@ -92,7 +89,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { if (modeConfiguration.completionItems) { providers.push( - monaco.languages.registerCompletionItemProvider( + languages.registerCompletionItemProvider( languageId, new languageFeatures.CompletionAdapter(worker) ) @@ -100,7 +97,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { } if (modeConfiguration.hovers) { providers.push( - monaco.languages.registerHoverProvider( + languages.registerHoverProvider( languageId, new languageFeatures.HoverAdapter(worker) ) @@ -108,7 +105,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { } if (modeConfiguration.documentHighlights) { providers.push( - monaco.languages.registerDocumentHighlightProvider( + languages.registerDocumentHighlightProvider( languageId, new languageFeatures.DocumentHighlightAdapter(worker) ) @@ -116,7 +113,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { } if (modeConfiguration.links) { providers.push( - monaco.languages.registerLinkProvider( + languages.registerLinkProvider( languageId, new languageFeatures.DocumentLinkAdapter(worker) ) @@ -124,7 +121,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { } if (modeConfiguration.documentSymbols) { providers.push( - monaco.languages.registerDocumentSymbolProvider( + languages.registerDocumentSymbolProvider( languageId, new languageFeatures.DocumentSymbolAdapter(worker) ) @@ -132,7 +129,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { } if (modeConfiguration.rename) { providers.push( - monaco.languages.registerRenameProvider( + languages.registerRenameProvider( languageId, new languageFeatures.RenameAdapter(worker) ) @@ -140,7 +137,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { } if (modeConfiguration.foldingRanges) { providers.push( - monaco.languages.registerFoldingRangeProvider( + languages.registerFoldingRangeProvider( languageId, new languageFeatures.FoldingRangeAdapter(worker) ) @@ -148,7 +145,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { } if (modeConfiguration.selectionRanges) { providers.push( - monaco.languages.registerSelectionRangeProvider( + languages.registerSelectionRangeProvider( languageId, new languageFeatures.SelectionRangeAdapter(worker) ) @@ -156,7 +153,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { } if (modeConfiguration.documentFormattingEdits) { providers.push( - monaco.languages.registerDocumentFormattingEditProvider( + languages.registerDocumentFormattingEditProvider( languageId, new languageFeatures.DocumentFormattingEditProvider(worker) ) @@ -164,7 +161,7 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { } if (modeConfiguration.documentRangeFormattingEdits) { providers.push( - monaco.languages.registerDocumentRangeFormattingEditProvider( + languages.registerDocumentRangeFormattingEditProvider( languageId, new languageFeatures.DocumentRangeFormattingEditProvider(worker) ) diff --git a/src/htmlWorker.ts b/src/htmlWorker.ts index 83b5979..a563074 100644 --- a/src/htmlWorker.ts +++ b/src/htmlWorker.ts @@ -2,19 +2,18 @@ * 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 IWorkerContext = monaco.worker.IWorkerContext; +import { worker } from './fillers/monaco-editor-core'; import * as htmlService from 'vscode-html-languageservice'; +import type { Options } from './monaco.contribution'; export class HTMLWorker { - private _ctx: IWorkerContext; + private _ctx: worker.IWorkerContext; private _languageService: htmlService.LanguageService; - private _languageSettings: monaco.languages.html.Options; + private _languageSettings: Options; private _languageId: string; - constructor(ctx: IWorkerContext, createData: ICreateData) { + constructor(ctx: worker.IWorkerContext, createData: ICreateData) { this._ctx = ctx; this._languageSettings = createData.languageSettings; this._languageId = createData.languageId; @@ -140,11 +139,11 @@ export class HTMLWorker { export interface ICreateData { languageId: string; - languageSettings: monaco.languages.html.Options; + languageSettings: Options; } export function create( - ctx: IWorkerContext, + ctx: worker.IWorkerContext, createData: ICreateData ): HTMLWorker { return new HTMLWorker(ctx, createData); diff --git a/src/languageFeatures.ts b/src/languageFeatures.ts index c4a75ca..35be1e9 100644 --- a/src/languageFeatures.ts +++ b/src/languageFeatures.ts @@ -2,18 +2,21 @@ * 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 { LanguageServiceDefaultsImpl } from './monaco.contribution'; -import { HTMLWorker } from './htmlWorker'; +import { LanguageServiceDefaults } from './monaco.contribution'; +import type { HTMLWorker } from './htmlWorker'; import * as htmlService from 'vscode-html-languageservice'; - -import Uri = monaco.Uri; -import Position = monaco.Position; -import Range = monaco.Range; -import CancellationToken = monaco.CancellationToken; -import IDisposable = monaco.IDisposable; +import { + languages, + editor, + Uri, + Position, + Range, + CancellationToken, + IDisposable, + MarkerSeverity, + IMarkdownString +} from './fillers/monaco-editor-core'; export interface WorkerAccessor { (...more: Uri[]): Promise; @@ -28,9 +31,9 @@ export class DiagnosticsAdapter { constructor( private _languageId: string, private _worker: WorkerAccessor, - defaults: LanguageServiceDefaultsImpl + defaults: LanguageServiceDefaults ) { - const onModelAdd = (model: monaco.editor.IModel): void => { + const onModelAdd = (model: editor.IModel): void => { const modeId = model.getModeId(); if (modeId !== this._languageId) { return; @@ -45,8 +48,8 @@ export class DiagnosticsAdapter { this._doValidate(model.uri, modeId); }; - const onModelRemoved = (model: monaco.editor.IModel): void => { - monaco.editor.setModelMarkers(model, this._languageId, []); + const onModelRemoved = (model: editor.IModel): void => { + editor.setModelMarkers(model, this._languageId, []); const uriStr = model.uri.toString(); const listener = this._listener[uriStr]; if (listener) { @@ -55,14 +58,14 @@ export class DiagnosticsAdapter { } }; - this._disposables.push(monaco.editor.onDidCreateModel(onModelAdd)); + this._disposables.push(editor.onDidCreateModel(onModelAdd)); this._disposables.push( - monaco.editor.onWillDisposeModel((model) => { + editor.onWillDisposeModel((model) => { onModelRemoved(model); }) ); this._disposables.push( - monaco.editor.onDidChangeModelLanguage((event) => { + editor.onDidChangeModelLanguage((event) => { onModelRemoved(event.model); onModelAdd(event.model); }) @@ -70,7 +73,7 @@ export class DiagnosticsAdapter { this._disposables.push( defaults.onDidChange((_) => { - monaco.editor.getModels().forEach((model) => { + editor.getModels().forEach((model) => { if (model.getModeId() === this._languageId) { onModelRemoved(model); onModelAdd(model); @@ -87,7 +90,7 @@ export class DiagnosticsAdapter { } }); - monaco.editor.getModels().forEach(onModelAdd); + editor.getModels().forEach(onModelAdd); } public dispose(): void { @@ -100,8 +103,8 @@ export class DiagnosticsAdapter { .then((worker) => { return worker.doValidation(resource.toString()).then((diagnostics) => { const markers = diagnostics.map((d) => toDiagnostics(resource, d)); - monaco.editor.setModelMarkers( - monaco.editor.getModel(resource), + editor.setModelMarkers( + editor.getModel(resource), languageId, markers ); @@ -113,25 +116,25 @@ export class DiagnosticsAdapter { } } -function toSeverity(lsSeverity: number): monaco.MarkerSeverity { +function toSeverity(lsSeverity: number): MarkerSeverity { switch (lsSeverity) { case htmlService.DiagnosticSeverity.Error: - return monaco.MarkerSeverity.Error; + return MarkerSeverity.Error; case htmlService.DiagnosticSeverity.Warning: - return monaco.MarkerSeverity.Warning; + return MarkerSeverity.Warning; case htmlService.DiagnosticSeverity.Information: - return monaco.MarkerSeverity.Info; + return MarkerSeverity.Info; case htmlService.DiagnosticSeverity.Hint: - return monaco.MarkerSeverity.Hint; + return MarkerSeverity.Hint; default: - return monaco.MarkerSeverity.Info; + return MarkerSeverity.Info; } } function toDiagnostics( resource: Uri, diag: htmlService.Diagnostic -): monaco.editor.IMarkerData { +): editor.IMarkerData { const code = typeof diag.code === 'number' ? String(diag.code) : diag.code; @@ -178,10 +181,8 @@ function toRange(range: htmlService.Range): Range { ); } -function toCompletionItemKind( - kind: number -): monaco.languages.CompletionItemKind { - const mItemKind = monaco.languages.CompletionItemKind; +function toCompletionItemKind(kind: number): languages.CompletionItemKind { + const mItemKind = languages.CompletionItemKind; switch (kind) { case htmlService.CompletionItemKind.Text: @@ -225,9 +226,9 @@ function toCompletionItemKind( } function fromCompletionItemKind( - kind: monaco.languages.CompletionItemKind + kind: languages.CompletionItemKind ): htmlService.CompletionItemKind { - const mItemKind = monaco.languages.CompletionItemKind; + const mItemKind = languages.CompletionItemKind; switch (kind) { case mItemKind.Text: @@ -272,7 +273,7 @@ function fromCompletionItemKind( function toTextEdit( textEdit: htmlService.TextEdit -): monaco.editor.ISingleEditOperation { +): editor.ISingleEditOperation { if (!textEdit) { return void 0; } @@ -282,8 +283,7 @@ function toTextEdit( }; } -export class CompletionAdapter - implements monaco.languages.CompletionItemProvider { +export class CompletionAdapter implements languages.CompletionItemProvider { constructor(private _worker: WorkerAccessor) {} public get triggerCharacters(): string[] { @@ -291,11 +291,11 @@ export class CompletionAdapter } provideCompletionItems( - model: monaco.editor.IReadOnlyModel, + model: editor.IReadOnlyModel, position: Position, - context: monaco.languages.CompletionContext, + context: languages.CompletionContext, token: CancellationToken - ): Promise { + ): Promise { const resource = model.uri; return this._worker(resource) @@ -314,36 +314,32 @@ export class CompletionAdapter wordInfo.endColumn ); - const items: monaco.languages.CompletionItem[] = info.items.map( - (entry) => { - const item: monaco.languages.CompletionItem = { - label: entry.label, - insertText: entry.insertText || entry.label, - sortText: entry.sortText, - filterText: entry.filterText, - documentation: entry.documentation, - detail: entry.detail, - range: wordRange, - kind: toCompletionItemKind(entry.kind) - }; - if (entry.textEdit) { - item.range = toRange(entry.textEdit.range); - item.insertText = entry.textEdit.newText; - } - if (entry.additionalTextEdits) { - item.additionalTextEdits = entry.additionalTextEdits.map( - toTextEdit - ); - } - if ( - entry.insertTextFormat === htmlService.InsertTextFormat.Snippet - ) { - item.insertTextRules = - monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet; - } - return item; + const items: languages.CompletionItem[] = info.items.map((entry) => { + const item: languages.CompletionItem = { + label: entry.label, + insertText: entry.insertText || entry.label, + sortText: entry.sortText, + filterText: entry.filterText, + documentation: entry.documentation, + detail: entry.detail, + range: wordRange, + kind: toCompletionItemKind(entry.kind) + }; + if (entry.textEdit) { + item.range = toRange(entry.textEdit.range); + item.insertText = entry.textEdit.newText; } - ); + if (entry.additionalTextEdits) { + item.additionalTextEdits = entry.additionalTextEdits.map( + toTextEdit + ); + } + if (entry.insertTextFormat === htmlService.InsertTextFormat.Snippet) { + item.insertTextRules = + languages.CompletionItemInsertTextRule.InsertAsSnippet; + } + return item; + }); return { isIncomplete: info.isIncomplete, @@ -365,7 +361,7 @@ function isMarkupContent(thing: any): thing is htmlService.MarkupContent { function toMarkdownString( entry: htmlService.MarkupContent | htmlService.MarkedString -): monaco.IMarkdownString { +): IMarkdownString { if (typeof entry === 'string') { return { value: entry @@ -390,7 +386,7 @@ function toMarkedStringArray( | htmlService.MarkupContent | htmlService.MarkedString | htmlService.MarkedString[] -): monaco.IMarkdownString[] { +): IMarkdownString[] { if (!contents) { return void 0; } @@ -400,14 +396,14 @@ function toMarkedStringArray( return [toMarkdownString(contents)]; } -export class HoverAdapter implements monaco.languages.HoverProvider { +export class HoverAdapter implements languages.HoverProvider { constructor(private _worker: WorkerAccessor) {} provideHover( - model: monaco.editor.IReadOnlyModel, + model: editor.IReadOnlyModel, position: Position, token: CancellationToken - ): Promise { + ): Promise { let resource = model.uri; return this._worker(resource) @@ -418,7 +414,7 @@ export class HoverAdapter implements monaco.languages.HoverProvider { if (!info) { return; } - return { + return { range: toRange(info.range), contents: toMarkedStringArray(info.contents) }; @@ -430,8 +426,8 @@ export class HoverAdapter implements monaco.languages.HoverProvider { function toHighlighKind( kind: htmlService.DocumentHighlightKind -): monaco.languages.DocumentHighlightKind { - const mKind = monaco.languages.DocumentHighlightKind; +): languages.DocumentHighlightKind { + const mKind = languages.DocumentHighlightKind; switch (kind) { case htmlService.DocumentHighlightKind.Read: @@ -445,14 +441,14 @@ function toHighlighKind( } export class DocumentHighlightAdapter - implements monaco.languages.DocumentHighlightProvider { + implements languages.DocumentHighlightProvider { constructor(private _worker: WorkerAccessor) {} public provideDocumentHighlights( - model: monaco.editor.IReadOnlyModel, + model: editor.IReadOnlyModel, position: Position, token: CancellationToken - ): Promise { + ): Promise { const resource = model.uri; return this._worker(resource) @@ -476,10 +472,8 @@ export class DocumentHighlightAdapter // --- document symbols ------ -function toSymbolKind( - kind: htmlService.SymbolKind -): monaco.languages.SymbolKind { - let mKind = monaco.languages.SymbolKind; +function toSymbolKind(kind: htmlService.SymbolKind): languages.SymbolKind { + let mKind = languages.SymbolKind; switch (kind) { case htmlService.SymbolKind.File: @@ -522,14 +516,13 @@ function toSymbolKind( return mKind.Function; } -export class DocumentSymbolAdapter - implements monaco.languages.DocumentSymbolProvider { +export class DocumentSymbolAdapter implements languages.DocumentSymbolProvider { constructor(private _worker: WorkerAccessor) {} public provideDocumentSymbols( - model: monaco.editor.IReadOnlyModel, + model: editor.IReadOnlyModel, token: CancellationToken - ): Promise { + ): Promise { const resource = model.uri; return this._worker(resource) @@ -551,13 +544,13 @@ export class DocumentSymbolAdapter } } -export class DocumentLinkAdapter implements monaco.languages.LinkProvider { +export class DocumentLinkAdapter implements languages.LinkProvider { constructor(private _worker: WorkerAccessor) {} public provideLinks( - model: monaco.editor.IReadOnlyModel, + model: editor.IReadOnlyModel, token: CancellationToken - ): Promise { + ): Promise { const resource = model.uri; return this._worker(resource) @@ -577,7 +570,7 @@ export class DocumentLinkAdapter implements monaco.languages.LinkProvider { } function fromFormattingOptions( - options: monaco.languages.FormattingOptions + options: languages.FormattingOptions ): htmlService.FormattingOptions { return { tabSize: options.tabSize, @@ -586,14 +579,14 @@ function fromFormattingOptions( } export class DocumentFormattingEditProvider - implements monaco.languages.DocumentFormattingEditProvider { + implements languages.DocumentFormattingEditProvider { constructor(private _worker: WorkerAccessor) {} public provideDocumentFormattingEdits( - model: monaco.editor.IReadOnlyModel, - options: monaco.languages.FormattingOptions, + model: editor.IReadOnlyModel, + options: languages.FormattingOptions, token: CancellationToken - ): Promise { + ): Promise { const resource = model.uri; return this._worker(resource).then((worker) => { @@ -610,15 +603,15 @@ export class DocumentFormattingEditProvider } export class DocumentRangeFormattingEditProvider - implements monaco.languages.DocumentRangeFormattingEditProvider { + implements languages.DocumentRangeFormattingEditProvider { constructor(private _worker: WorkerAccessor) {} public provideDocumentRangeFormattingEdits( - model: monaco.editor.IReadOnlyModel, + model: editor.IReadOnlyModel, range: Range, - options: monaco.languages.FormattingOptions, + options: languages.FormattingOptions, token: CancellationToken - ): Promise { + ): Promise { const resource = model.uri; return this._worker(resource).then((worker) => { @@ -638,15 +631,15 @@ export class DocumentRangeFormattingEditProvider } } -export class RenameAdapter implements monaco.languages.RenameProvider { +export class RenameAdapter implements languages.RenameProvider { constructor(private _worker: WorkerAccessor) {} provideRenameEdits( - model: monaco.editor.IReadOnlyModel, + model: editor.IReadOnlyModel, position: Position, newName: string, token: CancellationToken - ): Promise { + ): Promise { const resource = model.uri; return this._worker(resource) @@ -665,11 +658,11 @@ export class RenameAdapter implements monaco.languages.RenameProvider { function toWorkspaceEdit( edit: htmlService.WorkspaceEdit -): monaco.languages.WorkspaceEdit { +): languages.WorkspaceEdit { if (!edit || !edit.changes) { return void 0; } - let resourceEdits: monaco.languages.WorkspaceTextEdit[] = []; + let resourceEdits: languages.WorkspaceTextEdit[] = []; for (let uri in edit.changes) { const _uri = Uri.parse(uri); for (let e of edit.changes[uri]) { @@ -687,15 +680,14 @@ function toWorkspaceEdit( }; } -export class FoldingRangeAdapter - implements monaco.languages.FoldingRangeProvider { +export class FoldingRangeAdapter implements languages.FoldingRangeProvider { constructor(private _worker: WorkerAccessor) {} public provideFoldingRanges( - model: monaco.editor.IReadOnlyModel, - context: monaco.languages.FoldingContext, + model: editor.IReadOnlyModel, + context: languages.FoldingContext, token: CancellationToken - ): Promise { + ): Promise { const resource = model.uri; return this._worker(resource) @@ -705,7 +697,7 @@ export class FoldingRangeAdapter return; } return ranges.map((range) => { - const result: monaco.languages.FoldingRange = { + const result: languages.FoldingRange = { start: range.startLine + 1, end: range.endLine + 1 }; @@ -722,26 +714,25 @@ export class FoldingRangeAdapter function toFoldingRangeKind( kind: htmlService.FoldingRangeKind -): monaco.languages.FoldingRangeKind { +): languages.FoldingRangeKind { switch (kind) { case htmlService.FoldingRangeKind.Comment: - return monaco.languages.FoldingRangeKind.Comment; + return languages.FoldingRangeKind.Comment; case htmlService.FoldingRangeKind.Imports: - return monaco.languages.FoldingRangeKind.Imports; + return languages.FoldingRangeKind.Imports; case htmlService.FoldingRangeKind.Region: - return monaco.languages.FoldingRangeKind.Region; + return languages.FoldingRangeKind.Region; } } -export class SelectionRangeAdapter - implements monaco.languages.SelectionRangeProvider { +export class SelectionRangeAdapter implements languages.SelectionRangeProvider { constructor(private _worker: WorkerAccessor) {} public provideSelectionRanges( - model: monaco.editor.IReadOnlyModel, + model: editor.IReadOnlyModel, positions: Position[], token: CancellationToken - ): Promise { + ): Promise { const resource = model.uri; return this._worker(resource) @@ -756,7 +747,7 @@ export class SelectionRangeAdapter return; } return selectionRanges.map((selectionRange) => { - const result: monaco.languages.SelectionRange[] = []; + const result: languages.SelectionRange[] = []; while (selectionRange) { result.push({ range: toRange(selectionRange.range) }); selectionRange = selectionRange.parent; diff --git a/src/monaco.contribution.ts b/src/monaco.contribution.ts index 9de42c3..74d5d8c 100644 --- a/src/monaco.contribution.ts +++ b/src/monaco.contribution.ts @@ -2,35 +2,133 @@ * 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 mode from './htmlMode'; +import { languages, Emitter, IEvent } from './fillers/monaco-editor-core'; + +export interface HTMLFormatConfiguration { + readonly tabSize: number; + readonly insertSpaces: boolean; + readonly wrapLineLength: number; + readonly unformatted: string; + readonly contentUnformatted: string; + readonly indentInnerHtml: boolean; + readonly preserveNewLines: boolean; + readonly maxPreserveNewLines: number; + readonly indentHandlebars: boolean; + readonly endWithNewline: boolean; + readonly extraLiners: string; + readonly wrapAttributes: + | 'auto' + | 'force' + | 'force-aligned' + | 'force-expand-multiline'; +} + +export interface CompletionConfiguration { + [provider: string]: boolean; +} -import Emitter = monaco.Emitter; -import IEvent = monaco.IEvent; +export interface Options { + /** + * If set, comments are tolerated. If set to false, syntax errors will be emitted for comments. + */ + readonly format?: HTMLFormatConfiguration; + /** + * A list of known schemas and/or associations of schemas to file names. + */ + readonly suggest?: CompletionConfiguration; +} + +export interface ModeConfiguration { + /** + * Defines whether the built-in completionItemProvider is enabled. + */ + readonly completionItems?: boolean; + + /** + * Defines whether the built-in hoverProvider is enabled. + */ + readonly hovers?: boolean; + + /** + * Defines whether the built-in documentSymbolProvider is enabled. + */ + readonly documentSymbols?: boolean; + + /** + * Defines whether the built-in definitions provider is enabled. + */ + readonly links?: boolean; + + /** + * Defines whether the built-in references provider is enabled. + */ + readonly documentHighlights?: boolean; + + /** + * Defines whether the built-in rename provider is enabled. + */ + readonly rename?: boolean; + + /** + * Defines whether the built-in color provider is enabled. + */ + readonly colors?: boolean; + + /** + * Defines whether the built-in foldingRange provider is enabled. + */ + readonly foldingRanges?: boolean; + + /** + * Defines whether the built-in diagnostic provider is enabled. + */ + readonly diagnostics?: boolean; + + /** + * Defines whether the built-in selection range provider is enabled. + */ + readonly selectionRanges?: boolean; + + /** + * Defines whether the built-in documentFormattingEdit provider is enabled. + */ + readonly documentFormattingEdits?: boolean; + + /** + * Defines whether the built-in documentRangeFormattingEdit provider is enabled. + */ + readonly documentRangeFormattingEdits?: boolean; +} + +export interface LanguageServiceDefaults { + readonly languageId: string; + readonly modeConfiguration: ModeConfiguration; + readonly onDidChange: IEvent; + readonly options: Options; + setOptions(options: Options): void; +} // --- HTML configuration and defaults --------- -export class LanguageServiceDefaultsImpl - implements monaco.languages.html.LanguageServiceDefaults { - private _onDidChange = new Emitter< - monaco.languages.html.LanguageServiceDefaults - >(); - private _options: monaco.languages.html.Options; - private _modeConfiguration: monaco.languages.html.ModeConfiguration; +class LanguageServiceDefaultsImpl implements LanguageServiceDefaults { + private _onDidChange = new Emitter(); + private _options: Options; + private _modeConfiguration: ModeConfiguration; private _languageId: string; constructor( languageId: string, - options: monaco.languages.html.Options, - modeConfiguration: monaco.languages.html.ModeConfiguration + options: Options, + modeConfiguration: ModeConfiguration ) { this._languageId = languageId; this.setOptions(options); this.setModeConfiguration(modeConfiguration); } - get onDidChange(): IEvent { + get onDidChange(): IEvent { return this._onDidChange.event; } @@ -38,28 +136,26 @@ export class LanguageServiceDefaultsImpl return this._languageId; } - get options(): monaco.languages.html.Options { + get options(): Options { return this._options; } - get modeConfiguration(): monaco.languages.html.ModeConfiguration { + get modeConfiguration(): ModeConfiguration { return this._modeConfiguration; } - setOptions(options: monaco.languages.html.Options): void { + setOptions(options: Options): void { this._options = options || Object.create(null); this._onDidChange.fire(this); } - setModeConfiguration( - modeConfiguration: monaco.languages.html.ModeConfiguration - ): void { + setModeConfiguration(modeConfiguration: ModeConfiguration): void { this._modeConfiguration = modeConfiguration || Object.create(null); this._onDidChange.fire(this); } } -const formatDefaults: Required = { +const formatDefaults: Required = { tabSize: 4, insertSpaces: false, wrapLineLength: 120, @@ -75,24 +171,24 @@ const formatDefaults: Required = wrapAttributes: 'auto' }; -const htmlOptionsDefault: Required = { +const htmlOptionsDefault: Required = { format: formatDefaults, suggest: { html5: true, angular1: true, ionic: true } }; -const handlebarOptionsDefault: Required = { +const handlebarOptionsDefault: Required = { format: formatDefaults, suggest: { html5: true } }; -const razorOptionsDefault: Required = { +const razorOptionsDefault: Required = { format: formatDefaults, suggest: { html5: true, razor: true } }; function getConfigurationDefault( languageId: string -): Required { +): Required { return { completionItems: true, hovers: true, @@ -113,31 +209,24 @@ const htmlLanguageId = 'html'; const handlebarsLanguageId = 'handlebars'; const razorLanguageId = 'razor'; -const htmlDefaults = new LanguageServiceDefaultsImpl( +export const htmlDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl( htmlLanguageId, htmlOptionsDefault, getConfigurationDefault(htmlLanguageId) ); -const handlebarDefaults = new LanguageServiceDefaultsImpl( +export const handlebarDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl( handlebarsLanguageId, handlebarOptionsDefault, getConfigurationDefault(handlebarsLanguageId) ); -const razorDefaults = new LanguageServiceDefaultsImpl( +export const razorDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl( razorLanguageId, razorOptionsDefault, getConfigurationDefault(razorLanguageId) ); -// Export API -function createAPI(): typeof monaco.languages.html { - return { - htmlDefaults: htmlDefaults, - razorDefaults: razorDefaults, - handlebarDefaults: handlebarDefaults - }; -} -monaco.languages.html = createAPI(); +// export to the global based API +(languages).html = { htmlDefaults, razorDefaults, handlebarDefaults }; // --- Registration to monaco editor --- @@ -145,12 +234,12 @@ function getMode(): Promise { return import('./htmlMode'); } -monaco.languages.onLanguage(htmlLanguageId, () => { +languages.onLanguage(htmlLanguageId, () => { getMode().then((mode) => mode.setupMode(htmlDefaults)); }); -monaco.languages.onLanguage(handlebarsLanguageId, () => { +languages.onLanguage(handlebarsLanguageId, () => { getMode().then((mode) => mode.setupMode(handlebarDefaults)); }); -monaco.languages.onLanguage(razorLanguageId, () => { +languages.onLanguage(razorLanguageId, () => { getMode().then((mode) => mode.setupMode(razorDefaults)); }); diff --git a/src/tsconfig.esm.json b/src/tsconfig.esm.json index bc85fbc..2023da4 100644 --- a/src/tsconfig.esm.json +++ b/src/tsconfig.esm.json @@ -3,6 +3,7 @@ "module": "esnext", "moduleResolution": "node", "outDir": "../out/esm", + "declaration": true, "target": "es5", "lib": [ "dom", diff --git a/src/tsconfig.json b/src/tsconfig.json index f809bad..6b43d98 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -3,6 +3,7 @@ "module": "amd", "moduleResolution": "node", "outDir": "../out/amd", + "declaration": true, "target": "es5", "lib": [ "dom", diff --git a/src/workerManager.ts b/src/workerManager.ts index 276131d..955e19a 100644 --- a/src/workerManager.ts +++ b/src/workerManager.ts @@ -2,26 +2,23 @@ * 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 { LanguageServiceDefaultsImpl } from './monaco.contribution'; -import { HTMLWorker } from './htmlWorker'; - -import IDisposable = monaco.IDisposable; -import Uri = monaco.Uri; +import { LanguageServiceDefaults } from './monaco.contribution'; +import type { HTMLWorker } from './htmlWorker'; +import { Uri, IDisposable, editor } from './fillers/monaco-editor-core'; const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min export class WorkerManager { - private _defaults: LanguageServiceDefaultsImpl; + private _defaults: LanguageServiceDefaults; private _idleCheckInterval: number; private _lastUsedTime: number; private _configChangeListener: IDisposable; - private _worker: monaco.editor.MonacoWebWorker; + private _worker: editor.MonacoWebWorker; private _client: Promise; - constructor(defaults: LanguageServiceDefaultsImpl) { + constructor(defaults: LanguageServiceDefaults) { this._defaults = defaults; this._worker = null; this._idleCheckInterval = setInterval(() => this._checkIfIdle(), 30 * 1000); @@ -59,7 +56,7 @@ export class WorkerManager { this._lastUsedTime = Date.now(); if (!this._client) { - this._worker = monaco.editor.createWebWorker({ + this._worker = editor.createWebWorker({ // module that exports the create() method and returns a `HTMLWorker` instance moduleId: 'vs/language/html/htmlWorker',