fix(editor): Count wide characters as two columns in column editing (#172)

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
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-10-29 08:32:15 +08:00
1 джерело 9c3347df95
коміт c6621c5c36
15 files changed
+613 -58

No files matched your search

+1 -4
Переглянути файл
@@ -11,8 +11,6 @@ import {
cursorGroupRight,
cursorLineBoundaryBackward,
cursorLineBoundaryForward,
cursorLineDown,
cursorLineUp,
cursorPageDown,
cursorPageUp,
deleteCharBackward,
@@ -30,12 +28,11 @@ import {
selectGroupRight,
selectLineBoundaryBackward,
selectLineBoundaryForward,
selectLineDown,
selectLineUp,
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> = {