mirror of
https://github.com/danbulant/monaco-yaml
synced 2026-07-06 03:20:43 +00:00
chore: upgrade dependencies and bump version to 1.2.0
This commit is contained in:
parent
21933e3875
commit
fb04c29c52
18 changed files with 175 additions and 333 deletions
|
|
@ -7,7 +7,7 @@ YAML language plugin for the Monaco Editor. It provides the following features w
|
||||||
* Formatting
|
* Formatting
|
||||||
* Document Symbols
|
* Document Symbols
|
||||||
* Syntax highlighting
|
* Syntax highlighting
|
||||||
* Automatically load remote schema files
|
* 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)
|
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.
|
for the API that the JSON plugin offers to configure the JSON language support.
|
||||||
|
|
|
||||||
14
package.json
14
package.json
|
|
@ -1,11 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "monaco-yaml",
|
"name": "monaco-yaml",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"description": "YAML plugin for the Monaco Editor",
|
"description": "YAML plugin for the Monaco Editor",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"compile": "rimraf ./out && tsc -p ./src/tsconfig.json && tsc -p ./src/tsconfig.esm.json",
|
"compile": "rimraf ./out && yarn compile:umd && yarn compile:esm",
|
||||||
|
"compile:umd": "tsc -p ./src/tsconfig.json",
|
||||||
|
"compile:esm": "tsc -p ./src/tsconfig.esm.json",
|
||||||
"watch": "tsc -p ./src --watch",
|
"watch": "tsc -p ./src --watch",
|
||||||
"prepublish": "rimraf ./release && yarn run compile && node ./scripts/release.js && node ./scripts/bundle && mcopy ./src/monaco.d.ts ./release/monaco.d.ts"
|
"prepublish": "rimraf ./out && rimraf ./release && yarn compile:umd && node ./scripts/bundle && mcopy ./src/monaco.d.ts ./release/monaco.d.ts"
|
||||||
},
|
},
|
||||||
"author": "Kevin Decker <kpdecker@gmail.com> (http://incaseofstairs.com)",
|
"author": "Kevin Decker <kpdecker@gmail.com> (http://incaseofstairs.com)",
|
||||||
"maintainers": [
|
"maintainers": [
|
||||||
|
|
@ -26,12 +28,12 @@
|
||||||
"@types/node": "^10.9.3",
|
"@types/node": "^10.9.3",
|
||||||
"js-yaml": "^3.12.0",
|
"js-yaml": "^3.12.0",
|
||||||
"jsonc-parser": "^2.0.2",
|
"jsonc-parser": "^2.0.2",
|
||||||
"monaco-editor-core": "0.14.6",
|
"monaco-editor-core": "0.15.0",
|
||||||
"monaco-languages": "1.5.1",
|
"monaco-languages": "1.6.0",
|
||||||
"monaco-plugin-helpers": "^1.0.2",
|
"monaco-plugin-helpers": "^1.0.2",
|
||||||
"requirejs": "^2.3.5",
|
"requirejs": "^2.3.5",
|
||||||
"rimraf": "^2.6.2",
|
"rimraf": "^2.6.2",
|
||||||
"typescript": "^3.0.3",
|
"typescript": "^3.1.6",
|
||||||
"uglify-es": "^3.3.9",
|
"uglify-es": "^3.3.9",
|
||||||
"vscode-json-languageservice": "^3.1.6",
|
"vscode-json-languageservice": "^3.1.6",
|
||||||
"vscode-languageserver-types": "3.12.0"
|
"vscode-languageserver-types": "3.12.0"
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import Position = monaco.Position;
|
||||||
import Range = monaco.Range;
|
import Range = monaco.Range;
|
||||||
import IRange = monaco.IRange;
|
import IRange = monaco.IRange;
|
||||||
import Thenable = monaco.Thenable;
|
import Thenable = monaco.Thenable;
|
||||||
import Promise = monaco.Promise;
|
|
||||||
import CancellationToken = monaco.CancellationToken;
|
import CancellationToken = monaco.CancellationToken;
|
||||||
import IDisposable = monaco.IDisposable;
|
import IDisposable = monaco.IDisposable;
|
||||||
|
|
||||||
|
|
@ -225,54 +224,6 @@ function toTextEdit(textEdit: ls.TextEdit): monaco.editor.ISingleEditOperation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DataCompletionItem extends monaco.languages.CompletionItem {
|
|
||||||
data?: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toCompletionItem(entry: ls.CompletionItem): DataCompletionItem {
|
|
||||||
return {
|
|
||||||
label: entry.label,
|
|
||||||
insertText: entry.insertText,
|
|
||||||
sortText: entry.sortText,
|
|
||||||
filterText: entry.filterText,
|
|
||||||
documentation: entry.documentation,
|
|
||||||
detail: entry.detail,
|
|
||||||
kind: toCompletionItemKind(entry.kind),
|
|
||||||
textEdit: toTextEdit(entry.textEdit),
|
|
||||||
data: entry.data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromMarkdownString(entry: string | monaco.IMarkdownString): ls.MarkupContent {
|
|
||||||
return {
|
|
||||||
kind: (typeof entry === 'string' ? ls.MarkupKind.PlainText : ls.MarkupKind.Markdown),
|
|
||||||
value: (typeof entry === 'string' ? entry : entry.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromCompletionItem(entry: DataCompletionItem): ls.CompletionItem {
|
|
||||||
let item: ls.CompletionItem = {
|
|
||||||
label: entry.label,
|
|
||||||
sortText: entry.sortText,
|
|
||||||
filterText: entry.filterText,
|
|
||||||
documentation: fromMarkdownString(entry.documentation),
|
|
||||||
detail: entry.detail,
|
|
||||||
kind: fromCompletionItemKind(entry.kind),
|
|
||||||
data: entry.data
|
|
||||||
};
|
|
||||||
if (typeof entry.insertText === 'object' && typeof entry.insertText.value === 'string') {
|
|
||||||
item.insertText = entry.insertText.value;
|
|
||||||
item.insertTextFormat = ls.InsertTextFormat.Snippet
|
|
||||||
} else {
|
|
||||||
item.insertText = <string>entry.insertText;
|
|
||||||
}
|
|
||||||
if (entry.range) {
|
|
||||||
item.textEdit = ls.TextEdit.replace(fromRange(entry.range), item.insertText);
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export class CompletionAdapter implements monaco.languages.CompletionItemProvider {
|
export class CompletionAdapter implements monaco.languages.CompletionItemProvider {
|
||||||
|
|
||||||
constructor(private _worker: WorkerAccessor) {
|
constructor(private _worker: WorkerAccessor) {
|
||||||
|
|
@ -282,11 +233,11 @@ export class CompletionAdapter implements monaco.languages.CompletionItemProvide
|
||||||
return [' ', ':'];
|
return [' ', ':'];
|
||||||
}
|
}
|
||||||
|
|
||||||
provideCompletionItems(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<monaco.languages.CompletionList> {
|
provideCompletionItems(model: monaco.editor.IReadOnlyModel, position: Position, context: monaco.languages.CompletionContext, token: CancellationToken): Thenable<monaco.languages.CompletionList> {
|
||||||
const wordInfo = model.getWordUntilPosition(position);
|
const wordInfo = model.getWordUntilPosition(position);
|
||||||
const resource = model.uri;
|
const resource = model.uri;
|
||||||
|
|
||||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
return this._worker(resource).then(worker => {
|
||||||
return worker.doComplete(resource.toString(), fromPosition(position));
|
return worker.doComplete(resource.toString(), fromPosition(position));
|
||||||
}).then(info => {
|
}).then(info => {
|
||||||
if (!info) {
|
if (!info) {
|
||||||
|
|
@ -295,7 +246,7 @@ export class CompletionAdapter implements monaco.languages.CompletionItemProvide
|
||||||
let items: monaco.languages.CompletionItem[] = info.items.map(entry => {
|
let items: monaco.languages.CompletionItem[] = info.items.map(entry => {
|
||||||
let item: monaco.languages.CompletionItem = {
|
let item: monaco.languages.CompletionItem = {
|
||||||
label: entry.label,
|
label: entry.label,
|
||||||
insertText: entry.insertText,
|
insertText: entry.insertText || entry.label,
|
||||||
sortText: entry.sortText,
|
sortText: entry.sortText,
|
||||||
filterText: entry.filterText,
|
filterText: entry.filterText,
|
||||||
documentation: entry.documentation,
|
documentation: entry.documentation,
|
||||||
|
|
@ -306,17 +257,20 @@ export class CompletionAdapter implements monaco.languages.CompletionItemProvide
|
||||||
item.range = toRange(entry.textEdit.range);
|
item.range = toRange(entry.textEdit.range);
|
||||||
item.insertText = entry.textEdit.newText;
|
item.insertText = entry.textEdit.newText;
|
||||||
}
|
}
|
||||||
|
if (entry.additionalTextEdits) {
|
||||||
|
item.additionalTextEdits = entry.additionalTextEdits.map(toTextEdit)
|
||||||
|
}
|
||||||
if (entry.insertTextFormat === ls.InsertTextFormat.Snippet) {
|
if (entry.insertTextFormat === ls.InsertTextFormat.Snippet) {
|
||||||
item.insertText = { value: <string>item.insertText };
|
item.insertTextRules = monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet;
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isIncomplete: info.isIncomplete,
|
isIncomplete: info.isIncomplete,
|
||||||
items: items
|
suggestions: items
|
||||||
};
|
};
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -359,13 +313,12 @@ function toMarkedStringArray(contents: ls.MarkupContent | ls.MarkedString | ls.M
|
||||||
|
|
||||||
export class HoverAdapter implements monaco.languages.HoverProvider {
|
export class HoverAdapter implements monaco.languages.HoverProvider {
|
||||||
|
|
||||||
constructor(private _worker: WorkerAccessor) {
|
constructor(private _worker: WorkerAccessor) {}
|
||||||
}
|
|
||||||
|
|
||||||
provideHover(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<monaco.languages.Hover> {
|
provideHover(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<monaco.languages.Hover> {
|
||||||
let resource = model.uri;
|
let resource = model.uri;
|
||||||
|
|
||||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
return this._worker(resource).then(worker => {
|
||||||
return worker.doHover(resource.toString(), fromPosition(position));
|
return worker.doHover(resource.toString(), fromPosition(position));
|
||||||
}).then(info => {
|
}).then(info => {
|
||||||
if (!info) {
|
if (!info) {
|
||||||
|
|
@ -375,20 +328,10 @@ export class HoverAdapter implements monaco.languages.HoverProvider {
|
||||||
range: toRange(info.range),
|
range: toRange(info.range),
|
||||||
contents: toMarkedStringArray(info.contents)
|
contents: toMarkedStringArray(info.contents)
|
||||||
};
|
};
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- definition ------
|
|
||||||
|
|
||||||
function toLocation(location: ls.Location): monaco.languages.Location {
|
|
||||||
return {
|
|
||||||
uri: Uri.parse(location.uri),
|
|
||||||
range: toRange(location.range)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --- document symbols ------
|
// --- document symbols ------
|
||||||
|
|
||||||
function toSymbolKind(kind: ls.SymbolKind): monaco.languages.SymbolKind {
|
function toSymbolKind(kind: ls.SymbolKind): monaco.languages.SymbolKind {
|
||||||
|
|
@ -426,7 +369,7 @@ export class DocumentSymbolAdapter implements monaco.languages.DocumentSymbolPro
|
||||||
public provideDocumentSymbols(model: monaco.editor.IReadOnlyModel, token: CancellationToken): Thenable<monaco.languages.DocumentSymbol[]> {
|
public provideDocumentSymbols(model: monaco.editor.IReadOnlyModel, token: CancellationToken): Thenable<monaco.languages.DocumentSymbol[]> {
|
||||||
const resource = model.uri;
|
const resource = model.uri;
|
||||||
|
|
||||||
return wireCancellationToken(token, this._worker(resource).then(worker => worker.findDocumentSymbols(resource.toString())).then(items => {
|
return this._worker(resource).then(worker => worker.findDocumentSymbols(resource.toString())).then(items => {
|
||||||
if (!items) {
|
if (!items) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -438,7 +381,7 @@ export class DocumentSymbolAdapter implements monaco.languages.DocumentSymbolPro
|
||||||
range: toRange(item.location.range),
|
range: toRange(item.location.range),
|
||||||
selectionRange: toRange(item.location.range)
|
selectionRange: toRange(item.location.range)
|
||||||
}));
|
}));
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -458,14 +401,14 @@ export class DocumentFormattingEditProvider implements monaco.languages.Document
|
||||||
public provideDocumentFormattingEdits(model: monaco.editor.IReadOnlyModel, options: monaco.languages.FormattingOptions, token: CancellationToken): Thenable<monaco.editor.ISingleEditOperation[]> {
|
public provideDocumentFormattingEdits(model: monaco.editor.IReadOnlyModel, options: monaco.languages.FormattingOptions, token: CancellationToken): Thenable<monaco.editor.ISingleEditOperation[]> {
|
||||||
const resource = model.uri;
|
const resource = model.uri;
|
||||||
|
|
||||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
return this._worker(resource).then(worker => {
|
||||||
return worker.format(resource.toString(), null, fromFormattingOptions(options)).then(edits => {
|
return worker.format(resource.toString(), null, fromFormattingOptions(options)).then(edits => {
|
||||||
if (!edits || edits.length === 0) {
|
if (!edits || edits.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return edits.map(toTextEdit);
|
return edits.map(toTextEdit);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -477,23 +420,13 @@ export class DocumentRangeFormattingEditProvider implements monaco.languages.Doc
|
||||||
public provideDocumentRangeFormattingEdits(model: monaco.editor.IReadOnlyModel, range: Range, options: monaco.languages.FormattingOptions, token: CancellationToken): Thenable<monaco.editor.ISingleEditOperation[]> {
|
public provideDocumentRangeFormattingEdits(model: monaco.editor.IReadOnlyModel, range: Range, options: monaco.languages.FormattingOptions, token: CancellationToken): Thenable<monaco.editor.ISingleEditOperation[]> {
|
||||||
const resource = model.uri;
|
const resource = model.uri;
|
||||||
|
|
||||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
return this._worker(resource).then(worker => {
|
||||||
return worker.format(resource.toString(), fromRange(range), fromFormattingOptions(options)).then(edits => {
|
return worker.format(resource.toString(), fromRange(range), fromFormattingOptions(options)).then(edits => {
|
||||||
if (!edits || edits.length === 0) {
|
if (!edits || edits.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return edits.map(toTextEdit);
|
return edits.map(toTextEdit);
|
||||||
});
|
});
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook a cancellation token to a WinJS Promise
|
|
||||||
*/
|
|
||||||
function wireCancellationToken<T>(token: CancellationToken, promise: Thenable<T>): Thenable<T> {
|
|
||||||
if ((<Promise<T>>promise).cancel) {
|
|
||||||
token.onCancellationRequested(() => (<Promise<T>>promise).cancel());
|
|
||||||
}
|
|
||||||
return promise;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -835,7 +835,7 @@ export interface ISchemaCollector {
|
||||||
schemas: IApplicableSchema[];
|
schemas: IApplicableSchema[];
|
||||||
add(schema: IApplicableSchema): void;
|
add(schema: IApplicableSchema): void;
|
||||||
merge(other: ISchemaCollector): void;
|
merge(other: ISchemaCollector): void;
|
||||||
include(node: ASTNode): void;
|
include(node: ASTNode): boolean;
|
||||||
newSub(): ISchemaCollector;
|
newSub(): ISchemaCollector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
16
src/languageservice/parser/scalar-type.ts
Normal file
16
src/languageservice/parser/scalar-type.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
/**
|
||||||
|
* Parse a boolean according to the specification
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* true if its a true value
|
||||||
|
* false if its a false value
|
||||||
|
*/
|
||||||
|
export function parseYamlBoolean(input: string): boolean {
|
||||||
|
if (["true", "True", "TRUE", 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON'].lastIndexOf(input) >= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (["false", "False", "FALSE", 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'].lastIndexOf(input) >= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw `Invalid boolean "${input}"`
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,7 @@ import { Kind } from '../../yaml-ast-parser/index'
|
||||||
import { Schema, Type } from 'js-yaml';
|
import { Schema, Type } from 'js-yaml';
|
||||||
|
|
||||||
import { getLineStartPositions, getPosition } from '../utils/documentPositionCalculator'
|
import { getLineStartPositions, getPosition } from '../utils/documentPositionCalculator'
|
||||||
import YAMLException from '../../yaml-ast-parser/exception';
|
import { parseYamlBoolean } from './scalar-type';
|
||||||
|
|
||||||
export class SingleYAMLDocument extends JSONDocument {
|
export class SingleYAMLDocument extends JSONDocument {
|
||||||
private lines;
|
private lines;
|
||||||
|
|
@ -153,8 +153,8 @@ function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode): ASTNode {
|
||||||
|
|
||||||
//This is a patch for redirecting values with these strings to be boolean nodes because its not supported in the parser.
|
//This is a patch for redirecting values with these strings to be boolean nodes because its not supported in the parser.
|
||||||
let possibleBooleanValues = ['y', 'Y', 'yes', 'Yes', 'YES', 'n', 'N', 'no', 'No', 'NO', 'on', 'On', 'ON', 'off', 'Off', 'OFF'];
|
let possibleBooleanValues = ['y', 'Y', 'yes', 'Yes', 'YES', 'n', 'N', 'no', 'No', 'NO', 'on', 'On', 'ON', 'off', 'Off', 'OFF'];
|
||||||
if (possibleBooleanValues.indexOf(value.toString()) !== -1) {
|
if (instance.plainScalar && possibleBooleanValues.indexOf(value.toString()) !== -1) {
|
||||||
return new BooleanASTNode(parent, name, value, node.startPosition, node.endPosition)
|
return new BooleanASTNode(parent, name, parseYamlBoolean(value), node.startPosition, node.endPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
@ -199,7 +199,7 @@ function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode): ASTNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertError(e: YAMLException) {
|
function convertError(e: Yaml.Error) {
|
||||||
return { message: `${e.reason}`, location: { start: e.mark.position, end: e.mark.position + e.mark.column, code: ErrorCode.Undefined } }
|
return { message: `${e.reason}`, location: { start: e.mark.position, end: e.mark.position + e.mark.column, code: ErrorCode.Undefined } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,7 +215,7 @@ function createJSONDocument(yamlDoc: Yaml.YAMLNode, startPositions: number[], te
|
||||||
const duplicateKeyReason = 'duplicate key'
|
const duplicateKeyReason = 'duplicate key'
|
||||||
|
|
||||||
//Patch ontop of yaml-ast-parser to disable duplicate key message on merge key
|
//Patch ontop of yaml-ast-parser to disable duplicate key message on merge key
|
||||||
let isDuplicateAndNotMergeKey = function (error: YAMLException, yamlText: string) {
|
let isDuplicateAndNotMergeKey = function (error: Yaml.Error, yamlText: string) {
|
||||||
let errorConverted = convertError(error);
|
let errorConverted = convertError(error);
|
||||||
let errorStart = errorConverted.location.start;
|
let errorStart = errorConverted.location.start;
|
||||||
let errorEnd = errorConverted.location.end;
|
let errorEnd = errorConverted.location.end;
|
||||||
|
|
|
||||||
|
|
@ -243,14 +243,14 @@ export class JSONSchemaService implements IJSONSchemaService {
|
||||||
private callOnDispose: Function[];
|
private callOnDispose: Function[];
|
||||||
private requestService: SchemaRequestService;
|
private requestService: SchemaRequestService;
|
||||||
private promiseConstructor: PromiseConstructor;
|
private promiseConstructor: PromiseConstructor;
|
||||||
private customSchemaProvider: CustomSchemaProvider;
|
private customSchemaProvider: CustomSchemaProvider | undefined;
|
||||||
|
|
||||||
constructor(requestService: SchemaRequestService, contextService?: WorkspaceContextService, customSchemaProvider?: CustomSchemaProvider, promiseConstructor?: PromiseConstructor) {
|
constructor(requestService: SchemaRequestService, contextService?: WorkspaceContextService, promiseConstructor?: PromiseConstructor) {
|
||||||
this.contextService = contextService;
|
this.contextService = contextService;
|
||||||
this.requestService = requestService;
|
this.requestService = requestService;
|
||||||
this.promiseConstructor = promiseConstructor || Promise;
|
this.promiseConstructor = promiseConstructor || Promise;
|
||||||
this.callOnDispose = [];
|
this.callOnDispose = [];
|
||||||
this.customSchemaProvider = customSchemaProvider;
|
this.customSchemaProvider = undefined;
|
||||||
this.contributionSchemas = {};
|
this.contributionSchemas = {};
|
||||||
this.contributionAssociations = {};
|
this.contributionAssociations = {};
|
||||||
this.schemasById = {};
|
this.schemasById = {};
|
||||||
|
|
@ -259,6 +259,10 @@ export class JSONSchemaService implements IJSONSchemaService {
|
||||||
this.registeredSchemasIds = {};
|
this.registeredSchemasIds = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerCustomSchemaProvider(customSchemaProvider: CustomSchemaProvider) {
|
||||||
|
this.customSchemaProvider = customSchemaProvider;
|
||||||
|
}
|
||||||
|
|
||||||
public getRegisteredSchemaIds(filter?: (scheme) => boolean): string[] {
|
public getRegisteredSchemaIds(filter?: (scheme) => boolean): string[] {
|
||||||
return Object.keys(this.registeredSchemasIds).filter(id => {
|
return Object.keys(this.registeredSchemasIds).filter(id => {
|
||||||
let scheme = URI.parse(id).scheme;
|
let scheme = URI.parse(id).scheme;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import { CompletionItem, CompletionItemKind, CompletionList, TextDocument, Posit
|
||||||
|
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
import { matchOffsetToDocument } from '../utils/arrUtils';
|
import { matchOffsetToDocument } from '../utils/arrUtils';
|
||||||
|
import { LanguageSettings } from '../yamlLanguageService';
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -26,15 +27,20 @@ export class YAMLCompletion {
|
||||||
private contributions: JSONWorkerContribution[];
|
private contributions: JSONWorkerContribution[];
|
||||||
private promise: PromiseConstructor;
|
private promise: PromiseConstructor;
|
||||||
private customTags: Array<String>;
|
private customTags: Array<String>;
|
||||||
|
private completion: boolean;
|
||||||
|
|
||||||
constructor(schemaService: SchemaService.IJSONSchemaService, contributions: JSONWorkerContribution[] = [], promiseConstructor?: PromiseConstructor) {
|
constructor(schemaService: SchemaService.IJSONSchemaService, contributions: JSONWorkerContribution[] = [], promiseConstructor?: PromiseConstructor) {
|
||||||
this.schemaService = schemaService;
|
this.schemaService = schemaService;
|
||||||
this.contributions = contributions;
|
this.contributions = contributions;
|
||||||
this.promise = promiseConstructor || Promise;
|
this.promise = promiseConstructor || Promise;
|
||||||
this.customTags = [];
|
this.customTags = [];
|
||||||
|
this.completion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public configure(customTags: Array<String>){
|
public configure(languageSettings: LanguageSettings, customTags: Array<String>){
|
||||||
|
if (languageSettings) {
|
||||||
|
this.completion = languageSettings.completion;
|
||||||
|
}
|
||||||
this.customTags = customTags;
|
this.customTags = customTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,6 +63,10 @@ export class YAMLCompletion {
|
||||||
isIncomplete: false
|
isIncomplete: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!this.completion) {
|
||||||
|
return Promise.resolve(result);
|
||||||
|
}
|
||||||
|
|
||||||
let offset = document.offsetAt(position);
|
let offset = document.offsetAt(position);
|
||||||
if(document.getText()[offset] === ":"){
|
if(document.getText()[offset] === ":"){
|
||||||
return Promise.resolve(result);
|
return Promise.resolve(result);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
import * as jsyaml from 'js-yaml';
|
import * as jsyaml from 'js-yaml';
|
||||||
import * as Yaml from '../../yaml-ast-parser/index'
|
import * as Yaml from '../../yaml-ast-parser/index'
|
||||||
import { EOL } from '../../fillers/os';
|
import { EOL } from '../../fillers/os';
|
||||||
|
|
|
||||||
|
|
@ -13,23 +13,32 @@ import {PromiseConstructor, Thenable} from 'vscode-json-languageservice';
|
||||||
|
|
||||||
import {Hover, TextDocument, Position, Range, MarkedString} from 'vscode-languageserver-types';
|
import {Hover, TextDocument, Position, Range, MarkedString} from 'vscode-languageserver-types';
|
||||||
import { matchOffsetToDocument } from '../utils/arrUtils';
|
import { matchOffsetToDocument } from '../utils/arrUtils';
|
||||||
|
import { LanguageSettings } from '../yamlLanguageService';
|
||||||
|
|
||||||
export class YAMLHover {
|
export class YAMLHover {
|
||||||
|
|
||||||
private schemaService: SchemaService.IJSONSchemaService;
|
private schemaService: SchemaService.IJSONSchemaService;
|
||||||
private contributions: JSONWorkerContribution[];
|
private contributions: JSONWorkerContribution[];
|
||||||
private promise: PromiseConstructor;
|
private promise: PromiseConstructor;
|
||||||
|
private shouldHover: boolean;
|
||||||
|
|
||||||
constructor(schemaService: SchemaService.IJSONSchemaService, contributions: JSONWorkerContribution[] = [], promiseConstructor: PromiseConstructor) {
|
constructor(schemaService: SchemaService.IJSONSchemaService, contributions: JSONWorkerContribution[] = [], promiseConstructor: PromiseConstructor) {
|
||||||
this.schemaService = schemaService;
|
this.schemaService = schemaService;
|
||||||
this.contributions = contributions;
|
this.contributions = contributions;
|
||||||
this.promise = promiseConstructor || Promise;
|
this.promise = promiseConstructor || Promise;
|
||||||
|
this.shouldHover = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public configure(languageSettings: LanguageSettings){
|
||||||
|
if(languageSettings){
|
||||||
|
this.shouldHover = languageSettings.hover;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public doHover(document: TextDocument, position: Position, doc): Thenable<Hover> {
|
public doHover(document: TextDocument, position: Position, doc): Thenable<Hover> {
|
||||||
|
|
||||||
if(!document){
|
if(!this.shouldHover || !document){
|
||||||
this.promise.resolve(void 0);
|
return this.promise.resolve(void 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let offset = document.offsetAt(position);
|
let offset = document.offsetAt(position);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
* Copyright (c) Red Hat, Inc. All rights reserved.
|
* Copyright (c) Red Hat, Inc. All rights reserved.
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
export class ErrorHandler {
|
export class ErrorHandler {
|
||||||
private errorResultsList;
|
private errorResultsList;
|
||||||
private textDocument;
|
private textDocument;
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,22 @@
|
||||||
* Copyright (c) Microsoft Corporation. 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.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
import { JSONSchemaService } from "./services/jsonSchemaService";
|
|
||||||
import {
|
import { JSONSchemaService, CustomSchemaProvider } from './services/jsonSchemaService'
|
||||||
TextDocument,
|
import { TextDocument, Position, CompletionList, Diagnostic, FormattingOptions } from 'vscode-languageserver-types';
|
||||||
Position,
|
import { JSONSchema } from './jsonSchema';
|
||||||
CompletionList,
|
import { YAMLDocumentSymbols } from './services/documentSymbols';
|
||||||
FormattingOptions,
|
import { YAMLCompletion } from './services/yamlCompletion';
|
||||||
Diagnostic
|
import { YAMLHover } from './services/yamlHover';
|
||||||
} from "vscode-languageserver-types";
|
import { YAMLValidation } from './services/yamlValidation';
|
||||||
import { JSONSchema } from "./jsonSchema";
|
import { format } from './services/yamlFormatter';
|
||||||
import { YAMLDocumentSymbols } from "./services/documentSymbols";
|
import { JSONDocument } from 'vscode-json-languageservice';
|
||||||
import { YAMLCompletion } from "./services/yamlCompletion";
|
|
||||||
import { JSONDocument } from "vscode-json-languageservice";
|
|
||||||
import { YAMLHover } from "./services/yamlHover";
|
|
||||||
import { YAMLValidation } from "./services/yamlValidation";
|
|
||||||
import { format } from "./services/yamlFormatter";
|
|
||||||
import { parse as parseYAML } from "./parser/yamlParser";
|
import { parse as parseYAML } from "./parser/yamlParser";
|
||||||
|
|
||||||
export interface LanguageSettings {
|
export interface LanguageSettings {
|
||||||
validate?: boolean; //Setting for whether we want to validate the schema
|
validate?: boolean; //Setting for whether we want to validate the schema
|
||||||
|
hover?: boolean; //Setting for whether we want to have hover results
|
||||||
|
completion?: boolean; //Setting for whether we want to have completion results
|
||||||
isKubernetes?: boolean; //If true then its validating against kubernetes
|
isKubernetes?: boolean; //If true then its validating against kubernetes
|
||||||
schemas?: any[]; //List of schemas,
|
schemas?: any[]; //List of schemas,
|
||||||
customTags?: Array<String>; //Array of Custom Tags
|
customTags?: Array<String>; //Array of Custom Tags
|
||||||
|
|
@ -35,12 +33,7 @@ export interface PromiseConstructor {
|
||||||
* a resolve callback used resolve the promise with a value or the result of another promise,
|
* a resolve callback used resolve the promise with a value or the result of another promise,
|
||||||
* and a reject callback used to reject the promise with a provided reason or error.
|
* and a reject callback used to reject the promise with a provided reason or error.
|
||||||
*/
|
*/
|
||||||
new <T>(
|
new <T>(executor: (resolve: (value?: T | Thenable<T>) => void, reject: (reason?: any) => void) => void): Thenable<T>;
|
||||||
executor: (
|
|
||||||
resolve: (value?: T | Thenable<T>) => void,
|
|
||||||
reject: (reason?: any) => void
|
|
||||||
) => void
|
|
||||||
): Thenable<T>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises
|
* Creates a Promise that is resolved with an array of results when all of the provided Promises
|
||||||
|
|
@ -72,14 +65,8 @@ export interface Thenable<R> {
|
||||||
* @param onrejected The callback to execute when the Promise is rejected.
|
* @param onrejected The callback to execute when the Promise is rejected.
|
||||||
* @returns A Promise for the completion of which ever callback is executed.
|
* @returns A Promise for the completion of which ever callback is executed.
|
||||||
*/
|
*/
|
||||||
then<TResult>(
|
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
|
||||||
onfulfilled?: (value: R) => TResult | Thenable<TResult>,
|
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
|
||||||
onrejected?: (reason: any) => TResult | Thenable<TResult>
|
|
||||||
): Thenable<TResult>;
|
|
||||||
then<TResult>(
|
|
||||||
onfulfilled?: (value: R) => TResult | Thenable<TResult>,
|
|
||||||
onrejected?: (reason: any) => void
|
|
||||||
): Thenable<TResult>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkspaceContextService {
|
export interface WorkspaceContextService {
|
||||||
|
|
@ -110,7 +97,8 @@ export interface SchemaConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LanguageService {
|
export interface LanguageService {
|
||||||
configure(settings): void;
|
configure(settings: LanguageSettings): void;
|
||||||
|
registerCustomSchemaProvider(schemaProvider: CustomSchemaProvider): void; // Register a custom schema provider
|
||||||
doComplete(document: TextDocument, position: Position, doc): Thenable<CompletionList>;
|
doComplete(document: TextDocument, position: Position, doc): Thenable<CompletionList>;
|
||||||
doValidation(document: TextDocument, yamlDocument): Thenable<Diagnostic[]>;
|
doValidation(document: TextDocument, yamlDocument): Thenable<Diagnostic[]>;
|
||||||
doHover(document: TextDocument, position: Position, doc);
|
doHover(document: TextDocument, position: Position, doc);
|
||||||
|
|
@ -121,10 +109,10 @@ export interface LanguageService {
|
||||||
parseYAMLDocument(document: TextDocument): YAMLDocument;
|
parseYAMLDocument(document: TextDocument): YAMLDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLanguageService(schemaRequestService, workspaceContext, contributions, customSchemaProvider, promiseConstructor?): LanguageService {
|
export function getLanguageService(schemaRequestService, workspaceContext, contributions, promiseConstructor?): LanguageService {
|
||||||
let promise = promiseConstructor || Promise;
|
let promise = promiseConstructor || Promise;
|
||||||
|
|
||||||
let schemaService = new JSONSchemaService(schemaRequestService, workspaceContext, customSchemaProvider);
|
let schemaService = new JSONSchemaService(schemaRequestService, workspaceContext);
|
||||||
|
|
||||||
let completer = new YAMLCompletion(schemaService, contributions, promise);
|
let completer = new YAMLCompletion(schemaService, contributions, promise);
|
||||||
let hover = new YAMLHover(schemaService, contributions, promise);
|
let hover = new YAMLHover(schemaService, contributions, promise);
|
||||||
|
|
@ -140,8 +128,12 @@ export function getLanguageService(schemaRequestService, workspaceContext, contr
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
yamlValidation.configure(settings);
|
yamlValidation.configure(settings);
|
||||||
let customTagsSetting = settings && settings["customTags"] ? settings["customTags"] : [];
|
hover.configure(settings);
|
||||||
completer.configure(customTagsSetting);
|
let customTagsSetting = settings && settings['customTags'] ? settings['customTags'] : [];
|
||||||
|
completer.configure(settings, customTagsSetting);
|
||||||
|
},
|
||||||
|
registerCustomSchemaProvider: (schemaProvider: CustomSchemaProvider) => {
|
||||||
|
schemaService.registerCustomSchemaProvider(schemaProvider);
|
||||||
},
|
},
|
||||||
doComplete: completer.doComplete.bind(completer),
|
doComplete: completer.doComplete.bind(completer),
|
||||||
doResolve: completer.doResolve.bind(completer),
|
doResolve: completer.doResolve.bind(completer),
|
||||||
|
|
@ -150,6 +142,6 @@ export function getLanguageService(schemaRequestService, workspaceContext, contr
|
||||||
findDocumentSymbols: yamlDocumentSymbols.findDocumentSymbols.bind(yamlDocumentSymbols),
|
findDocumentSymbols: yamlDocumentSymbols.findDocumentSymbols.bind(yamlDocumentSymbols),
|
||||||
resetSchema: (uri: string) => schemaService.onResourceChange(uri),
|
resetSchema: (uri: string) => schemaService.onResourceChange(uri),
|
||||||
doFormat: format,
|
doFormat: format,
|
||||||
parseYAMLDocument: (document: TextDocument) => parseYAML(document.getText())
|
parseYAMLDocument: (document: TextDocument) => parseYAML(document.getText()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,8 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.yaml.Langua
|
||||||
|
|
||||||
const diagnosticDefault: monaco.languages.yaml.DiagnosticsOptions = {
|
const diagnosticDefault: monaco.languages.yaml.DiagnosticsOptions = {
|
||||||
validate: true,
|
validate: true,
|
||||||
schemas: []
|
schemas: [],
|
||||||
|
enableSchemaRequest: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
const yamlDefaults = new LanguageServiceDefaultsImpl('yaml', diagnosticDefault);
|
const yamlDefaults = new LanguageServiceDefaultsImpl('yaml', diagnosticDefault);
|
||||||
|
|
|
||||||
59
src/monaco.d.ts
vendored
59
src/monaco.d.ts
vendored
|
|
@ -4,36 +4,41 @@
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
declare module monaco.languages.yaml {
|
declare module monaco.languages.yaml {
|
||||||
export interface DiagnosticsOptions {
|
export interface DiagnosticsOptions {
|
||||||
|
/**
|
||||||
|
* 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?: {
|
||||||
/**
|
/**
|
||||||
* If set, the validator will be enabled and perform syntax validation as well as schema based validation.
|
* The URI of the schema, which is also the identifier of the schema.
|
||||||
*/
|
*/
|
||||||
readonly validate?: boolean;
|
readonly uri: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of known schemas and/or associations of schemas to file names.
|
* A list of file names that are associated to the schema. The '*' wildcard can be used. For example '*.schema.json', 'package.json'
|
||||||
*/
|
*/
|
||||||
readonly schemas?: {
|
readonly fileMatch?: string[];
|
||||||
/**
|
/**
|
||||||
* The URI of the schema, which is also the identifier of the schema.
|
* The schema for the given URI.
|
||||||
*/
|
*/
|
||||||
readonly uri: string;
|
readonly schema?: any;
|
||||||
/**
|
}[];
|
||||||
* 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;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LanguageServiceDefaults {
|
/**
|
||||||
readonly onDidChange: IEvent<LanguageServiceDefaults>;
|
* If set, the schema service would load schema content on-demand with 'fetch' if available
|
||||||
readonly diagnosticsOptions: DiagnosticsOptions;
|
*/
|
||||||
setDiagnosticsOptions(options: DiagnosticsOptions): void;
|
readonly enableSchemaRequest?: boolean;
|
||||||
}
|
|
||||||
|
|
||||||
export var yamlDefaults: LanguageServiceDefaults;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LanguageServiceDefaults {
|
||||||
|
readonly onDidChange: IEvent<LanguageServiceDefaults>;
|
||||||
|
readonly diagnosticsOptions: DiagnosticsOptions;
|
||||||
|
setDiagnosticsOptions(options: DiagnosticsOptions): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const yamlDefaults: LanguageServiceDefaults;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,8 @@ export class WorkerManager {
|
||||||
// passed in to the create() method
|
// passed in to the create() method
|
||||||
createData: {
|
createData: {
|
||||||
languageSettings: this._defaults.diagnosticsOptions,
|
languageSettings: this._defaults.diagnosticsOptions,
|
||||||
languageId: this._defaults.languageId
|
languageId: this._defaults.languageId,
|
||||||
|
enableSchemaRequest: this._defaults.diagnosticsOptions.enableSchemaRequest
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -81,26 +82,10 @@ export class WorkerManager {
|
||||||
|
|
||||||
getLanguageServiceWorker(...resources: Uri[]): Promise<YAMLWorker> {
|
getLanguageServiceWorker(...resources: Uri[]): Promise<YAMLWorker> {
|
||||||
let _client: YAMLWorker;
|
let _client: YAMLWorker;
|
||||||
return toShallowCancelPromise(
|
return this._getClient().then((client) => {
|
||||||
this._getClient().then((client) => {
|
_client = client
|
||||||
_client = client
|
}).then(_ => {
|
||||||
}).then(_ => {
|
return this._worker.withSyncedResources(resources)
|
||||||
return this._worker.withSyncedResources(resources)
|
}).then(_ => _client);
|
||||||
}).then(_ => _client)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toShallowCancelPromise<T>(p: Promise<T>): Promise<T> {
|
|
||||||
let completeCallback: (value: T) => void;
|
|
||||||
let errorCallback: (err: any) => void;
|
|
||||||
|
|
||||||
let r = new Promise<T>((c, e) => {
|
|
||||||
completeCallback = c;
|
|
||||||
errorCallback = e;
|
|
||||||
}, () => { });
|
|
||||||
|
|
||||||
p.then(completeCallback, errorCallback);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,11 @@ import IWorkerContext = monaco.worker.IWorkerContext;
|
||||||
|
|
||||||
import * as ls from 'vscode-languageserver-types';
|
import * as ls from 'vscode-languageserver-types';
|
||||||
import * as yamlService from './languageservice/yamlLanguageService';
|
import * as yamlService from './languageservice/yamlLanguageService';
|
||||||
import { SchemaRequestService } from './languageservice/yamlLanguageService';
|
|
||||||
|
let defaultSchemaRequestService;
|
||||||
|
if (typeof fetch !== 'undefined'){
|
||||||
|
defaultSchemaRequestService = function (url) { return fetch(url).then(response => response.text())};
|
||||||
|
}
|
||||||
|
|
||||||
class PromiseAdapter<T> implements yamlService.Thenable<T> {
|
class PromiseAdapter<T> implements yamlService.Thenable<T> {
|
||||||
private wrapped: monaco.Promise<T>;
|
private wrapped: monaco.Promise<T>;
|
||||||
|
|
@ -21,17 +25,14 @@ class PromiseAdapter<T> implements yamlService.Thenable<T> {
|
||||||
this.wrapped = new monaco.Promise<T>(executor);
|
this.wrapped = new monaco.Promise<T>(executor);
|
||||||
}
|
}
|
||||||
public then<TResult>(onfulfilled?: (value: T) => TResult | yamlService.Thenable<TResult>, onrejected?: (reason: any) => void): yamlService.Thenable<TResult> {
|
public then<TResult>(onfulfilled?: (value: T) => TResult | yamlService.Thenable<TResult>, onrejected?: (reason: any) => void): yamlService.Thenable<TResult> {
|
||||||
let thenable : yamlService.Thenable<T> = this.wrapped;
|
let thenable: yamlService.Thenable<T> = this.wrapped;
|
||||||
return thenable.then(onfulfilled, onrejected);
|
return thenable.then(onfulfilled, onrejected);
|
||||||
}
|
}
|
||||||
public getWrapped(): monaco.Thenable<T> {
|
public getWrapped(): monaco.Thenable<T> {
|
||||||
return this.wrapped;
|
return this.wrapped;
|
||||||
}
|
}
|
||||||
public cancel(): void {
|
|
||||||
this.wrapped.cancel();
|
|
||||||
}
|
|
||||||
public static resolve<T>(v: T | Thenable<T>): yamlService.Thenable<T> {
|
public static resolve<T>(v: T | Thenable<T>): yamlService.Thenable<T> {
|
||||||
return <monaco.Thenable<T>> monaco.Promise.as(v);
|
return <monaco.Thenable<T>>monaco.Promise.as(v);
|
||||||
}
|
}
|
||||||
public static reject<T>(v: T): yamlService.Thenable<T> {
|
public static reject<T>(v: T): yamlService.Thenable<T> {
|
||||||
return monaco.Promise.wrapError(<any>v);
|
return monaco.Promise.wrapError(<any>v);
|
||||||
|
|
@ -41,25 +42,6 @@ class PromiseAdapter<T> implements yamlService.Thenable<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently we only support loading schemas via xhr:
|
|
||||||
const ajax = (url: string) =>
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
const request = new XMLHttpRequest();
|
|
||||||
request.onreadystatechange = () => {
|
|
||||||
if (request.readyState === XMLHttpRequest.DONE) {
|
|
||||||
const response = request.responseText;
|
|
||||||
if (request.status < 400) {
|
|
||||||
resolve(response);
|
|
||||||
} else {
|
|
||||||
reject(response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
request.onerror = reject;
|
|
||||||
request.open('GET', url);
|
|
||||||
request.send();
|
|
||||||
});
|
|
||||||
|
|
||||||
export class YAMLWorker {
|
export class YAMLWorker {
|
||||||
|
|
||||||
private _ctx: IWorkerContext;
|
private _ctx: IWorkerContext;
|
||||||
|
|
@ -71,8 +53,10 @@ export class YAMLWorker {
|
||||||
this._ctx = ctx;
|
this._ctx = ctx;
|
||||||
this._languageSettings = createData.languageSettings;
|
this._languageSettings = createData.languageSettings;
|
||||||
this._languageId = createData.languageId;
|
this._languageId = createData.languageId;
|
||||||
this._languageService = yamlService.getLanguageService(ajax, null, [], null, PromiseAdapter);
|
this._languageService = yamlService.getLanguageService(createData.enableSchemaRequest && defaultSchemaRequestService,
|
||||||
this._languageService.configure(this._languageSettings);
|
null, [], PromiseAdapter,
|
||||||
|
);
|
||||||
|
this._languageService.configure({ ...this._languageSettings, hover: true, isKubernetes: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
doValidation(uri: string): Thenable<ls.Diagnostic[]> {
|
doValidation(uri: string): Thenable<ls.Diagnostic[]> {
|
||||||
|
|
@ -83,10 +67,8 @@ export class YAMLWorker {
|
||||||
}
|
}
|
||||||
return Promise.as([]);
|
return Promise.as([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
doComplete(uri: string, position: ls.Position): Thenable<ls.CompletionList> {
|
doComplete(uri: string, position: ls.Position): Thenable<ls.CompletionList> {
|
||||||
let document = this._getTextDocument(uri);
|
let document = this._getTextDocument(uri);
|
||||||
let completionFix = completionHelper(document, position);
|
|
||||||
let yamlDocument = this._languageService.parseYAMLDocument(document);
|
let yamlDocument = this._languageService.parseYAMLDocument(document);
|
||||||
return this._languageService.doComplete(document, position, yamlDocument);
|
return this._languageService.doComplete(document, position, yamlDocument);
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +77,7 @@ export class YAMLWorker {
|
||||||
}
|
}
|
||||||
doHover(uri: string, position: ls.Position): Thenable<ls.Hover> {
|
doHover(uri: string, position: ls.Position): Thenable<ls.Hover> {
|
||||||
let document = this._getTextDocument(uri);
|
let document = this._getTextDocument(uri);
|
||||||
let yamlDocument = this._languageService.parseYAMLDocument(document)
|
let yamlDocument = this._languageService.parseYAMLDocument(document);
|
||||||
return this._languageService.doHover(document, position, yamlDocument);
|
return this._languageService.doHover(document, position, yamlDocument);
|
||||||
}
|
}
|
||||||
format(uri: string, range: ls.Range, options: ls.FormattingOptions): Thenable<ls.TextEdit[]> {
|
format(uri: string, range: ls.Range, options: ls.FormattingOptions): Thenable<ls.TextEdit[]> {
|
||||||
|
|
@ -126,89 +108,9 @@ export class YAMLWorker {
|
||||||
export interface ICreateData {
|
export interface ICreateData {
|
||||||
languageId: string;
|
languageId: string;
|
||||||
languageSettings: yamlService.LanguageSettings;
|
languageSettings: yamlService.LanguageSettings;
|
||||||
schemaRequestService?: SchemaRequestService;
|
enableSchemaRequest: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function create(ctx: IWorkerContext, createData: ICreateData): YAMLWorker {
|
export function create(ctx: IWorkerContext, createData: ICreateData): YAMLWorker {
|
||||||
return new YAMLWorker(ctx, createData);
|
return new YAMLWorker(ctx, createData);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLineOffsets(textDocString: String): number[] {
|
|
||||||
|
|
||||||
let lineOffsets: number[] = [];
|
|
||||||
let text = textDocString;
|
|
||||||
let isLineStart = true;
|
|
||||||
for (let i = 0; i < text.length; i++) {
|
|
||||||
if (isLineStart) {
|
|
||||||
lineOffsets.push(i);
|
|
||||||
isLineStart = false;
|
|
||||||
}
|
|
||||||
let ch = text.charAt(i);
|
|
||||||
isLineStart = (ch === '\r' || ch === '\n');
|
|
||||||
if (ch === '\r' && i + 1 < text.length && text.charAt(i + 1) === '\n') {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isLineStart && text.length > 0) {
|
|
||||||
lineOffsets.push(text.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return lineOffsets;
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/redhat-developer/yaml-language-server/blob/5e069c0e9d7004d57f1fa6e93df670d4895883d1/src/server.ts#L453
|
|
||||||
function completionHelper(document: ls.TextDocument, textDocumentPosition: ls.Position) {
|
|
||||||
|
|
||||||
//Get the string we are looking at via a substring
|
|
||||||
let linePos = textDocumentPosition.line;
|
|
||||||
let position = textDocumentPosition;
|
|
||||||
let lineOffset = getLineOffsets(document.getText());
|
|
||||||
let start = lineOffset[linePos]; //Start of where the autocompletion is happening
|
|
||||||
let end = 0; //End of where the autocompletion is happening
|
|
||||||
if (lineOffset[linePos + 1]) {
|
|
||||||
end = lineOffset[linePos + 1];
|
|
||||||
} else {
|
|
||||||
end = document.getText().length;
|
|
||||||
}
|
|
||||||
let textLine = document.getText().substring(start, end);
|
|
||||||
|
|
||||||
//Check if the string we are looking at is a node
|
|
||||||
if (textLine.indexOf(":") === -1) {
|
|
||||||
//We need to add the ":" to load the nodes
|
|
||||||
let newText = "";
|
|
||||||
|
|
||||||
//This is for the empty line case
|
|
||||||
let trimmedText = textLine.trim();
|
|
||||||
if (trimmedText.length === 0 || (trimmedText.length === 1 && trimmedText[0] === '-')) {
|
|
||||||
//Add a temp node that is in the document but we don't use at all.
|
|
||||||
if (lineOffset[linePos + 1]) {
|
|
||||||
newText = document.getText().substring(0, start + (textLine.length - 1)) + "holder:\r\n" + document.getText().substr(end + 2);
|
|
||||||
} else {
|
|
||||||
newText = document.getText().substring(0, start + (textLine.length)) + "holder:\r\n" + document.getText().substr(end + 2);
|
|
||||||
}
|
|
||||||
//For when missing semi colon case
|
|
||||||
} else {
|
|
||||||
//Add a semicolon to the end of the current line so we can validate the node
|
|
||||||
if (lineOffset[linePos + 1]) {
|
|
||||||
newText = document.getText().substring(0, start + (textLine.length - 1)) + ":\r\n" + document.getText().substr(end + 2);
|
|
||||||
} else {
|
|
||||||
newText = document.getText().substring(0, start + (textLine.length)) + ":\r\n" + document.getText().substr(end + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
"newText": newText,
|
|
||||||
"newPosition": textDocumentPosition
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
//All the nodes are loaded
|
|
||||||
position.character = position.character - 1;
|
|
||||||
return {
|
|
||||||
"newText": document.getText(),
|
|
||||||
"newPosition": position
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ spec:
|
||||||
});
|
});
|
||||||
|
|
||||||
monaco.languages.yaml.yamlDefaults.setDiagnosticsOptions({
|
monaco.languages.yaml.yamlDefaults.setDiagnosticsOptions({
|
||||||
|
enableSchemaRequest: true,
|
||||||
validate: true,
|
validate: true,
|
||||||
schemas: [
|
schemas: [
|
||||||
{
|
{
|
||||||
|
|
@ -81,27 +82,6 @@ spec:
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
// See: https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/quickOpen/quickOpen.ts
|
|
||||||
require(['vs/editor/contrib/quickOpen/quickOpen'], quickOpen => {
|
|
||||||
|
|
||||||
// Breadcrumbs emulation:
|
|
||||||
editor.onDidChangeCursorSelection(({ selection }) => {
|
|
||||||
quickOpen.getDocumentSymbols(editor.getModel()).then(symbols => {
|
|
||||||
symbols = symbols.filter(symbol => symbol.range.containsPosition(selection.getPosition()));
|
|
||||||
symbols = symbols.map(symbol => {
|
|
||||||
if (symbol.kind === 17) {
|
|
||||||
return `[]${symbol.name}`;
|
|
||||||
} else if (symbol.kind === 18 || symbol.kind === 1) {
|
|
||||||
return `{}${symbol.name}`;
|
|
||||||
} else {
|
|
||||||
return symbol.name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
document.querySelector('#path').innerHTML = symbols.join(' > ');
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
21
yarn.lock
21
yarn.lock
|
|
@ -86,13 +86,15 @@ minimatch@^3.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
monaco-editor-core@0.14.6:
|
monaco-editor-core@0.15.0:
|
||||||
version "0.14.6"
|
version "0.15.0"
|
||||||
resolved "https://registry.yarnpkg.com/monaco-editor-core/-/monaco-editor-core-0.14.6.tgz#25fae6a2e7c7da6eb2a3bba653a283627dc624e4"
|
resolved "https://registry.yarnpkg.com/monaco-editor-core/-/monaco-editor-core-0.15.0.tgz#1ad5f130ed8efae9d9ed85d8a58a55067e14d983"
|
||||||
|
integrity sha512-s1zuo+p6Gl6IC4WJP6HBkr4pWULm+HdFfacB8vOFPQLLi2oJseO20UuSkxYuZTUJQIjvhNrQfLNAmPKLZaf7tg==
|
||||||
|
|
||||||
monaco-languages@1.5.1:
|
monaco-languages@1.6.0:
|
||||||
version "1.5.1"
|
version "1.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/monaco-languages/-/monaco-languages-1.5.1.tgz#e0b754a3db9de2133859d88abbf3b2b376439b58"
|
resolved "https://registry.yarnpkg.com/monaco-languages/-/monaco-languages-1.6.0.tgz#54ec5510b31f3132939014f171ade235e84ef0bc"
|
||||||
|
integrity sha512-LBEWj8tngYwsq4kasQr+dIhnO4xUIEN36ns+cRepWAQiXZnzcrZ84gFHXm8f4mR4tssxvHVU5Vw7xMUYro6h3g==
|
||||||
|
|
||||||
monaco-plugin-helpers@^1.0.2:
|
monaco-plugin-helpers@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
|
@ -132,9 +134,10 @@ typescript@^2.7.2:
|
||||||
version "2.9.2"
|
version "2.9.2"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
|
||||||
|
|
||||||
typescript@^3.0.3:
|
typescript@^3.1.6:
|
||||||
version "3.0.3"
|
version "3.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.3.tgz#4853b3e275ecdaa27f78fda46dc273a7eb7fc1c8"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68"
|
||||||
|
integrity sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==
|
||||||
|
|
||||||
uglify-es@^3.3.9:
|
uglify-es@^3.3.9:
|
||||||
version "3.3.9"
|
version "3.3.9"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue