monaco-editor
Version:
A browser based code editor
946 lines • 56.9 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Position } from '../core/position.js';
import { Range } from '../core/range.js';
import { ModelDecorationOptions } from '../model/textModel.js';
import * as viewEvents from '../view/viewEvents.js';
import { PrefixSumComputerWithCache } from './prefixSumComputer.js';
import { ViewLineData } from './viewModel.js';
var OutputPosition = /** @class */ (function () {
function OutputPosition(outputLineIndex, outputOffset) {
this.outputLineIndex = outputLineIndex;
this.outputOffset = outputOffset;
}
return OutputPosition;
}());
export { OutputPosition };
var CoordinatesConverter = /** @class */ (function () {
function CoordinatesConverter(lines) {
this._lines = lines;
}
// View -> Model conversion and related methods
CoordinatesConverter.prototype.convertViewPositionToModelPosition = function (viewPosition) {
return this._lines.convertViewPositionToModelPosition(viewPosition.lineNumber, viewPosition.column);
};
CoordinatesConverter.prototype.convertViewRangeToModelRange = function (viewRange) {
var start = this._lines.convertViewPositionToModelPosition(viewRange.startLineNumber, viewRange.startColumn);
var end = this._lines.convertViewPositionToModelPosition(viewRange.endLineNumber, viewRange.endColumn);
return new Range(start.lineNumber, start.column, end.lineNumber, end.column);
};
CoordinatesConverter.prototype.validateViewPosition = function (viewPosition, expectedModelPosition) {
return this._lines.validateViewPosition(viewPosition.lineNumber, viewPosition.column, expectedModelPosition);
};
CoordinatesConverter.prototype.validateViewRange = function (viewRange, expectedModelRange) {
var validViewStart = this._lines.validateViewPosition(viewRange.startLineNumber, viewRange.startColumn, expectedModelRange.getStartPosition());
var validViewEnd = this._lines.validateViewPosition(viewRange.endLineNumber, viewRange.endColumn, expectedModelRange.getEndPosition());
return new Range(validViewStart.lineNumber, validViewStart.column, validViewEnd.lineNumber, validViewEnd.column);
};
// Model -> View conversion and related methods
CoordinatesConverter.prototype.convertModelPositionToViewPosition = function (modelPosition) {
return this._lines.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column);
};
CoordinatesConverter.prototype.convertModelRangeToViewRange = function (modelRange) {
var start = this._lines.convertModelPositionToViewPosition(modelRange.startLineNumber, modelRange.startColumn);
var end = this._lines.convertModelPositionToViewPosition(modelRange.endLineNumber, modelRange.endColumn);
return new Range(start.lineNumber, start.column, end.lineNumber, end.column);
};
CoordinatesConverter.prototype.modelPositionIsVisible = function (modelPosition) {
return this._lines.modelPositionIsVisible(modelPosition.lineNumber, modelPosition.column);
};
return CoordinatesConverter;
}());
export { CoordinatesConverter };
var SplitLinesCollection = /** @class */ (function () {
function SplitLinesCollection(model, linePositionMapperFactory, tabSize, wrappingColumn, columnsForFullWidthChar, wrappingIndent) {
this.model = model;
this._validModelVersionId = -1;
this.tabSize = tabSize;
this.wrappingColumn = wrappingColumn;
this.columnsForFullWidthChar = columnsForFullWidthChar;
this.wrappingIndent = wrappingIndent;
this.linePositionMapperFactory = linePositionMapperFactory;
this._constructLines(true);
}
SplitLinesCollection.prototype.dispose = function () {
this.hiddenAreasIds = this.model.deltaDecorations(this.hiddenAreasIds, []);
};
SplitLinesCollection.prototype.createCoordinatesConverter = function () {
return new CoordinatesConverter(this);
};
SplitLinesCollection.prototype._ensureValidState = function () {
var modelVersion = this.model.getVersionId();
if (modelVersion !== this._validModelVersionId) {
// This is pretty bad, it means we lost track of the model...
throw new Error("ViewModel is out of sync with Model!");
}
if (this.lines.length !== this.model.getLineCount()) {
// This is pretty bad, it means we lost track of the model...
this._constructLines(false);
}
};
SplitLinesCollection.prototype._constructLines = function (resetHiddenAreas) {
var _this = this;
this.lines = [];
if (resetHiddenAreas) {
this.hiddenAreasIds = [];
}
var linesContent = this.model.getLinesContent();
var lineCount = linesContent.length;
var values = new Uint32Array(lineCount);
var hiddenAreas = this.hiddenAreasIds.map(function (areaId) { return _this.model.getDecorationRange(areaId); }).sort(Range.compareRangesUsingStarts);
var hiddenAreaStart = 1, hiddenAreaEnd = 0;
var hiddenAreaIdx = -1;
var nextLineNumberToUpdateHiddenArea = (hiddenAreaIdx + 1 < hiddenAreas.length) ? hiddenAreaEnd + 1 : lineCount + 2;
for (var i = 0; i < lineCount; i++) {
var lineNumber = i + 1;
if (lineNumber === nextLineNumberToUpdateHiddenArea) {
hiddenAreaIdx++;
hiddenAreaStart = hiddenAreas[hiddenAreaIdx].startLineNumber;
hiddenAreaEnd = hiddenAreas[hiddenAreaIdx].endLineNumber;
nextLineNumberToUpdateHiddenArea = (hiddenAreaIdx + 1 < hiddenAreas.length) ? hiddenAreaEnd + 1 : lineCount + 2;
}
var isInHiddenArea = (lineNumber >= hiddenAreaStart && lineNumber <= hiddenAreaEnd);
var line = createSplitLine(this.linePositionMapperFactory, linesContent[i], this.tabSize, this.wrappingColumn, this.columnsForFullWidthChar, this.wrappingIndent, !isInHiddenArea);
values[i] = line.getViewLineCount();
this.lines[i] = line;
}
this._validModelVersionId = this.model.getVersionId();
this.prefixSumComputer = new PrefixSumComputerWithCache(values);
};
SplitLinesCollection.prototype.getHiddenAreas = function () {
var _this = this;
return this.hiddenAreasIds.map(function (decId) {
return _this.model.getDecorationRange(decId);
});
};
SplitLinesCollection.prototype._reduceRanges = function (_ranges) {
var _this = this;
if (_ranges.length === 0) {
return [];
}
var ranges = _ranges.map(function (r) { return _this.model.validateRange(r); }).sort(Range.compareRangesUsingStarts);
var result = [];
var currentRangeStart = ranges[0].startLineNumber;
var currentRangeEnd = ranges[0].endLineNumber;
for (var i = 1, len = ranges.length; i < len; i++) {
var range = ranges[i];
if (range.startLineNumber > currentRangeEnd + 1) {
result.push(new Range(currentRangeStart, 1, currentRangeEnd, 1));
currentRangeStart = range.startLineNumber;
currentRangeEnd = range.endLineNumber;
}
else if (range.endLineNumber > currentRangeEnd) {
currentRangeEnd = range.endLineNumber;
}
}
result.push(new Range(currentRangeStart, 1, currentRangeEnd, 1));
return result;
};
SplitLinesCollection.prototype.setHiddenAreas = function (_ranges) {
var _this = this;
var newRanges = this._reduceRanges(_ranges);
// BEGIN TODO@Martin: Please stop calling this method on each model change!
var oldRanges = this.hiddenAreasIds.map(function (areaId) { return _this.model.getDecorationRange(areaId); }).sort(Range.compareRangesUsingStarts);
if (newRanges.length === oldRanges.length) {
var hasDifference = false;
for (var i = 0; i < newRanges.length; i++) {
if (!newRanges[i].equalsRange(oldRanges[i])) {
hasDifference = true;
break;
}
}
if (!hasDifference) {
return false;
}
}
// END TODO@Martin: Please stop calling this method on each model change!
var newDecorations = [];
for (var i = 0; i < newRanges.length; i++) {
newDecorations.push({
range: newRanges[i],
options: ModelDecorationOptions.EMPTY
});
}
this.hiddenAreasIds = this.model.deltaDecorations(this.hiddenAreasIds, newDecorations);
var hiddenAreas = newRanges;
var hiddenAreaStart = 1, hiddenAreaEnd = 0;
var hiddenAreaIdx = -1;
var nextLineNumberToUpdateHiddenArea = (hiddenAreaIdx + 1 < hiddenAreas.length) ? hiddenAreaEnd + 1 : this.lines.length + 2;
var hasVisibleLine = false;
for (var i = 0; i < this.lines.length; i++) {
var lineNumber = i + 1;
if (lineNumber === nextLineNumberToUpdateHiddenArea) {
hiddenAreaIdx++;
hiddenAreaStart = hiddenAreas[hiddenAreaIdx].startLineNumber;
hiddenAreaEnd = hiddenAreas[hiddenAreaIdx].endLineNumber;
nextLineNumberToUpdateHiddenArea = (hiddenAreaIdx + 1 < hiddenAreas.length) ? hiddenAreaEnd + 1 : this.lines.length + 2;
}
var lineChanged = false;
if (lineNumber >= hiddenAreaStart && lineNumber <= hiddenAreaEnd) {
// Line should be hidden
if (this.lines[i].isVisible()) {
this.lines[i] = this.lines[i].setVisible(false);
lineChanged = true;
}
}
else {
hasVisibleLine = true;
// Line should be visible
if (!this.lines[i].isVisible()) {
this.lines[i] = this.lines[i].setVisible(true);
lineChanged = true;
}
}
if (lineChanged) {
var newOutputLineCount = this.lines[i].getViewLineCount();
this.prefixSumComputer.changeValue(i, newOutputLineCount);
}
}
if (!hasVisibleLine) {
// Cannot have everything be hidden => reveal everything!
this.setHiddenAreas([]);
}
return true;
};
SplitLinesCollection.prototype.modelPositionIsVisible = function (modelLineNumber, _modelColumn) {
if (modelLineNumber < 1 || modelLineNumber > this.lines.length) {
// invalid arguments
return false;
}
return this.lines[modelLineNumber - 1].isVisible();
};
SplitLinesCollection.prototype.setTabSize = function (newTabSize) {
if (this.tabSize === newTabSize) {
return false;
}
this.tabSize = newTabSize;
this._constructLines(false);
return true;
};
SplitLinesCollection.prototype.setWrappingSettings = function (wrappingIndent, wrappingColumn, columnsForFullWidthChar) {
if (this.wrappingIndent === wrappingIndent && this.wrappingColumn === wrappingColumn && this.columnsForFullWidthChar === columnsForFullWidthChar) {
return false;
}
this.wrappingIndent = wrappingIndent;
this.wrappingColumn = wrappingColumn;
this.columnsForFullWidthChar = columnsForFullWidthChar;
this._constructLines(false);
return true;
};
SplitLinesCollection.prototype.onModelFlushed = function () {
this._constructLines(true);
};
SplitLinesCollection.prototype.onModelLinesDeleted = function (versionId, fromLineNumber, toLineNumber) {
if (versionId <= this._validModelVersionId) {
// Here we check for versionId in case the lines were reconstructed in the meantime.
// We don't want to apply stale change events on top of a newer read model state.
return null;
}
var outputFromLineNumber = (fromLineNumber === 1 ? 1 : this.prefixSumComputer.getAccumulatedValue(fromLineNumber - 2) + 1);
var outputToLineNumber = this.prefixSumComputer.getAccumulatedValue(toLineNumber - 1);
this.lines.splice(fromLineNumber - 1, toLineNumber - fromLineNumber + 1);
this.prefixSumComputer.removeValues(fromLineNumber - 1, toLineNumber - fromLineNumber + 1);
return new viewEvents.ViewLinesDeletedEvent(outputFromLineNumber, outputToLineNumber);
};
SplitLinesCollection.prototype.onModelLinesInserted = function (versionId, fromLineNumber, _toLineNumber, text) {
if (versionId <= this._validModelVersionId) {
// Here we check for versionId in case the lines were reconstructed in the meantime.
// We don't want to apply stale change events on top of a newer read model state.
return null;
}
var hiddenAreas = this.getHiddenAreas();
var isInHiddenArea = false;
var testPosition = new Position(fromLineNumber, 1);
for (var i = 0; i < hiddenAreas.length; i++) {
if (hiddenAreas[i].containsPosition(testPosition)) {
isInHiddenArea = true;
break;
}
}
var outputFromLineNumber = (fromLineNumber === 1 ? 1 : this.prefixSumComputer.getAccumulatedValue(fromLineNumber - 2) + 1);
var totalOutputLineCount = 0;
var insertLines = [];
var insertPrefixSumValues = new Uint32Array(text.length);
for (var i = 0, len = text.length; i < len; i++) {
var line = createSplitLine(this.linePositionMapperFactory, text[i], this.tabSize, this.wrappingColumn, this.columnsForFullWidthChar, this.wrappingIndent, !isInHiddenArea);
insertLines.push(line);
var outputLineCount = line.getViewLineCount();
totalOutputLineCount += outputLineCount;
insertPrefixSumValues[i] = outputLineCount;
}
// TODO@Alex: use arrays.arrayInsert
this.lines = this.lines.slice(0, fromLineNumber - 1).concat(insertLines).concat(this.lines.slice(fromLineNumber - 1));
this.prefixSumComputer.insertValues(fromLineNumber - 1, insertPrefixSumValues);
return new viewEvents.ViewLinesInsertedEvent(outputFromLineNumber, outputFromLineNumber + totalOutputLineCount - 1);
};
SplitLinesCollection.prototype.onModelLineChanged = function (versionId, lineNumber, newText) {
if (versionId <= this._validModelVersionId) {
// Here we check for versionId in case the lines were reconstructed in the meantime.
// We don't want to apply stale change events on top of a newer read model state.
return [false, null, null, null];
}
var lineIndex = lineNumber - 1;
var oldOutputLineCount = this.lines[lineIndex].getViewLineCount();
var isVisible = this.lines[lineIndex].isVisible();
var line = createSplitLine(this.linePositionMapperFactory, newText, this.tabSize, this.wrappingColumn, this.columnsForFullWidthChar, this.wrappingIndent, isVisible);
this.lines[lineIndex] = line;
var newOutputLineCount = this.lines[lineIndex].getViewLineCount();
var lineMappingChanged = false;
var changeFrom = 0;
var changeTo = -1;
var insertFrom = 0;
var insertTo = -1;
var deleteFrom = 0;
var deleteTo = -1;
if (oldOutputLineCount > newOutputLineCount) {
changeFrom = (lineNumber === 1 ? 1 : this.prefixSumComputer.getAccumulatedValue(lineNumber - 2) + 1);
changeTo = changeFrom + newOutputLineCount - 1;
deleteFrom = changeTo + 1;
deleteTo = deleteFrom + (oldOutputLineCount - newOutputLineCount) - 1;
lineMappingChanged = true;
}
else if (oldOutputLineCount < newOutputLineCount) {
changeFrom = (lineNumber === 1 ? 1 : this.prefixSumComputer.getAccumulatedValue(lineNumber - 2) + 1);
changeTo = changeFrom + oldOutputLineCount - 1;
insertFrom = changeTo + 1;
insertTo = insertFrom + (newOutputLineCount - oldOutputLineCount) - 1;
lineMappingChanged = true;
}
else {
changeFrom = (lineNumber === 1 ? 1 : this.prefixSumComputer.getAccumulatedValue(lineNumber - 2) + 1);
changeTo = changeFrom + newOutputLineCount - 1;
}
this.prefixSumComputer.changeValue(lineIndex, newOutputLineCount);
var viewLinesChangedEvent = (changeFrom <= changeTo ? new viewEvents.ViewLinesChangedEvent(changeFrom, changeTo) : null);
var viewLinesInsertedEvent = (insertFrom <= insertTo ? new viewEvents.ViewLinesInsertedEvent(insertFrom, insertTo) : null);
var viewLinesDeletedEvent = (deleteFrom <= deleteTo ? new viewEvents.ViewLinesDeletedEvent(deleteFrom, deleteTo) : null);
return [lineMappingChanged, viewLinesChangedEvent, viewLinesInsertedEvent, viewLinesDeletedEvent];
};
SplitLinesCollection.prototype.acceptVersionId = function (versionId) {
this._validModelVersionId = versionId;
if (this.lines.length === 1 && !this.lines[0].isVisible()) {
// At least one line must be visible => reset hidden areas
this.setHiddenAreas([]);
}
};
SplitLinesCollection.prototype.getViewLineCount = function () {
this._ensureValidState();
return this.prefixSumComputer.getTotalValue();
};
SplitLinesCollection.prototype._toValidViewLineNumber = function (viewLineNumber) {
if (viewLineNumber < 1) {
return 1;
}
var viewLineCount = this.getViewLineCount();
if (viewLineNumber > viewLineCount) {
return viewLineCount;
}
return viewLineNumber;
};
/**
* Gives a hint that a lot of requests are about to come in for these line numbers.
*/
SplitLinesCollection.prototype.warmUpLookupCache = function (viewStartLineNumber, viewEndLineNumber) {
this.prefixSumComputer.warmUpCache(viewStartLineNumber - 1, viewEndLineNumber - 1);
};
SplitLinesCollection.prototype.getActiveIndentGuide = function (viewLineNumber, minLineNumber, maxLineNumber) {
this._ensureValidState();
viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
minLineNumber = this._toValidViewLineNumber(minLineNumber);
maxLineNumber = this._toValidViewLineNumber(maxLineNumber);
var modelPosition = this.convertViewPositionToModelPosition(viewLineNumber, this.getViewLineMinColumn(viewLineNumber));
var modelMinPosition = this.convertViewPositionToModelPosition(minLineNumber, this.getViewLineMinColumn(minLineNumber));
var modelMaxPosition = this.convertViewPositionToModelPosition(maxLineNumber, this.getViewLineMinColumn(maxLineNumber));
var result = this.model.getActiveIndentGuide(modelPosition.lineNumber, modelMinPosition.lineNumber, modelMaxPosition.lineNumber);
var viewStartPosition = this.convertModelPositionToViewPosition(result.startLineNumber, 1);
var viewEndPosition = this.convertModelPositionToViewPosition(result.endLineNumber, this.model.getLineMaxColumn(result.endLineNumber));
return {
startLineNumber: viewStartPosition.lineNumber,
endLineNumber: viewEndPosition.lineNumber,
indent: result.indent
};
};
SplitLinesCollection.prototype.getViewLinesIndentGuides = function (viewStartLineNumber, viewEndLineNumber) {
this._ensureValidState();
viewStartLineNumber = this._toValidViewLineNumber(viewStartLineNumber);
viewEndLineNumber = this._toValidViewLineNumber(viewEndLineNumber);
var modelStart = this.convertViewPositionToModelPosition(viewStartLineNumber, this.getViewLineMinColumn(viewStartLineNumber));
var modelEnd = this.convertViewPositionToModelPosition(viewEndLineNumber, this.getViewLineMaxColumn(viewEndLineNumber));
var result = [];
var resultRepeatCount = [];
var resultRepeatOption = [];
var modelStartLineIndex = modelStart.lineNumber - 1;
var modelEndLineIndex = modelEnd.lineNumber - 1;
var reqStart = null;
for (var modelLineIndex = modelStartLineIndex; modelLineIndex <= modelEndLineIndex; modelLineIndex++) {
var line = this.lines[modelLineIndex];
if (line.isVisible()) {
var viewLineStartIndex = line.getViewLineNumberOfModelPosition(0, modelLineIndex === modelStartLineIndex ? modelStart.column : 1);
var viewLineEndIndex = line.getViewLineNumberOfModelPosition(0, this.model.getLineMaxColumn(modelLineIndex + 1));
var count = viewLineEndIndex - viewLineStartIndex + 1;
var option = 0 /* BlockNone */;
if (count > 1 && line.getViewLineMinColumn(this.model, modelLineIndex + 1, viewLineEndIndex) === 1) {
// wrapped lines should block indent guides
option = (viewLineStartIndex === 0 ? 1 /* BlockSubsequent */ : 2 /* BlockAll */);
}
resultRepeatCount.push(count);
resultRepeatOption.push(option);
// merge into previous request
if (reqStart === null) {
reqStart = new Position(modelLineIndex + 1, 0);
}
}
else {
// hit invisible line => flush request
if (reqStart !== null) {
result = result.concat(this.model.getLinesIndentGuides(reqStart.lineNumber, modelLineIndex));
reqStart = null;
}
}
}
if (reqStart !== null) {
result = result.concat(this.model.getLinesIndentGuides(reqStart.lineNumber, modelEnd.lineNumber));
reqStart = null;
}
var viewLineCount = viewEndLineNumber - viewStartLineNumber + 1;
var viewIndents = new Array(viewLineCount);
var currIndex = 0;
for (var i = 0, len = result.length; i < len; i++) {
var value = result[i];
var count = Math.min(viewLineCount - currIndex, resultRepeatCount[i]);
var option = resultRepeatOption[i];
var blockAtIndex = void 0;
if (option === 2 /* BlockAll */) {
blockAtIndex = 0;
}
else if (option === 1 /* BlockSubsequent */) {
blockAtIndex = 1;
}
else {
blockAtIndex = count;
}
for (var j = 0; j < count; j++) {
if (j === blockAtIndex) {
value = 0;
}
viewIndents[currIndex++] = value;
}
}
return viewIndents;
};
SplitLinesCollection.prototype.getViewLineContent = function (viewLineNumber) {
this._ensureValidState();
viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
var r = this.prefixSumComputer.getIndexOf(viewLineNumber - 1);
var lineIndex = r.index;
var remainder = r.remainder;
return this.lines[lineIndex].getViewLineContent(this.model, lineIndex + 1, remainder);
};
SplitLinesCollection.prototype.getViewLineLength = function (viewLineNumber) {
this._ensureValidState();
viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
var r = this.prefixSumComputer.getIndexOf(viewLineNumber - 1);
var lineIndex = r.index;
var remainder = r.remainder;
return this.lines[lineIndex].getViewLineLength(this.model, lineIndex + 1, remainder);
};
SplitLinesCollection.prototype.getViewLineMinColumn = function (viewLineNumber) {
this._ensureValidState();
viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
var r = this.prefixSumComputer.getIndexOf(viewLineNumber - 1);
var lineIndex = r.index;
var remainder = r.remainder;
return this.lines[lineIndex].getViewLineMinColumn(this.model, lineIndex + 1, remainder);
};
SplitLinesCollection.prototype.getViewLineMaxColumn = function (viewLineNumber) {
this._ensureValidState();
viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
var r = this.prefixSumComputer.getIndexOf(viewLineNumber - 1);
var lineIndex = r.index;
var remainder = r.remainder;
return this.lines[lineIndex].getViewLineMaxColumn(this.model, lineIndex + 1, remainder);
};
SplitLinesCollection.prototype.getViewLineData = function (viewLineNumber) {
this._ensureValidState();
viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
var r = this.prefixSumComputer.getIndexOf(viewLineNumber - 1);
var lineIndex = r.index;
var remainder = r.remainder;
return this.lines[lineIndex].getViewLineData(this.model, lineIndex + 1, remainder);
};
SplitLinesCollection.prototype.getViewLinesData = function (viewStartLineNumber, viewEndLineNumber, needed) {
this._ensureValidState();
viewStartLineNumber = this._toValidViewLineNumber(viewStartLineNumber);
viewEndLineNumber = this._toValidViewLineNumber(viewEndLineNumber);
var start = this.prefixSumComputer.getIndexOf(viewStartLineNumber - 1);
var viewLineNumber = viewStartLineNumber;
var startModelLineIndex = start.index;
var startRemainder = start.remainder;
var result = [];
for (var modelLineIndex = startModelLineIndex, len = this.model.getLineCount(); modelLineIndex < len; modelLineIndex++) {
var line = this.lines[modelLineIndex];
if (!line.isVisible()) {
continue;
}
var fromViewLineIndex = (modelLineIndex === startModelLineIndex ? startRemainder : 0);
var remainingViewLineCount = line.getViewLineCount() - fromViewLineIndex;
var lastLine = false;
if (viewLineNumber + remainingViewLineCount > viewEndLineNumber) {
lastLine = true;
remainingViewLineCount = viewEndLineNumber - viewLineNumber + 1;
}
var toViewLineIndex = fromViewLineIndex + remainingViewLineCount;
line.getViewLinesData(this.model, modelLineIndex + 1, fromViewLineIndex, toViewLineIndex, viewLineNumber - viewStartLineNumber, needed, result);
viewLineNumber += remainingViewLineCount;
if (lastLine) {
break;
}
}
return result;
};
SplitLinesCollection.prototype.validateViewPosition = function (viewLineNumber, viewColumn, expectedModelPosition) {
this._ensureValidState();
viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
var r = this.prefixSumComputer.getIndexOf(viewLineNumber - 1);
var lineIndex = r.index;
var remainder = r.remainder;
var line = this.lines[lineIndex];
var minColumn = line.getViewLineMinColumn(this.model, lineIndex + 1, remainder);
var maxColumn = line.getViewLineMaxColumn(this.model, lineIndex + 1, remainder);
if (viewColumn < minColumn) {
viewColumn = minColumn;
}
if (viewColumn > maxColumn) {
viewColumn = maxColumn;
}
var computedModelColumn = line.getModelColumnOfViewPosition(remainder, viewColumn);
var computedModelPosition = this.model.validatePosition(new Position(lineIndex + 1, computedModelColumn));
if (computedModelPosition.equals(expectedModelPosition)) {
return new Position(viewLineNumber, viewColumn);
}
return this.convertModelPositionToViewPosition(expectedModelPosition.lineNumber, expectedModelPosition.column);
};
SplitLinesCollection.prototype.convertViewPositionToModelPosition = function (viewLineNumber, viewColumn) {
this._ensureValidState();
viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
var r = this.prefixSumComputer.getIndexOf(viewLineNumber - 1);
var lineIndex = r.index;
var remainder = r.remainder;
var inputColumn = this.lines[lineIndex].getModelColumnOfViewPosition(remainder, viewColumn);
// console.log('out -> in ' + viewLineNumber + ',' + viewColumn + ' ===> ' + (lineIndex+1) + ',' + inputColumn);
return this.model.validatePosition(new Position(lineIndex + 1, inputColumn));
};
SplitLinesCollection.prototype.convertModelPositionToViewPosition = function (_modelLineNumber, _modelColumn) {
this._ensureValidState();
var validPosition = this.model.validatePosition(new Position(_modelLineNumber, _modelColumn));
var inputLineNumber = validPosition.lineNumber;
var inputColumn = validPosition.column;
var lineIndex = inputLineNumber - 1, lineIndexChanged = false;
while (lineIndex > 0 && !this.lines[lineIndex].isVisible()) {
lineIndex--;
lineIndexChanged = true;
}
if (lineIndex === 0 && !this.lines[lineIndex].isVisible()) {
// Could not reach a real line
// console.log('in -> out ' + inputLineNumber + ',' + inputColumn + ' ===> ' + 1 + ',' + 1);
return new Position(1, 1);
}
var deltaLineNumber = 1 + (lineIndex === 0 ? 0 : this.prefixSumComputer.getAccumulatedValue(lineIndex - 1));
var r;
if (lineIndexChanged) {
r = this.lines[lineIndex].getViewPositionOfModelPosition(deltaLineNumber, this.model.getLineMaxColumn(lineIndex + 1));
}
else {
r = this.lines[inputLineNumber - 1].getViewPositionOfModelPosition(deltaLineNumber, inputColumn);
}
// console.log('in -> out ' + inputLineNumber + ',' + inputColumn + ' ===> ' + r.lineNumber + ',' + r);
return r;
};
SplitLinesCollection.prototype._getViewLineNumberForModelPosition = function (inputLineNumber, inputColumn) {
var lineIndex = inputLineNumber - 1;
if (this.lines[lineIndex].isVisible()) {
// this model line is visible
var deltaLineNumber_1 = 1 + (lineIndex === 0 ? 0 : this.prefixSumComputer.getAccumulatedValue(lineIndex - 1));
return this.lines[lineIndex].getViewLineNumberOfModelPosition(deltaLineNumber_1, inputColumn);
}
// this model line is not visible
while (lineIndex > 0 && !this.lines[lineIndex].isVisible()) {
lineIndex--;
}
if (lineIndex === 0 && !this.lines[lineIndex].isVisible()) {
// Could not reach a real line
return 1;
}
var deltaLineNumber = 1 + (lineIndex === 0 ? 0 : this.prefixSumComputer.getAccumulatedValue(lineIndex - 1));
return this.lines[lineIndex].getViewLineNumberOfModelPosition(deltaLineNumber, this.model.getLineMaxColumn(lineIndex + 1));
};
SplitLinesCollection.prototype.getAllOverviewRulerDecorations = function (ownerId, filterOutValidation, theme) {
var decorations = this.model.getOverviewRulerDecorations(ownerId, filterOutValidation);
var result = new OverviewRulerDecorations();
for (var i = 0, len = decorations.length; i < len; i++) {
var decoration = decorations[i];
var opts = decoration.options.overviewRuler;
var lane = opts ? opts.position : 0;
if (lane === 0) {
continue;
}
var color = opts.getColor(theme);
var viewStartLineNumber = this._getViewLineNumberForModelPosition(decoration.range.startLineNumber, decoration.range.startColumn);
var viewEndLineNumber = this._getViewLineNumberForModelPosition(decoration.range.endLineNumber, decoration.range.endColumn);
result.accept(color, viewStartLineNumber, viewEndLineNumber, lane);
}
return result.result;
};
SplitLinesCollection.prototype.getDecorationsInRange = function (range, ownerId, filterOutValidation) {
var modelStart = this.convertViewPositionToModelPosition(range.startLineNumber, range.startColumn);
var modelEnd = this.convertViewPositionToModelPosition(range.endLineNumber, range.endColumn);
if (modelEnd.lineNumber - modelStart.lineNumber <= range.endLineNumber - range.startLineNumber) {
// most likely there are no hidden lines => fast path
// fetch decorations from column 1 to cover the case of wrapped lines that have whole line decorations at column 1
return this.model.getDecorationsInRange(new Range(modelStart.lineNumber, 1, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation);
}
var result = [];
var modelStartLineIndex = modelStart.lineNumber - 1;
var modelEndLineIndex = modelEnd.lineNumber - 1;
var reqStart = null;
for (var modelLineIndex = modelStartLineIndex; modelLineIndex <= modelEndLineIndex; modelLineIndex++) {
var line = this.lines[modelLineIndex];
if (line.isVisible()) {
// merge into previous request
if (reqStart === null) {
reqStart = new Position(modelLineIndex + 1, modelLineIndex === modelStartLineIndex ? modelStart.column : 1);
}
}
else {
// hit invisible line => flush request
if (reqStart !== null) {
var maxLineColumn = this.model.getLineMaxColumn(modelLineIndex);
result = result.concat(this.model.getDecorationsInRange(new Range(reqStart.lineNumber, reqStart.column, modelLineIndex, maxLineColumn), ownerId, filterOutValidation));
reqStart = null;
}
}
}
if (reqStart !== null) {
result = result.concat(this.model.getDecorationsInRange(new Range(reqStart.lineNumber, reqStart.column, modelEnd.lineNumber, modelEnd.column), ownerId, filterOutValidation));
reqStart = null;
}
result.sort(function (a, b) {
var res = Range.compareRangesUsingStarts(a.range, b.range);
if (res === 0) {
if (a.id < b.id) {
return -1;
}
if (a.id > b.id) {
return 1;
}
return 0;
}
return res;
});
// Eliminate duplicate decorations that might have intersected our visible ranges multiple times
var finalResult = [], finalResultLen = 0;
var prevDecId = null;
for (var i = 0, len = result.length; i < len; i++) {
var dec = result[i];
var decId = dec.id;
if (prevDecId === decId) {
// skip
continue;
}
prevDecId = decId;
finalResult[finalResultLen++] = dec;
}
return finalResult;
};
return SplitLinesCollection;
}());
export { SplitLinesCollection };
var VisibleIdentitySplitLine = /** @class */ (function () {
function VisibleIdentitySplitLine() {
}
VisibleIdentitySplitLine.prototype.isVisible = function () {
return true;
};
VisibleIdentitySplitLine.prototype.setVisible = function (isVisible) {
if (isVisible) {
return this;
}
return InvisibleIdentitySplitLine.INSTANCE;
};
VisibleIdentitySplitLine.prototype.getViewLineCount = function () {
return 1;
};
VisibleIdentitySplitLine.prototype.getViewLineContent = function (model, modelLineNumber, _outputLineIndex) {
return model.getLineContent(modelLineNumber);
};
VisibleIdentitySplitLine.prototype.getViewLineLength = function (model, modelLineNumber, _outputLineIndex) {
return model.getLineLength(modelLineNumber);
};
VisibleIdentitySplitLine.prototype.getViewLineMinColumn = function (model, modelLineNumber, _outputLineIndex) {
return model.getLineMinColumn(modelLineNumber);
};
VisibleIdentitySplitLine.prototype.getViewLineMaxColumn = function (model, modelLineNumber, _outputLineIndex) {
return model.getLineMaxColumn(modelLineNumber);
};
VisibleIdentitySplitLine.prototype.getViewLineData = function (model, modelLineNumber, _outputLineIndex) {
var lineTokens = model.getLineTokens(modelLineNumber);
var lineContent = lineTokens.getLineContent();
return new ViewLineData(lineContent, false, 1, lineContent.length + 1, lineTokens.inflate());
};
VisibleIdentitySplitLine.prototype.getViewLinesData = function (model, modelLineNumber, _fromOuputLineIndex, _toOutputLineIndex, globalStartIndex, needed, result) {
if (!needed[globalStartIndex]) {
result[globalStartIndex] = null;
return;
}
result[globalStartIndex] = this.getViewLineData(model, modelLineNumber, 0);
};
VisibleIdentitySplitLine.prototype.getModelColumnOfViewPosition = function (_outputLineIndex, outputColumn) {
return outputColumn;
};
VisibleIdentitySplitLine.prototype.getViewPositionOfModelPosition = function (deltaLineNumber, inputColumn) {
return new Position(deltaLineNumber, inputColumn);
};
VisibleIdentitySplitLine.prototype.getViewLineNumberOfModelPosition = function (deltaLineNumber, _inputColumn) {
return deltaLineNumber;
};
VisibleIdentitySplitLine.INSTANCE = new VisibleIdentitySplitLine();
return VisibleIdentitySplitLine;
}());
var InvisibleIdentitySplitLine = /** @class */ (function () {
function InvisibleIdentitySplitLine() {
}
InvisibleIdentitySplitLine.prototype.isVisible = function () {
return false;
};
InvisibleIdentitySplitLine.prototype.setVisible = function (isVisible) {
if (!isVisible) {
return this;
}
return VisibleIdentitySplitLine.INSTANCE;
};
InvisibleIdentitySplitLine.prototype.getViewLineCount = function () {
return 0;
};
InvisibleIdentitySplitLine.prototype.getViewLineContent = function (_model, _modelLineNumber, _outputLineIndex) {
throw new Error('Not supported');
};
InvisibleIdentitySplitLine.prototype.getViewLineLength = function (_model, _modelLineNumber, _outputLineIndex) {
throw new Error('Not supported');
};
InvisibleIdentitySplitLine.prototype.getViewLineMinColumn = function (_model, _modelLineNumber, _outputLineIndex) {
throw new Error('Not supported');
};
InvisibleIdentitySplitLine.prototype.getViewLineMaxColumn = function (_model, _modelLineNumber, _outputLineIndex) {
throw new Error('Not supported');
};
InvisibleIdentitySplitLine.prototype.getViewLineData = function (_model, _modelLineNumber, _outputLineIndex) {
throw new Error('Not supported');
};
InvisibleIdentitySplitLine.prototype.getViewLinesData = function (_model, _modelLineNumber, _fromOuputLineIndex, _toOutputLineIndex, _globalStartIndex, _needed, _result) {
throw new Error('Not supported');
};
InvisibleIdentitySplitLine.prototype.getModelColumnOfViewPosition = function (_outputLineIndex, _outputColumn) {
throw new Error('Not supported');
};
InvisibleIdentitySplitLine.prototype.getViewPositionOfModelPosition = function (_deltaLineNumber, _inputColumn) {
throw new Error('Not supported');
};
InvisibleIdentitySplitLine.prototype.getViewLineNumberOfModelPosition = function (_deltaLineNumber, _inputColumn) {
throw new Error('Not supported');
};
InvisibleIdentitySplitLine.INSTANCE = new InvisibleIdentitySplitLine();
return InvisibleIdentitySplitLine;
}());
var SplitLine = /** @class */ (function () {
function SplitLine(positionMapper, isVisible) {
this.positionMapper = positionMapper;
this.wrappedIndent = this.positionMapper.getWrappedLinesIndent();
this.wrappedIndentLength = this.wrappedIndent.length;
this.outputLineCount = this.positionMapper.getOutputLineCount();
this._isVisible = isVisible;
}
SplitLine.prototype.isVisible = function () {
return this._isVisible;
};
SplitLine.prototype.setVisible = function (isVisible) {
this._isVisible = isVisible;
return this;
};
SplitLine.prototype.getViewLineCount = function () {
if (!this._isVisible) {
return 0;
}
return this.outputLineCount;
};
SplitLine.prototype.getInputStartOffsetOfOutputLineIndex = function (outputLineIndex) {
return this.positionMapper.getInputOffsetOfOutputPosition(outputLineIndex, 0);
};
SplitLine.prototype.getInputEndOffsetOfOutputLineIndex = function (model, modelLineNumber, outputLineIndex) {
if (outputLineIndex + 1 === this.outputLineCount) {
return model.getLineMaxColumn(modelLineNumber) - 1;
}
return this.positionMapper.getInputOffsetOfOutputPosition(outputLineIndex + 1, 0);
};
SplitLine.prototype.getViewLineContent = function (model, modelLineNumber, outputLineIndex) {
if (!this._isVisible) {
throw new Error('Not supported');
}
var startOffset = this.getInputStartOffsetOfOutputLineIndex(outputLineIndex);
var endOffset = this.getInputEndOffsetOfOutputLineIndex(model, modelLineNumber, outputLineIndex);
var r = model.getValueInRange({
startLineNumber: modelLineNumber,
startColumn: startOffset + 1,
endLineNumber: modelLineNumber,
endColumn: endOffset + 1
});
if (outputLineIndex > 0) {
r = this.wrappedIndent + r;
}
return r;
};
SplitLine.prototype.getViewLineLength = function (model, modelLineNumber, outputLineIndex) {
if (!this._isVisible) {
throw new Error('Not supported');
}
var startOffset = this.getInputStartOffsetOfOutputLineIndex(outputLineIndex);
var endOffset = this.getInputEndOffsetOfOutputLineIndex(model, modelLineNumber, outputLineIndex);
var r = endOffset - startOffset;
if (outputLineIndex > 0) {
r = this.wrappedIndent.length + r;
}
return r;
};
SplitLine.prototype.getViewLineMinColumn = function (_model, _modelLineNumber, outputLineIndex) {
if (!this._isVisible) {
throw new Error('Not supported');
}
if (outputLineIndex > 0) {
return this.wrappedIndentLength + 1;
}
return 1;
};
SplitLine.prototype.getViewLineMaxColumn = function (model, modelLineNumber, outputLineIndex) {
if (!this._isVisible) {
throw new Error('Not supported');
}
return this.getViewLineContent(model, modelLineNumber, outputLineIndex).length + 1;
};
SplitLine.prototype.getViewLineData = function (model, modelLineNumber, outputLineIndex) {
if (!this._isVisible) {
throw new Error('Not supported');
}
var startOffset = this.getInputStartOffsetOfOutputLineIndex(outputLineIndex);
var endOffset = this.getInputEndOffsetOfOutputLineIndex(model, modelLineNumber, outputLineIndex);
var lineContent = model.getValueInRange({
startLineNumber: modelLineNumber,
startColumn: startOffset + 1,
endLineNumber: modelLineNumber,
endColumn: endOffset + 1
});
if (outputLineIndex > 0) {
lineContent = this.wrappedIndent + lineContent;
}
var minColumn = (outputLineIndex > 0 ? this.wrappedIndentLength + 1 : 1);
var maxColumn = lineContent.length + 1;
var continuesWithWrappedLine = (outputLineIndex + 1 < this.getViewLineCount());
var deltaStartIndex = 0;
if (outputLineIndex > 0) {
deltaStartIndex = this.wrappedIndentLength;
}
var lineTokens = model.getLineTokens(modelLineNumber);
return new ViewLineData(lineContent, continuesWithWrappedLine, minColumn, maxColumn, lineTokens.sliceAndInflate(startOffset, endOffset, deltaStartIndex));
};
SplitLine.prototype.getViewLinesData = function (model, modelLineNumber, fromOuputLineIndex, toOutputLineIndex, globalStartIndex, needed, result) {
if (!this._isVisible) {
throw new Error('Not supported');
}
for (var outputLineIndex = fromOuputLineIndex; outputLineIndex < toOutputLineIndex; outputLineIndex++) {
var globalIndex = globalStartIndex + outputLineIndex - fromOuputLineIndex;
if (!needed[globalIndex]) {
result[globalIndex] = null;
continue;
}
result[globalIndex] = this.getViewLineData(model, modelLineNumber, outputLineIndex);
}
};
SplitLine.prototype.getModelColumnOfViewPosition = function (outputLineIndex, outputColumn) {
if (!this._isVisible) {
throw new Error('Not supported');
}
var adjustedColumn = outputColumn - 1;
if (outputLineIndex > 0) {
if (adjustedColumn < this.wrappedIndentLength) {
adjustedColumn = 0;
}
else {
adjustedColumn -= this.wrappedIndentLength;
}
}
return this.positionMapper.getInputOffsetOfOutputPosition(outputLineIndex, adjustedColumn) + 1;
};
SplitLine.prototype.getViewPositionOfModelPosition = function (deltaLineNumber, inputColumn) {
if (!this._isVisible) {
throw new Error('Not supported');
}
var r = this.positionMapper.getOutputPositionOfInputOffset(inputColumn - 1);
var outputLineIndex = r.outputLineIndex;
var outputColumn = r.outputOffset + 1;
if (outputLineIndex > 0) {
outputColumn += this.wrappedIndentLength;
}
// console.log('in -> out ' + deltaLineNumber + ',' + inputColumn + ' ===> ' + (deltaLineNumber+outputLineIndex) + ',' + outputColumn);
return new Position(deltaLineNumber + outputLineIndex, outputColumn);
};
SplitLine.prototype.getViewLineNumberOfModelPosition = function (deltaLineNumber, inputColumn) {
if (!this._isVisible) {
throw new Error('Not supported');
}
var r = this.positionMapper.getOutputPositionOfInputOffset(inputColumn - 1);
return (deltaLineNumber + r.outputLineIndex);
};
return SplitLine;
}());
export { SplitLine };
function createSplitLine(linePositionMapperFactory, text, tabSize, wrappingColumn, columnsForFullWidthChar, wrappingIndent, isVisible) {
var positionMapper = linePositionMapperFactory.createLineMapping(text, tabSize, wrappingColumn, columnsForFullWidthChar, wrappingIndent);
if (positionMapper === null) {
// No mapping needed
if (isVisible) {
return VisibleIdentitySplitLine.INSTANCE;
}
return InvisibleIdentitySplitLine.INSTANCE;
}
else {
return new SplitLine(positionMapper, isVisible);
}
}
var IdentityCoordinatesConverter = /** @class */ (function () {
function IdentityCoordinatesConverter(lines) {
this._lines = lines;
}
IdentityCoordinatesConverter.prototype._validPosition = function (pos) {
return this._lines.model.validatePosition(pos);
};
IdentityCoordinatesConverter.prototype._validRange = function (range) {
return this._lines.model.validateRange(range);
};
// View -> Model conversion and related methods
IdentityCoordinatesConverter.prototype.convertViewPositionToModelPosition = function (viewPosition) {
return this._validPosition(viewPosition);
};
IdentityCoordinatesConverter.prototype.convertViewRangeToModelRange = function (viewRange) {
return this._validRange(viewRange);
};
IdentityCoordinatesConverter.prototype.validateViewPosition = function (_viewPosition, expectedModelPosition) {
return this._validPosition(expectedModelPosition);
};
IdentityCoordinatesConverter.prototype.validateViewRange = function (_viewRange, expectedModelRange) {
return this._validRange(expectedModelRange);
};
// Model -> View conversion and related methods
IdentityCoordinatesConverter.prototype.convertModelPositionToViewPosition = function (modelPosition) {
return this._validPosition(modelPosition);
};
IdentityCoordinatesConverter.prototype.con