From 81bbc2ed47a357ed467be5cd777e28875afd714f Mon Sep 17 00:00:00 2001 From: wolimst <64784258+wolimst@users.noreply.github.com> Date: Tue, 20 Feb 2024 23:25:27 +0900 Subject: [PATCH] Add feature for moving the current block up and down --- src/editor/block/commands.js | 55 ++++++++++++++++++++++++++++++++++++ src/editor/keymap.js | 3 ++ 2 files changed, 58 insertions(+) diff --git a/src/editor/block/commands.js b/src/editor/block/commands.js index 7265b37..63144f7 100644 --- a/src/editor/block/commands.js +++ b/src/editor/block/commands.js @@ -313,3 +313,58 @@ export function triggerCurrenciesLoaded(state, dispatch) { annotations: [heynoteEvent.of(CURRENCIES_LOADED)], })) } + +export function moveCurrentBlockUp({state, dispatch}) { + return moveCurrentBlock(state, dispatch, true) +} + +export function moveCurrentBlockDown({state, dispatch}) { + return moveCurrentBlock(state, dispatch, false) +} + +function moveCurrentBlock(state, dispatch, up) { + if (state.readOnly) { + return false + } + + const blocks = state.facet(blockState) + const currentBlock = getActiveNoteBlock(state) + const blockIndex = blocks.indexOf(currentBlock) + if ((up && blockIndex === 0) || (!up && blockIndex === blocks.length - 1)) { + return false + } + + const dir = up ? -1 : 1 + const neighborBlock = blocks[blockIndex + dir] + + const currentBlockContent = state.sliceDoc(currentBlock.delimiter.from, currentBlock.content.to) + const neighborBlockContent = state.sliceDoc(neighborBlock.delimiter.from, neighborBlock.content.to) + const newContent = up ? currentBlockContent + neighborBlockContent : neighborBlockContent + currentBlockContent + + const selectionRange = state.selection.asSingle().ranges[0] + let newSelectionRange + if (up) { + newSelectionRange = EditorSelection.range( + selectionRange.anchor - currentBlock.delimiter.from + neighborBlock.delimiter.from, + selectionRange.head - currentBlock.delimiter.from + neighborBlock.delimiter.from, + ) + } else { + newSelectionRange = EditorSelection.range( + selectionRange.anchor + neighborBlock.content.to - neighborBlock.delimiter.from, + selectionRange.head + neighborBlock.content.to - neighborBlock.delimiter.from, + ) + } + + dispatch(state.update({ + changes: { + from: up ? neighborBlock.delimiter.from : currentBlock.delimiter.from, + to: up ? currentBlock.content.to : neighborBlock.content.to, + insert: newContent, + }, + selection: newSelectionRange, + }, { + scrollIntoView: true, + userEvent: "input", + })) + return true +} diff --git a/src/editor/keymap.js b/src/editor/keymap.js index 745aaf3..1037bb9 100644 --- a/src/editor/keymap.js +++ b/src/editor/keymap.js @@ -15,6 +15,7 @@ import { gotoPreviousParagraph, gotoNextParagraph, selectNextParagraph, selectPreviousParagraph, newCursorBelow, newCursorAbove, + moveCurrentBlockUp, moveCurrentBlockDown, } from "./block/commands.js" import { pasteCommand, copyCommand, cutCommand } from "./copy-paste.js" @@ -65,5 +66,7 @@ export function heynoteKeymap(editor) { {key:"Mod-ArrowDown", run:gotoNextBlock, shift:selectNextBlock}, {key:"Ctrl-ArrowUp", run:gotoPreviousParagraph, shift:selectPreviousParagraph}, {key:"Ctrl-ArrowDown", run:gotoNextParagraph, shift:selectNextParagraph}, + ["Mod-Shift-Alt-ArrowUp", moveCurrentBlockUp], + ["Mod-Shift-Alt-ArrowDown", moveCurrentBlockDown], ]) }