+ this.#dispatchChange(line.from, line.to, newLineContent, selectionRange.from + lineOffset);
+ }
+
+ /**
+ * Dispatch changes to the editor.
+ * @param {Number} from
+ * @param {?Number} to
+ * @param {?String} text
+ * @param {?Number} selectFrom
+ * @param {?Number} selectTo
+ */
+ #dispatchChange(from, to = null, text = null, selectFrom = null, selectTo = null) {
+ const tr = {changes: {from, to, insert: text}};
+
+ if (selectFrom) {
+ tr.selection = {anchor: selectFrom};
+ if (selectTo) {
+ tr.selection.head = selectTo;
+ }
+ }
+
+ this.editor.cm.dispatch(tr);
+ }
+
+ /**
+ * Set the current selection range.
+ * Optionally will scroll the new range into view.
+ * @param {Number} from
+ * @param {Number} to
+ * @param {Boolean} scrollIntoView
+ */
+ #setSelection(from, to, scrollIntoView = false) {