Files
voidraft/frontend/src/views/editor/extensions/codeblock/transposeChars.ts
2025-06-18 21:19:19 +08:00

53 lines
1.4 KiB
TypeScript

/**
* 字符转置功能
* 交换光标前后的字符
*/
import { EditorSelection, findClusterBreak } from "@codemirror/state";
import { getNoteBlockFromPos } from "./state";
/**
* 交换光标前后的字符
*/
export const transposeChars = ({ state, dispatch }: { state: any; dispatch: any }): boolean => {
if (state.readOnly) {
return false;
}
let changes = state.changeByRange((range: any) => {
// 防止在代码块的开始或结束位置进行字符转置,因为这会破坏块语法
const block = getNoteBlockFromPos(state, range.from);
if (block && (range.from === block.content.from || range.from === block.content.to)) {
return { range };
}
if (!range.empty || range.from == 0 || range.from == state.doc.length) {
return { range };
}
let pos = range.from;
let line = state.doc.lineAt(pos);
let from = pos == line.from ? pos - 1 : findClusterBreak(line.text, pos - line.from, false) + line.from;
let to = pos == line.to ? pos + 1 : findClusterBreak(line.text, pos - line.from, true) + line.from;
return {
changes: {
from,
to,
insert: state.doc.slice(pos, to).append(state.doc.slice(from, pos))
},
range: EditorSelection.cursor(to)
};
});
if (changes.changes.empty) {
return false;
}
dispatch(state.update(changes, {
scrollIntoView: true,
userEvent: "move.character"
}));
return true;
};