дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
Column-based editing computed columns with countColumn / findColumn, which count every grapheme as one column, and up/down and Clone Caret moved by pixel x, so block selections and cloned carets drifted on lines with CJK, fullwidth punctuation, Hangul, kana or emoji. A shared visible-column helper (UI side only, UTF-16 offsets in and out) now counts East Asian wide/fullwidth characters and emoji (ZWJ sequences, modifiers, flags, VS16) as 2, combining marks and format characters as 0, and expands tabs to the next tab stop. It drives Alt+drag block selection, drag and Shift+arrows in Column Selection Mode, middle-drag block selection (new; not on Linux, where middle-click pastes the primary selection), the up/down goal column (kept across short lines; soft-wrapped and folded lines still move visually), Clone Caret Above/Below, the caret move after Comment Line, Tab padding to the next indent stop, and macro playback of arrow keys. Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
89 рядки
2.8 KiB
TypeScript
89 рядки
2.8 KiB
TypeScript
/**
|
|
* Editing and caret keys a macro records in the editor (keys the IDE keymap
|
|
* does not bind run CodeMirror commands directly), and their replay.
|
|
*/
|
|
import {
|
|
cursorCharLeft,
|
|
cursorCharRight,
|
|
cursorDocEnd,
|
|
cursorDocStart,
|
|
cursorGroupLeft,
|
|
cursorGroupRight,
|
|
cursorLineBoundaryBackward,
|
|
cursorLineBoundaryForward,
|
|
cursorPageDown,
|
|
cursorPageUp,
|
|
deleteCharBackward,
|
|
deleteCharForward,
|
|
deleteGroupBackward,
|
|
deleteGroupForward,
|
|
indentLess,
|
|
insertNewlineAndIndent,
|
|
insertTab,
|
|
selectCharLeft,
|
|
selectCharRight,
|
|
selectDocEnd,
|
|
selectDocStart,
|
|
selectGroupLeft,
|
|
selectGroupRight,
|
|
selectLineBoundaryBackward,
|
|
selectLineBoundaryForward,
|
|
selectPageDown,
|
|
selectPageUp,
|
|
} from "@codemirror/commands";
|
|
import type { Command } from "@codemirror/view";
|
|
import { cursorLineDown, cursorLineUp, selectLineDown, selectLineUp } from "@/editor/core/cm/verticalMotion";
|
|
|
|
/** Recorded key name (`Shift+ArrowLeft`, `Alt+Backspace`) → command. */
|
|
export const EDITOR_KEY_COMMANDS: Record<string, Command> = {
|
|
Enter: insertNewlineAndIndent,
|
|
Backspace: deleteCharBackward,
|
|
Delete: deleteCharForward,
|
|
"Alt+Backspace": deleteGroupBackward,
|
|
"Alt+Delete": deleteGroupForward,
|
|
Tab: insertTab,
|
|
"Shift+Tab": indentLess,
|
|
ArrowLeft: cursorCharLeft,
|
|
ArrowRight: cursorCharRight,
|
|
ArrowUp: cursorLineUp,
|
|
ArrowDown: cursorLineDown,
|
|
"Shift+ArrowLeft": selectCharLeft,
|
|
"Shift+ArrowRight": selectCharRight,
|
|
"Shift+ArrowUp": selectLineUp,
|
|
"Shift+ArrowDown": selectLineDown,
|
|
"Alt+ArrowLeft": cursorGroupLeft,
|
|
"Alt+ArrowRight": cursorGroupRight,
|
|
"Alt+Shift+ArrowLeft": selectGroupLeft,
|
|
"Alt+Shift+ArrowRight": selectGroupRight,
|
|
Home: cursorLineBoundaryBackward,
|
|
End: cursorLineBoundaryForward,
|
|
"Shift+Home": selectLineBoundaryBackward,
|
|
"Shift+End": selectLineBoundaryForward,
|
|
PageUp: cursorPageUp,
|
|
PageDown: cursorPageDown,
|
|
"Shift+PageUp": selectPageUp,
|
|
"Shift+PageDown": selectPageDown,
|
|
"Meta+ArrowLeft": cursorLineBoundaryBackward,
|
|
"Meta+ArrowRight": cursorLineBoundaryForward,
|
|
"Meta+Shift+ArrowLeft": selectLineBoundaryBackward,
|
|
"Meta+Shift+ArrowRight": selectLineBoundaryForward,
|
|
"Meta+ArrowUp": cursorDocStart,
|
|
"Meta+ArrowDown": cursorDocEnd,
|
|
"Ctrl+Home": cursorDocStart,
|
|
"Ctrl+End": cursorDocEnd,
|
|
"Ctrl+Shift+Home": selectDocStart,
|
|
"Ctrl+Shift+End": selectDocEnd,
|
|
"Ctrl+ArrowLeft": cursorGroupLeft,
|
|
"Ctrl+ArrowRight": cursorGroupRight,
|
|
};
|
|
|
|
/** The recorded name of a key event, or null when it is not an editor key a macro records. */
|
|
export function editorKeyName(
|
|
e: Pick<KeyboardEvent, "key" | "altKey" | "ctrlKey" | "metaKey" | "shiftKey">,
|
|
): string | null {
|
|
const name = [e.metaKey && "Meta", e.ctrlKey && "Ctrl", e.altKey && "Alt", e.shiftKey && "Shift", e.key]
|
|
.filter(Boolean)
|
|
.join("+");
|
|
return name in EDITOR_KEY_COMMANDS ? name : null;
|
|
}
|