Update single line filter extension

This commit is contained in:
Gregory Schier
2025-07-10 11:46:27 -07:00
parent 2b07d1a493
commit 4038666986

View File

@@ -1,33 +1,34 @@
import type {Extension, Transaction, TransactionSpec} from '@codemirror/state'; import type { Extension, TransactionSpec } from '@codemirror/state';
import { EditorSelection, EditorState } from '@codemirror/state'; import { EditorSelection, EditorState, Transaction } from '@codemirror/state';
export function singleLineExtensions(): Extension { export function singleLineExtensions(): Extension {
return EditorState.transactionFilter.of( return EditorState.transactionFilter.of(
(tr: Transaction): TransactionSpec | TransactionSpec[] => { (tr: Transaction): TransactionSpec | readonly TransactionSpec[] => {
if (!tr.isUserEvent('input')) return tr; if (!tr.isUserEvent('input') || tr.isUserEvent('input.type.compose')) return tr;
// when composing text via IME, return const changes: { from: number; to: number; insert: string }[] = [];
if (tr.isUserEvent('input.type.compose')) return tr;
const specs: TransactionSpec[] = []; tr.changes.iterChanges((_fromA, toA, fromB, _toB, inserted) => {
tr.changes.iterChanges((_, toA, fromB, toB, inserted) => {
let insert = ''; let insert = '';
let newlinesRemoved = 0; for (const line of inserted.iterLines()) {
for (const line of inserted) { insert += line.replace(/\n/g, '');
const newLine = line.replace('\n', '');
newlinesRemoved += line.length - newLine.length;
insert += newLine;
} }
// Update cursor position based on how many newlines were removed if (insert !== inserted.toString()) {
const cursor = EditorSelection.cursor(toB - newlinesRemoved); changes.push({ from: fromB, to: toA, insert });
const selection = EditorSelection.create([cursor], 0); }
const changes = [{ from: fromB, to: toA, insert }];
specs.push({ ...tr, selection, changes });
}); });
return specs; const lastChange = changes[changes.length - 1];
if (lastChange == null) return tr;
const selection = EditorSelection.cursor(lastChange.from + lastChange.insert.length);
return {
changes,
selection,
userEvent: tr.annotation(Transaction.userEvent) ?? undefined,
};
}, },
); );
} }