Copy moveLineUp/moveLineDown command from Codemirror source into move-lines.js. Plan is to modify them to fix issue when moving the only line from a a single line block. When that happens it results in the following text data in the buffer:

∞∞∞text
∞∞∞text

And the separator needs a newline on both sides to be valid
This commit is contained in:
Jonatan Heyman 2023-01-21 16:01:11 +01:00
parent 4b4e113aa5
commit 99a6d0fcc7
3 changed files with 78 additions and 16 deletions

View File

@ -7,6 +7,9 @@ import {
import { heynoteEvent, LANGUAGE_CHANGE } from "../annotation.js";
import { blockState, getActiveNoteBlock, getNoteBlockFromPos } from "./block"
import { levenshtein_distance } from "../language-detection/levenshtein"
import { moveLineDown, moveLineUp } from "./move-lines.js";
export { moveLineDown, moveLineUp }
export const insertNewBlockAtCursor = ({ state, dispatch }) => {
@ -60,21 +63,6 @@ export const selectAll = ({ state, dispatch }) => {
return true
}
/**
* Prevent moveLineUp from executing if any cursor is on the first line of the first note
*/
export function moveLineUp({ state, dispatch }) {
if (state.readOnly)
return false
if (state.selection.ranges.some(range => {
let startLine = state.doc.lineAt(range.from)
return startLine.from <= state.facet(blockState)[0].content.from
})) {
return true;
}
return defaultMoveLineUp({state, dispatch})
}
export function changeLanguageTo(state, dispatch, block, language, auto) {
if (state.readOnly)

View File

@ -0,0 +1,73 @@
import { EditorSelection } from "@codemirror/state"
import { blockState } from "./block"
function selectedLineBlocks(state) {
let blocks = [], upto = -1;
for (let range of state.selection.ranges) {
let startLine = state.doc.lineAt(range.from), endLine = state.doc.lineAt(range.to);
if (!range.empty && range.to == endLine.from)
endLine = state.doc.lineAt(range.to - 1);
if (upto >= startLine.number) {
let prev = blocks[blocks.length - 1];
prev.to = endLine.to;
prev.ranges.push(range);
}
else {
blocks.push({ from: startLine.from, to: endLine.to, ranges: [range] });
}
upto = endLine.number + 1;
}
return blocks;
}
function moveLine(state, dispatch, forward) {
if (state.readOnly)
return false;
let changes = [], ranges = [];
for (let block of selectedLineBlocks(state)) {
if (forward ? block.to == state.doc.length : block.from == 0)
continue;
let nextLine = state.doc.lineAt(forward ? block.to + 1 : block.from - 1);
let size = nextLine.length + 1;
if (forward) {
changes.push({ from: block.to, to: nextLine.to }, { from: block.from, insert: nextLine.text + state.lineBreak });
for (let r of block.ranges)
ranges.push(EditorSelection.range(Math.min(state.doc.length, r.anchor + size), Math.min(state.doc.length, r.head + size)));
}
else {
changes.push({ from: nextLine.from, to: block.from }, { from: block.to, insert: state.lineBreak + nextLine.text });
for (let r of block.ranges)
ranges.push(EditorSelection.range(r.anchor - size, r.head - size));
}
}
if (!changes.length)
return false;
dispatch(state.update({
changes,
scrollIntoView: true,
selection: EditorSelection.create(ranges, state.selection.mainIndex),
userEvent: "move.line"
}));
return true;
}
/**
Move the selected lines up one line.
*/
export const moveLineUp = ({ state, dispatch }) => {
// prevent moving lines up before the first block separator
if (state.selection.ranges.some(range => {
let startLine = state.doc.lineAt(range.from)
return startLine.from <= state.facet(blockState)[0].content.from
})) {
return true;
}
return moveLine(state, dispatch, false)
}
/**
Move the selected lines down one line.
*/
export const moveLineDown = ({ state, dispatch }) => moveLine(state, dispatch, true);

View File

@ -1,7 +1,7 @@
import { EditorView, keymap } from "@codemirror/view"
import { EditorSelection } from "@codemirror/state"
import { indentWithTab, insertTab, indentLess, indentMore, undo, redo } from "@codemirror/commands"
import { insertNewBlockAtCursor, addNewBlockAfterCurrent, moveLineUp, selectAll, gotoPreviousBlock, gotoNextBlock, gotoPreviousParagraph, gotoNextParagraph } from "./block/commands.js";
import { insertNewBlockAtCursor, addNewBlockAfterCurrent, moveLineUp, moveLineDown, selectAll, gotoPreviousBlock, gotoNextBlock, gotoPreviousParagraph, gotoNextParagraph } from "./block/commands.js";
export function heynoteKeymap(editor) {
return keymap.of([
@ -11,6 +11,7 @@ export function heynoteKeymap(editor) {
["Mod-Shift-Enter", insertNewBlockAtCursor],
["Mod-a", selectAll],
["Alt-ArrowUp", moveLineUp],
["Alt-ArrowDown", moveLineDown],
["Mod-ArrowUp", gotoPreviousBlock],
["Mod-ArrowDown", gotoNextBlock],
["Ctrl-ArrowUp", gotoPreviousParagraph],