area: apiarea: editinggood first issuepriority: highroam parity
Repository metrics
- Stars
- (21 stars)
- PR merge metrics
- (No merged PRs in 30d)
Description
Summary
Allow reordering blocks among siblings by moving them up or down. This is a basic outliner operation present in Roam web and every outliner tool.
Roam web behavior: Cmd+Shift+Up / Cmd+Shift+Down moves the selected block up or down within its siblings, changing its order value.
TUI adaptation: Use Alt+Up / Alt+Down across all presets (consistent with most editors). Vim preset could also support K / J (shift+k/j) as alternatives.
Implementation hints
Existing pattern to follow
src/app.rs:1071—handle_indent()is the closest pattern: it finds the block, computes new parent/order, applies locally, returnsWriteAction::MoveBlocksrc/app.rs:1122—handle_dedent()same pattern- The new
handle_move_up()/handle_move_down()functions should follow this exact structure
API
src/api/types.rs:111-115—WriteAction::MoveBlock { block, location }already exists and supports this- Set
location.parent_uidto same parent,location.ordertoorder - 1(move up) ororder + 1(move down)
Local state update
- Find the block in
state.days[].blockstree - Swap
ordervalues with the sibling above/below - Reorder the
childrenvec of the parent to reflect new order - Update
selected_blockindex to follow the moved block
Edge cases
- Block is first child → move up does nothing
- Block is last child → move down does nothing
- After move, the flat index changes — recalculate
selected_blockto track the block
Keybindings
src/keys/preset.rs— add new actions:MoveUp,MoveDown(orMoveBlockUp,MoveBlockDownto avoid confusion with cursor movement)- Map to
Alt+Up/Alt+Downin all presets
Undo/redo
- Add
UndoEntry::MoveBlockvariant or reuse existing one - Store: block_uid, old_parent_uid, old_order, selected_block
Acceptance criteria
-
Alt+Upmoves block before its previous sibling -
Alt+Downmoves block after its next sibling - API receives
MoveBlockwrite action - Selection follows the moved block
- Undo/redo works for move operations
- No-op at boundaries (first/last child)