Move single list items with Alt Shift arrows (#143)

Adds Alt+Shift+Up/Down for moving only the current list or task item while preserving the existing Alt+Up/Down block movement.

Reviewed-on: https://codeberg.org/ArkHost/HelixNotes/pulls/143
This commit is contained in:
mf
2026-06-19 12:14:34 +02:00
committed by ArkHost
parent 1dc78ca916
commit 80a6fdca69
2 changed files with 42 additions and 2 deletions
+41 -2
View File
@@ -1325,6 +1325,45 @@
event.preventDefault(); event.preventDefault();
const { state, dispatch } = view; const { state, dispatch } = view;
const resolvedPos = state.selection.$from; const resolvedPos = state.selection.$from;
if (event.shiftKey) {
for (let depth = resolvedPos.depth; depth > 0; depth--) {
const itemNode = resolvedPos.node(depth);
if (itemNode.type.name !== 'listItem' && itemNode.type.name !== 'taskItem') continue;
const parentListDepth = depth - 1;
const itemIndex = resolvedPos.index(parentListDepth);
const itemPos = resolvedPos.before(depth);
const itemSlice = state.doc.slice(itemPos, itemPos + itemNode.nodeSize);
const cursorOffset = resolvedPos.pos - itemPos;
const tr = state.tr;
if (event.key === 'ArrowUp') {
if (itemIndex <= 0) return true;
const prevPos = resolvedPos.posAtIndex(itemIndex - 1, parentListDepth);
tr.delete(itemPos, itemPos + itemNode.nodeSize);
const insertAt = tr.mapping.map(prevPos);
tr.insert(insertAt, itemSlice.content);
const newCursorPos = Math.min(insertAt + cursorOffset, tr.doc.content.size);
tr.setSelection(Selection.near(tr.doc.resolve(newCursorPos)));
dispatch(tr.scrollIntoView());
return true;
}
const parentList = resolvedPos.node(parentListDepth);
if (itemIndex >= parentList.childCount - 1) return true;
const nextPos = resolvedPos.posAtIndex(itemIndex + 1, parentListDepth);
const nextNode = state.doc.nodeAt(nextPos);
if (!nextNode) return true;
const nextSlice = state.doc.slice(nextPos, nextPos + nextNode.nodeSize);
tr.delete(nextPos, nextPos + nextNode.nodeSize);
const insertAt = tr.mapping.map(itemPos);
tr.insert(insertAt, nextSlice.content);
const newCursorPos = Math.min(tr.mapping.map(itemPos) + cursorOffset, tr.doc.content.size);
tr.setSelection(Selection.near(tr.doc.resolve(newCursorPos)));
dispatch(tr.scrollIntoView());
return true;
}
return true;
}
// Find the top-level block index // Find the top-level block index
const depth = 1; // top-level blocks in doc const depth = 1; // top-level blocks in doc
if (resolvedPos.depth < depth) return true; if (resolvedPos.depth < depth) return true;
@@ -1345,7 +1384,7 @@
const insertAt = tr.mapping.map(prevPos); const insertAt = tr.mapping.map(prevPos);
tr.insert(insertAt, curSlice.content); tr.insert(insertAt, curSlice.content);
const newCursorPos = Math.min(insertAt + cursorOffset, tr.doc.content.size); const newCursorPos = Math.min(insertAt + cursorOffset, tr.doc.content.size);
tr.setSelection(state.selection.constructor.near(tr.doc.resolve(newCursorPos))); tr.setSelection(Selection.near(tr.doc.resolve(newCursorPos)));
dispatch(tr.scrollIntoView()); dispatch(tr.scrollIntoView());
} else { } else {
if (parentIndex >= state.doc.childCount - 1) return true; if (parentIndex >= state.doc.childCount - 1) return true;
@@ -1360,7 +1399,7 @@
const insertAt = tr.mapping.map(parentPos); const insertAt = tr.mapping.map(parentPos);
tr.insert(insertAt, nextSlice.content); tr.insert(insertAt, nextSlice.content);
const newCursorPos = Math.min(tr.mapping.map(parentPos) + cursorOffset, tr.doc.content.size); const newCursorPos = Math.min(tr.mapping.map(parentPos) + cursorOffset, tr.doc.content.size);
tr.setSelection(state.selection.constructor.near(tr.doc.resolve(newCursorPos))); tr.setSelection(Selection.near(tr.doc.resolve(newCursorPos)));
dispatch(tr.scrollIntoView()); dispatch(tr.scrollIntoView());
} }
return true; return true;
+1
View File
@@ -189,6 +189,7 @@
<div class="shortcut-row"><span class="shortcut-desc">Undo</span><span class="shortcut-keys"><kbd>{modKey}</kbd>+<kbd>Z</kbd></span></div> <div class="shortcut-row"><span class="shortcut-desc">Undo</span><span class="shortcut-keys"><kbd>{modKey}</kbd>+<kbd>Z</kbd></span></div>
<div class="shortcut-row"><span class="shortcut-desc">Redo</span><span class="shortcut-keys"><kbd>{modKey}</kbd>+<kbd>Shift</kbd>+<kbd>Z</kbd></span></div> <div class="shortcut-row"><span class="shortcut-desc">Redo</span><span class="shortcut-keys"><kbd>{modKey}</kbd>+<kbd>Shift</kbd>+<kbd>Z</kbd></span></div>
<div class="shortcut-row"><span class="shortcut-desc">Move line up / down</span><span class="shortcut-keys"><kbd>Alt</kbd>+<kbd>↑↓</kbd></span></div> <div class="shortcut-row"><span class="shortcut-desc">Move line up / down</span><span class="shortcut-keys"><kbd>Alt</kbd>+<kbd>↑↓</kbd></span></div>
<div class="shortcut-row"><span class="shortcut-desc">Move list item up / down</span><span class="shortcut-keys"><kbd>Alt</kbd>+<kbd>Shift</kbd>+<kbd>↑↓</kbd></span></div>
<h4 class="shortcuts-group-title">Editor Commands</h4> <h4 class="shortcuts-group-title">Editor Commands</h4>
<div class="shortcut-row"><span class="shortcut-desc">Slash commands</span><span class="shortcut-keys"><kbd>/</kbd></span></div> <div class="shortcut-row"><span class="shortcut-desc">Slash commands</span><span class="shortcut-keys"><kbd>/</kbd></span></div>