mirror of
https://github.com/danbulant/monaco-yaml
synced 2026-05-19 04:08:48 +00:00
Introduce ESLint
The ESLint preset `eslint-config-remcohaszing` is used.
This commit is contained in:
parent
9a107bf7cc
commit
ac7b6fe307
22 changed files with 7696 additions and 628 deletions
|
|
@ -3,12 +3,12 @@ root = true
|
|||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = 100
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
[COMMIT_EDITMSG]
|
||||
max_line_length = 72
|
||||
|
|
|
|||
21
.eslintrc.yaml
Normal file
21
.eslintrc.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
extends: remcohaszing
|
||||
rules:
|
||||
class-methods-use-this: off
|
||||
max-classes-per-file: off
|
||||
no-console: off
|
||||
no-restricted-globals: off
|
||||
no-underscore-dangle: off
|
||||
no-useless-constructor: off
|
||||
|
||||
'@typescript-eslint/naming-convention': off
|
||||
'@typescript-eslint/no-parameter-properties': off
|
||||
'@typescript-eslint/prefer-optional-chain': off
|
||||
|
||||
import/no-extraneous-dependencies: off
|
||||
import/no-unresolved: off
|
||||
import/no-webpack-loader-syntax: off
|
||||
|
||||
jsdoc/require-jsdoc: off
|
||||
|
||||
node/no-extraneous-import: off
|
||||
node/no-unpublished-import: off
|
||||
3
.prettierrc.yaml
Normal file
3
.prettierrc.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
proseWrap: always
|
||||
singleQuote: true
|
||||
trailingComma: all
|
||||
25
LICENSE.md
25
LICENSE.md
|
|
@ -2,20 +2,17 @@ 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
|
||||
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 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.
|
||||
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.
|
||||
|
|
|
|||
29
README.md
29
README.md
|
|
@ -1,6 +1,7 @@
|
|||
# Monaco YAML
|
||||
|
||||
YAML language plugin for the Monaco Editor. It provides the following features when editing YAML files:
|
||||
YAML language plugin for the Monaco Editor. It provides the following features when editing YAML
|
||||
files:
|
||||
|
||||
- Code completion, based on JSON schemas or by looking at similar objects in the same file
|
||||
- Hovers, based on JSON schemas
|
||||
|
|
@ -10,8 +11,9 @@ YAML language plugin for the Monaco Editor. It provides the following features w
|
|||
- Syntax highlighting
|
||||
- Automatically load remote schema files (by enabling DiagnosticsOptions.enableSchemaRequest)
|
||||
|
||||
Schemas can also be provided by configuration. See [here](https://github.com/Microsoft/monaco-json/blob/master/src/monaco.d.ts)
|
||||
for the API that the JSON plugin offers to configure the JSON language support.
|
||||
Schemas can also be provided by configuration. See
|
||||
[here](https://github.com/Microsoft/monaco-json/blob/master/src/monaco.d.ts) for the API that the
|
||||
JSON plugin offers to configure the JSON language support.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
@ -38,8 +40,10 @@ languages.yaml.yamlDefaults.setDiagnosticsOptions({
|
|||
format: true,
|
||||
schemas: [
|
||||
{
|
||||
uri: 'http://myserver/foo-schema.json', // id of the first schema
|
||||
fileMatch: [modelUri.toString()], // associate with our model
|
||||
// Id of the first schema
|
||||
uri: 'http://myserver/foo-schema.json',
|
||||
// Associate with our model
|
||||
fileMatch: [String(modelUri)],
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
|
|
@ -47,13 +51,15 @@ languages.yaml.yamlDefaults.setDiagnosticsOptions({
|
|||
enum: ['v1', 'v2'],
|
||||
},
|
||||
p2: {
|
||||
$ref: 'http://myserver/bar-schema.json', // reference the second schema
|
||||
// Reference the second schema
|
||||
$ref: 'http://myserver/bar-schema.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
uri: 'http://myserver/bar-schema.json', // id of the first schema
|
||||
// Id of the first schema
|
||||
uri: 'http://myserver/bar-schema.json',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
|
|
@ -67,13 +73,15 @@ languages.yaml.yamlDefaults.setDiagnosticsOptions({
|
|||
});
|
||||
|
||||
editor.create(document.createElement('editor'), {
|
||||
// monaco-yaml features should just work if the editor language is set to 'yaml'.
|
||||
// Monaco-yaml features should just work if the editor language is set to 'yaml'.
|
||||
language: 'yaml',
|
||||
model: editor.createModel('p1: \n', 'yaml', modelUri),
|
||||
});
|
||||
```
|
||||
|
||||
Also make sure to register the service worker. See the [examples](https://github.com/pengx17/monaco-yaml/tree/master/examples) directory for full fledged examples.
|
||||
Also make sure to register the service worker. See the
|
||||
[examples](https://github.com/pengx17/monaco-yaml/tree/master/examples) directory for full fledged
|
||||
examples.
|
||||
|
||||
## Development
|
||||
|
||||
|
|
@ -81,8 +89,7 @@ Also make sure to register the service worker. See the [examples](https://github
|
|||
- `cd monaco-yaml`
|
||||
- `npm ci`
|
||||
|
||||
A running example:
|
||||

|
||||
A running example: 
|
||||
|
||||
## Credits
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import './index.css';
|
||||
|
||||
import { editor, languages } from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import 'monaco-yaml/lib/esm/monaco.contribution';
|
||||
|
||||
// NOTE: This will give you all editor featues. If you would prefer to limit to only the editor
|
||||
// features you want to use, import them each individually. See this example: (https://github.com/microsoft/monaco-editor-samples/blob/master/browser-esm-webpack-small/index.js#L1-L91)
|
||||
import 'monaco-editor';
|
||||
|
||||
import { editor, languages } from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import 'monaco-yaml/lib/esm/monaco.contribution';
|
||||
// NOTE: using loader syntax becuase Yaml worker imports editor.worker directly and that
|
||||
// import shouldn't go through loader syntax.
|
||||
import EditorWorker from 'worker-loader!monaco-editor/esm/vs/editor/editor.worker';
|
||||
|
|
@ -28,25 +27,31 @@ languages.yaml.yamlDefaults.setDiagnosticsOptions({
|
|||
completion: true,
|
||||
schemas: [
|
||||
{
|
||||
uri: 'http://myserver/foo-schema.json', // id of the first schema
|
||||
fileMatch: ['*'], // associate with our model
|
||||
// Id of the first schema
|
||||
uri: 'http://myserver/foo-schema.json',
|
||||
// Associate with our model
|
||||
fileMatch: ['*'],
|
||||
schema: {
|
||||
id: 'http://myserver/foo-schema.json', // id of the first schema
|
||||
// Id of the first schema
|
||||
id: 'http://myserver/foo-schema.json',
|
||||
type: 'object',
|
||||
properties: {
|
||||
p1: {
|
||||
enum: ['v1', 'v2'],
|
||||
},
|
||||
p2: {
|
||||
$ref: 'http://myserver/bar-schema.json', // reference the second schema
|
||||
// Reference the second schema
|
||||
$ref: 'http://myserver/bar-schema.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
uri: 'http://myserver/bar-schema.json', // id of the first schema
|
||||
// Id of the first schema
|
||||
uri: 'http://myserver/bar-schema.json',
|
||||
schema: {
|
||||
id: 'http://myserver/bar-schema.json', // id of the first schema
|
||||
// Id of the first schema
|
||||
id: 'http://myserver/bar-schema.json',
|
||||
type: 'object',
|
||||
properties: {
|
||||
q1: {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const { resolve } = require('path');
|
||||
|
||||
const HtmlWebPackPlugin = require('html-webpack-plugin');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
|
|
@ -8,7 +9,7 @@ module.exports = {
|
|||
output: {
|
||||
globalObject: 'this',
|
||||
filename: '[name].bundle.js',
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
path: resolve(__dirname, 'dist'),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
|
|
|||
|
|
@ -23,25 +23,31 @@ languages.yaml.yamlDefaults.setDiagnosticsOptions({
|
|||
completion: true,
|
||||
schemas: [
|
||||
{
|
||||
uri: 'http://myserver/foo-schema.json', // id of the first schema
|
||||
fileMatch: ['*'], // associate with our model
|
||||
// Id of the first schema
|
||||
uri: 'http://myserver/foo-schema.json',
|
||||
// Associate with our model
|
||||
fileMatch: ['*'],
|
||||
schema: {
|
||||
id: 'http://myserver/foo-schema.json', // id of the first schema
|
||||
// Id of the first schema
|
||||
id: 'http://myserver/foo-schema.json',
|
||||
type: 'object',
|
||||
properties: {
|
||||
p1: {
|
||||
enum: ['v1', 'v2'],
|
||||
},
|
||||
p2: {
|
||||
$ref: 'http://myserver/bar-schema.json', // reference the second schema
|
||||
// Reference the second schema
|
||||
$ref: 'http://myserver/bar-schema.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
uri: 'http://myserver/bar-schema.json', // id of the first schema
|
||||
// Id of the first schema
|
||||
uri: 'http://myserver/bar-schema.json',
|
||||
schema: {
|
||||
id: 'http://myserver/bar-schema.json', // id of the first schema
|
||||
// Id of the first schema
|
||||
id: 'http://myserver/bar-schema.json',
|
||||
type: 'object',
|
||||
properties: {
|
||||
q1: {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const { resolve } = require('path');
|
||||
|
||||
const HtmlWebPackPlugin = require('html-webpack-plugin');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
|
|
@ -10,7 +11,7 @@ module.exports = {
|
|||
output: {
|
||||
globalObject: 'this',
|
||||
filename: '[name].bundle.js',
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
path: resolve(__dirname, 'dist'),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
|
|
|||
7307
package-lock.json
generated
7307
package-lock.json
generated
File diff suppressed because it is too large
Load diff
21
package.json
21
package.json
|
|
@ -6,9 +6,9 @@
|
|||
"watch": "tsc -p ./src --watch",
|
||||
"compile": "rimraf ./out && tsc",
|
||||
"bundle": "rimraf ./lib && node ./scripts/bundle-esm && mcopy ./src/monaco.d.ts ./lib/monaco.d.ts",
|
||||
"build": "npm run compile && npm run bundle",
|
||||
"prepack": "npm run compile && npm run bundle",
|
||||
"prepare": "husky install",
|
||||
"lint": "prettier --check ."
|
||||
"lint": "eslint . && prettier --check ."
|
||||
},
|
||||
"main": "./lib/esm/monaco.contribution.js",
|
||||
"module": "./lib/esm/monaco.contribution.js",
|
||||
|
|
@ -36,7 +36,14 @@
|
|||
"js-yaml": "^3.14.1",
|
||||
"yaml-ast-parser-custom-tags": "^0.0.43"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"monaco-editor": ">=0.22"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^4.28.3",
|
||||
"@typescript-eslint/parser": "^4.28.3",
|
||||
"eslint": "^7.30.0",
|
||||
"eslint-config-remcohaszing": "^3.4.0",
|
||||
"husky": "^7.0.1",
|
||||
"lint-staged": "^10.5.4",
|
||||
"monaco-editor": "^0.26.1",
|
||||
|
|
@ -46,14 +53,12 @@
|
|||
"typescript": "^4.3.5",
|
||||
"yaml-language-server": "^0.11.1"
|
||||
},
|
||||
"prettier": {
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"semi": true
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{css,json,md,html,ts,js,jsx,yaml}": [
|
||||
"*.{css,json,md,html,yaml}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{js,ts}": [
|
||||
"eslint"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
const { join } = require('path');
|
||||
|
||||
const path = require('path');
|
||||
const helpers = require('monaco-plugin-helpers');
|
||||
|
||||
const REPO_ROOT = path.join(__dirname, '../');
|
||||
const REPO_ROOT = join(__dirname, '../');
|
||||
|
||||
helpers.packageESM({
|
||||
repoRoot: REPO_ROOT,
|
||||
|
|
@ -14,54 +10,46 @@ helpers.packageESM({
|
|||
esmDestination: 'lib/esm',
|
||||
entryPoints: ['monaco.contribution.js', 'yamlMode.js', 'yaml.worker.js'],
|
||||
resolveAlias: {
|
||||
'vscode-nls': path.join(REPO_ROOT, 'out/esm/fillers/vscode-nls.js'),
|
||||
'vscode-json-languageservice/lib/umd/services/jsonValidation': path.join(
|
||||
'vscode-nls': join(REPO_ROOT, 'out/esm/fillers/vscode-nls.js'),
|
||||
'vscode-json-languageservice/lib/umd/services/jsonValidation': join(
|
||||
REPO_ROOT,
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonValidation.js'
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonValidation.js',
|
||||
),
|
||||
'vscode-json-languageservice': path.join(
|
||||
'vscode-json-languageservice': join(
|
||||
REPO_ROOT,
|
||||
'node_modules/vscode-json-languageservice/lib/esm/jsonLanguageService.js'
|
||||
'node_modules/vscode-json-languageservice/lib/esm/jsonLanguageService.js',
|
||||
),
|
||||
'vscode-json-languageservice/lib/umd/services/jsonHover': path.join(
|
||||
'vscode-json-languageservice/lib/umd/services/jsonHover': join(
|
||||
REPO_ROOT,
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonHover.js'
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonHover.js',
|
||||
),
|
||||
'vscode-json-languageservice/lib/umd/services/jsonDocumentSymbols': path.join(
|
||||
'vscode-json-languageservice/lib/umd/services/jsonDocumentSymbols': join(
|
||||
REPO_ROOT,
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonDocumentSymbols.js'
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonDocumentSymbols.js',
|
||||
),
|
||||
'vscode-json-languageservice/lib/umd/services/jsonSchemaService': path.join(
|
||||
'vscode-json-languageservice/lib/umd/services/jsonSchemaService': join(
|
||||
REPO_ROOT,
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonSchemaService.js'
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonSchemaService.js',
|
||||
),
|
||||
|
||||
'vscode-json-languageservice/lib/umd/services/jsonCompletion': path.join(
|
||||
'vscode-json-languageservice/lib/umd/services/jsonCompletion': join(
|
||||
REPO_ROOT,
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonCompletion.js'
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonCompletion.js',
|
||||
),
|
||||
'vscode-json-languageservice/lib/umd/services/jsonDefinition': path.join(
|
||||
'vscode-json-languageservice/lib/umd/services/jsonDefinition': join(
|
||||
REPO_ROOT,
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonDefinition.js'
|
||||
'node_modules/vscode-json-languageservice/lib/esm/services/jsonDefinition.js',
|
||||
),
|
||||
'yaml-language-server': path.join(
|
||||
'yaml-language-server': join(
|
||||
REPO_ROOT,
|
||||
'node_modules/yaml-language-server/lib/esm/languageservice/yamlLanguageService.js'
|
||||
),
|
||||
prettier: path.join(REPO_ROOT, 'node_modules/prettier/standalone.js'),
|
||||
'prettier/parser-yaml': path.join(
|
||||
REPO_ROOT,
|
||||
'node_modules/prettier/parser-yaml.js'
|
||||
'node_modules/yaml-language-server/lib/esm/languageservice/yamlLanguageService.js',
|
||||
),
|
||||
prettier: join(REPO_ROOT, 'node_modules/prettier/standalone.js'),
|
||||
'prettier/parser-yaml': join(REPO_ROOT, 'node_modules/prettier/parser-yaml.js'),
|
||||
},
|
||||
resolveSkip: [
|
||||
'monaco-editor',
|
||||
'monaco-editor-core',
|
||||
'js-yaml',
|
||||
|
||||
'yaml-ast-parser-custom-tags',
|
||||
],
|
||||
resolveSkip: ['monaco-editor', 'monaco-editor-core', 'js-yaml', 'yaml-ast-parser-custom-tags'],
|
||||
destinationFolderSimplification: {
|
||||
// eslint-disable-next-line camelcase
|
||||
node_modules: '_deps',
|
||||
'jsonc-parser/lib/esm': 'jsonc-parser',
|
||||
'vscode-languageserver-types/lib/esm': 'vscode-languageserver-types',
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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;
|
||||
});
|
||||
|
|
@ -1,8 +1,3 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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;
|
||||
|
|
@ -11,38 +6,30 @@ 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 type LocalizeFunc = (
|
||||
info: LocalizeInfo | string,
|
||||
message: string,
|
||||
...args: unknown[]
|
||||
) => string;
|
||||
export type 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) => {
|
||||
const index = rest[0];
|
||||
return typeof args[index] !== 'undefined' ? args[index] : match;
|
||||
});
|
||||
}
|
||||
return result;
|
||||
function format(message: string, args: string[]): string {
|
||||
return args.length === 0
|
||||
? message
|
||||
: message.replace(/{(\d+)}/g, (match, rest) => {
|
||||
const [index] = rest;
|
||||
return typeof args[index] === 'undefined' ? match : args[index];
|
||||
});
|
||||
}
|
||||
|
||||
function localize(
|
||||
key: string | LocalizeInfo,
|
||||
message: string,
|
||||
...args: any[]
|
||||
): string {
|
||||
function localize(key: LocalizeInfo | string, message: string, ...args: string[]): string {
|
||||
return format(message, args);
|
||||
}
|
||||
|
||||
export function loadMessageBundle(file?: string): LocalizeFunc {
|
||||
export function loadMessageBundle(): LocalizeFunc {
|
||||
return localize;
|
||||
}
|
||||
|
||||
export function config(opt?: Options | string): LoadFunc {
|
||||
export function config(): LoadFunc {
|
||||
return loadMessageBundle;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,131 +1,24 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { LanguageServiceDefaultsImpl } from './monaco.contribution';
|
||||
import { YAMLWorker } from './yamlWorker';
|
||||
|
||||
import * as ls from 'vscode-languageserver-types';
|
||||
import {
|
||||
editor,
|
||||
languages,
|
||||
CancellationToken,
|
||||
IDisposable,
|
||||
IMarkdownString,
|
||||
IRange,
|
||||
languages,
|
||||
MarkerSeverity,
|
||||
Position,
|
||||
Range,
|
||||
Uri,
|
||||
} from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import * as ls from 'vscode-languageserver-types';
|
||||
import { CustomFormatterOptions } from 'yaml-language-server';
|
||||
|
||||
import { LanguageServiceDefaultsImpl } from './monaco.contribution';
|
||||
import { YAMLWorker } from './yamlWorker';
|
||||
|
||||
export type WorkerAccessor = (...more: Uri[]) => PromiseLike<YAMLWorker>;
|
||||
|
||||
// --- diagnostics --- ---
|
||||
|
||||
export class DiagnosticsAdapter {
|
||||
private _disposables: IDisposable[] = [];
|
||||
private _listener: { [uri: string]: IDisposable } = Object.create(null);
|
||||
|
||||
constructor(
|
||||
private _languageId: string,
|
||||
private _worker: WorkerAccessor,
|
||||
defaults: LanguageServiceDefaultsImpl
|
||||
) {
|
||||
const onModelAdd = (model: editor.IModel): void => {
|
||||
const modeId = model.getModeId();
|
||||
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, []);
|
||||
const uriStr = model.uri.toString();
|
||||
const 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.getModeId() === this._languageId) {
|
||||
onModelRemoved(model);
|
||||
onModelAdd(model);
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
this._disposables.push({
|
||||
dispose: () => {
|
||||
editor.getModels().forEach(onModelRemoved);
|
||||
for (const 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));
|
||||
const model = editor.getModel(resource);
|
||||
if (model.getModeId() === languageId) {
|
||||
editor.setModelMarkers(model, languageId, markers);
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(undefined, (err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function toSeverity(lsSeverity: number): MarkerSeverity {
|
||||
switch (lsSeverity) {
|
||||
case ls.DiagnosticSeverity.Error:
|
||||
|
|
@ -142,8 +35,7 @@ function toSeverity(lsSeverity: number): MarkerSeverity {
|
|||
}
|
||||
|
||||
function toDiagnostics(resource: Uri, diag: ls.Diagnostic): editor.IMarkerData {
|
||||
const code =
|
||||
typeof diag.code === 'number' ? String(diag.code) : (diag.code as string);
|
||||
const code = typeof diag.code === 'number' ? String(diag.code) : (diag.code as string);
|
||||
|
||||
return {
|
||||
severity: toSeverity(diag.severity),
|
||||
|
|
@ -157,18 +49,112 @@ function toDiagnostics(resource: Uri, diag: ls.Diagnostic): editor.IMarkerData {
|
|||
};
|
||||
}
|
||||
|
||||
export class DiagnosticsAdapter {
|
||||
private _disposables: IDisposable[] = [];
|
||||
private _listener: Record<string, IDisposable> = Object.create(null);
|
||||
|
||||
constructor(
|
||||
private _languageId: string,
|
||||
private _worker: WorkerAccessor,
|
||||
defaults: LanguageServiceDefaultsImpl,
|
||||
) {
|
||||
const onModelAdd = (model: editor.IModel): void => {
|
||||
const modeId = model.getModeId();
|
||||
if (modeId !== this._languageId) {
|
||||
return;
|
||||
}
|
||||
|
||||
let handle: number;
|
||||
this._listener[String(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, []);
|
||||
const uriStr = String(model.uri);
|
||||
const listener = this._listener[uriStr];
|
||||
if (listener) {
|
||||
listener.dispose();
|
||||
delete this._listener[uriStr];
|
||||
}
|
||||
};
|
||||
|
||||
this._disposables.push(
|
||||
editor.onDidCreateModel(onModelAdd),
|
||||
editor.onWillDisposeModel((model) => {
|
||||
onModelRemoved(model);
|
||||
this._resetSchema(model.uri);
|
||||
}),
|
||||
editor.onDidChangeModelLanguage((event) => {
|
||||
onModelRemoved(event.model);
|
||||
onModelAdd(event.model);
|
||||
this._resetSchema(event.model.uri);
|
||||
}),
|
||||
defaults.onDidChange(() => {
|
||||
editor.getModels().forEach((model) => {
|
||||
if (model.getModeId() === this._languageId) {
|
||||
onModelRemoved(model);
|
||||
onModelAdd(model);
|
||||
}
|
||||
});
|
||||
}),
|
||||
{
|
||||
dispose: () => {
|
||||
editor.getModels().forEach(onModelRemoved);
|
||||
for (const disposable of Object.values(this._listener)) {
|
||||
disposable.dispose();
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
editor.getModels().forEach(onModelAdd);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposables.forEach((d) => d && d.dispose());
|
||||
this._disposables = [];
|
||||
}
|
||||
|
||||
private _resetSchema(resource: Uri): void {
|
||||
this._worker().then((worker) => {
|
||||
worker.resetSchema(String(resource));
|
||||
});
|
||||
}
|
||||
|
||||
private _doValidate(resource: Uri, languageId: string): void {
|
||||
this._worker(resource)
|
||||
.then((worker) =>
|
||||
worker.doValidation(String(resource)).then((diagnostics) => {
|
||||
const markers = diagnostics.map((d) => toDiagnostics(resource, d));
|
||||
const model = editor.getModel(resource);
|
||||
if (model.getModeId() === languageId) {
|
||||
editor.setModelMarkers(model, languageId, markers);
|
||||
}
|
||||
}),
|
||||
)
|
||||
.then(undefined, (err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- completion ------
|
||||
|
||||
function fromPosition(position: Position): ls.Position {
|
||||
if (!position) {
|
||||
return void 0;
|
||||
return;
|
||||
}
|
||||
return { character: position.column - 1, line: position.lineNumber - 1 };
|
||||
}
|
||||
|
||||
function fromRange(range: IRange): ls.Range {
|
||||
if (!range) {
|
||||
return void 0;
|
||||
return;
|
||||
}
|
||||
return {
|
||||
start: {
|
||||
|
|
@ -180,13 +166,13 @@ function fromRange(range: IRange): ls.Range {
|
|||
}
|
||||
function toRange(range: ls.Range): Range {
|
||||
if (!range) {
|
||||
return void 0;
|
||||
return;
|
||||
}
|
||||
return new Range(
|
||||
range.start.line + 1,
|
||||
range.start.character + 1,
|
||||
range.end.line + 1,
|
||||
range.end.character + 1
|
||||
range.end.character + 1,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -230,59 +216,14 @@ function toCompletionItemKind(kind: number): languages.CompletionItemKind {
|
|||
return mItemKind.File;
|
||||
case ls.CompletionItemKind.Reference:
|
||||
return mItemKind.Reference;
|
||||
default:
|
||||
return mItemKind.Property;
|
||||
}
|
||||
return mItemKind.Property;
|
||||
}
|
||||
|
||||
function fromCompletionItemKind(
|
||||
kind: languages.CompletionItemKind
|
||||
): ls.CompletionItemKind {
|
||||
const mItemKind = languages.CompletionItemKind;
|
||||
|
||||
switch (kind) {
|
||||
case mItemKind.Text:
|
||||
return ls.CompletionItemKind.Text;
|
||||
case mItemKind.Method:
|
||||
return ls.CompletionItemKind.Method;
|
||||
case mItemKind.Function:
|
||||
return ls.CompletionItemKind.Function;
|
||||
case mItemKind.Constructor:
|
||||
return ls.CompletionItemKind.Constructor;
|
||||
case mItemKind.Field:
|
||||
return ls.CompletionItemKind.Field;
|
||||
case mItemKind.Variable:
|
||||
return ls.CompletionItemKind.Variable;
|
||||
case mItemKind.Class:
|
||||
return ls.CompletionItemKind.Class;
|
||||
case mItemKind.Interface:
|
||||
return ls.CompletionItemKind.Interface;
|
||||
case mItemKind.Module:
|
||||
return ls.CompletionItemKind.Module;
|
||||
case mItemKind.Property:
|
||||
return ls.CompletionItemKind.Property;
|
||||
case mItemKind.Unit:
|
||||
return ls.CompletionItemKind.Unit;
|
||||
case mItemKind.Value:
|
||||
return ls.CompletionItemKind.Value;
|
||||
case mItemKind.Enum:
|
||||
return ls.CompletionItemKind.Enum;
|
||||
case mItemKind.Keyword:
|
||||
return ls.CompletionItemKind.Keyword;
|
||||
case mItemKind.Snippet:
|
||||
return ls.CompletionItemKind.Snippet;
|
||||
case mItemKind.Color:
|
||||
return ls.CompletionItemKind.Color;
|
||||
case mItemKind.File:
|
||||
return ls.CompletionItemKind.File;
|
||||
case mItemKind.Reference:
|
||||
return ls.CompletionItemKind.Reference;
|
||||
}
|
||||
return ls.CompletionItemKind.Property;
|
||||
}
|
||||
|
||||
function toTextEdit(textEdit: ls.TextEdit): editor.ISingleEditOperation {
|
||||
if (!textEdit) {
|
||||
return void 0;
|
||||
return;
|
||||
}
|
||||
return {
|
||||
range: toRange(textEdit.range),
|
||||
|
|
@ -291,24 +232,18 @@ function toTextEdit(textEdit: ls.TextEdit): editor.ISingleEditOperation {
|
|||
}
|
||||
|
||||
export class CompletionAdapter implements languages.CompletionItemProvider {
|
||||
triggetCharacters = [' ', ':'];
|
||||
|
||||
constructor(private _worker: WorkerAccessor) {}
|
||||
|
||||
public get triggerCharacters(): string[] {
|
||||
return [' ', ':'];
|
||||
}
|
||||
|
||||
public provideCompletionItems(
|
||||
provideCompletionItems(
|
||||
model: editor.IReadOnlyModel,
|
||||
position: Position,
|
||||
context: languages.CompletionContext,
|
||||
token: CancellationToken
|
||||
): PromiseLike<languages.CompletionList> {
|
||||
const resource = model.uri;
|
||||
|
||||
return this._worker(resource)
|
||||
.then((worker) => {
|
||||
return worker.doComplete(resource.toString(), fromPosition(position));
|
||||
})
|
||||
.then((worker) => worker.doComplete(String(resource), fromPosition(position)))
|
||||
.then((info) => {
|
||||
if (!info) {
|
||||
return;
|
||||
|
|
@ -319,7 +254,7 @@ export class CompletionAdapter implements languages.CompletionItemProvider {
|
|||
position.lineNumber,
|
||||
wordInfo.startColumn,
|
||||
position.lineNumber,
|
||||
wordInfo.endColumn
|
||||
wordInfo.endColumn,
|
||||
);
|
||||
|
||||
const items: languages.CompletionItem[] = info.items.map((entry) => {
|
||||
|
|
@ -335,20 +270,15 @@ export class CompletionAdapter implements languages.CompletionItemProvider {
|
|||
};
|
||||
if (entry.textEdit) {
|
||||
item.range = toRange(
|
||||
'range' in entry.textEdit
|
||||
? entry.textEdit.range
|
||||
: entry.textEdit.replace
|
||||
'range' in entry.textEdit ? entry.textEdit.range : entry.textEdit.replace,
|
||||
);
|
||||
item.insertText = entry.textEdit.newText;
|
||||
}
|
||||
if (entry.additionalTextEdits) {
|
||||
item.additionalTextEdits = entry.additionalTextEdits.map(
|
||||
toTextEdit
|
||||
);
|
||||
item.additionalTextEdits = entry.additionalTextEdits.map(toTextEdit);
|
||||
}
|
||||
if (entry.insertTextFormat === ls.InsertTextFormat.Snippet) {
|
||||
item.insertTextRules =
|
||||
languages.CompletionItemInsertTextRule.InsertAsSnippet;
|
||||
item.insertTextRules = languages.CompletionItemInsertTextRule.InsertAsSnippet;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
|
|
@ -361,17 +291,11 @@ export class CompletionAdapter implements languages.CompletionItemProvider {
|
|||
}
|
||||
}
|
||||
|
||||
function isMarkupContent(thing: any): thing is ls.MarkupContent {
|
||||
return (
|
||||
thing &&
|
||||
typeof thing === 'object' &&
|
||||
typeof (thing as ls.MarkupContent).kind === 'string'
|
||||
);
|
||||
function isMarkupContent(thing: unknown): thing is ls.MarkupContent {
|
||||
return thing && typeof thing === 'object' && typeof (thing as ls.MarkupContent).kind === 'string';
|
||||
}
|
||||
|
||||
function toMarkdownString(
|
||||
entry: ls.MarkupContent | ls.MarkedString
|
||||
): IMarkdownString {
|
||||
function toMarkdownString(entry: ls.MarkedString | ls.MarkupContent): IMarkdownString {
|
||||
if (typeof entry === 'string') {
|
||||
return {
|
||||
value: entry,
|
||||
|
|
@ -380,7 +304,7 @@ function toMarkdownString(
|
|||
if (isMarkupContent(entry)) {
|
||||
if (entry.kind === 'plaintext') {
|
||||
return {
|
||||
value: entry.value.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&'),
|
||||
value: entry.value.replace(/[!#()*+.[\\\]_`{}-]/g, '\\$&'),
|
||||
};
|
||||
}
|
||||
return {
|
||||
|
|
@ -388,14 +312,14 @@ function toMarkdownString(
|
|||
};
|
||||
}
|
||||
|
||||
return { value: '```' + entry.language + '\n' + entry.value + '\n```\n' };
|
||||
return { value: `\`\`\`${entry.language}\n${entry.value}\n\`\`\`\n` };
|
||||
}
|
||||
|
||||
function toMarkedStringArray(
|
||||
contents: ls.MarkupContent | ls.MarkedString | ls.MarkedString[]
|
||||
contents: ls.MarkedString | ls.MarkedString[] | ls.MarkupContent,
|
||||
): IMarkdownString[] {
|
||||
if (!contents) {
|
||||
return void 0;
|
||||
return;
|
||||
}
|
||||
if (Array.isArray(contents)) {
|
||||
return contents.map(toMarkdownString);
|
||||
|
|
@ -408,17 +332,11 @@ function toMarkedStringArray(
|
|||
export class HoverAdapter implements languages.HoverProvider {
|
||||
constructor(private _worker: WorkerAccessor) {}
|
||||
|
||||
public provideHover(
|
||||
model: editor.IReadOnlyModel,
|
||||
position: Position,
|
||||
token: CancellationToken
|
||||
): PromiseLike<languages.Hover> {
|
||||
provideHover(model: editor.IReadOnlyModel, position: Position): PromiseLike<languages.Hover> {
|
||||
const resource = model.uri;
|
||||
|
||||
return this._worker(resource)
|
||||
.then((worker) => {
|
||||
return worker.doHover(resource.toString(), fromPosition(position));
|
||||
})
|
||||
.then((worker) => worker.doHover(String(resource), fromPosition(position)))
|
||||
.then((info) => {
|
||||
if (!info) {
|
||||
return;
|
||||
|
|
@ -473,27 +391,8 @@ function toSymbolKind(kind: ls.SymbolKind): languages.SymbolKind {
|
|||
return mKind.Boolean;
|
||||
case ls.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
|
||||
): PromiseLike<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) => toDocumentSymbol(item));
|
||||
});
|
||||
default:
|
||||
return mKind.Function;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -509,9 +408,26 @@ function toDocumentSymbol(item: ls.DocumentSymbol): languages.DocumentSymbol {
|
|||
};
|
||||
}
|
||||
|
||||
export class DocumentSymbolAdapter implements languages.DocumentSymbolProvider {
|
||||
constructor(private _worker: WorkerAccessor) {}
|
||||
|
||||
provideDocumentSymbols(model: editor.IReadOnlyModel): PromiseLike<languages.DocumentSymbol[]> {
|
||||
const resource = model.uri;
|
||||
|
||||
return this._worker(resource)
|
||||
.then((worker) => worker.findDocumentSymbols(String(resource)))
|
||||
.then((items) => {
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
return items.map((item) => toDocumentSymbol(item));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function fromFormattingOptions(
|
||||
options: languages.FormattingOptions
|
||||
): ls.FormattingOptions & CustomFormatterOptions {
|
||||
options: languages.FormattingOptions,
|
||||
): CustomFormatterOptions & ls.FormattingOptions {
|
||||
return {
|
||||
tabSize: options.tabSize,
|
||||
insertSpaces: options.insertSpaces,
|
||||
|
|
@ -519,27 +435,23 @@ function fromFormattingOptions(
|
|||
};
|
||||
}
|
||||
|
||||
export class DocumentFormattingEditProvider
|
||||
implements languages.DocumentFormattingEditProvider {
|
||||
export class DocumentFormattingEditProvider implements languages.DocumentFormattingEditProvider {
|
||||
constructor(private _worker: WorkerAccessor) {}
|
||||
|
||||
public provideDocumentFormattingEdits(
|
||||
provideDocumentFormattingEdits(
|
||||
model: editor.IReadOnlyModel,
|
||||
options: languages.FormattingOptions,
|
||||
token: CancellationToken
|
||||
): PromiseLike<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);
|
||||
});
|
||||
});
|
||||
return this._worker(resource).then((worker) =>
|
||||
worker.format(String(resource), null, fromFormattingOptions(options)).then((edits) => {
|
||||
if (!edits || edits.length === 0) {
|
||||
return;
|
||||
}
|
||||
return edits.map(toTextEdit);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -547,87 +459,22 @@ export class DocumentRangeFormattingEditProvider
|
|||
implements languages.DocumentRangeFormattingEditProvider {
|
||||
constructor(private _worker: WorkerAccessor) {}
|
||||
|
||||
public provideDocumentRangeFormattingEdits(
|
||||
provideDocumentRangeFormattingEdits(
|
||||
model: editor.IReadOnlyModel,
|
||||
range: Range,
|
||||
options: languages.FormattingOptions,
|
||||
token: CancellationToken
|
||||
): PromiseLike<editor.ISingleEditOperation[]> {
|
||||
const resource = model.uri;
|
||||
|
||||
return this._worker(resource).then((worker) => {
|
||||
return worker
|
||||
.format(
|
||||
resource.toString(),
|
||||
fromRange(range),
|
||||
fromFormattingOptions(options)
|
||||
)
|
||||
return this._worker(resource).then((worker) =>
|
||||
worker
|
||||
.format(String(resource), 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
|
||||
// ): PromiseLike<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
|
||||
// ): PromiseLike<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 => {
|
||||
// const 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;
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -1,33 +1,15 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
import { Emitter, IEvent, languages } from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
|
||||
import {
|
||||
languages,
|
||||
Emitter,
|
||||
IEvent,
|
||||
} from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import { setupMode } from './yamlMode';
|
||||
|
||||
declare var require: <T>(
|
||||
moduleId: [string],
|
||||
callback: (module: T) => void
|
||||
) => void;
|
||||
|
||||
// --- YAML configuration and defaults ---------
|
||||
|
||||
export class LanguageServiceDefaultsImpl
|
||||
implements languages.yaml.LanguageServiceDefaults {
|
||||
export class LanguageServiceDefaultsImpl implements languages.yaml.LanguageServiceDefaults {
|
||||
private _onDidChange = new Emitter<languages.yaml.LanguageServiceDefaults>();
|
||||
private _diagnosticsOptions: languages.yaml.DiagnosticsOptions;
|
||||
private _languageId: string;
|
||||
|
||||
constructor(
|
||||
languageId: string,
|
||||
diagnosticsOptions: languages.yaml.DiagnosticsOptions
|
||||
) {
|
||||
constructor(languageId: string, diagnosticsOptions: languages.yaml.DiagnosticsOptions) {
|
||||
this._languageId = languageId;
|
||||
this.setDiagnosticsOptions(diagnosticsOptions);
|
||||
}
|
||||
|
|
@ -44,9 +26,7 @@ export class LanguageServiceDefaultsImpl
|
|||
return this._diagnosticsOptions;
|
||||
}
|
||||
|
||||
public setDiagnosticsOptions(
|
||||
options: languages.yaml.DiagnosticsOptions
|
||||
): void {
|
||||
setDiagnosticsOptions(options: languages.yaml.DiagnosticsOptions): void {
|
||||
this._diagnosticsOptions = options || Object.create(null);
|
||||
this._onDidChange.fire(this);
|
||||
}
|
||||
|
|
|
|||
21
src/monaco.d.ts
vendored
21
src/monaco.d.ts
vendored
|
|
@ -1,38 +1,35 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IEvent } from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
|
||||
declare module 'monaco-editor/esm/vs/editor/editor.api' {
|
||||
namespace languages.yaml {
|
||||
export interface DiagnosticsOptions {
|
||||
/**
|
||||
* If set, the validator will be enabled and perform syntax validation as well as schema based validation.
|
||||
* If set, the validator will be enabled and perform syntax validation as well as schema
|
||||
* based validation.
|
||||
*/
|
||||
readonly validate?: boolean;
|
||||
|
||||
/**
|
||||
* A list of known schemas and/or associations of schemas to file names.
|
||||
*/
|
||||
readonly schemas?: Array<{
|
||||
readonly schemas?: {
|
||||
/**
|
||||
* The URI of the schema, which is also the identifier of the schema.
|
||||
*/
|
||||
readonly uri: string;
|
||||
/**
|
||||
* A list of file names that are associated to the schema. The '*' wildcard can be used. For example '*.schema.json', 'package.json'
|
||||
* A list of file names that are associated to the schema. The '*' wildcard can be used.
|
||||
* For example '*.schema.json', 'package.json'
|
||||
*/
|
||||
readonly fileMatch?: string[];
|
||||
/**
|
||||
* The schema for the given URI.
|
||||
*/
|
||||
readonly schema?: any;
|
||||
}>;
|
||||
readonly schema?: unknown;
|
||||
}[];
|
||||
|
||||
/**
|
||||
* If set, the schema service would load schema content on-demand with 'fetch' if available
|
||||
* If set, the schema service would load schema content on-demand with 'fetch' if available
|
||||
*/
|
||||
readonly enableSchemaRequest?: boolean;
|
||||
/**
|
||||
|
|
@ -50,7 +47,7 @@ declare module 'monaco-editor/esm/vs/editor/editor.api' {
|
|||
export interface LanguageServiceDefaults {
|
||||
readonly onDidChange: IEvent<LanguageServiceDefaults>;
|
||||
readonly diagnosticsOptions: DiagnosticsOptions;
|
||||
setDiagnosticsOptions(options: DiagnosticsOptions): void;
|
||||
setDiagnosticsOptions: (options: DiagnosticsOptions) => void;
|
||||
}
|
||||
|
||||
export const yamlDefaults: LanguageServiceDefaults;
|
||||
|
|
|
|||
|
|
@ -1,18 +1,10 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
import { editor, IDisposable, Uri } from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
|
||||
import {
|
||||
editor,
|
||||
Uri,
|
||||
IDisposable,
|
||||
} from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import { LanguageServiceDefaultsImpl } from './monaco.contribution';
|
||||
import { YAMLWorker } from './yamlWorker';
|
||||
|
||||
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min
|
||||
// 2min
|
||||
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000;
|
||||
|
||||
export class WorkerManager {
|
||||
private _defaults: LanguageServiceDefaultsImpl;
|
||||
|
|
@ -28,27 +20,23 @@ export class WorkerManager {
|
|||
this._worker = null;
|
||||
this._idleCheckInterval = setInterval(() => this._checkIfIdle(), 30 * 1000);
|
||||
this._lastUsedTime = 0;
|
||||
this._configChangeListener = this._defaults.onDidChange(() =>
|
||||
this._stopWorker()
|
||||
);
|
||||
this._configChangeListener = this._defaults.onDidChange(() => this._stopWorker());
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
dispose(): void {
|
||||
clearInterval(this._idleCheckInterval);
|
||||
this._configChangeListener.dispose();
|
||||
this._stopWorker();
|
||||
}
|
||||
|
||||
public getLanguageServiceWorker(...resources: Uri[]): Promise<YAMLWorker> {
|
||||
getLanguageServiceWorker(...resources: Uri[]): Promise<YAMLWorker> {
|
||||
let _client: YAMLWorker;
|
||||
return this._getClient()
|
||||
.then((client) => {
|
||||
_client = client;
|
||||
})
|
||||
.then((_) => {
|
||||
return this._worker.withSyncedResources(resources);
|
||||
})
|
||||
.then((_) => _client);
|
||||
.then(() => this._worker.withSyncedResources(resources))
|
||||
.then(() => _client);
|
||||
}
|
||||
|
||||
private _stopWorker(): void {
|
||||
|
|
@ -74,17 +62,16 @@ export class WorkerManager {
|
|||
|
||||
if (!this._client) {
|
||||
this._worker = editor.createWebWorker<YAMLWorker>({
|
||||
// module that exports the create() method and returns a `YAMLWorker` instance
|
||||
// Module that exports the create() method and returns a `YAMLWorker` instance
|
||||
moduleId: 'vs/language/yaml/yamlWorker',
|
||||
|
||||
label: this._defaults.languageId,
|
||||
|
||||
// passed in to the create() method
|
||||
// Passed in to the create() method
|
||||
createData: {
|
||||
languageSettings: this._defaults.diagnosticsOptions,
|
||||
languageId: this._defaults.languageId,
|
||||
enableSchemaRequest: this._defaults.diagnosticsOptions
|
||||
.enableSchemaRequest,
|
||||
enableSchemaRequest: this._defaults.diagnosticsOptions.enableSchemaRequest,
|
||||
prefix: this._defaults.diagnosticsOptions.prefix,
|
||||
isKubernetes: this._defaults.diagnosticsOptions.isKubernetes,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,15 +1,8 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as worker from 'monaco-editor/esm/vs/editor/editor.worker';
|
||||
|
||||
import { YAMLWorker } from './yamlWorker';
|
||||
|
||||
self.onmessage = () => {
|
||||
// ignore the first message
|
||||
worker.initialize((ctx, createData) => {
|
||||
return new YAMLWorker(ctx, createData);
|
||||
});
|
||||
// Ignore the first message
|
||||
worker.initialize((ctx, createData) => new YAMLWorker(ctx, createData));
|
||||
};
|
||||
|
|
|
|||
108
src/yamlMode.ts
108
src/yamlMode.ts
|
|
@ -1,74 +1,10 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
import { IDisposable, languages, Uri } from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
|
||||
import {
|
||||
languages,
|
||||
Uri,
|
||||
IDisposable,
|
||||
} from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import * as languageFeatures from './languageFeatures';
|
||||
import { LanguageServiceDefaultsImpl } from './monaco.contribution';
|
||||
import { WorkerManager } from './workerManager';
|
||||
import { YAMLWorker } from './yamlWorker';
|
||||
|
||||
export function setupMode(defaults: LanguageServiceDefaultsImpl): void {
|
||||
const disposables: IDisposable[] = [];
|
||||
|
||||
const client = new WorkerManager(defaults);
|
||||
disposables.push(client);
|
||||
|
||||
const worker: languageFeatures.WorkerAccessor = (
|
||||
...uris: Uri[]
|
||||
): Promise<YAMLWorker> => {
|
||||
return client.getLanguageServiceWorker(...uris);
|
||||
};
|
||||
|
||||
const languageId = defaults.languageId;
|
||||
|
||||
disposables.push(
|
||||
languages.registerCompletionItemProvider(
|
||||
languageId,
|
||||
new languageFeatures.CompletionAdapter(worker)
|
||||
)
|
||||
);
|
||||
disposables.push(
|
||||
languages.registerHoverProvider(
|
||||
languageId,
|
||||
new languageFeatures.HoverAdapter(worker)
|
||||
)
|
||||
);
|
||||
disposables.push(
|
||||
languages.registerDocumentSymbolProvider(
|
||||
languageId,
|
||||
new languageFeatures.DocumentSymbolAdapter(worker)
|
||||
)
|
||||
);
|
||||
disposables.push(
|
||||
languages.registerDocumentFormattingEditProvider(
|
||||
languageId,
|
||||
new languageFeatures.DocumentFormattingEditProvider(worker)
|
||||
)
|
||||
);
|
||||
disposables.push(
|
||||
languages.registerDocumentRangeFormattingEditProvider(
|
||||
languageId,
|
||||
new languageFeatures.DocumentRangeFormattingEditProvider(worker)
|
||||
)
|
||||
);
|
||||
disposables.push(
|
||||
new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults)
|
||||
);
|
||||
disposables.push(
|
||||
languages.setLanguageConfiguration(languageId, richEditConfiguration)
|
||||
);
|
||||
|
||||
// Color adapter should be necessary most of the time:
|
||||
// disposables.push(languages.registerColorProvider(languageId, new languageFeatures.DocumentColorAdapter(worker)));
|
||||
}
|
||||
|
||||
const richEditConfiguration: languages.LanguageConfiguration = {
|
||||
comments: {
|
||||
lineComment: '#',
|
||||
|
|
@ -100,3 +36,45 @@ const richEditConfiguration: languages.LanguageConfiguration = {
|
|||
},
|
||||
],
|
||||
};
|
||||
|
||||
export function setupMode(defaults: LanguageServiceDefaultsImpl): void {
|
||||
const disposables: IDisposable[] = [];
|
||||
|
||||
const client = new WorkerManager(defaults);
|
||||
disposables.push(client);
|
||||
|
||||
const worker: languageFeatures.WorkerAccessor = (...uris: Uri[]): Promise<YAMLWorker> =>
|
||||
client.getLanguageServiceWorker(...uris);
|
||||
|
||||
const { languageId } = defaults;
|
||||
|
||||
disposables.push(
|
||||
languages.registerCompletionItemProvider(
|
||||
languageId,
|
||||
new languageFeatures.CompletionAdapter(worker),
|
||||
),
|
||||
languages.registerHoverProvider(languageId, new languageFeatures.HoverAdapter(worker)),
|
||||
languages.registerDocumentSymbolProvider(
|
||||
languageId,
|
||||
new languageFeatures.DocumentSymbolAdapter(worker),
|
||||
),
|
||||
languages.registerDocumentFormattingEditProvider(
|
||||
languageId,
|
||||
new languageFeatures.DocumentFormattingEditProvider(worker),
|
||||
),
|
||||
languages.registerDocumentRangeFormattingEditProvider(
|
||||
languageId,
|
||||
new languageFeatures.DocumentRangeFormattingEditProvider(worker),
|
||||
),
|
||||
new languageFeatures.DiagnosticsAdapter(languageId, worker, defaults),
|
||||
languages.setLanguageConfiguration(languageId, richEditConfiguration),
|
||||
);
|
||||
|
||||
// Color adapter should be necessary most of the time:
|
||||
// disposables.push(
|
||||
// languages.registerColorProvider(
|
||||
// languageId,
|
||||
// new languageFeatures.DocumentColorAdapter(worker)
|
||||
// )
|
||||
// );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,11 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) Adam Voss. All rights reserved.
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { worker } from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import * as ls from 'vscode-languageserver-types';
|
||||
import * as yamlService from 'yaml-language-server';
|
||||
|
||||
let defaultSchemaRequestService;
|
||||
let defaultSchemaRequestService: (url: string) => PromiseLike<string>;
|
||||
|
||||
if (typeof fetch !== 'undefined') {
|
||||
defaultSchemaRequestService = function (url) {
|
||||
return fetch(url).then((response) => response.text());
|
||||
};
|
||||
defaultSchemaRequestService = (url) => fetch(url).then((response) => response.text());
|
||||
}
|
||||
|
||||
export class YAMLWorker {
|
||||
|
|
@ -26,7 +17,7 @@ export class YAMLWorker {
|
|||
|
||||
constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
|
||||
const prefix = createData.prefix || '';
|
||||
const service = (url: string) =>
|
||||
const service = (url: string): PromiseLike<string> =>
|
||||
defaultSchemaRequestService(`${prefix}${url}`);
|
||||
this._ctx = ctx;
|
||||
this._languageSettings = createData.languageSettings;
|
||||
|
|
@ -34,7 +25,7 @@ export class YAMLWorker {
|
|||
this._languageService = yamlService.getLanguageService(
|
||||
createData.enableSchemaRequest && service,
|
||||
null,
|
||||
[]
|
||||
[],
|
||||
);
|
||||
this._isKubernetes = createData.isKubernetes || false;
|
||||
this._languageService.configure({
|
||||
|
|
@ -44,7 +35,7 @@ export class YAMLWorker {
|
|||
});
|
||||
}
|
||||
|
||||
public doValidation(uri: string): PromiseLike<ls.Diagnostic[]> {
|
||||
doValidation(uri: string): PromiseLike<ls.Diagnostic[]> {
|
||||
const document = this._getTextDocument(uri);
|
||||
if (document) {
|
||||
return this._languageService.doValidation(document, this._isKubernetes);
|
||||
|
|
@ -52,42 +43,35 @@ export class YAMLWorker {
|
|||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
public doComplete(
|
||||
uri: string,
|
||||
position: ls.Position
|
||||
): PromiseLike<ls.CompletionList> {
|
||||
doComplete(uri: string, position: ls.Position): PromiseLike<ls.CompletionList> {
|
||||
const document = this._getTextDocument(uri);
|
||||
return this._languageService.doComplete(
|
||||
document,
|
||||
position,
|
||||
this._isKubernetes
|
||||
);
|
||||
return this._languageService.doComplete(document, position, this._isKubernetes);
|
||||
}
|
||||
|
||||
public doResolve(item: ls.CompletionItem): PromiseLike<ls.CompletionItem> {
|
||||
doResolve(item: ls.CompletionItem): PromiseLike<ls.CompletionItem> {
|
||||
return this._languageService.doResolve(item);
|
||||
}
|
||||
|
||||
public doHover(uri: string, position: ls.Position): PromiseLike<ls.Hover> {
|
||||
doHover(uri: string, position: ls.Position): PromiseLike<ls.Hover> {
|
||||
const document = this._getTextDocument(uri);
|
||||
return this._languageService.doHover(document, position);
|
||||
}
|
||||
|
||||
public format(
|
||||
format(
|
||||
uri: string,
|
||||
range: ls.Range,
|
||||
options: yamlService.CustomFormatterOptions
|
||||
options: yamlService.CustomFormatterOptions,
|
||||
): PromiseLike<ls.TextEdit[]> {
|
||||
const document = this._getTextDocument(uri);
|
||||
const textEdits = this._languageService.doFormat(document, options);
|
||||
return Promise.resolve(textEdits);
|
||||
}
|
||||
|
||||
public resetSchema(uri: string): PromiseLike<boolean> {
|
||||
resetSchema(uri: string): PromiseLike<boolean> {
|
||||
return Promise.resolve(this._languageService.resetSchema(uri));
|
||||
}
|
||||
|
||||
public findDocumentSymbols(uri: string): PromiseLike<ls.DocumentSymbol[]> {
|
||||
findDocumentSymbols(uri: string): PromiseLike<ls.DocumentSymbol[]> {
|
||||
const document = this._getTextDocument(uri);
|
||||
const symbols = this._languageService.findDocumentSymbols2(document);
|
||||
return Promise.resolve(symbols);
|
||||
|
|
@ -96,13 +80,8 @@ export class YAMLWorker {
|
|||
private _getTextDocument(uri: string): ls.TextDocument {
|
||||
const models = this._ctx.getMirrorModels();
|
||||
for (const model of models) {
|
||||
if (model.uri.toString() === uri) {
|
||||
return ls.TextDocument.create(
|
||||
uri,
|
||||
this._languageId,
|
||||
model.version,
|
||||
model.getValue()
|
||||
);
|
||||
if (String(model.uri) === uri) {
|
||||
return ls.TextDocument.create(uri, this._languageId, model.version, model.getValue());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
@ -117,9 +96,6 @@ export interface ICreateData {
|
|||
isKubernetes?: boolean;
|
||||
}
|
||||
|
||||
export function create(
|
||||
ctx: worker.IWorkerContext,
|
||||
createData: ICreateData
|
||||
): YAMLWorker {
|
||||
export function create(ctx: worker.IWorkerContext, createData: ICreateData): YAMLWorker {
|
||||
return new YAMLWorker(ctx, createData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
"downlevelIteration": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"lib": ["dom", "es2016"],
|
||||
"lib": ["dom", "es2017"],
|
||||
"outDir": "./out/esm",
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
|
|
|
|||
Loading…
Reference in a new issue