UNPKG

monaco-editor-core

Version:

A browser based code editor

126 lines (125 loc) 5.11 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { LineTokens } from './lineTokens.js'; export const EMPTY_LINE_TOKENS = (new Uint32Array(0)).buffer; export class ContiguousTokensEditing { static deleteBeginning(lineTokens, toChIndex) { if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) { return lineTokens; } return ContiguousTokensEditing.delete(lineTokens, 0, toChIndex); } static deleteEnding(lineTokens, fromChIndex) { if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) { return lineTokens; } const tokens = toUint32Array(lineTokens); const lineTextLength = tokens[tokens.length - 2]; return ContiguousTokensEditing.delete(lineTokens, fromChIndex, lineTextLength); } static delete(lineTokens, fromChIndex, toChIndex) { if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS || fromChIndex === toChIndex) { return lineTokens; } const tokens = toUint32Array(lineTokens); const tokensCount = (tokens.length >>> 1); // special case: deleting everything if (fromChIndex === 0 && tokens[tokens.length - 2] === toChIndex) { return EMPTY_LINE_TOKENS; } const fromTokenIndex = LineTokens.findIndexInTokensArray(tokens, fromChIndex); const fromTokenStartOffset = (fromTokenIndex > 0 ? tokens[(fromTokenIndex - 1) << 1] : 0); const fromTokenEndOffset = tokens[fromTokenIndex << 1]; if (toChIndex < fromTokenEndOffset) { // the delete range is inside a single token const delta = (toChIndex - fromChIndex); for (let i = fromTokenIndex; i < tokensCount; i++) { tokens[i << 1] -= delta; } return lineTokens; } let dest; let lastEnd; if (fromTokenStartOffset !== fromChIndex) { tokens[fromTokenIndex << 1] = fromChIndex; dest = ((fromTokenIndex + 1) << 1); lastEnd = fromChIndex; } else { dest = (fromTokenIndex << 1); lastEnd = fromTokenStartOffset; } const delta = (toChIndex - fromChIndex); for (let tokenIndex = fromTokenIndex + 1; tokenIndex < tokensCount; tokenIndex++) { const tokenEndOffset = tokens[tokenIndex << 1] - delta; if (tokenEndOffset > lastEnd) { tokens[dest++] = tokenEndOffset; tokens[dest++] = tokens[(tokenIndex << 1) + 1]; lastEnd = tokenEndOffset; } } if (dest === tokens.length) { // nothing to trim return lineTokens; } const tmp = new Uint32Array(dest); tmp.set(tokens.subarray(0, dest), 0); return tmp.buffer; } static append(lineTokens, _otherTokens) { if (_otherTokens === EMPTY_LINE_TOKENS) { return lineTokens; } if (lineTokens === EMPTY_LINE_TOKENS) { return _otherTokens; } if (lineTokens === null) { return lineTokens; } if (_otherTokens === null) { // cannot determine combined line length... return null; } const myTokens = toUint32Array(lineTokens); const otherTokens = toUint32Array(_otherTokens); const otherTokensCount = (otherTokens.length >>> 1); const result = new Uint32Array(myTokens.length + otherTokens.length); result.set(myTokens, 0); let dest = myTokens.length; const delta = myTokens[myTokens.length - 2]; for (let i = 0; i < otherTokensCount; i++) { result[dest++] = otherTokens[(i << 1)] + delta; result[dest++] = otherTokens[(i << 1) + 1]; } return result.buffer; } static insert(lineTokens, chIndex, textLength) { if (lineTokens === null || lineTokens === EMPTY_LINE_TOKENS) { // nothing to do return lineTokens; } const tokens = toUint32Array(lineTokens); const tokensCount = (tokens.length >>> 1); let fromTokenIndex = LineTokens.findIndexInTokensArray(tokens, chIndex); if (fromTokenIndex > 0) { const fromTokenStartOffset = tokens[(fromTokenIndex - 1) << 1]; if (fromTokenStartOffset === chIndex) { fromTokenIndex--; } } for (let tokenIndex = fromTokenIndex; tokenIndex < tokensCount; tokenIndex++) { tokens[tokenIndex << 1] += textLength; } return lineTokens; } } export function toUint32Array(arr) { if (arr instanceof Uint32Array) { return arr; } else { return new Uint32Array(arr); } }