61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
import type { ChangeSpec, EditorState, SelectionRange, Text, TransactionSpec } from "@codemirror/state";
|
|
|
|
export interface DispatchableEditorView {
|
|
state: EditorState;
|
|
dispatch(spec: TransactionSpec): void;
|
|
}
|
|
|
|
export function replaceSelectedEditorText(view: DispatchableEditorView, insert: string): boolean {
|
|
if (view.state.readOnly) return false;
|
|
|
|
const selection = view.state.selection.main;
|
|
if (selection.empty) return false;
|
|
|
|
view.dispatch({
|
|
changes: { from: selection.from, to: selection.to, insert },
|
|
selection: { anchor: selection.from + insert.length },
|
|
scrollIntoView: true,
|
|
});
|
|
return true;
|
|
}
|
|
|
|
export function blankLineDeletionChanges(doc: Text, selection: SelectionRange): ChangeSpec[] {
|
|
if (doc.length === 0) return [];
|
|
|
|
const hasSelection = !selection.empty;
|
|
const firstLine = hasSelection ? doc.lineAt(selection.from).number : 1;
|
|
const lastSelectedPosition = hasSelection ? Math.max(selection.from, selection.to - 1) : doc.length;
|
|
const lastLine = hasSelection ? doc.lineAt(lastSelectedPosition).number : doc.lines;
|
|
const changes: ChangeSpec[] = [];
|
|
|
|
let lineNumber = firstLine;
|
|
while (lineNumber <= lastLine) {
|
|
const line = doc.line(lineNumber);
|
|
if (line.text.trim().length > 0) {
|
|
lineNumber += 1;
|
|
continue;
|
|
}
|
|
|
|
const firstBlankLine = line;
|
|
let lastBlankLine = line;
|
|
while (lineNumber < lastLine) {
|
|
const nextLine = doc.line(lineNumber + 1);
|
|
if (nextLine.text.trim().length > 0) break;
|
|
lineNumber += 1;
|
|
lastBlankLine = nextLine;
|
|
}
|
|
|
|
// Prefer the following separator so non-empty lines retain their existing newline.
|
|
if (lastBlankLine.to < doc.length) {
|
|
changes.push({ from: firstBlankLine.from, to: lastBlankLine.to + 1 });
|
|
} else if (firstBlankLine.from > 0) {
|
|
changes.push({ from: firstBlankLine.from - 1, to: lastBlankLine.to });
|
|
} else {
|
|
changes.push({ from: 0, to: doc.length });
|
|
}
|
|
lineNumber += 1;
|
|
}
|
|
|
|
return changes;
|
|
}
|