diff --git a/src/editor/block/block.js b/src/editor/block/block.js index bb10ec5..5746f4b 100644 --- a/src/editor/block/block.js +++ b/src/editor/block/block.js @@ -72,6 +72,10 @@ export function getActiveNoteBlock(state) { return state.facet(blockState).find(block => block.content.from <= range.from && block.content.to >= range.from) } +export function getNoteBlockFromPos(state, pos) { + return state.facet(blockState).find(block => block.content.from <= pos && block.content.to >= pos) +} + class NoteBlockStart extends WidgetType { constructor(isFirst) { diff --git a/src/editor/block/commands.js b/src/editor/block/commands.js index ee58577..a530f33 100644 --- a/src/editor/block/commands.js +++ b/src/editor/block/commands.js @@ -1,11 +1,12 @@ import { EditorView } from "@codemirror/view" +import { EditorSelection } from "@codemirror/state" import { selectAll as defaultSelectAll, moveLineUp as defaultMoveLineUp, } from "@codemirror/commands" import { heynoteEvent, LANGUAGE_CHANGE } from "../annotation.js"; import { HIGHLIGHTJS_TO_TOKEN } from "../languages" -import { blockState, getActiveNoteBlock } from "./block" +import { blockState, getActiveNoteBlock, getNoteBlockFromPos } from "./block" import { levenshtein_distance } from "../language-detection/levenshtein" @@ -72,3 +73,41 @@ export function changeLanguageTo(state, dispatch, block, language, auto) { } } +export function gotoPreviousBlock({state, dispatch}) { + const blocks = state.facet(blockState) + const newSelection = EditorSelection.create(state.selection.ranges.map(sel => { + const block = getNoteBlockFromPos(state, sel.head) + if (sel.head === block.content.from) { + const index = blocks.indexOf(block) + const previousBlockIndex = index > 0 ? index - 1 : 0 + return EditorSelection.cursor(blocks[previousBlockIndex].content.from) + } else { + return EditorSelection.cursor(block.content.from) + } + }), state.selection.mainIndex) + dispatch(state.update({ + selection: newSelection, + scrollIntoView: true, + })) + return true +} + +export function gotoNextBlock({state, dispatch}) { + const blocks = state.facet(blockState) + const newSelection = EditorSelection.create(state.selection.ranges.map(sel => { + const block = getNoteBlockFromPos(state, sel.head) + if (sel.head === block.content.to) { + const index = blocks.indexOf(block) + const previousBlockIndex = index < blocks.length - 1 ? index + 1 : index + return EditorSelection.cursor(blocks[previousBlockIndex].content.to) + } else { + return EditorSelection.cursor(block.content.to) + } + }), state.selection.mainIndex) + dispatch(state.update({ + selection: newSelection, + scrollIntoView: true, + })) + return true +} + diff --git a/src/editor/keymap.js b/src/editor/keymap.js index f38b5ef..a0b483d 100644 --- a/src/editor/keymap.js +++ b/src/editor/keymap.js @@ -1,6 +1,6 @@ import { keymap } from "@codemirror/view" import { indentWithTab, insertTab, indentLess, indentMore } from "@codemirror/commands" -import { insertNewNote, moveLineUp, selectAll } from "./block/commands.js"; +import { insertNewNote, moveLineUp, selectAll, gotoPreviousBlock, gotoNextBlock } from "./block/commands.js"; export const heynoteKeymap = keymap.of([ { @@ -29,4 +29,14 @@ export const heynoteKeymap = keymap.of([ preventDefault: true, run: moveLineUp, }, + { + key: "Mod-ArrowUp", + preventDefault: true, + run: gotoPreviousBlock, + }, + { + key: "Mod-ArrowDown", + preventDefault: true, + run: gotoNextBlock, + }, ])