diff --git a/go.mod b/go.mod index 193ee48..2fdcc2a 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.25.0 github.com/charmbracelet/lipgloss v0.10.0 + github.com/mattn/go-runewidth v0.0.15 ) require ( @@ -14,7 +15,6 @@ require ( github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/reflow v0.3.0 // indirect diff --git a/render.go b/render.go index 020eeb2..05185d6 100644 --- a/render.go +++ b/render.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/charmbracelet/lipgloss" + "github.com/mattn/go-runewidth" ) // === UI стили === @@ -330,83 +331,8 @@ func renderLineWithCursor(line string, cursorX int, fileType string) string { // === ANSI утилиты === -// runeWidth возвращает визуальную ширину символа в терминале. -// Большинство символов = 1, но wide characters (CJK, emoji) = 2. -func runeWidth(r rune) int { - // Управляющие символы - if r < 32 || r == 127 { - return 0 - } - // ASCII и Latin-1 - if r < 0x300 { - return 1 - } - // Combining marks (нулевая ширина) - if r >= 0x300 && r <= 0x36F { - return 0 - } - if r >= 0x1AB0 && r <= 0x1AFF { - return 0 - } - if r >= 0x1DC0 && r <= 0x1DFF { - return 0 - } - if r >= 0x20D0 && r <= 0x20FF { - return 0 - } - if r >= 0xFE20 && r <= 0xFE2F { - return 0 - } - // CJK и широкие блоки - switch { - case r >= 0x1100 && r <= 0x115F: - return 2 // Hangul Jamo - case r == 0x2329 || r == 0x232A: - return 2 - case r >= 0x2E80 && r <= 0x303E: - return 2 // CJK Radicals - case r >= 0x3040 && r <= 0x33FF: - return 2 // Japanese - case r >= 0x3400 && r <= 0x4DBF: - return 2 // CJK Extension A - case r >= 0x4E00 && r <= 0xA4CF: - return 2 // CJK Unified - case r >= 0xA960 && r <= 0xA97F: - return 2 // Hangul Jamo Extended-A - case r >= 0xAC00 && r <= 0xD7AF: - return 2 // Hangul Syllables - case r >= 0xF900 && r <= 0xFAFF: - return 2 // CJK Compatibility - case r >= 0xFE10 && r <= 0xFE19: - return 2 - case r >= 0xFE30 && r <= 0xFE6F: - return 2 - case r >= 0xFF00 && r <= 0xFF60: - return 2 // Fullwidth - case r >= 0xFFE0 && r <= 0xFFE6: - return 2 - case r >= 0x1B000 && r <= 0x1B0FF: - return 2 // Kana Supplement - case r >= 0x1F004 && r <= 0x1F0CF: - return 2 // Playing cards etc - case r >= 0x1F100 && r <= 0x1F1FF: - return 1 // Enclosed Alphanumeric Supplement (flags base) - case r >= 0x1F200 && r <= 0x1F2FF: - return 2 // Enclosed IdeographicSupplement - case r >= 0x1F300 && r <= 0x1F9FF: - return 2 // Misc symbols, emoji - case r >= 0x1FA00 && r <= 0x1FAFF: - return 2 // Chess, symbols - case r >= 0x20000 && r <= 0x2FFFD: - return 2 // CJK Extension B-F - case r >= 0x30000 && r <= 0x3FFFD: - return 2 - } - return 1 -} - // visibleWidth возвращает визуальную ширину строки в терминале, -// учитывая ANSI escape-коды и double-width символы (CJK, emoji). +// учитывая ANSI escape-коды и double-width символы через go-runewidth. func visibleWidth(s string) int { w := 0 inEsc := false @@ -421,7 +347,7 @@ func visibleWidth(s string) int { } continue } - w += runeWidth(r) + w += runewidth.RuneWidth(r) } return w } @@ -467,7 +393,7 @@ func truncateVisible(s string, maxWidth int) string { } continue } - rw := runeWidth(r) + rw := runewidth.RuneWidth(r) if vis+rw > maxWidth { break } diff --git a/untitled.md b/untitled.md deleted file mode 100644 index b0bff1c..0000000 --- a/untitled.md +++ /dev/null @@ -1,4 +0,0 @@ -```bash -deqwdq wdaw -SDW -``` \ No newline at end of file