UNPKG

monaco-editor

Version:
621 lines (620 loc) • 26.8 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); } return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var Uri = monaco.Uri; var Promise = monaco.Promise; //#region utils copied from typescript to prevent loading the entire typescriptServices --- var IndentStyle; (function (IndentStyle) { IndentStyle[IndentStyle["None"] = 0] = "None"; IndentStyle[IndentStyle["Block"] = 1] = "Block"; IndentStyle[IndentStyle["Smart"] = 2] = "Smart"; })(IndentStyle || (IndentStyle = {})); function flattenDiagnosticMessageText(messageText, newLine) { if (typeof messageText === "string") { return messageText; } else { var diagnosticChain = messageText; var result = ""; var indent = 0; while (diagnosticChain) { if (indent) { result += newLine; for (var i = 0; i < indent; i++) { result += " "; } } result += diagnosticChain.messageText; indent++; diagnosticChain = diagnosticChain.next; } return result; } } function displayPartsToString(displayParts) { if (displayParts) { return displayParts.map(function (displayPart) { return displayPart.text; }).join(""); } return ""; } //#endregion var Adapter = /** @class */ (function () { function Adapter(_worker) { this._worker = _worker; } Adapter.prototype._positionToOffset = function (uri, position) { var model = monaco.editor.getModel(uri); return model.getOffsetAt(position); }; Adapter.prototype._offsetToPosition = function (uri, offset) { var model = monaco.editor.getModel(uri); return model.getPositionAt(offset); }; Adapter.prototype._textSpanToRange = function (uri, span) { var p1 = this._offsetToPosition(uri, span.start); var p2 = this._offsetToPosition(uri, span.start + span.length); var startLineNumber = p1.lineNumber, startColumn = p1.column; var endLineNumber = p2.lineNumber, endColumn = p2.column; return { startLineNumber: startLineNumber, startColumn: startColumn, endLineNumber: endLineNumber, endColumn: endColumn }; }; return Adapter; }()); export { Adapter }; // --- diagnostics --- --- var DiagnostcsAdapter = /** @class */ (function (_super) { __extends(DiagnostcsAdapter, _super); function DiagnostcsAdapter(_defaults, _selector, worker) { var _this = _super.call(this, worker) || this; _this._defaults = _defaults; _this._selector = _selector; _this._disposables = []; _this._listener = Object.create(null); var onModelAdd = function (model) { if (model.getModeId() !== _selector) { return; } var handle; var changeSubscription = model.onDidChangeContent(function () { clearTimeout(handle); handle = setTimeout(function () { return _this._doValidate(model.uri); }, 500); }); _this._listener[model.uri.toString()] = { dispose: function () { changeSubscription.dispose(); clearTimeout(handle); } }; _this._doValidate(model.uri); }; var onModelRemoved = function (model) { monaco.editor.setModelMarkers(model, _this._selector, []); var key = model.uri.toString(); if (_this._listener[key]) { _this._listener[key].dispose(); delete _this._listener[key]; } }; _this._disposables.push(monaco.editor.onDidCreateModel(onModelAdd)); _this._disposables.push(monaco.editor.onWillDisposeModel(onModelRemoved)); _this._disposables.push(monaco.editor.onDidChangeModelLanguage(function (event) { onModelRemoved(event.model); onModelAdd(event.model); })); _this._disposables.push({ dispose: function () { for (var _i = 0, _a = monaco.editor.getModels(); _i < _a.length; _i++) { var model = _a[_i]; onModelRemoved(model); } } }); _this._disposables.push(_this._defaults.onDidChange(function () { // redo diagnostics when options change for (var _i = 0, _a = monaco.editor.getModels(); _i < _a.length; _i++) { var model = _a[_i]; onModelRemoved(model); onModelAdd(model); } })); monaco.editor.getModels().forEach(onModelAdd); return _this; } DiagnostcsAdapter.prototype.dispose = function () { this._disposables.forEach(function (d) { return d && d.dispose(); }); this._disposables = []; }; DiagnostcsAdapter.prototype._doValidate = function (resource) { var _this = this; this._worker(resource).then(function (worker) { if (!monaco.editor.getModel(resource)) { // model was disposed in the meantime return null; } var promises = []; var _a = _this._defaults.getDiagnosticsOptions(), noSyntaxValidation = _a.noSyntaxValidation, noSemanticValidation = _a.noSemanticValidation; if (!noSyntaxValidation) { promises.push(worker.getSyntacticDiagnostics(resource.toString())); } if (!noSemanticValidation) { promises.push(worker.getSemanticDiagnostics(resource.toString())); } return Promise.join(promises); }).then(function (diagnostics) { if (!diagnostics || !monaco.editor.getModel(resource)) { // model was disposed in the meantime return null; } var markers = diagnostics .reduce(function (p, c) { return c.concat(p); }, []) .map(function (d) { return _this._convertDiagnostics(resource, d); }); monaco.editor.setModelMarkers(monaco.editor.getModel(resource), _this._selector, markers); }).then(undefined, function (err) { console.error(err); }); }; DiagnostcsAdapter.prototype._convertDiagnostics = function (resource, diag) { var _a = this._offsetToPosition(resource, diag.start), startLineNumber = _a.lineNumber, startColumn = _a.column; var _b = this._offsetToPosition(resource, diag.start + diag.length), endLineNumber = _b.lineNumber, endColumn = _b.column; return { severity: monaco.MarkerSeverity.Error, startLineNumber: startLineNumber, startColumn: startColumn, endLineNumber: endLineNumber, endColumn: endColumn, message: flattenDiagnosticMessageText(diag.messageText, '\n') }; }; return DiagnostcsAdapter; }(Adapter)); export { DiagnostcsAdapter }; var SuggestAdapter = /** @class */ (function (_super) { __extends(SuggestAdapter, _super); function SuggestAdapter() { return _super !== null && _super.apply(this, arguments) || this; } Object.defineProperty(SuggestAdapter.prototype, "triggerCharacters", { get: function () { return ['.']; }, enumerable: true, configurable: true }); SuggestAdapter.prototype.provideCompletionItems = function (model, position, _context, token) { var wordInfo = model.getWordUntilPosition(position); var resource = model.uri; var offset = this._positionToOffset(resource, position); return this._worker(resource).then(function (worker) { return worker.getCompletionsAtPosition(resource.toString(), offset); }).then(function (info) { if (!info) { return; } var suggestions = info.entries.map(function (entry) { return { uri: resource, position: position, label: entry.name, insertText: entry.name, sortText: entry.sortText, kind: SuggestAdapter.convertKind(entry.kind) }; }); return { suggestions: suggestions }; }); }; SuggestAdapter.prototype.resolveCompletionItem = function (_model, _position, item, token) { var _this = this; var myItem = item; var resource = myItem.uri; var position = myItem.position; return this._worker(resource).then(function (worker) { return worker.getCompletionEntryDetails(resource.toString(), _this._positionToOffset(resource, position), myItem.label); }).then(function (details) { if (!details) { return myItem; } return { uri: resource, position: position, label: details.name, kind: SuggestAdapter.convertKind(details.kind), detail: displayPartsToString(details.displayParts), documentation: { value: displayPartsToString(details.documentation) } }; }); }; SuggestAdapter.convertKind = function (kind) { switch (kind) { case Kind.primitiveType: case Kind.keyword: return monaco.languages.CompletionItemKind.Keyword; case Kind.variable: case Kind.localVariable: return monaco.languages.CompletionItemKind.Variable; case Kind.memberVariable: case Kind.memberGetAccessor: case Kind.memberSetAccessor: return monaco.languages.CompletionItemKind.Field; case Kind.function: case Kind.memberFunction: case Kind.constructSignature: case Kind.callSignature: case Kind.indexSignature: return monaco.languages.CompletionItemKind.Function; case Kind.enum: return monaco.languages.CompletionItemKind.Enum; case Kind.module: return monaco.languages.CompletionItemKind.Module; case Kind.class: return monaco.languages.CompletionItemKind.Class; case Kind.interface: return monaco.languages.CompletionItemKind.Interface; case Kind.warning: return monaco.languages.CompletionItemKind.File; } return monaco.languages.CompletionItemKind.Property; }; return SuggestAdapter; }(Adapter)); export { SuggestAdapter }; var SignatureHelpAdapter = /** @class */ (function (_super) { __extends(SignatureHelpAdapter, _super); function SignatureHelpAdapter() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.signatureHelpTriggerCharacters = ['(', ',']; return _this; } SignatureHelpAdapter.prototype.provideSignatureHelp = function (model, position, token) { var _this = this; var resource = model.uri; return this._worker(resource).then(function (worker) { return worker.getSignatureHelpItems(resource.toString(), _this._positionToOffset(resource, position)); }).then(function (info) { if (!info) { return; } var ret = { activeSignature: info.selectedItemIndex, activeParameter: info.argumentIndex, signatures: [] }; info.items.forEach(function (item) { var signature = { label: '', documentation: null, parameters: [] }; signature.label += displayPartsToString(item.prefixDisplayParts); item.parameters.forEach(function (p, i, a) { var label = displayPartsToString(p.displayParts); var parameter = { label: label, documentation: displayPartsToString(p.documentation) }; signature.label += label; signature.parameters.push(parameter); if (i < a.length - 1) { signature.label += displayPartsToString(item.separatorDisplayParts); } }); signature.label += displayPartsToString(item.suffixDisplayParts); ret.signatures.push(signature); }); return ret; }); }; return SignatureHelpAdapter; }(Adapter)); export { SignatureHelpAdapter }; // --- hover ------ var QuickInfoAdapter = /** @class */ (function (_super) { __extends(QuickInfoAdapter, _super); function QuickInfoAdapter() { return _super !== null && _super.apply(this, arguments) || this; } QuickInfoAdapter.prototype.provideHover = function (model, position, token) { var _this = this; var resource = model.uri; return this._worker(resource).then(function (worker) { return worker.getQuickInfoAtPosition(resource.toString(), _this._positionToOffset(resource, position)); }).then(function (info) { if (!info) { return; } var documentation = displayPartsToString(info.documentation); var tags = info.tags ? info.tags.map(function (tag) { var label = "*@" + tag.name + "*"; if (!tag.text) { return label; } return label + (tag.text.match(/\r\n|\n/g) ? ' \n' + tag.text : " - " + tag.text); }) .join(' \n\n') : ''; var contents = displayPartsToString(info.displayParts); return { range: _this._textSpanToRange(resource, info.textSpan), contents: [{ value: '```js\n' + contents + '\n```\n' }, { value: documentation + (tags ? '\n\n' + tags : '') }] }; }); }; return QuickInfoAdapter; }(Adapter)); export { QuickInfoAdapter }; // --- occurrences ------ var OccurrencesAdapter = /** @class */ (function (_super) { __extends(OccurrencesAdapter, _super); function OccurrencesAdapter() { return _super !== null && _super.apply(this, arguments) || this; } OccurrencesAdapter.prototype.provideDocumentHighlights = function (model, position, token) { var _this = this; var resource = model.uri; return this._worker(resource).then(function (worker) { return worker.getOccurrencesAtPosition(resource.toString(), _this._positionToOffset(resource, position)); }).then(function (entries) { if (!entries) { return; } return entries.map(function (entry) { return { range: _this._textSpanToRange(resource, entry.textSpan), kind: entry.isWriteAccess ? monaco.languages.DocumentHighlightKind.Write : monaco.languages.DocumentHighlightKind.Text }; }); }); }; return OccurrencesAdapter; }(Adapter)); export { OccurrencesAdapter }; // --- definition ------ var DefinitionAdapter = /** @class */ (function (_super) { __extends(DefinitionAdapter, _super); function DefinitionAdapter() { return _super !== null && _super.apply(this, arguments) || this; } DefinitionAdapter.prototype.provideDefinition = function (model, position, token) { var _this = this; var resource = model.uri; return this._worker(resource).then(function (worker) { return worker.getDefinitionAtPosition(resource.toString(), _this._positionToOffset(resource, position)); }).then(function (entries) { if (!entries) { return; } var result = []; for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { var entry = entries_1[_i]; var uri = Uri.parse(entry.fileName); if (monaco.editor.getModel(uri)) { result.push({ uri: uri, range: _this._textSpanToRange(uri, entry.textSpan) }); } } return result; }); }; return DefinitionAdapter; }(Adapter)); export { DefinitionAdapter }; // --- references ------ var ReferenceAdapter = /** @class */ (function (_super) { __extends(ReferenceAdapter, _super); function ReferenceAdapter() { return _super !== null && _super.apply(this, arguments) || this; } ReferenceAdapter.prototype.provideReferences = function (model, position, context, token) { var _this = this; var resource = model.uri; return this._worker(resource).then(function (worker) { return worker.getReferencesAtPosition(resource.toString(), _this._positionToOffset(resource, position)); }).then(function (entries) { if (!entries) { return; } var result = []; for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { var entry = entries_2[_i]; var uri = Uri.parse(entry.fileName); if (monaco.editor.getModel(uri)) { result.push({ uri: uri, range: _this._textSpanToRange(uri, entry.textSpan) }); } } return result; }); }; return ReferenceAdapter; }(Adapter)); export { ReferenceAdapter }; // --- outline ------ var OutlineAdapter = /** @class */ (function (_super) { __extends(OutlineAdapter, _super); function OutlineAdapter() { return _super !== null && _super.apply(this, arguments) || this; } OutlineAdapter.prototype.provideDocumentSymbols = function (model, token) { var _this = this; var resource = model.uri; return this._worker(resource).then(function (worker) { return worker.getNavigationBarItems(resource.toString()); }).then(function (items) { if (!items) { return; } var convert = function (bucket, item, containerLabel) { var result = { name: item.text, detail: '', kind: (outlineTypeTable[item.kind] || monaco.languages.SymbolKind.Variable), range: _this._textSpanToRange(resource, item.spans[0]), selectionRange: _this._textSpanToRange(resource, item.spans[0]), containerName: containerLabel }; if (item.childItems && item.childItems.length > 0) { for (var _i = 0, _a = item.childItems; _i < _a.length; _i++) { var child = _a[_i]; convert(bucket, child, result.name); } } bucket.push(result); }; var result = []; items.forEach(function (item) { return convert(result, item); }); return result; }); }; return OutlineAdapter; }(Adapter)); export { OutlineAdapter }; var Kind = /** @class */ (function () { function Kind() { } Kind.unknown = ''; Kind.keyword = 'keyword'; Kind.script = 'script'; Kind.module = 'module'; Kind.class = 'class'; Kind.interface = 'interface'; Kind.type = 'type'; Kind.enum = 'enum'; Kind.variable = 'var'; Kind.localVariable = 'local var'; Kind.function = 'function'; Kind.localFunction = 'local function'; Kind.memberFunction = 'method'; Kind.memberGetAccessor = 'getter'; Kind.memberSetAccessor = 'setter'; Kind.memberVariable = 'property'; Kind.constructorImplementation = 'constructor'; Kind.callSignature = 'call'; Kind.indexSignature = 'index'; Kind.constructSignature = 'construct'; Kind.parameter = 'parameter'; Kind.typeParameter = 'type parameter'; Kind.primitiveType = 'primitive type'; Kind.label = 'label'; Kind.alias = 'alias'; Kind.const = 'const'; Kind.let = 'let'; Kind.warning = 'warning'; return Kind; }()); export { Kind }; var outlineTypeTable = Object.create(null); outlineTypeTable[Kind.module] = monaco.languages.SymbolKind.Module; outlineTypeTable[Kind.class] = monaco.languages.SymbolKind.Class; outlineTypeTable[Kind.enum] = monaco.languages.SymbolKind.Enum; outlineTypeTable[Kind.interface] = monaco.languages.SymbolKind.Interface; outlineTypeTable[Kind.memberFunction] = monaco.languages.SymbolKind.Method; outlineTypeTable[Kind.memberVariable] = monaco.languages.SymbolKind.Property; outlineTypeTable[Kind.memberGetAccessor] = monaco.languages.SymbolKind.Property; outlineTypeTable[Kind.memberSetAccessor] = monaco.languages.SymbolKind.Property; outlineTypeTable[Kind.variable] = monaco.languages.SymbolKind.Variable; outlineTypeTable[Kind.const] = monaco.languages.SymbolKind.Variable; outlineTypeTable[Kind.localVariable] = monaco.languages.SymbolKind.Variable; outlineTypeTable[Kind.variable] = monaco.languages.SymbolKind.Variable; outlineTypeTable[Kind.function] = monaco.languages.SymbolKind.Function; outlineTypeTable[Kind.localFunction] = monaco.languages.SymbolKind.Function; // --- formatting ---- var FormatHelper = /** @class */ (function (_super) { __extends(FormatHelper, _super); function FormatHelper() { return _super !== null && _super.apply(this, arguments) || this; } FormatHelper._convertOptions = function (options) { return { ConvertTabsToSpaces: options.insertSpaces, TabSize: options.tabSize, IndentSize: options.tabSize, IndentStyle: IndentStyle.Smart, NewLineCharacter: '\n', InsertSpaceAfterCommaDelimiter: true, InsertSpaceAfterSemicolonInForStatements: true, InsertSpaceBeforeAndAfterBinaryOperators: true, InsertSpaceAfterKeywordsInControlFlowStatements: true, InsertSpaceAfterFunctionKeywordForAnonymousFunctions: true, InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, PlaceOpenBraceOnNewLineForControlBlocks: false, PlaceOpenBraceOnNewLineForFunctions: false }; }; FormatHelper.prototype._convertTextChanges = function (uri, change) { return { text: change.newText, range: this._textSpanToRange(uri, change.span) }; }; return FormatHelper; }(Adapter)); export { FormatHelper }; var FormatAdapter = /** @class */ (function (_super) { __extends(FormatAdapter, _super); function FormatAdapter() { return _super !== null && _super.apply(this, arguments) || this; } FormatAdapter.prototype.provideDocumentRangeFormattingEdits = function (model, range, options, token) { var _this = this; var resource = model.uri; return this._worker(resource).then(function (worker) { return worker.getFormattingEditsForRange(resource.toString(), _this._positionToOffset(resource, { lineNumber: range.startLineNumber, column: range.startColumn }), _this._positionToOffset(resource, { lineNumber: range.endLineNumber, column: range.endColumn }), FormatHelper._convertOptions(options)); }).then(function (edits) { if (edits) { return edits.map(function (edit) { return _this._convertTextChanges(resource, edit); }); } }); }; return FormatAdapter; }(FormatHelper)); export { FormatAdapter }; var FormatOnTypeAdapter = /** @class */ (function (_super) { __extends(FormatOnTypeAdapter, _super); function FormatOnTypeAdapter() { return _super !== null && _super.apply(this, arguments) || this; } Object.defineProperty(FormatOnTypeAdapter.prototype, "autoFormatTriggerCharacters", { get: function () { return [';', '}', '\n']; }, enumerable: true, configurable: true }); FormatOnTypeAdapter.prototype.provideOnTypeFormattingEdits = function (model, position, ch, options, token) { var _this = this; var resource = model.uri; return this._worker(resource).then(function (worker) { return worker.getFormattingEditsAfterKeystroke(resource.toString(), _this._positionToOffset(resource, position), ch, FormatHelper._convertOptions(options)); }).then(function (edits) { if (edits) { return edits.map(function (edit) { return _this._convertTextChanges(resource, edit); }); } }); }; return FormatOnTypeAdapter; }(FormatHelper)); export { FormatOnTypeAdapter };