Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save BrianHung/7dcd9644048045fef8cd617e4bc9cde2 to your computer and use it in GitHub Desktop.
Save BrianHung/7dcd9644048045fef8cd617e4bc9cde2 to your computer and use it in GitHub Desktop.
Combine commands on the ProseMirror undo stack
/**
* Given two commands (commandA and commandB), returns a new command that when applied
* to a ProseMirror state that uses the prosemirror-history plugin applies commandA and
* then commandB so that both commands are undone with a single undo action.
**/
const combineCommands =
(commandA: Command, commandB: Command) =>
(state: EditorState, dispatch?: (tr: Transaction) => void): boolean => {
return commandA(state, (transactionA: Transaction) => {
const { state: stateA } = state.applyTransaction(transactionA)
commandB(stateA, (transactionB: Transaction) => {
transactionB.setMeta('appendedTransaction', transactionA)
if (dispatch) {
dispatch(transactionA)
dispatch(transactionB)
}
})
})
}
import { Command, Transaction } from 'prosemirror-state';
/**
* Combine a number of command functions into a single function (which
* calls them one by one until one returns false).
*
* All commands are undone with a single undo action.
*/
export function runAllCommands(...commands: readonly Command[]): Command {
return function (state, dispatch, view) {
let prevState = state;
const tx: Transaction[] = [];
for (let i = 0; i < commands.length; i++) {
const dispatchInner = (transaction: Transaction) => {
if (i > 0) transaction.setMeta('appendedTransaction', tx.at(i - 1));
const { state: newState } = prevState.applyTransaction(transaction);
prevState = newState;
tx.push(transaction);
};
if (!commands[i](prevState, dispatchInner, view)) return false;
}
// Only dispatch transactions if all succeed.
if (dispatch) {
tx.forEach(dispatch);
}
return true;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment