Skip to content

Commit

Permalink
feat(Lists): add auto merging of adjacent list of same type (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
d3m1d0v committed May 27, 2024
1 parent c494301 commit c02de80
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/extensions/markdown/Lists/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {actions} from './actions';
import {joinPrevList, liftIfCursorIsAtBeginningOfItem, toList} from './commands';
import {ListAction} from './const';
import {ListsInputRulesExtension, ListsInputRulesOptions} from './inputrules';
import {mergeListsPlugin} from './plugins/MergeListsPlugin';

export {ListNode, blType, liType, olType} from './ListsSpecs';

Expand Down Expand Up @@ -48,6 +49,8 @@ export const Lists: ExtensionAuto<ListsOptions> = (builder, opts) => {

builder.use(ListsInputRulesExtension, {bulletListInputRule: opts?.ulInputRules});

builder.addPlugin(mergeListsPlugin);

builder
.addAction(ListAction.ToBulletList, actions.toBulletList)
.addAction(ListAction.ToOrderedList, actions.toOrderedList)
Expand Down
41 changes: 41 additions & 0 deletions src/extensions/markdown/Lists/plugins/MergeListsPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {Plugin, Transaction} from 'prosemirror-state';
import {findChildren, hasParentNode} from 'prosemirror-utils';

import {isListNode} from '../utils';

export const mergeListsPlugin = () =>
new Plugin({
appendTransaction(trs, oldState, newState) {
const docChanged = trs.some((tr) => tr.docChanged);
if (!docChanged) return null;

const hasParentList =
hasParentNode(isListNode)(newState.selection) ||
hasParentNode(isListNode)(oldState.selection);
if (!hasParentList) return null;

const {tr} = newState;
const listNodes = findChildren(tr.doc, isListNode, true);

mergeAdjacentNodesWithSameType(tr, listNodes);

return tr.docChanged ? tr : null;
},
});

function mergeAdjacentNodesWithSameType(
tr: Transaction,
nodes: ReturnType<typeof findChildren>,
): void {
for (let i = 0; i < nodes.length - 1; i++) {
const current = nodes[i];
const next = nodes[i + 1];

if (
current.node.type === next.node.type &&
current.pos + current.node.nodeSize === next.pos
) {
tr.join(next.pos);
}
}
}

0 comments on commit c02de80

Please sign in to comment.