import type { Command, TextSelection } from '@blockeditor/block-std'; import { PathFinder } from '@blockeditor/block-std'; import { assertExists } from '@blockeditor/global/utils'; import type { Text } from '@blockeditor/store'; import { matchFlavours } from '../../../_common/utils/index.js'; export const deleteTextCommand: Command< 'currentTextSelection' | 'host', never, { textSelection?: TextSelection; } > = (ctx, next) => { const textSelection = ctx.textSelection ?? ctx.currentTextSelection; assertExists( textSelection, '`textSelection` is required, you need to pass it in args or use `getTextSelection` command before adding this command to the pipeline.' ); const host = ctx.host; assertExists( host, '`host` is required, you need to use `withHost` command before adding this command to the pipeline.' ); assertExists(host.rangeManager); const range = host.rangeManager.textSelectionToRange(textSelection); if (!range) return; const selectedElements = host.rangeManager.getSelectedBlockElementsByRange( range, { mode: 'flat', } ); const { from, to } = textSelection; const fromElement = selectedElements.find(el => PathFinder.equals(from.path, el.path) ); assertExists(fromElement); let fromText: Text | undefined; if (matchFlavours(fromElement.model, ['affine:page'])) { fromText = fromElement.model.title; } else { fromText = fromElement.model.text; } assertExists(fromText); if (!to) { fromText.delete(from.index, from.length); ctx.std.selection.setGroup('note', [ ctx.std.selection.create('text', { from: { path: from.path, index: from.index, length: 0, }, to: null, }), ]); return next(); } const toElement = selectedElements.find(el => PathFinder.equals(to.path, el.path) ); assertExists(toElement); const toText = toElement.model.text; assertExists(toText); fromText.delete(from.index, from.length); toText.delete(0, to.length); selectedElements .filter( el => el.model.id !== fromElement.model.id && el.model.id !== toElement.model.id ) .forEach(el => { ctx.std.page.deleteBlock(el.model); }); ctx.std.selection.setGroup('note', [ ctx.std.selection.create('text', { from: { path: to.path, index: to.index, length: 0, }, to: null, }), ]); next(); }; declare global { namespace BlockEditor { interface Commands { deleteText: typeof deleteTextCommand; } } }