monaco-editor
Version:
A browser based code editor
91 lines (90 loc) • 3.42 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 { BugIndicatingError } from '../../../../base/common/errors.js';
import { DisposableStore } from '../../../../base/common/lifecycle.js';
import { autorunOpts } from '../../../../base/common/observable.js';
import { Position } from '../../../common/core/position.js';
import { Range } from '../../../common/core/range.js';
export function applyEdits(text, edits) {
const transformer = new PositionOffsetTransformer(text);
const offsetEdits = edits.map(e => {
const range = Range.lift(e.range);
return ({
startOffset: transformer.getOffset(range.getStartPosition()),
endOffset: transformer.getOffset(range.getEndPosition()),
text: e.text
});
});
offsetEdits.sort((a, b) => b.startOffset - a.startOffset);
for (const edit of offsetEdits) {
text = text.substring(0, edit.startOffset) + edit.text + text.substring(edit.endOffset);
}
return text;
}
class PositionOffsetTransformer {
constructor(text) {
this.lineStartOffsetByLineIdx = [];
this.lineStartOffsetByLineIdx.push(0);
for (let i = 0; i < text.length; i++) {
if (text.charAt(i) === '\n') {
this.lineStartOffsetByLineIdx.push(i + 1);
}
}
}
getOffset(position) {
return this.lineStartOffsetByLineIdx[position.lineNumber - 1] + position.column - 1;
}
}
const array = [];
export function getReadonlyEmptyArray() {
return array;
}
export class ColumnRange {
constructor(startColumn, endColumnExclusive) {
this.startColumn = startColumn;
this.endColumnExclusive = endColumnExclusive;
if (startColumn > endColumnExclusive) {
throw new BugIndicatingError(`startColumn ${startColumn} cannot be after endColumnExclusive ${endColumnExclusive}`);
}
}
toRange(lineNumber) {
return new Range(lineNumber, this.startColumn, lineNumber, this.endColumnExclusive);
}
equals(other) {
return this.startColumn === other.startColumn
&& this.endColumnExclusive === other.endColumnExclusive;
}
}
export function applyObservableDecorations(editor, decorations) {
const d = new DisposableStore();
const decorationsCollection = editor.createDecorationsCollection();
d.add(autorunOpts({ debugName: () => `Apply decorations from ${decorations.debugName}` }, reader => {
const d = decorations.read(reader);
decorationsCollection.set(d);
}));
d.add({
dispose: () => {
decorationsCollection.clear();
}
});
return d;
}
export function addPositions(pos1, pos2) {
return new Position(pos1.lineNumber + pos2.lineNumber - 1, pos2.lineNumber === 1 ? pos1.column + pos2.column - 1 : pos2.column);
}
export function lengthOfText(text) {
let line = 1;
let column = 1;
for (const c of text) {
if (c === '\n') {
line++;
column = 1;
}
else {
column++;
}
}
return new Position(line, column);
}