diff --git a/README.md b/README.md index f3fbf4c3..c9ae0f7c 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,10 @@ This npm module is bundled and distributed in the [monaco-editor](https://www.np ## Development * `git clone https://github.com/Microsoft/monaco-json` -* `cd monaco-json` * `npm install .` -* `npm run prepublish` +* compile with `npm run compile` +* watch with `npm run watch` +* `npm run prepublishOnly` * open `$/monaco-json/test/index.html` in your favorite browser. ## License diff --git a/package-lock.json b/package-lock.json index 8e9cc599..8af390a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "monaco-json", - "version": "2.5.1", + "version": "2.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -17,21 +17,21 @@ "dev": true }, "jsonc-parser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.1.0.tgz", - "integrity": "sha512-n9GrT8rrr2fhvBbANa1g+xFmgGK5X91KFeDwlKQ3+SJfmH5+tKv/M/kahx/TXOMflfWHKGKqKyfHQaLKTNzJ6w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.1.1.tgz", + "integrity": "sha512-VC0CjnWJylKB1iov4u76/W/5Ef0ydDkjtYWxoZ9t3HdWlSnZQwZL5MgFikaB/EtQ4RmMEw3tmQzuYnZA2/Ja1g==", "dev": true }, "monaco-editor-core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.17.0.tgz", - "integrity": "sha512-8q7b0itiX4UDv6e2F/EJc53G0iLL7P905IZsemu/bXffS7mIcjKKtX+TlzT13YbkuGFC/86Q32ANXERaJTM+mw==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.18.1.tgz", + "integrity": "sha512-euzXzmwjZFG0oAPGjICMwINcZBzQDyfGDYlAR5YNMBJZO9Bmkqq1xpTTze/qQ0KKbVmawFXiwgUbg7WVgebP9Q==", "dev": true }, "monaco-languages": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/monaco-languages/-/monaco-languages-1.7.0.tgz", - "integrity": "sha512-2YrYlkCF/g2H0PDt/ERax2IStaihZ17v1JkYnj2xEALYNah0pbQvGH9gXJvdVx0EpBoSRmxVnrwwM2oBWWOjSQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/monaco-languages/-/monaco-languages-1.8.0.tgz", + "integrity": "sha512-vC/lqNgSslQT3vSlNOpyT34ELK0eoNbA/rHUvTUjQemIiR1GpRMKhuwB21BqzWk+0MjZuJydGSCQMCebBge7jg==", "dev": true }, "monaco-plugin-helpers": { @@ -74,9 +74,9 @@ } }, "terser": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.4.tgz", - "integrity": "sha512-+ZwXJvdSwbd60jG0Illav0F06GDJF0R4ydZ21Q3wGAFKoBGyJGo34F63vzJHgvYxc1ukOtIjvwEvl9MkjzM6Pg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.1.tgz", + "integrity": "sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==", "dev": true, "requires": { "commander": "^2.20.0", @@ -91,21 +91,21 @@ "dev": true }, "vscode-json-languageservice": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.3.1.tgz", - "integrity": "sha512-Qyvlrftexu1acvwbMt+CDehVrDZtFV1GAJrKdOCHQL9bWNhzI06KEiSd4iXR0NUOuAdroG/uU4wBkH6e5CcTXg==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.3.3.tgz", + "integrity": "sha512-5vL3OXTUuQpn6+tGd47dopio+7WwbtIZ07zfYMzAUX8eVWPZjfEsLeSWmQk5Xw+vwgu+j5zC4koz5UofLDGGRA==", "dev": true, "requires": { - "jsonc-parser": "^2.1.0", + "jsonc-parser": "^2.1.1", "vscode-languageserver-types": "^3.15.0-next.2", "vscode-nls": "^4.1.1", "vscode-uri": "^2.0.3" }, "dependencies": { "vscode-languageserver-types": { - "version": "3.15.0-next.2", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.2.tgz", - "integrity": "sha512-2JkrMWWUi2rlVLSo9OFR2PIGUzdiowEM8NgNYiwLKnXTjpwpjjIrJbNNxDik7Rv4oo9KtikcFQZKXbrKilL/MQ==", + "version": "3.15.0-next.4", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.4.tgz", + "integrity": "sha512-IKIWTdUPBnOtwznIrhxKnjVZ7hYxEzwZ3M2xmDi7OjjexuOM6LnGtoo1Dv4wYSik4epK4STEib6e8da2GxUsJA==", "dev": true } } diff --git a/package.json b/package.json index 74ec20bc..680df994 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "monaco-json", - "version": "2.5.1", + "version": "2.6.0", "description": "JSON plugin for the Monaco Editor", "scripts": { "compile": "mrmdir ./out && tsc -p ./src/tsconfig.json && tsc -p ./src/tsconfig.esm.json", @@ -19,14 +19,14 @@ "url": "https://github.com/Microsoft/monaco-json/issues" }, "devDependencies": { - "jsonc-parser": "^2.1.0", - "monaco-editor-core": "0.17.0", - "monaco-languages": "1.7.0", + "jsonc-parser": "^2.1.1", + "monaco-editor-core": "0.18.1", + "monaco-languages": "1.8.0", "monaco-plugin-helpers": "^1.0.2", "requirejs": "^2.3.6", "typescript": "3.5.3", - "terser": "^4.1.4", - "vscode-json-languageservice": "3.3.1", + "terser": "^4.3.1", + "vscode-json-languageservice": "3.3.3", "vscode-languageserver-types": "3.14.0" } } diff --git a/src/jsonMode.ts b/src/jsonMode.ts index cbdd06e3..656136fb 100644 --- a/src/jsonMode.ts +++ b/src/jsonMode.ts @@ -13,9 +13,10 @@ import { createTokenizationSupport } from './tokenization'; import Uri = monaco.Uri; import IDisposable = monaco.IDisposable; -export function setupMode(defaults: LanguageServiceDefaultsImpl): void { +export function setupMode(defaults: LanguageServiceDefaultsImpl): IDisposable { - let disposables: IDisposable[] = []; + const disposables: IDisposable[] = []; + const providers: IDisposable[] = []; const client = new WorkerManager(defaults); disposables.push(client); @@ -24,20 +25,67 @@ export function setupMode(defaults: LanguageServiceDefaultsImpl): void { return client.getLanguageServiceWorker(...uris); }; - let languageId = defaults.languageId; - disposables.push(monaco.languages.registerCompletionItemProvider(languageId, new languageFeatures.CompletionAdapter(worker))); - disposables.push(monaco.languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker))); - disposables.push(monaco.languages.registerDocumentSymbolProvider(languageId, new languageFeatures.DocumentSymbolAdapter(worker))); - disposables.push(monaco.languages.registerDocumentFormattingEditProvider(languageId, new languageFeatures.DocumentFormattingEditProvider(worker))); - disposables.push(monaco.languages.registerDocumentRangeFormattingEditProvider(languageId, new languageFeatures.DocumentRangeFormattingEditProvider(worker))); - 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))); - disposables.push(monaco.languages.registerFoldingRangeProvider(languageId, new languageFeatures.FoldingRangeAdapter(worker))); + function registerProviders(): void { + const { languageId, modeConfiguration } = defaults; + + disposeAll(providers); + + if (modeConfiguration.documentFormattingEdits) { + providers.push(monaco.languages.registerDocumentFormattingEditProvider(languageId, new languageFeatures.DocumentFormattingEditProvider(worker))); + } + if (modeConfiguration.documentRangeFormattingEdits) { + providers.push(monaco.languages.registerDocumentRangeFormattingEditProvider(languageId, new languageFeatures.DocumentRangeFormattingEditProvider(worker))); + } + if (modeConfiguration.completionItems) { + providers.push(monaco.languages.registerCompletionItemProvider(languageId, new languageFeatures.CompletionAdapter(worker))); + } + if (modeConfiguration.hovers) { + providers.push(monaco.languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker))); + } + if (modeConfiguration.documentSymbols) { + providers.push(monaco.languages.registerDocumentSymbolProvider(languageId, new languageFeatures.DocumentSymbolAdapter(worker))); + } + if (modeConfiguration.tokens) { + providers.push(monaco.languages.setTokensProvider(languageId, createTokenizationSupport(true))); + } + if (modeConfiguration.colors) { + providers.push(monaco.languages.registerColorProvider(languageId, new languageFeatures.DocumentColorAdapter(worker))); + } + if (modeConfiguration.foldingRanges) { + providers.push(monaco.languages.registerFoldingRangeProvider(languageId, new languageFeatures.FoldingRangeAdapter(worker))); + } + if (modeConfiguration.diagnostics) { + providers.push(new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults)); + } + } + + registerProviders(); + + disposables.push(monaco.languages.setLanguageConfiguration(defaults.languageId, richEditConfiguration)); + + let modeConfiguration = defaults.modeConfiguration; + defaults.onDidChange((newDefaults) => { + if (newDefaults.modeConfiguration !== modeConfiguration) { + modeConfiguration = newDefaults.modeConfiguration; + registerProviders(); + } + }); + + disposables.push(asDisposable(providers)); + + return asDisposable(disposables); } +function asDisposable(disposables: IDisposable[]): IDisposable { + return { dispose: () => disposeAll(disposables) }; +} + +function disposeAll(disposables: IDisposable[]) { + while (disposables.length) { + disposables.pop().dispose(); + } +} const richEditConfiguration: monaco.languages.LanguageConfiguration = { wordPattern: /(-?\d*\.\d\w*)|([^\[\{\]\}\:\"\,\s]+)/g, diff --git a/src/languageFeatures.ts b/src/languageFeatures.ts index 88085318..c050aeed 100644 --- a/src/languageFeatures.ts +++ b/src/languageFeatures.ts @@ -393,7 +393,8 @@ export class DocumentSymbolAdapter implements monaco.languages.DocumentSymbolPro containerName: item.containerName, kind: toSymbolKind(item.kind), range: toRange(item.location.range), - selectionRange: toRange(item.location.range) + selectionRange: toRange(item.location.range), + tags: [] })); }); } diff --git a/src/monaco.contribution.ts b/src/monaco.contribution.ts index 2408c6d7..49c5108f 100644 --- a/src/monaco.contribution.ts +++ b/src/monaco.contribution.ts @@ -8,7 +8,6 @@ import * as mode from './jsonMode'; import Emitter = monaco.Emitter; import IEvent = monaco.IEvent; -import IDisposable = monaco.IDisposable; // --- JSON configuration and defaults --------- @@ -16,11 +15,13 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.json.Langua private _onDidChange = new Emitter(); private _diagnosticsOptions: monaco.languages.json.DiagnosticsOptions; + private _modeConfiguration: monaco.languages.json.ModeConfiguration; private _languageId: string; - constructor(languageId: string, diagnosticsOptions: monaco.languages.json.DiagnosticsOptions) { + constructor(languageId: string, diagnosticsOptions: monaco.languages.json.DiagnosticsOptions, modeConfiguration: monaco.languages.json.ModeConfiguration) { this._languageId = languageId; this.setDiagnosticsOptions(diagnosticsOptions); + this.setModeConfiguration(modeConfiguration) } get onDidChange(): IEvent { @@ -31,6 +32,10 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.json.Langua return this._languageId; } + get modeConfiguration(): monaco.languages.json.ModeConfiguration { + return this._modeConfiguration; + } + get diagnosticsOptions(): monaco.languages.json.DiagnosticsOptions { return this._diagnosticsOptions; } @@ -39,22 +44,37 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.json.Langua this._diagnosticsOptions = options || Object.create(null); this._onDidChange.fire(this); } + setModeConfiguration(modeConfiguration: monaco.languages.json.ModeConfiguration): void { + this._modeConfiguration = modeConfiguration || Object.create(null); + this._onDidChange.fire(this); + }; } const diagnosticDefault: monaco.languages.json.DiagnosticsOptions = { validate: true, allowComments: true, schemas: [], - enableSchemaRequest: false + enableSchemaRequest: false }; -const jsonDefaults = new LanguageServiceDefaultsImpl('json', diagnosticDefault); +const modeConfigurationDefault: monaco.languages.json.ModeConfiguration = { + documentFormattingEdits: true, + documentRangeFormattingEdits: true, + completionItems: true, + hovers: true, + documentSymbols: true, + tokens: true, + colors: true, + foldingRanges: true, + diagnostics: true +} +const jsonDefaults = new LanguageServiceDefaultsImpl('json', diagnosticDefault, modeConfigurationDefault); // Export API function createAPI(): typeof monaco.languages.json { return { - jsonDefaults: jsonDefaults, + jsonDefaults: jsonDefaults } } monaco.languages.json = createAPI(); @@ -67,10 +87,11 @@ function getMode(): Promise { monaco.languages.register({ id: 'json', - extensions: ['.json', '.bowerrc', '.jshintrc', '.jscsrc', '.eslintrc', '.babelrc'], + extensions: ['.json', '.bowerrc', '.jshintrc', '.jscsrc', '.eslintrc', '.babelrc', '.har'], aliases: ['JSON', 'json'], mimetypes: ['application/json'], }); + monaco.languages.onLanguage('json', () => { getMode().then(mode => mode.setupMode(jsonDefaults)); }); diff --git a/src/monaco.d.ts b/src/monaco.d.ts index c1b21edc..091b2184 100644 --- a/src/monaco.d.ts +++ b/src/monaco.d.ts @@ -33,13 +33,63 @@ declare module monaco.languages.json { /** * If set, the schema service would load schema content on-demand with 'fetch' if available */ - readonly enableSchemaRequest? : boolean + readonly enableSchemaRequest?: boolean; + } + + export interface ModeConfiguration { + /** + * Defines whether the built-in documentFormattingEdit provider is enabled. + */ + readonly documentFormattingEdits?: boolean; + + /** + * Defines whether the built-in documentRangeFormattingEdit provider is enabled. + */ + readonly documentRangeFormattingEdits?: boolean; + + /** + * 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 tokens provider is enabled. + */ + readonly tokens?: 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; + } export interface LanguageServiceDefaults { readonly onDidChange: IEvent; readonly diagnosticsOptions: DiagnosticsOptions; + readonly modeConfiguration: ModeConfiguration; setDiagnosticsOptions(options: DiagnosticsOptions): void; + setModeConfiguration(modeConfiguration: ModeConfiguration): void; } export var jsonDefaults: LanguageServiceDefaults;