Move into monaco-json folder

This commit is contained in:
Alex Dima 2021-11-05 12:08:41 +01:00
parent 49f367aaca
commit fb0da62177
No known key found for this signature in database
GPG key ID: 39563C1504FDD0C9
27 changed files with 0 additions and 0 deletions

3
monaco-json/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/node_modules/
/out/
/release/

12
monaco-json/.npmignore Normal file
View file

@ -0,0 +1,12 @@
/.vscode/
/out/
/scripts/
/src/
/test/
/.gitignore
/.npmignore
/.prettierrc
/.prettierignore
/package-lock.json
/webpack.dev.config.js
/webpack.min.config.js

View file

@ -0,0 +1,2 @@
/out/
/release/

8
monaco-json/.prettierrc Normal file
View file

@ -0,0 +1,8 @@
{
"arrowParens": "always",
"singleQuote": true,
"trailingComma": "none",
"semi": true,
"useTabs": true,
"printWidth": 100
}

9
monaco-json/.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,9 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.trimTrailingWhitespace": true,
"search.exclude": {
"**/node_modules": true,
"**/release": true,
"**/out": true
}
}

21
monaco-json/LICENSE.md Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

39
monaco-json/README.md Normal file
View file

@ -0,0 +1,39 @@
# Monaco JSON
JSON language plugin for the Monaco Editor. It provides the following features when editing JSON files:
- Code completion, based on JSON schemas or by looking at similar objects in the same file
- Hovers, based on JSON schemas
- Validation: Syntax errors and schema validation
- Formatting
- Document Symbols
- Syntax highlighting
- Color decorators for all properties matching a schema containing `format: "color-hex"'` (non-standard schema extension)
Schemas can be provided by configuration. See [here](https://github.com/Microsoft/monaco-json/blob/master/monaco.d.ts)
for the API that the JSON plugin offers to configure the JSON language support.
Internally the JSON plugin uses the [vscode-json-languageservice](https://github.com/Microsoft/vscode-json-languageservice)
node module, providing the implementation of the features listed above. The same module is also used
in [Visual Studio Code](https://github.com/Microsoft/vscode) to power the JSON editing experience.
## Issues
Please file issues concerning `monaco-json` in the [`monaco-editor` repository](https://github.com/Microsoft/monaco-editor/issues).
## Installing
This npm module is bundled and distributed in the [monaco-editor](https://www.npmjs.com/package/monaco-editor) npm module.
## Development
- `git clone https://github.com/Microsoft/monaco-json`
- `npm install .`
- compile with `npm run compile`
- watch with `npm run watch`
- `npm run prepublishOnly`
- open `$/monaco-json/test/index.html` in your favorite browser.
## License
[MIT](https://github.com/Microsoft/monaco-json/blob/master/LICENSE.md)

41
monaco-json/SECURITY.md Normal file
View file

@ -0,0 +1,41 @@
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->
## Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](<https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)>), please report it to us as described below.
## Reporting Security Issues
**Please do not report security vulnerabilities through public GitHub issues.**
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
- Full paths of source file(s) related to the manifestation of the issue
- The location of the affected source code (tag/branch/commit or direct URL)
- Any special configuration required to reproduce the issue
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the issue, including how an attacker might exploit the issue
This information will help us triage your report more quickly.
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
## Preferred Languages
We prefer all communications to be in English.
## Policy
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).
<!-- END MICROSOFT SECURITY.MD BLOCK -->

113
monaco-json/monaco.d.ts vendored Normal file
View file

@ -0,0 +1,113 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path="node_modules/monaco-editor-core/monaco.d.ts" />
declare namespace monaco.languages.json {
export interface DiagnosticsOptions {
/**
* If set, the validator will be enabled and perform syntax and schema based validation,
* unless `DiagnosticsOptions.schemaValidation` is set to `ignore`.
*/
readonly validate?: boolean;
/**
* If set, comments are tolerated. If set to false, syntax errors will be emitted for comments.
* `DiagnosticsOptions.allowComments` will override this setting.
*/
readonly allowComments?: boolean;
/**
* A list of known schemas and/or associations of schemas to file names.
*/
readonly schemas?: {
/**
* The URI of the schema, which is also the identifier of the schema.
*/
readonly uri: string;
/**
* A list of glob patterns that describe for which file URIs the JSON schema will be used.
* '*' and '**' wildcards are supported. Exclusion patterns start with '!'.
* For example '*.schema.json', 'package.json', '!foo*.schema.json', 'foo/**\/BADRESP.json'.
* A match succeeds when there is at least one pattern matching and last matching pattern does not start with '!'.
*/
readonly fileMatch?: string[];
/**
* The schema for the given URI.
*/
readonly schema?: any;
}[];
/**
* If set, the schema service would load schema content on-demand with 'fetch' if available
*/
readonly enableSchemaRequest?: boolean;
/**
* The severity of problems from schema validation. If set to 'ignore', schema validation will be skipped. If not set, 'warning' is used.
*/
readonly schemaValidation?: SeverityLevel;
/**
* The severity of problems that occurred when resolving and loading schemas. If set to 'ignore', schema resolving problems are not reported. If not set, 'warning' is used.
*/
readonly schemaRequest?: SeverityLevel;
/**
* The severity of reported trailing commas. If not set, trailing commas will be reported as errors.
*/
readonly trailingCommas?: SeverityLevel;
/**
* The severity of reported comments. If not set, 'DiagnosticsOptions.allowComments' defines whether comments are ignored or reported as errors.
*/
readonly comments?: SeverityLevel;
}
export type SeverityLevel = 'error' | 'warning' | 'ignore';
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;
/**
* Defines whether the built-in selection range provider is enabled.
*/
readonly selectionRanges?: boolean;
}
export interface LanguageServiceDefaults {
readonly languageId: string;
readonly onDidChange: IEvent<LanguageServiceDefaults>;
readonly diagnosticsOptions: DiagnosticsOptions;
readonly modeConfiguration: ModeConfiguration;
setDiagnosticsOptions(options: DiagnosticsOptions): void;
setModeConfiguration(modeConfiguration: ModeConfiguration): void;
}
export const jsonDefaults: LanguageServiceDefaults;
}

504
monaco-json/package-lock.json generated Normal file
View file

@ -0,0 +1,504 @@
{
"name": "monaco-json",
"version": "3.9.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"array-differ": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
"integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
"dev": true
},
"array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"dev": true
},
"arrify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
"integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
"dev": true
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
"chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"requires": {
"once": "^1.4.0"
}
},
"execa": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
"integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
"dev": true,
"requires": {
"cross-spawn": "^7.0.0",
"get-stream": "^5.0.0",
"human-signals": "^1.1.1",
"is-stream": "^2.0.0",
"merge-stream": "^2.0.0",
"npm-run-path": "^4.0.0",
"onetime": "^5.1.0",
"signal-exit": "^3.0.2",
"strip-final-newline": "^2.0.0"
}
},
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"human-signals": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
"dev": true
},
"husky": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/husky/-/husky-5.1.3.tgz",
"integrity": "sha512-fbNJ+Gz5wx2LIBtMweJNY1D7Uc8p1XERi5KNRMccwfQA+rXlxWNSdUxswo0gT8XqxywTIw7Ywm/F4v/O35RdMg==",
"dev": true
},
"ignore": {
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
"dev": true
},
"is-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
"integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
"dev": true
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"jsonc-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
"integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
"dev": true
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"requires": {
"p-locate": "^4.1.0"
}
},
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"monaco-editor-core": {
"version": "0.30.0",
"resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.30.0.tgz",
"integrity": "sha512-vFJ7BEOCqLv4xWgFW+UheI/PtccHHNht29lNmo79Re1kNhWCBLLb2nThjRMLPO1rd41vX9hhd9C07/iKOk9/jQ==",
"dev": true
},
"monaco-languages": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/monaco-languages/-/monaco-languages-2.11.0.tgz",
"integrity": "sha512-fpeP8XUPejcdoUEMZ5bo4MW8VzEadhrsuyDtT48p2a2PSRT/CXptQm4eGnIfgxf5R95jrCZ0456c5dSEPBuktA==",
"dev": true
},
"monaco-plugin-helpers": {
"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"
},
"dependencies": {
"typescript": {
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
"dev": true
}
}
},
"mri": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.1.6.tgz",
"integrity": "sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ==",
"dev": true
},
"multimatch": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
"integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
"dev": true,
"requires": {
"@types/minimatch": "^3.0.3",
"array-differ": "^3.0.0",
"array-union": "^2.1.0",
"arrify": "^2.0.1",
"minimatch": "^3.0.4"
}
},
"npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
"requires": {
"path-key": "^3.0.0"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
"requires": {
"mimic-fn": "^2.1.0"
}
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"requires": {
"p-limit": "^2.2.0"
}
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
"prettier": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz",
"integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==",
"dev": true
},
"pretty-quick": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.0.tgz",
"integrity": "sha512-DtxIxksaUWCgPFN7E1ZZk4+Aav3CCuRdhrDSFZENb404sYMtuo9Zka823F+Mgeyt8Zt3bUiCjFzzWYE9LYqkmQ==",
"dev": true,
"requires": {
"chalk": "^3.0.0",
"execa": "^4.0.0",
"find-up": "^4.1.0",
"ignore": "^5.1.4",
"mri": "^1.1.5",
"multimatch": "^4.0.0"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"requirejs": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
"integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==",
"dev": true
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
"dev": true
},
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true
},
"source-map-support": {
"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",
"source-map": "^0.6.0"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"dev": true
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"terser": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.6.0.tgz",
"integrity": "sha512-vyqLMoqadC1uR0vywqOZzriDYzgEkNJFK4q9GeyOBHIbiECHiWLKcWfbQWAUaPfxkjDhapSlZB9f7fkMrvkVjA==",
"dev": true,
"requires": {
"commander": "^2.20.0",
"source-map": "~0.7.2",
"source-map-support": "~0.5.19"
}
},
"typescript": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
"integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
"dev": true
},
"vscode-json-languageservice": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.1.9.tgz",
"integrity": "sha512-kxNHitUy2fCxmP6vAp0SRLrUSuecUYzzxlC+85cC3jJlFHWmvtCJOzikC+kcUnIdls9fQSB8n0yHs8Sl6taxJw==",
"dev": true,
"requires": {
"jsonc-parser": "^3.0.0",
"vscode-languageserver-textdocument": "^1.0.1",
"vscode-languageserver-types": "^3.16.0",
"vscode-nls": "^5.0.0",
"vscode-uri": "^3.0.2"
}
},
"vscode-languageserver-textdocument": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.2.tgz",
"integrity": "sha512-T7uPC18+f8mYE4lbVZwb3OSmvwTZm3cuFhrdx9Bn2l11lmp3SvSuSVjy2JtvrghzjAo4G6Trqny2m9XGnFnWVA==",
"dev": true
},
"vscode-languageserver-types": {
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
"integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==",
"dev": true
},
"vscode-nls": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.0.0.tgz",
"integrity": "sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA==",
"dev": true
},
"vscode-uri": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.2.tgz",
"integrity": "sha512-jkjy6pjU1fxUvI51P+gCsxg1u2n8LSt0W6KrCNQceaziKzff74GoWmjVG46KieVzybO1sttPQmYfrwSHey7GUA==",
"dev": true
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
}
}
}

43
monaco-json/package.json Normal file
View file

@ -0,0 +1,43 @@
{
"name": "monaco-json",
"version": "3.9.0",
"description": "JSON plugin for the Monaco Editor",
"scripts": {
"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 ./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-json-languageservice@next -f -D && npm install vscode-languageserver-types@next -f -D",
"install-service-local": "npm install ../vscode-json-languageservice -f -D && npm install ../vscode-languageserver-node/types -f -D",
"prettier": "prettier --write ."
},
"author": "Microsoft Corporation",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/monaco-json"
},
"bugs": {
"url": "https://github.com/Microsoft/monaco-json/issues"
},
"module": "./release/esm/monaco.contribution.js",
"typings": "./release/esm/monaco.contribution.d.ts",
"devDependencies": {
"husky": "^5.1.3",
"jsonc-parser": "^3.0.0",
"monaco-editor-core": "0.30.0",
"monaco-languages": "2.11.0",
"monaco-plugin-helpers": "^1.0.3",
"prettier": "^2.2.1",
"pretty-quick": "^3.1.0",
"requirejs": "^2.3.6",
"terser": "^5.6.0",
"typescript": "4.2.4",
"vscode-json-languageservice": "4.1.9",
"vscode-uri": "3.0.2"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
}
}
}

View file

@ -0,0 +1,90 @@
const requirejs = require('requirejs');
const path = require('path');
const fs = require('fs');
const Terser = require('terser');
const helpers = require('monaco-plugin-helpers');
const REPO_ROOT = path.resolve(__dirname, '..');
const sha1 = helpers.getGitVersion(REPO_ROOT);
const semver = require('../package.json').version;
const headerVersion = semver + '(' + sha1 + ')';
const BUNDLED_FILE_HEADER = [
'/*!-----------------------------------------------------------------------------',
' * Copyright (c) Microsoft Corporation. All rights reserved.',
' * monaco-json version: ' + headerVersion,
' * Released under the MIT license',
' * https://github.com/Microsoft/monaco-json/blob/master/LICENSE.md',
' *-----------------------------------------------------------------------------*/',
''
].join('\n');
bundleOne('monaco.contribution');
bundleOne('jsonMode', ['vs/language/json/monaco.contribution']);
bundleOne('jsonWorker');
function bundleOne(moduleId, exclude) {
requirejs.optimize(
{
baseUrl: 'out/amd/',
name: 'vs/language/json/' + moduleId,
out: 'release/dev/' + moduleId + '.js',
exclude: exclude,
paths: {
'vs/language/json': REPO_ROOT + '/out/amd',
'vs/language/json/fillers/monaco-editor-core':
REPO_ROOT + '/out/amd/fillers/monaco-editor-core-amd'
},
optimize: 'none',
packages: [
{
name: 'vscode-json-languageservice',
location: path.join(REPO_ROOT, 'node_modules/vscode-json-languageservice/lib/umd'),
main: 'jsonLanguageService'
},
{
name: 'vscode-languageserver-types',
location: path.join(REPO_ROOT, 'node_modules/vscode-languageserver-types/lib/umd'),
main: 'main'
},
{
name: 'vscode-languageserver-textdocument',
location: path.join(REPO_ROOT, 'node_modules/vscode-languageserver-textdocument/lib/umd'),
main: 'main'
},
{
name: 'jsonc-parser',
location: path.join(REPO_ROOT, 'node_modules/jsonc-parser/lib/umd'),
main: 'main'
},
{
name: 'vscode-uri',
location: path.join(REPO_ROOT, 'node_modules/vscode-uri/lib/umd'),
main: 'index'
},
{
name: 'vscode-nls',
location: path.join(REPO_ROOT, '/out/amd/fillers'),
main: 'vscode-nls'
}
]
},
async function (buildResponse) {
const devFilePath = path.join(REPO_ROOT, 'release/dev/' + moduleId + '.js');
const minFilePath = path.join(REPO_ROOT, 'release/min/' + moduleId + '.js');
const fileContents = fs.readFileSync(devFilePath).toString();
console.log(`Minifying ${devFilePath}...`);
const result = await Terser.minify(fileContents, {
output: {
comments: 'some'
}
});
console.log(`Done minifying ${devFilePath}.`);
try {
fs.mkdirSync(path.join(REPO_ROOT, 'release/min'));
} catch (err) {}
fs.writeFileSync(minFilePath, BUNDLED_FILE_HEADER + result.code);
}
);
}

View file

@ -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.`,
` *--------------------------------------------------------------------------------------------*/`,
``,
`/// <reference path="node_modules/monaco-editor-core/monaco.d.ts" />`,
``,
`declare namespace monaco.languages.json {`
];
for (let line of lines) {
if (/^import/.test(line)) {
continue;
}
line = line.replace(/ /g, '\t');
line = line.replace(/declare /g, '');
if (line.length > 0) {
line = `\t${line}`;
result.push(line);
}
}
result.push(`}`);
result.push(``);
fs.writeFileSync(DST_PATH, result.join('\n'));

View file

@ -0,0 +1,27 @@
/*---------------------------------------------------------------------------------------------
* 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 helpers = require('monaco-plugin-helpers');
const REPO_ROOT = path.join(__dirname, '../');
helpers.packageESM({
repoRoot: REPO_ROOT,
esmSource: 'out/esm',
esmDestination: 'release/esm',
entryPoints: ['monaco.contribution.js', 'jsonMode.js', 'json.worker.js'],
resolveAlias: {
'vscode-nls': path.join(REPO_ROOT, 'out/esm/fillers/vscode-nls.js')
},
resolveSkip: ['monaco-editor-core'],
destinationFolderSimplification: {
node_modules: '_deps',
'jsonc-parser/lib/esm': 'jsonc-parser',
'vscode-languageserver-types/lib/esm': 'vscode-languageserver-types',
'vscode-uri/lib/esm': 'vscode-uri',
'vscode-json-languageservice/lib/esm': 'vscode-json-languageservice'
}
});

View file

@ -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 (<any>self).monaco;
});

View file

@ -0,0 +1,6 @@
/*---------------------------------------------------------------------------------------------
* 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';

View file

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export interface Options {
locale?: string;
cacheLanguageResolution?: boolean;
}
export interface LocalizeInfo {
key: string;
comment: string[];
}
export interface LocalizeFunc {
(info: LocalizeInfo, message: string, ...args: any[]): string;
(key: string, message: string, ...args: any[]): string;
}
export interface LoadFunc {
(file?: string): LocalizeFunc;
}
function format(message: string, args: any[]): string {
let result: string;
if (args.length === 0) {
result = message;
} else {
result = message.replace(/\{(\d+)\}/g, (match, rest) => {
let index = rest[0];
return typeof args[index] !== 'undefined' ? args[index] : match;
});
}
return result;
}
function localize(key: string | LocalizeInfo, message: string, ...args: any[]): string {
return format(message, args);
}
export function loadMessageBundle(file?: string): LocalizeFunc {
return localize;
}
export function config(opt?: Options | string): LoadFunc {
return loadMessageBundle;
}

View file

@ -0,0 +1,14 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as worker from 'monaco-editor-core/esm/vs/editor/editor.worker';
import { JSONWorker } from './jsonWorker';
self.onmessage = () => {
// ignore the first message
worker.initialize((ctx, createData) => {
return new JSONWorker(ctx, createData);
});
};

143
monaco-json/src/jsonMode.ts Normal file
View file

@ -0,0 +1,143 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { WorkerManager } from './workerManager';
import type { JSONWorker } from './jsonWorker';
import { LanguageServiceDefaults } from './monaco.contribution';
import * as languageFeatures from './languageFeatures';
import { createTokenizationSupport } from './tokenization';
import { Uri, IDisposable, languages } from './fillers/monaco-editor-core';
export function setupMode(defaults: LanguageServiceDefaults): IDisposable {
const disposables: IDisposable[] = [];
const providers: IDisposable[] = [];
const client = new WorkerManager(defaults);
disposables.push(client);
const worker: languageFeatures.WorkerAccessor = (...uris: Uri[]): Promise<JSONWorker> => {
return client.getLanguageServiceWorker(...uris);
};
function registerProviders(): void {
const { languageId, modeConfiguration } = defaults;
disposeAll(providers);
if (modeConfiguration.documentFormattingEdits) {
providers.push(
languages.registerDocumentFormattingEditProvider(
languageId,
new languageFeatures.DocumentFormattingEditProvider(worker)
)
);
}
if (modeConfiguration.documentRangeFormattingEdits) {
providers.push(
languages.registerDocumentRangeFormattingEditProvider(
languageId,
new languageFeatures.DocumentRangeFormattingEditProvider(worker)
)
);
}
if (modeConfiguration.completionItems) {
providers.push(
languages.registerCompletionItemProvider(
languageId,
new languageFeatures.CompletionAdapter(worker)
)
);
}
if (modeConfiguration.hovers) {
providers.push(
languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker))
);
}
if (modeConfiguration.documentSymbols) {
providers.push(
languages.registerDocumentSymbolProvider(
languageId,
new languageFeatures.DocumentSymbolAdapter(worker)
)
);
}
if (modeConfiguration.tokens) {
providers.push(languages.setTokensProvider(languageId, createTokenizationSupport(true)));
}
if (modeConfiguration.colors) {
providers.push(
languages.registerColorProvider(
languageId,
new languageFeatures.DocumentColorAdapter(worker)
)
);
}
if (modeConfiguration.foldingRanges) {
providers.push(
languages.registerFoldingRangeProvider(
languageId,
new languageFeatures.FoldingRangeAdapter(worker)
)
);
}
if (modeConfiguration.diagnostics) {
providers.push(new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults));
}
if (modeConfiguration.selectionRanges) {
providers.push(
languages.registerSelectionRangeProvider(
languageId,
new languageFeatures.SelectionRangeAdapter(worker)
)
);
}
}
registerProviders();
disposables.push(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: languages.LanguageConfiguration = {
wordPattern: /(-?\d*\.\d\w*)|([^\[\{\]\}\:\"\,\s]+)/g,
comments: {
lineComment: '//',
blockComment: ['/*', '*/']
},
brackets: [
['{', '}'],
['[', ']']
],
autoClosingPairs: [
{ open: '{', close: '}', notIn: ['string'] },
{ open: '[', close: ']', notIn: ['string'] },
{ open: '"', close: '"', notIn: ['string'] }
]
};

View file

@ -0,0 +1,192 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as jsonService from 'vscode-json-languageservice';
import type { worker } from './fillers/monaco-editor-core';
import { URI } from 'vscode-uri';
import { DiagnosticsOptions } from './monaco.contribution';
let defaultSchemaRequestService;
if (typeof fetch !== 'undefined') {
defaultSchemaRequestService = function (url) {
return fetch(url).then((response) => response.text());
};
}
export class JSONWorker {
private _ctx: worker.IWorkerContext;
private _languageService: jsonService.LanguageService;
private _languageSettings: DiagnosticsOptions;
private _languageId: string;
constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
this._ctx = ctx;
this._languageSettings = createData.languageSettings;
this._languageId = createData.languageId;
this._languageService = jsonService.getLanguageService({
workspaceContext: {
resolveRelativePath: (relativePath: string, resource: string) => {
const base = resource.substr(0, resource.lastIndexOf('/') + 1);
return resolvePath(base, relativePath);
}
},
schemaRequestService: createData.enableSchemaRequest && defaultSchemaRequestService
});
this._languageService.configure(this._languageSettings);
}
async doValidation(uri: string): Promise<jsonService.Diagnostic[]> {
let document = this._getTextDocument(uri);
if (document) {
let jsonDocument = this._languageService.parseJSONDocument(document);
return this._languageService.doValidation(document, jsonDocument, this._languageSettings);
}
return Promise.resolve([]);
}
async doComplete(
uri: string,
position: jsonService.Position
): Promise<jsonService.CompletionList> {
let document = this._getTextDocument(uri);
let jsonDocument = this._languageService.parseJSONDocument(document);
return this._languageService.doComplete(document, position, jsonDocument);
}
async doResolve(item: jsonService.CompletionItem): Promise<jsonService.CompletionItem> {
return this._languageService.doResolve(item);
}
async doHover(uri: string, position: jsonService.Position): Promise<jsonService.Hover> {
let document = this._getTextDocument(uri);
let jsonDocument = this._languageService.parseJSONDocument(document);
return this._languageService.doHover(document, position, jsonDocument);
}
async format(
uri: string,
range: jsonService.Range,
options: jsonService.FormattingOptions
): Promise<jsonService.TextEdit[]> {
let document = this._getTextDocument(uri);
let textEdits = this._languageService.format(document, range, options);
return Promise.resolve(textEdits);
}
async resetSchema(uri: string): Promise<boolean> {
return Promise.resolve(this._languageService.resetSchema(uri));
}
async findDocumentSymbols(uri: string): Promise<jsonService.SymbolInformation[]> {
let document = this._getTextDocument(uri);
let jsonDocument = this._languageService.parseJSONDocument(document);
let symbols = this._languageService.findDocumentSymbols(document, jsonDocument);
return Promise.resolve(symbols);
}
async findDocumentColors(uri: string): Promise<jsonService.ColorInformation[]> {
let document = this._getTextDocument(uri);
let jsonDocument = this._languageService.parseJSONDocument(document);
let colorSymbols = this._languageService.findDocumentColors(document, jsonDocument);
return Promise.resolve(colorSymbols);
}
async getColorPresentations(
uri: string,
color: jsonService.Color,
range: jsonService.Range
): Promise<jsonService.ColorPresentation[]> {
let document = this._getTextDocument(uri);
let jsonDocument = this._languageService.parseJSONDocument(document);
let colorPresentations = this._languageService.getColorPresentations(
document,
jsonDocument,
color,
range
);
return Promise.resolve(colorPresentations);
}
async getFoldingRanges(
uri: string,
context?: { rangeLimit?: number }
): Promise<jsonService.FoldingRange[]> {
let document = this._getTextDocument(uri);
let ranges = this._languageService.getFoldingRanges(document, context);
return Promise.resolve(ranges);
}
async getSelectionRanges(
uri: string,
positions: jsonService.Position[]
): Promise<jsonService.SelectionRange[]> {
let document = this._getTextDocument(uri);
let jsonDocument = this._languageService.parseJSONDocument(document);
let ranges = this._languageService.getSelectionRanges(document, positions, jsonDocument);
return Promise.resolve(ranges);
}
private _getTextDocument(uri: string): jsonService.TextDocument {
let models = this._ctx.getMirrorModels();
for (let model of models) {
if (model.uri.toString() === uri) {
return jsonService.TextDocument.create(
uri,
this._languageId,
model.version,
model.getValue()
);
}
}
return null;
}
}
// URI path utilities, will (hopefully) move to vscode-uri
const Slash = '/'.charCodeAt(0);
const Dot = '.'.charCodeAt(0);
function isAbsolutePath(path: string) {
return path.charCodeAt(0) === Slash;
}
function resolvePath(uriString: string, path: string): string {
if (isAbsolutePath(path)) {
const uri = URI.parse(uriString);
const parts = path.split('/');
return uri.with({ path: normalizePath(parts) }).toString();
}
return joinPath(uriString, path);
}
function normalizePath(parts: string[]): string {
const newParts: string[] = [];
for (const part of parts) {
if (part.length === 0 || (part.length === 1 && part.charCodeAt(0) === Dot)) {
// ignore
} else if (part.length === 2 && part.charCodeAt(0) === Dot && part.charCodeAt(1) === Dot) {
newParts.pop();
} else {
newParts.push(part);
}
}
if (parts.length > 1 && parts[parts.length - 1].length === 0) {
newParts.push('');
}
let res = newParts.join('/');
if (parts[0].length === 0) {
res = '/' + res;
}
return res;
}
function joinPath(uriString: string, ...paths: string[]): string {
const uri = URI.parse(uriString);
const parts = uri.path.split('/');
for (let path of paths) {
parts.push(...path.split('/'));
}
return uri.with({ path: normalizePath(parts) }).toString();
}
export interface ICreateData {
languageId: string;
languageSettings: DiagnosticsOptions;
enableSchemaRequest: boolean;
}
export function create(ctx: worker.IWorkerContext, createData: ICreateData): JSONWorker {
return new JSONWorker(ctx, createData);
}

View file

@ -0,0 +1,722 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { LanguageServiceDefaults } from './monaco.contribution';
import type { JSONWorker } from './jsonWorker';
import {
Uri,
Position,
Range,
IRange,
CancellationToken,
IDisposable,
editor,
languages,
MarkerSeverity,
IMarkdownString
} from './fillers/monaco-editor-core';
import * as jsonService from 'vscode-json-languageservice';
export interface WorkerAccessor {
(...more: Uri[]): Promise<JSONWorker>;
}
// --- diagnostics --- ---
export class DiagnosticsAdapter {
private _disposables: IDisposable[] = [];
private _listener: { [uri: string]: IDisposable } = Object.create(null);
constructor(
private _languageId: string,
private _worker: WorkerAccessor,
defaults: LanguageServiceDefaults
) {
const onModelAdd = (model: editor.IModel): void => {
let modeId = model.getLanguageId();
if (modeId !== this._languageId) {
return;
}
let handle: number;
this._listener[model.uri.toString()] = model.onDidChangeContent(() => {
clearTimeout(handle);
handle = setTimeout(() => this._doValidate(model.uri, modeId), 500);
});
this._doValidate(model.uri, modeId);
};
const onModelRemoved = (model: editor.IModel): void => {
editor.setModelMarkers(model, this._languageId, []);
let uriStr = model.uri.toString();
let listener = this._listener[uriStr];
if (listener) {
listener.dispose();
delete this._listener[uriStr];
}
};
this._disposables.push(editor.onDidCreateModel(onModelAdd));
this._disposables.push(
editor.onWillDisposeModel((model) => {
onModelRemoved(model);
this._resetSchema(model.uri);
})
);
this._disposables.push(
editor.onDidChangeModelLanguage((event) => {
onModelRemoved(event.model);
onModelAdd(event.model);
this._resetSchema(event.model.uri);
})
);
this._disposables.push(
defaults.onDidChange((_) => {
editor.getModels().forEach((model) => {
if (model.getLanguageId() === this._languageId) {
onModelRemoved(model);
onModelAdd(model);
}
});
})
);
this._disposables.push({
dispose: () => {
editor.getModels().forEach(onModelRemoved);
for (let key in this._listener) {
this._listener[key].dispose();
}
}
});
editor.getModels().forEach(onModelAdd);
}
public dispose(): void {
this._disposables.forEach((d) => d && d.dispose());
this._disposables = [];
}
private _resetSchema(resource: Uri): void {
this._worker().then((worker) => {
worker.resetSchema(resource.toString());
});
}
private _doValidate(resource: Uri, languageId: string): void {
this._worker(resource)
.then((worker) => {
return worker.doValidation(resource.toString()).then((diagnostics) => {
const markers = diagnostics.map((d) => toDiagnostics(resource, d));
let model = editor.getModel(resource);
if (model && model.getLanguageId() === languageId) {
editor.setModelMarkers(model, languageId, markers);
}
});
})
.then(undefined, (err) => {
console.error(err);
});
}
}
function toSeverity(lsSeverity: number): MarkerSeverity {
switch (lsSeverity) {
case jsonService.DiagnosticSeverity.Error:
return MarkerSeverity.Error;
case jsonService.DiagnosticSeverity.Warning:
return MarkerSeverity.Warning;
case jsonService.DiagnosticSeverity.Information:
return MarkerSeverity.Info;
case jsonService.DiagnosticSeverity.Hint:
return MarkerSeverity.Hint;
default:
return MarkerSeverity.Info;
}
}
function toDiagnostics(resource: Uri, diag: jsonService.Diagnostic): editor.IMarkerData {
let code = typeof diag.code === 'number' ? String(diag.code) : <string>diag.code;
return {
severity: toSeverity(diag.severity),
startLineNumber: diag.range.start.line + 1,
startColumn: diag.range.start.character + 1,
endLineNumber: diag.range.end.line + 1,
endColumn: diag.range.end.character + 1,
message: diag.message,
code: code,
source: diag.source
};
}
// --- completion ------
function fromPosition(position: Position): jsonService.Position {
if (!position) {
return void 0;
}
return { character: position.column - 1, line: position.lineNumber - 1 };
}
function fromRange(range: IRange): jsonService.Range {
if (!range) {
return void 0;
}
return {
start: {
line: range.startLineNumber - 1,
character: range.startColumn - 1
},
end: { line: range.endLineNumber - 1, character: range.endColumn - 1 }
};
}
function toRange(range: jsonService.Range): Range {
if (!range) {
return void 0;
}
return new Range(
range.start.line + 1,
range.start.character + 1,
range.end.line + 1,
range.end.character + 1
);
}
interface InsertReplaceEdit {
/**
* The string to be inserted.
*/
newText: string;
/**
* The range if the insert is requested
*/
insert: jsonService.Range;
/**
* The range if the replace is requested.
*/
replace: jsonService.Range;
}
function isInsertReplaceEdit(
edit: jsonService.TextEdit | InsertReplaceEdit
): edit is InsertReplaceEdit {
return (
typeof (<InsertReplaceEdit>edit).insert !== 'undefined' &&
typeof (<InsertReplaceEdit>edit).replace !== 'undefined'
);
}
function toCompletionItemKind(kind: number): languages.CompletionItemKind {
let mItemKind = languages.CompletionItemKind;
switch (kind) {
case jsonService.CompletionItemKind.Text:
return mItemKind.Text;
case jsonService.CompletionItemKind.Method:
return mItemKind.Method;
case jsonService.CompletionItemKind.Function:
return mItemKind.Function;
case jsonService.CompletionItemKind.Constructor:
return mItemKind.Constructor;
case jsonService.CompletionItemKind.Field:
return mItemKind.Field;
case jsonService.CompletionItemKind.Variable:
return mItemKind.Variable;
case jsonService.CompletionItemKind.Class:
return mItemKind.Class;
case jsonService.CompletionItemKind.Interface:
return mItemKind.Interface;
case jsonService.CompletionItemKind.Module:
return mItemKind.Module;
case jsonService.CompletionItemKind.Property:
return mItemKind.Property;
case jsonService.CompletionItemKind.Unit:
return mItemKind.Unit;
case jsonService.CompletionItemKind.Value:
return mItemKind.Value;
case jsonService.CompletionItemKind.Enum:
return mItemKind.Enum;
case jsonService.CompletionItemKind.Keyword:
return mItemKind.Keyword;
case jsonService.CompletionItemKind.Snippet:
return mItemKind.Snippet;
case jsonService.CompletionItemKind.Color:
return mItemKind.Color;
case jsonService.CompletionItemKind.File:
return mItemKind.File;
case jsonService.CompletionItemKind.Reference:
return mItemKind.Reference;
}
return mItemKind.Property;
}
function fromCompletionItemKind(
kind: languages.CompletionItemKind
): jsonService.CompletionItemKind {
let mItemKind = languages.CompletionItemKind;
switch (kind) {
case mItemKind.Text:
return jsonService.CompletionItemKind.Text;
case mItemKind.Method:
return jsonService.CompletionItemKind.Method;
case mItemKind.Function:
return jsonService.CompletionItemKind.Function;
case mItemKind.Constructor:
return jsonService.CompletionItemKind.Constructor;
case mItemKind.Field:
return jsonService.CompletionItemKind.Field;
case mItemKind.Variable:
return jsonService.CompletionItemKind.Variable;
case mItemKind.Class:
return jsonService.CompletionItemKind.Class;
case mItemKind.Interface:
return jsonService.CompletionItemKind.Interface;
case mItemKind.Module:
return jsonService.CompletionItemKind.Module;
case mItemKind.Property:
return jsonService.CompletionItemKind.Property;
case mItemKind.Unit:
return jsonService.CompletionItemKind.Unit;
case mItemKind.Value:
return jsonService.CompletionItemKind.Value;
case mItemKind.Enum:
return jsonService.CompletionItemKind.Enum;
case mItemKind.Keyword:
return jsonService.CompletionItemKind.Keyword;
case mItemKind.Snippet:
return jsonService.CompletionItemKind.Snippet;
case mItemKind.Color:
return jsonService.CompletionItemKind.Color;
case mItemKind.File:
return jsonService.CompletionItemKind.File;
case mItemKind.Reference:
return jsonService.CompletionItemKind.Reference;
}
return jsonService.CompletionItemKind.Property;
}
function toTextEdit(textEdit: jsonService.TextEdit): editor.ISingleEditOperation {
if (!textEdit) {
return void 0;
}
return {
range: toRange(textEdit.range),
text: textEdit.newText
};
}
function toCommand(c: jsonService.Command | undefined): languages.Command {
return c && c.command === 'editor.action.triggerSuggest' ? { id: c.command, title: c.title, arguments: c.arguments } : undefined
}
export class CompletionAdapter implements languages.CompletionItemProvider {
constructor(private _worker: WorkerAccessor) {}
public get triggerCharacters(): string[] {
return [' ', ':', '"'];
}
provideCompletionItems(
model: editor.IReadOnlyModel,
position: Position,
context: languages.CompletionContext,
token: CancellationToken
): Promise<languages.CompletionList> {
const resource = model.uri;
return this._worker(resource)
.then((worker) => {
return worker.doComplete(resource.toString(), fromPosition(position));
})
.then((info) => {
if (!info) {
return;
}
const wordInfo = model.getWordUntilPosition(position);
const wordRange = new Range(
position.lineNumber,
wordInfo.startColumn,
position.lineNumber,
wordInfo.endColumn
);
let items: languages.CompletionItem[] = info.items.map((entry) => {
let item: languages.CompletionItem = {
label: entry.label,
insertText: entry.insertText || entry.label,
sortText: entry.sortText,
filterText: entry.filterText,
documentation: entry.documentation,
detail: entry.detail,
command: toCommand(entry.command),
range: wordRange,
kind: toCompletionItemKind(entry.kind)
};
if (entry.textEdit) {
if (isInsertReplaceEdit(entry.textEdit)) {
item.range = {
insert: toRange(entry.textEdit.insert),
replace: toRange(entry.textEdit.replace)
};
} else {
item.range = toRange(entry.textEdit.range);
}
item.insertText = entry.textEdit.newText;
}
if (entry.additionalTextEdits) {
item.additionalTextEdits = entry.additionalTextEdits.map(toTextEdit);
}
if (entry.insertTextFormat === jsonService.InsertTextFormat.Snippet) {
item.insertTextRules = languages.CompletionItemInsertTextRule.InsertAsSnippet;
}
return item;
});
return {
isIncomplete: info.isIncomplete,
suggestions: items
};
});
}
}
function isMarkupContent(thing: any): thing is jsonService.MarkupContent {
return (
thing &&
typeof thing === 'object' &&
typeof (<jsonService.MarkupContent>thing).kind === 'string'
);
}
function toMarkdownString(
entry: jsonService.MarkupContent | jsonService.MarkedString
): IMarkdownString {
if (typeof entry === 'string') {
return {
value: entry
};
}
if (isMarkupContent(entry)) {
if (entry.kind === 'plaintext') {
return {
value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
};
}
return {
value: entry.value
};
}
return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' };
}
function toMarkedStringArray(
contents: jsonService.MarkupContent | jsonService.MarkedString | jsonService.MarkedString[]
): IMarkdownString[] {
if (!contents) {
return void 0;
}
if (Array.isArray(contents)) {
return contents.map(toMarkdownString);
}
return [toMarkdownString(contents)];
}
// --- hover ------
export class HoverAdapter implements languages.HoverProvider {
constructor(private _worker: WorkerAccessor) {}
provideHover(
model: editor.IReadOnlyModel,
position: Position,
token: CancellationToken
): Promise<languages.Hover> {
let resource = model.uri;
return this._worker(resource)
.then((worker) => {
return worker.doHover(resource.toString(), fromPosition(position));
})
.then((info) => {
if (!info) {
return;
}
return <languages.Hover>{
range: toRange(info.range),
contents: toMarkedStringArray(info.contents)
};
});
}
}
// --- definition ------
function toLocation(location: jsonService.Location): languages.Location {
return {
uri: Uri.parse(location.uri),
range: toRange(location.range)
};
}
// --- document symbols ------
function toSymbolKind(kind: jsonService.SymbolKind): languages.SymbolKind {
let mKind = languages.SymbolKind;
switch (kind) {
case jsonService.SymbolKind.File:
return mKind.Array;
case jsonService.SymbolKind.Module:
return mKind.Module;
case jsonService.SymbolKind.Namespace:
return mKind.Namespace;
case jsonService.SymbolKind.Package:
return mKind.Package;
case jsonService.SymbolKind.Class:
return mKind.Class;
case jsonService.SymbolKind.Method:
return mKind.Method;
case jsonService.SymbolKind.Property:
return mKind.Property;
case jsonService.SymbolKind.Field:
return mKind.Field;
case jsonService.SymbolKind.Constructor:
return mKind.Constructor;
case jsonService.SymbolKind.Enum:
return mKind.Enum;
case jsonService.SymbolKind.Interface:
return mKind.Interface;
case jsonService.SymbolKind.Function:
return mKind.Function;
case jsonService.SymbolKind.Variable:
return mKind.Variable;
case jsonService.SymbolKind.Constant:
return mKind.Constant;
case jsonService.SymbolKind.String:
return mKind.String;
case jsonService.SymbolKind.Number:
return mKind.Number;
case jsonService.SymbolKind.Boolean:
return mKind.Boolean;
case jsonService.SymbolKind.Array:
return mKind.Array;
}
return mKind.Function;
}
export class DocumentSymbolAdapter implements languages.DocumentSymbolProvider {
constructor(private _worker: WorkerAccessor) {}
public provideDocumentSymbols(
model: editor.IReadOnlyModel,
token: CancellationToken
): Promise<languages.DocumentSymbol[]> {
const resource = model.uri;
return this._worker(resource)
.then((worker) => worker.findDocumentSymbols(resource.toString()))
.then((items) => {
if (!items) {
return;
}
return items.map((item) => ({
name: item.name,
detail: '',
containerName: item.containerName,
kind: toSymbolKind(item.kind),
range: toRange(item.location.range),
selectionRange: toRange(item.location.range),
tags: []
}));
});
}
}
function fromFormattingOptions(
options: languages.FormattingOptions
): jsonService.FormattingOptions {
return {
tabSize: options.tabSize,
insertSpaces: options.insertSpaces
};
}
export class DocumentFormattingEditProvider implements languages.DocumentFormattingEditProvider {
constructor(private _worker: WorkerAccessor) {}
public provideDocumentFormattingEdits(
model: editor.IReadOnlyModel,
options: languages.FormattingOptions,
token: CancellationToken
): Promise<editor.ISingleEditOperation[]> {
const resource = model.uri;
return this._worker(resource).then((worker) => {
return worker
.format(resource.toString(), null, fromFormattingOptions(options))
.then((edits) => {
if (!edits || edits.length === 0) {
return;
}
return edits.map(toTextEdit);
});
});
}
}
export class DocumentRangeFormattingEditProvider
implements languages.DocumentRangeFormattingEditProvider {
constructor(private _worker: WorkerAccessor) {}
public provideDocumentRangeFormattingEdits(
model: editor.IReadOnlyModel,
range: Range,
options: languages.FormattingOptions,
token: CancellationToken
): Promise<editor.ISingleEditOperation[]> {
const resource = model.uri;
return this._worker(resource).then((worker) => {
return worker
.format(resource.toString(), fromRange(range), fromFormattingOptions(options))
.then((edits) => {
if (!edits || edits.length === 0) {
return;
}
return edits.map(toTextEdit);
});
});
}
}
export class DocumentColorAdapter implements languages.DocumentColorProvider {
constructor(private _worker: WorkerAccessor) {}
public provideDocumentColors(
model: editor.IReadOnlyModel,
token: CancellationToken
): Promise<languages.IColorInformation[]> {
const resource = model.uri;
return 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: editor.IReadOnlyModel,
info: languages.IColorInformation,
token: CancellationToken
): Promise<languages.IColorPresentation[]> {
const resource = model.uri;
return 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: languages.IColorPresentation = {
label: presentation.label
};
if (presentation.textEdit) {
item.textEdit = toTextEdit(presentation.textEdit);
}
if (presentation.additionalTextEdits) {
item.additionalTextEdits = presentation.additionalTextEdits.map(toTextEdit);
}
return item;
});
});
}
}
export class FoldingRangeAdapter implements languages.FoldingRangeProvider {
constructor(private _worker: WorkerAccessor) {}
public provideFoldingRanges(
model: editor.IReadOnlyModel,
context: languages.FoldingContext,
token: CancellationToken
): Promise<languages.FoldingRange[]> {
const resource = model.uri;
return this._worker(resource)
.then((worker) => worker.getFoldingRanges(resource.toString(), context))
.then((ranges) => {
if (!ranges) {
return;
}
return ranges.map((range) => {
let result: languages.FoldingRange = {
start: range.startLine + 1,
end: range.endLine + 1
};
if (typeof range.kind !== 'undefined') {
result.kind = toFoldingRangeKind(<jsonService.FoldingRangeKind>range.kind);
}
return result;
});
});
}
}
function toFoldingRangeKind(kind: jsonService.FoldingRangeKind): languages.FoldingRangeKind {
switch (kind) {
case jsonService.FoldingRangeKind.Comment:
return languages.FoldingRangeKind.Comment;
case jsonService.FoldingRangeKind.Imports:
return languages.FoldingRangeKind.Imports;
case jsonService.FoldingRangeKind.Region:
return languages.FoldingRangeKind.Region;
}
return void 0;
}
export class SelectionRangeAdapter implements languages.SelectionRangeProvider {
constructor(private _worker: WorkerAccessor) {}
public provideSelectionRanges(
model: editor.IReadOnlyModel,
positions: Position[],
token: CancellationToken
): Promise<languages.SelectionRange[][]> {
const resource = model.uri;
return this._worker(resource)
.then((worker) => worker.getSelectionRanges(resource.toString(), positions.map(fromPosition)))
.then((selectionRanges) => {
if (!selectionRanges) {
return;
}
return selectionRanges.map((selectionRange) => {
const result: languages.SelectionRange[] = [];
while (selectionRange) {
result.push({ range: toRange(selectionRange.range) });
selectionRange = selectionRange.parent;
}
return result;
});
});
}
}

View file

@ -0,0 +1,218 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as mode from './jsonMode';
import { Emitter, IEvent, languages } from './fillers/monaco-editor-core';
// --- JSON configuration and defaults ---------
export interface DiagnosticsOptions {
/**
* If set, the validator will be enabled and perform syntax and schema based validation,
* unless `DiagnosticsOptions.schemaValidation` is set to `ignore`.
*/
readonly validate?: boolean;
/**
* If set, comments are tolerated. If set to false, syntax errors will be emitted for comments.
* `DiagnosticsOptions.allowComments` will override this setting.
*/
readonly allowComments?: boolean;
/**
* A list of known schemas and/or associations of schemas to file names.
*/
readonly schemas?: {
/**
* The URI of the schema, which is also the identifier of the schema.
*/
readonly uri: string;
/**
* A list of glob patterns that describe for which file URIs the JSON schema will be used.
* '*' and '**' wildcards are supported. Exclusion patterns start with '!'.
* For example '*.schema.json', 'package.json', '!foo*.schema.json', 'foo/**\/BADRESP.json'.
* A match succeeds when there is at least one pattern matching and last matching pattern does not start with '!'.
*/
readonly fileMatch?: string[];
/**
* The schema for the given URI.
*/
readonly schema?: any;
}[];
/**
* If set, the schema service would load schema content on-demand with 'fetch' if available
*/
readonly enableSchemaRequest?: boolean;
/**
* The severity of problems from schema validation. If set to 'ignore', schema validation will be skipped. If not set, 'warning' is used.
*/
readonly schemaValidation?: SeverityLevel;
/**
* The severity of problems that occurred when resolving and loading schemas. If set to 'ignore', schema resolving problems are not reported. If not set, 'warning' is used.
*/
readonly schemaRequest?: SeverityLevel;
/**
* The severity of reported trailing commas. If not set, trailing commas will be reported as errors.
*/
readonly trailingCommas?: SeverityLevel;
/**
* The severity of reported comments. If not set, 'DiagnosticsOptions.allowComments' defines whether comments are ignored or reported as errors.
*/
readonly comments?: SeverityLevel;
}
export declare type SeverityLevel = 'error' | 'warning' | 'ignore';
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;
/**
* Defines whether the built-in selection range provider is enabled.
*/
readonly selectionRanges?: boolean;
}
export interface LanguageServiceDefaults {
readonly languageId: string;
readonly onDidChange: IEvent<LanguageServiceDefaults>;
readonly diagnosticsOptions: DiagnosticsOptions;
readonly modeConfiguration: ModeConfiguration;
setDiagnosticsOptions(options: DiagnosticsOptions): void;
setModeConfiguration(modeConfiguration: ModeConfiguration): void;
}
class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
private _onDidChange = new Emitter<LanguageServiceDefaults>();
private _diagnosticsOptions: DiagnosticsOptions;
private _modeConfiguration: ModeConfiguration;
private _languageId: string;
constructor(
languageId: string,
diagnosticsOptions: DiagnosticsOptions,
modeConfiguration: ModeConfiguration
) {
this._languageId = languageId;
this.setDiagnosticsOptions(diagnosticsOptions);
this.setModeConfiguration(modeConfiguration);
}
get onDidChange(): IEvent<LanguageServiceDefaults> {
return this._onDidChange.event;
}
get languageId(): string {
return this._languageId;
}
get modeConfiguration(): ModeConfiguration {
return this._modeConfiguration;
}
get diagnosticsOptions(): DiagnosticsOptions {
return this._diagnosticsOptions;
}
setDiagnosticsOptions(options: DiagnosticsOptions): void {
this._diagnosticsOptions = options || Object.create(null);
this._onDidChange.fire(this);
}
setModeConfiguration(modeConfiguration: ModeConfiguration): void {
this._modeConfiguration = modeConfiguration || Object.create(null);
this._onDidChange.fire(this);
}
}
const diagnosticDefault: Required<DiagnosticsOptions> = {
validate: true,
allowComments: true,
schemas: [],
enableSchemaRequest: false,
schemaRequest: 'warning',
schemaValidation: 'warning',
comments: 'error',
trailingCommas: 'error'
};
const modeConfigurationDefault: Required<ModeConfiguration> = {
documentFormattingEdits: true,
documentRangeFormattingEdits: true,
completionItems: true,
hovers: true,
documentSymbols: true,
tokens: true,
colors: true,
foldingRanges: true,
diagnostics: true,
selectionRanges: true
};
export const jsonDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
'json',
diagnosticDefault,
modeConfigurationDefault
);
// export to the global based API
(<any>languages).json = { jsonDefaults };
// --- Registration to monaco editor ---
function getMode(): Promise<typeof mode> {
return import('./jsonMode');
}
languages.register({
id: 'json',
extensions: ['.json', '.bowerrc', '.jshintrc', '.jscsrc', '.eslintrc', '.babelrc', '.har'],
aliases: ['JSON', 'json'],
mimetypes: ['application/json']
});
languages.onLanguage('json', () => {
getMode().then((mode) => mode.setupMode(jsonDefaults));
});

View file

@ -0,0 +1,260 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as json from 'jsonc-parser';
import { languages } from './fillers/monaco-editor-core';
export function createTokenizationSupport(supportComments: boolean): languages.TokensProvider {
return {
getInitialState: () => new JSONState(null, null, false, null),
tokenize: (line, state, offsetDelta?, stopAtOffset?) =>
tokenize(supportComments, line, <JSONState>state, offsetDelta, stopAtOffset)
};
}
export const TOKEN_DELIM_OBJECT = 'delimiter.bracket.json';
export const TOKEN_DELIM_ARRAY = 'delimiter.array.json';
export const TOKEN_DELIM_COLON = 'delimiter.colon.json';
export const TOKEN_DELIM_COMMA = 'delimiter.comma.json';
export const TOKEN_VALUE_BOOLEAN = 'keyword.json';
export const TOKEN_VALUE_NULL = 'keyword.json';
export const TOKEN_VALUE_STRING = 'string.value.json';
export const TOKEN_VALUE_NUMBER = 'number.json';
export const TOKEN_PROPERTY_NAME = 'string.key.json';
export const TOKEN_COMMENT_BLOCK = 'comment.block.json';
export const TOKEN_COMMENT_LINE = 'comment.line.json';
const enum JSONParent {
Object = 0,
Array = 1
}
class ParentsStack {
constructor(
public readonly parent: ParentsStack | null,
public readonly type: JSONParent
) {}
public static pop(parents: ParentsStack | null): ParentsStack | null {
if (parents) {
return parents.parent;
}
return null;
}
public static push(
parents: ParentsStack | null,
type: JSONParent
): ParentsStack {
return new ParentsStack(parents, type);
}
public static equals(
a: ParentsStack | null,
b: ParentsStack | null
): boolean {
if (!a && !b) {
return true;
}
if (!a || !b) {
return false;
}
while (a && b) {
if (a === b) {
return true;
}
if (a.type !== b.type) {
return false;
}
a = a.parent;
b = b.parent;
}
return true;
}
}
class JSONState implements languages.IState {
private _state: languages.IState;
public scanError: json.ScanError;
public lastWasColon: boolean;
public parents: ParentsStack | null;
constructor(
state: languages.IState,
scanError: json.ScanError,
lastWasColon: boolean,
parents: ParentsStack | null
) {
this._state = state;
this.scanError = scanError;
this.lastWasColon = lastWasColon;
this.parents = parents;
}
public clone(): JSONState {
return new JSONState(
this._state,
this.scanError,
this.lastWasColon,
this.parents
);
}
public equals(other: languages.IState): boolean {
if (other === this) {
return true;
}
if (!other || !(other instanceof JSONState)) {
return false;
}
return (
this.scanError === other.scanError &&
this.lastWasColon === other.lastWasColon &&
ParentsStack.equals(this.parents, other.parents)
);
}
public getStateData(): languages.IState {
return this._state;
}
public setStateData(state: languages.IState): void {
this._state = state;
}
}
function tokenize(
comments: boolean,
line: string,
state: JSONState,
offsetDelta: number = 0,
stopAtOffset?: number
): languages.ILineTokens {
// handle multiline strings and block comments
let numberOfInsertedCharacters = 0;
let adjustOffset = false;
switch (state.scanError) {
case json.ScanError.UnexpectedEndOfString:
line = '"' + line;
numberOfInsertedCharacters = 1;
break;
case json.ScanError.UnexpectedEndOfComment:
line = '/*' + line;
numberOfInsertedCharacters = 2;
break;
}
const scanner = json.createScanner(line);
let lastWasColon = state.lastWasColon;
let parents = state.parents;
const ret: languages.ILineTokens = {
tokens: <languages.IToken[]>[],
endState: state.clone()
};
while (true) {
let offset = offsetDelta + scanner.getPosition();
let type = '';
const kind = scanner.scan();
if (kind === json.SyntaxKind.EOF) {
break;
}
// Check that the scanner has advanced
if (offset === offsetDelta + scanner.getPosition()) {
throw new Error(
'Scanner did not advance, next 3 characters are: ' + line.substr(scanner.getPosition(), 3)
);
}
// In case we inserted /* or " character, we need to
// adjust the offset of all tokens (except the first)
if (adjustOffset) {
offset -= numberOfInsertedCharacters;
}
adjustOffset = numberOfInsertedCharacters > 0;
// brackets and type
switch (kind) {
case json.SyntaxKind.OpenBraceToken:
parents = ParentsStack.push(parents, JSONParent.Object);
type = TOKEN_DELIM_OBJECT;
lastWasColon = false;
break;
case json.SyntaxKind.CloseBraceToken:
parents = ParentsStack.pop(parents);
type = TOKEN_DELIM_OBJECT;
lastWasColon = false;
break;
case json.SyntaxKind.OpenBracketToken:
parents = ParentsStack.push(parents, JSONParent.Array);
type = TOKEN_DELIM_ARRAY;
lastWasColon = false;
break;
case json.SyntaxKind.CloseBracketToken:
parents = ParentsStack.pop(parents);
type = TOKEN_DELIM_ARRAY;
lastWasColon = false;
break;
case json.SyntaxKind.ColonToken:
type = TOKEN_DELIM_COLON;
lastWasColon = true;
break;
case json.SyntaxKind.CommaToken:
type = TOKEN_DELIM_COMMA;
lastWasColon = false;
break;
case json.SyntaxKind.TrueKeyword:
case json.SyntaxKind.FalseKeyword:
type = TOKEN_VALUE_BOOLEAN;
lastWasColon = false;
break;
case json.SyntaxKind.NullKeyword:
type = TOKEN_VALUE_NULL;
lastWasColon = false;
break;
case json.SyntaxKind.StringLiteral:
const currentParent = parents ? parents.type : JSONParent.Object;
const inArray = currentParent === JSONParent.Array;
type =
lastWasColon || inArray ? TOKEN_VALUE_STRING : TOKEN_PROPERTY_NAME;
lastWasColon = false;
break;
case json.SyntaxKind.NumericLiteral:
type = TOKEN_VALUE_NUMBER;
lastWasColon = false;
break;
}
// comments, iff enabled
if (comments) {
switch (kind) {
case json.SyntaxKind.LineCommentTrivia:
type = TOKEN_COMMENT_LINE;
break;
case json.SyntaxKind.BlockCommentTrivia:
type = TOKEN_COMMENT_BLOCK;
break;
}
}
ret.endState = new JSONState(
state.getStateData(),
scanner.getTokenError(),
lastWasColon,
parents
);
ret.tokens.push({
startIndex: offset,
scopes: type
});
}
return ret;
}

View file

@ -0,0 +1,10 @@
{
"compilerOptions": {
"declaration": true,
"module": "esnext",
"moduleResolution": "node",
"outDir": "../out/esm",
"target": "es5",
"lib": ["dom", "es5", "es2015.collection", "es2015.promise", "es2015.iterable"]
}
}

View file

@ -0,0 +1,10 @@
{
"compilerOptions": {
"module": "amd",
"moduleResolution": "node",
"outDir": "../out/amd",
"declaration": true,
"target": "es5",
"lib": ["dom", "es5", "es2015.collection", "es2015.promise", "es2015.iterable"]
}
}

View file

@ -0,0 +1,88 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { LanguageServiceDefaults } from './monaco.contribution';
import type { JSONWorker } from './jsonWorker';
import { IDisposable, Uri, editor } from './fillers/monaco-editor-core';
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min
export class WorkerManager {
private _defaults: LanguageServiceDefaults;
private _idleCheckInterval: number;
private _lastUsedTime: number;
private _configChangeListener: IDisposable;
private _worker: editor.MonacoWebWorker<JSONWorker>;
private _client: Promise<JSONWorker>;
constructor(defaults: LanguageServiceDefaults) {
this._defaults = defaults;
this._worker = null;
this._idleCheckInterval = setInterval(() => this._checkIfIdle(), 30 * 1000);
this._lastUsedTime = 0;
this._configChangeListener = this._defaults.onDidChange(() => this._stopWorker());
}
private _stopWorker(): void {
if (this._worker) {
this._worker.dispose();
this._worker = null;
}
this._client = null;
}
dispose(): void {
clearInterval(this._idleCheckInterval);
this._configChangeListener.dispose();
this._stopWorker();
}
private _checkIfIdle(): void {
if (!this._worker) {
return;
}
let timePassedSinceLastUsed = Date.now() - this._lastUsedTime;
if (timePassedSinceLastUsed > STOP_WHEN_IDLE_FOR) {
this._stopWorker();
}
}
private _getClient(): Promise<JSONWorker> {
this._lastUsedTime = Date.now();
if (!this._client) {
this._worker = editor.createWebWorker<JSONWorker>({
// module that exports the create() method and returns a `JSONWorker` instance
moduleId: 'vs/language/json/jsonWorker',
label: this._defaults.languageId,
// passed in to the create() method
createData: {
languageSettings: this._defaults.diagnosticsOptions,
languageId: this._defaults.languageId,
enableSchemaRequest: this._defaults.diagnosticsOptions.enableSchemaRequest
}
});
this._client = <Promise<JSONWorker>>(<any>this._worker.getProxy());
}
return this._client;
}
getLanguageServiceWorker(...resources: Uri[]): Promise<JSONWorker> {
let _client: JSONWorker;
return this._getClient()
.then((client) => {
_client = client;
})
.then((_) => {
return this._worker.withSyncedResources(resources);
})
.then((_) => _client);
}
}

120
monaco-json/test/index.html Normal file
View file

@ -0,0 +1,120 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link
rel="stylesheet"
data-name="vs/editor/editor.main"
href="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.css"
/>
</head>
<body>
<h2>Monaco Editor JSON test page</h2>
<div id="container" style="width: 800px; height: 600px; border: 1px solid grey"></div>
<script>
// Loading basic-languages to get the json language definition
var paths = {
'vs/basic-languages': '../node_modules/monaco-languages/release/dev',
'vs/language/json': '../release/dev',
vs: '../node_modules/monaco-editor-core/dev/vs'
};
if (document.location.protocol === 'http:') {
// Add support for running local http server
let testIndex = document.location.pathname.indexOf('/test/');
if (testIndex !== -1) {
let prefix = document.location.pathname.substr(0, testIndex);
paths['vs/language/json'] = prefix + '/release/dev';
}
}
var require = {
paths: paths
};
</script>
<script src="../node_modules/monaco-editor-core/dev/vs/loader.js"></script>
<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.nls.js"></script>
<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.js"></script>
<script>
require([
'vs/basic-languages/monaco.contribution',
'vs/language/json/monaco.contribution'
], function () {
var editor = monaco.editor.create(document.getElementById('container'), {
value: [
'{',
' "type": "team",',
' "test": {',
' "testPage": "tools/testing/run-tests.htm",',
' "enabled": true',
' },',
' "search": {',
' "excludeFolders": [',
' ".git",',
' "node_modules",',
' "tools/bin",',
' "tools/counts",',
' "tools/policheck",',
' "tools/tfs_build_extensions",',
' "tools/testing/jscoverage",',
' "tools/testing/qunit",',
' "tools/testing/chutzpah",',
' "server.net"',
' ]',
' },',
' "languages": {',
' "vs.languages.typescript": {',
' "validationSettings": [{',
' "scope":"/",',
' "noImplicitAny":true,',
' "noLib":false,',
' "extraLibs":[],',
' "semanticValidation":true,',
' "syntaxValidation":true,',
' "codeGenTarget":"ES5",',
' "moduleGenTarget":"",',
' "lint": {',
' "emptyBlocksWithoutComment": "warning",',
' "curlyBracketsMustNotBeOmitted": "warning",',
' "comparisonOperatorsNotStrict": "warning",',
' "missingSemicolon": "warning",',
' "unknownTypeOfResults": "warning",',
' "semicolonsInsteadOfBlocks": "warning",',
' "functionsInsideLoops": "warning",',
' "functionsWithoutReturnType": "warning",',
' "tripleSlashReferenceAlike": "warning",',
' "unusedImports": "warning",',
' "unusedVariables": "warning",',
' "unusedFunctions": "warning",',
' "unusedMembers": "warning"',
' }',
' },',
' {',
' "scope":"/client",',
' "baseUrl":"/client",',
' "moduleGenTarget":"amd"',
' },',
' {',
' "scope":"/server",',
' "moduleGenTarget":"commonjs"',
' },',
' {',
' "scope":"/build",',
' "moduleGenTarget":"commonjs"',
' },',
' {',
' "scope":"/node_modules/nake",',
' "moduleGenTarget":"commonjs"',
' }],',
' "allowMultipleWorkers": true',
' }',
' }',
'}'
].join('\n'),
language: 'json'
});
});
</script>
</body>
</html>