export default { getSelectedText(selection = this.getSelection()) { const { startLineNumber, endLineNumber, startColumn, endColumn } = selection; const valArray = this.getValue().split('\n'); let text = ''; if (startLineNumber === endLineNumber) { text = valArray[startLineNumber - 1].slice(startColumn - 1, endColumn - 1); } else { const startLineText = valArray[startLineNumber - 1].slice(startColumn - 1); const endLineText = valArray[endLineNumber - 1].slice(0, endColumn - 1); for (let i = startLineNumber, k = endLineNumber - 1; i < k; i += 1) { text += `${valArray[i]}`; if (i !== k - 1) text += `\n`; } text = text ? [startLineText, text, endLineText].join('\n') : [startLineText, endLineText].join('\n'); } return text; }, replaceSelectedText(text, select = undefined) { const forceMoveMarkers = !select; this.executeEdits('', [{ range: this.getSelection(), text, forceMoveMarkers }]); }, moveCursor(dx = 0, dy = 0) { const pos = this.getPosition(); pos.column += dx; pos.lineNumber += dy; this.setPosition(pos); }, /** * Adjust existing selection to select text within the original selection. * - If `selectedText` is not supplied, we fetch selected text with * * ALGORITHM: * * MULTI-LINE SELECTION * 1. Find line that contains `toSelect` text. * 2. Using the index of this line and the position of `toSelect` text in it, * construct: * * newStartLineNumber * * newStartColumn * * SINGLE-LINE SELECTION * 1. Use `startLineNumber` from the current selection as `newStartLineNumber` * 2. Find the position of `toSelect` text in it to get `newStartColumn` * * 3. `newEndLineNumber` — Since this method is supposed to be used with * markdown decorators that are pretty short, the `newEndLineNumber` is * suggested to be assumed the same as the startLine. * 4. `newEndColumn` — pretty obvious * 5. Adjust the start and end positions of the current selection * 6. Re-set selection on the instance * * @param {string} toSelect - New text to select within current selection. * @param {string} selectedText - Currently selected text. It's just a * shortcut: If it's not supplied, we fetch selected text from the instance */ selectWithinSelection(toSelect, selectedText) { const currentSelection = this.getSelection(); if (currentSelection.isEmpty() || !toSelect) { return; } const text = selectedText || this.getSelectedText(currentSelection); let lineShift; let newStartLineNumber; let newStartColumn; const textLines = text.split('\n'); if (textLines.length > 1) { // Multi-line selection lineShift = textLines.findIndex(line => line.indexOf(toSelect) !== -1); newStartLineNumber = currentSelection.startLineNumber + lineShift; newStartColumn = textLines[lineShift].indexOf(toSelect) + 1; } else { // Single-line selection newStartLineNumber = currentSelection.startLineNumber; newStartColumn = currentSelection.startColumn + text.indexOf(toSelect); } const newEndLineNumber = newStartLineNumber; const newEndColumn = newStartColumn + toSelect.length; const newSelection = currentSelection .setStartPosition(newStartLineNumber, newStartColumn) .setEndPosition(newEndLineNumber, newEndColumn); this.setSelection(newSelection); }, };