UNPKG

monaco-editor

Version:
543 lines (542 loc) • 22.8 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 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 __()); }; })(); import { mergeSort } from '../../../base/common/arrays.js'; import { stringDiff } from '../../../base/common/diff/diff.js'; import { FIN } from '../../../base/common/iterator.js'; import { globals } from '../../../base/common/platform.js'; import { URI } from '../../../base/common/uri.js'; import { Position } from '../core/position.js'; import { Range } from '../core/range.js'; import { DiffComputer } from '../diff/diffComputer.js'; import { MirrorTextModel as BaseMirrorModel } from '../model/mirrorTextModel.js'; import { ensureValidWordDefinition, getWordAtText } from '../model/wordHelper.js'; import { computeLinks } from '../modes/linkComputer.js'; import { BasicInplaceReplace } from '../modes/supports/inplaceReplaceSupport.js'; import { createMonacoBaseAPI } from '../standalone/standaloneBase.js'; /** * @internal */ var MirrorModel = /** @class */ (function (_super) { __extends(MirrorModel, _super); function MirrorModel() { return _super !== null && _super.apply(this, arguments) || this; } Object.defineProperty(MirrorModel.prototype, "uri", { get: function () { return this._uri; }, enumerable: true, configurable: true }); Object.defineProperty(MirrorModel.prototype, "version", { get: function () { return this._versionId; }, enumerable: true, configurable: true }); Object.defineProperty(MirrorModel.prototype, "eol", { get: function () { return this._eol; }, enumerable: true, configurable: true }); MirrorModel.prototype.getValue = function () { return this.getText(); }; MirrorModel.prototype.getLinesContent = function () { return this._lines.slice(0); }; MirrorModel.prototype.getLineCount = function () { return this._lines.length; }; MirrorModel.prototype.getLineContent = function (lineNumber) { return this._lines[lineNumber - 1]; }; MirrorModel.prototype.getWordAtPosition = function (position, wordDefinition) { var wordAtText = getWordAtText(position.column, ensureValidWordDefinition(wordDefinition), this._lines[position.lineNumber - 1], 0); if (wordAtText) { return new Range(position.lineNumber, wordAtText.startColumn, position.lineNumber, wordAtText.endColumn); } return null; }; MirrorModel.prototype.getWordUntilPosition = function (position, wordDefinition) { var wordAtPosition = this.getWordAtPosition(position, wordDefinition); if (!wordAtPosition) { return { word: '', startColumn: position.column, endColumn: position.column }; } return { word: this._lines[position.lineNumber - 1].substring(wordAtPosition.startColumn - 1, position.column - 1), startColumn: wordAtPosition.startColumn, endColumn: position.column }; }; MirrorModel.prototype.createWordIterator = function (wordDefinition) { var _this = this; var obj; var lineNumber = 0; var lineText; var wordRangesIdx = 0; var wordRanges = []; var next = function () { if (wordRangesIdx < wordRanges.length) { var value = lineText.substring(wordRanges[wordRangesIdx].start, wordRanges[wordRangesIdx].end); wordRangesIdx += 1; if (!obj) { obj = { done: false, value: value }; } else { obj.value = value; } return obj; } else if (lineNumber >= _this._lines.length) { return FIN; } else { lineText = _this._lines[lineNumber]; wordRanges = _this._wordenize(lineText, wordDefinition); wordRangesIdx = 0; lineNumber += 1; return next(); } }; return { next: next }; }; MirrorModel.prototype.getLineWords = function (lineNumber, wordDefinition) { var content = this._lines[lineNumber - 1]; var ranges = this._wordenize(content, wordDefinition); var words = []; for (var _i = 0, ranges_1 = ranges; _i < ranges_1.length; _i++) { var range = ranges_1[_i]; words.push({ word: content.substring(range.start, range.end), startColumn: range.start + 1, endColumn: range.end + 1 }); } return words; }; MirrorModel.prototype._wordenize = function (content, wordDefinition) { var result = []; var match; wordDefinition.lastIndex = 0; // reset lastIndex just to be sure while (match = wordDefinition.exec(content)) { if (match[0].length === 0) { // it did match the empty string break; } result.push({ start: match.index, end: match.index + match[0].length }); } return result; }; MirrorModel.prototype.getValueInRange = function (range) { range = this._validateRange(range); if (range.startLineNumber === range.endLineNumber) { return this._lines[range.startLineNumber - 1].substring(range.startColumn - 1, range.endColumn - 1); } var lineEnding = this._eol; var startLineIndex = range.startLineNumber - 1; var endLineIndex = range.endLineNumber - 1; var resultLines = []; resultLines.push(this._lines[startLineIndex].substring(range.startColumn - 1)); for (var i = startLineIndex + 1; i < endLineIndex; i++) { resultLines.push(this._lines[i]); } resultLines.push(this._lines[endLineIndex].substring(0, range.endColumn - 1)); return resultLines.join(lineEnding); }; MirrorModel.prototype.offsetAt = function (position) { position = this._validatePosition(position); this._ensureLineStarts(); return this._lineStarts.getAccumulatedValue(position.lineNumber - 2) + (position.column - 1); }; MirrorModel.prototype.positionAt = function (offset) { offset = Math.floor(offset); offset = Math.max(0, offset); this._ensureLineStarts(); var out = this._lineStarts.getIndexOf(offset); var lineLength = this._lines[out.index].length; // Ensure we return a valid position return { lineNumber: 1 + out.index, column: 1 + Math.min(out.remainder, lineLength) }; }; MirrorModel.prototype._validateRange = function (range) { var start = this._validatePosition({ lineNumber: range.startLineNumber, column: range.startColumn }); var end = this._validatePosition({ lineNumber: range.endLineNumber, column: range.endColumn }); if (start.lineNumber !== range.startLineNumber || start.column !== range.startColumn || end.lineNumber !== range.endLineNumber || end.column !== range.endColumn) { return { startLineNumber: start.lineNumber, startColumn: start.column, endLineNumber: end.lineNumber, endColumn: end.column }; } return range; }; MirrorModel.prototype._validatePosition = function (position) { if (!Position.isIPosition(position)) { throw new Error('bad position'); } var lineNumber = position.lineNumber, column = position.column; var hasChanged = false; if (lineNumber < 1) { lineNumber = 1; column = 1; hasChanged = true; } else if (lineNumber > this._lines.length) { lineNumber = this._lines.length; column = this._lines[lineNumber - 1].length + 1; hasChanged = true; } else { var maxCharacter = this._lines[lineNumber - 1].length + 1; if (column < 1) { column = 1; hasChanged = true; } else if (column > maxCharacter) { column = maxCharacter; hasChanged = true; } } if (!hasChanged) { return position; } else { return { lineNumber: lineNumber, column: column }; } }; return MirrorModel; }(BaseMirrorModel)); /** * @internal */ var BaseEditorSimpleWorker = /** @class */ (function () { function BaseEditorSimpleWorker(foreignModuleFactory) { this._foreignModuleFactory = foreignModuleFactory; this._foreignModule = null; } // ---- BEGIN diff -------------------------------------------------------------------------- BaseEditorSimpleWorker.prototype.computeDiff = function (originalUrl, modifiedUrl, ignoreTrimWhitespace) { var original = this._getModel(originalUrl); var modified = this._getModel(modifiedUrl); if (!original || !modified) { return Promise.resolve(null); } var originalLines = original.getLinesContent(); var modifiedLines = modified.getLinesContent(); var diffComputer = new DiffComputer(originalLines, modifiedLines, { shouldComputeCharChanges: true, shouldPostProcessCharChanges: true, shouldIgnoreTrimWhitespace: ignoreTrimWhitespace, shouldMakePrettyDiff: true }); var changes = diffComputer.computeDiff(); var identical = (changes.length > 0 ? false : this._modelsAreIdentical(original, modified)); return Promise.resolve({ identical: identical, changes: changes }); }; BaseEditorSimpleWorker.prototype._modelsAreIdentical = function (original, modified) { var originalLineCount = original.getLineCount(); var modifiedLineCount = modified.getLineCount(); if (originalLineCount !== modifiedLineCount) { return false; } for (var line = 1; line <= originalLineCount; line++) { var originalLine = original.getLineContent(line); var modifiedLine = modified.getLineContent(line); if (originalLine !== modifiedLine) { return false; } } return true; }; BaseEditorSimpleWorker.prototype.computeMoreMinimalEdits = function (modelUrl, edits) { var model = this._getModel(modelUrl); if (!model) { return Promise.resolve(edits); } var result = []; var lastEol = undefined; edits = mergeSort(edits, function (a, b) { if (a.range && b.range) { return Range.compareRangesUsingStarts(a.range, b.range); } // eol only changes should go to the end var aRng = a.range ? 0 : 1; var bRng = b.range ? 0 : 1; return aRng - bRng; }); for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) { var _a = edits_1[_i], range = _a.range, text = _a.text, eol = _a.eol; if (typeof eol === 'number') { lastEol = eol; } if (!range) { // eol-change only continue; } var original = model.getValueInRange(range); text = text.replace(/\r\n|\n|\r/g, model.eol); if (original === text) { // noop continue; } // make sure diff won't take too long if (Math.max(text.length, original.length) > BaseEditorSimpleWorker._diffLimit) { result.push({ range: range, text: text }); continue; } // compute diff between original and edit.text var changes = stringDiff(original, text, false); var editOffset = model.offsetAt(Range.lift(range).getStartPosition()); for (var _b = 0, changes_1 = changes; _b < changes_1.length; _b++) { var change = changes_1[_b]; var start = model.positionAt(editOffset + change.originalStart); var end = model.positionAt(editOffset + change.originalStart + change.originalLength); var newEdit = { text: text.substr(change.modifiedStart, change.modifiedLength), range: { startLineNumber: start.lineNumber, startColumn: start.column, endLineNumber: end.lineNumber, endColumn: end.column } }; if (model.getValueInRange(newEdit.range) !== newEdit.text) { result.push(newEdit); } } } if (typeof lastEol === 'number') { result.push({ eol: lastEol, text: undefined, range: undefined }); } return Promise.resolve(result); }; // ---- END minimal edits --------------------------------------------------------------- BaseEditorSimpleWorker.prototype.computeLinks = function (modelUrl) { var model = this._getModel(modelUrl); if (!model) { return Promise.resolve(null); } return Promise.resolve(computeLinks(model)); }; BaseEditorSimpleWorker.prototype.textualSuggest = function (modelUrl, position, wordDef, wordDefFlags) { var model = this._getModel(modelUrl); if (!model) { return Promise.resolve(null); } var suggestions = []; var wordDefRegExp = new RegExp(wordDef, wordDefFlags); var currentWord = model.getWordUntilPosition(position, wordDefRegExp); var seen = Object.create(null); seen[currentWord.word] = true; for (var iter = model.createWordIterator(wordDefRegExp), e = iter.next(); !e.done && suggestions.length <= BaseEditorSimpleWorker._suggestionsLimit; e = iter.next()) { var word = e.value; if (seen[word]) { continue; } seen[word] = true; if (!isNaN(Number(word))) { continue; } suggestions.push({ kind: 18 /* Text */, label: word, insertText: word, range: { startLineNumber: position.lineNumber, startColumn: currentWord.startColumn, endLineNumber: position.lineNumber, endColumn: currentWord.endColumn } }); } return Promise.resolve({ suggestions: suggestions }); }; // ---- END suggest -------------------------------------------------------------------------- //#region -- word ranges -- BaseEditorSimpleWorker.prototype.computeWordRanges = function (modelUrl, range, wordDef, wordDefFlags) { var model = this._getModel(modelUrl); if (!model) { return Promise.resolve(Object.create(null)); } var wordDefRegExp = new RegExp(wordDef, wordDefFlags); var result = Object.create(null); for (var line = range.startLineNumber; line < range.endLineNumber; line++) { var words = model.getLineWords(line, wordDefRegExp); for (var _i = 0, words_1 = words; _i < words_1.length; _i++) { var word = words_1[_i]; if (!isNaN(Number(word.word))) { continue; } var array = result[word.word]; if (!array) { array = []; result[word.word] = array; } array.push({ startLineNumber: line, startColumn: word.startColumn, endLineNumber: line, endColumn: word.endColumn }); } } return Promise.resolve(result); }; //#endregion BaseEditorSimpleWorker.prototype.navigateValueSet = function (modelUrl, range, up, wordDef, wordDefFlags) { var model = this._getModel(modelUrl); if (!model) { return Promise.resolve(null); } var wordDefRegExp = new RegExp(wordDef, wordDefFlags); if (range.startColumn === range.endColumn) { range = { startLineNumber: range.startLineNumber, startColumn: range.startColumn, endLineNumber: range.endLineNumber, endColumn: range.endColumn + 1 }; } var selectionText = model.getValueInRange(range); var wordRange = model.getWordAtPosition({ lineNumber: range.startLineNumber, column: range.startColumn }, wordDefRegExp); if (!wordRange) { return Promise.resolve(null); } var word = model.getValueInRange(wordRange); var result = BasicInplaceReplace.INSTANCE.navigateValueSet(range, selectionText, wordRange, word, up); return Promise.resolve(result); }; // ---- BEGIN foreign module support -------------------------------------------------------------------------- BaseEditorSimpleWorker.prototype.loadForeignModule = function (moduleId, createData) { var _this = this; var ctx = { getMirrorModels: function () { return _this._getModels(); } }; if (this._foreignModuleFactory) { this._foreignModule = this._foreignModuleFactory(ctx, createData); // static foreing module var methods = []; for (var prop in this._foreignModule) { if (typeof this._foreignModule[prop] === 'function') { methods.push(prop); } } return Promise.resolve(methods); } // ESM-comment-begin // return new Promise<any>((resolve, reject) => { // require([moduleId], (foreignModule: { create: IForeignModuleFactory }) => { // this._foreignModule = foreignModule.create(ctx, createData); // // let methods: string[] = []; // for (let prop in this._foreignModule) { // if (typeof this._foreignModule[prop] === 'function') { // methods.push(prop); // } // } // // resolve(methods); // // }, reject); // }); // ESM-comment-end // ESM-uncomment-begin return Promise.reject(new Error("Unexpected usage")); // ESM-uncomment-end }; // foreign method request BaseEditorSimpleWorker.prototype.fmr = function (method, args) { if (!this._foreignModule || typeof this._foreignModule[method] !== 'function') { return Promise.reject(new Error('Missing requestHandler or method: ' + method)); } try { return Promise.resolve(this._foreignModule[method].apply(this._foreignModule, args)); } catch (e) { return Promise.reject(e); } }; // ---- END diff -------------------------------------------------------------------------- // ---- BEGIN minimal edits --------------------------------------------------------------- BaseEditorSimpleWorker._diffLimit = 10000; // ---- BEGIN suggest -------------------------------------------------------------------------- BaseEditorSimpleWorker._suggestionsLimit = 10000; return BaseEditorSimpleWorker; }()); export { BaseEditorSimpleWorker }; /** * @internal */ var EditorSimpleWorkerImpl = /** @class */ (function (_super) { __extends(EditorSimpleWorkerImpl, _super); function EditorSimpleWorkerImpl(foreignModuleFactory) { var _this = _super.call(this, foreignModuleFactory) || this; _this._models = Object.create(null); return _this; } EditorSimpleWorkerImpl.prototype.dispose = function () { this._models = Object.create(null); }; EditorSimpleWorkerImpl.prototype._getModel = function (uri) { return this._models[uri]; }; EditorSimpleWorkerImpl.prototype._getModels = function () { var _this = this; var all = []; Object.keys(this._models).forEach(function (key) { return all.push(_this._models[key]); }); return all; }; EditorSimpleWorkerImpl.prototype.acceptNewModel = function (data) { this._models[data.url] = new MirrorModel(URI.parse(data.url), data.lines, data.EOL, data.versionId); }; EditorSimpleWorkerImpl.prototype.acceptModelChanged = function (strURL, e) { if (!this._models[strURL]) { return; } var model = this._models[strURL]; model.onEvents(e); }; EditorSimpleWorkerImpl.prototype.acceptRemovedModel = function (strURL) { if (!this._models[strURL]) { return; } delete this._models[strURL]; }; return EditorSimpleWorkerImpl; }(BaseEditorSimpleWorker)); export { EditorSimpleWorkerImpl }; /** * Called on the worker side * @internal */ export function create() { return new EditorSimpleWorkerImpl(null); } if (typeof importScripts === 'function') { // Running in a web worker globals.monaco = createMonacoBaseAPI(); }