v0.7.1 ff50ee4

rune_width.go RawHistoryFolder

1package core
2
3import "unicode"
4
5// RuneWidth returns the terminal cell width of a rune.
6//
7// Returns 0 for combining marks, zero-width characters, and control codes.
8// Returns 2 for CJK, fullwidth, and wide emoji characters.
9// Returns 1 for all other printable characters.
10//
11// Wide runes (width 2) occupy two grid cells: a left cell holding the rune and
12// a right continuation cell. Combining marks (Mn/Me) and zero-width joiner
13// sequences are out of scope: combining marks report width 0 (current
14// behavior), ZWJ sequences are not coalesced (each rune is measured on its own).
15func RuneWidth(r rune) int {
16	if r >= 0x20 && r < 0x7F { // printable ASCII, the common case
17		return 1
18	}
19	switch {
20	case r < 0x20 || r == 0x7F || (r >= 0x80 && r <= 0x9F):
21		return 0
22	// Soft hyphen, combining grapheme joiner, Arabic sign, etc.
23	case r == 0x00AD || r == 0x034F || r == 0x061C:
24		return 0
25	// Hangul Jungseong O/E, Hangul Jungseong Yu
26	case r == 0x115F || r == 0x1160:
27		return 0
28	// Balinese musical symbols
29	case r == 0x17B4 || r == 0x17B5:
30		return 0
31	// Mongolian variation selectors, free variation selector
32	case r == 0x180B || r == 0x180E || r == 0x200B || r == 0x200C || r == 0x200D || r == 0x200E || r == 0x200F:
33		return 0
34	// Line/paragraph separator, bidirectional overrides
35	case r >= 0x2028 && r <= 0x202E:
36		return 0
37	// Word joiner, invisible operators, Arabic/Syriac number marks, etc.
38	case r >= 0x2060 && r <= 0x206F:
39		return 0
40	case r == 0xFEFF || r == 0xFFF9 || r == 0xFFFA || r == 0xFFFB:
41		return 0
42	// Tags
43	case r >= 0xE0001 && r <= 0xE007F:
44		return 0
45	// Combining diacritical marks (Unicode categories Mn, Me)
46	case unicode.Is(unicode.Mn, r) || unicode.Is(unicode.Me, r):
47		return 0
48	// --- Wide characters (width 2) ---
49	// Hangul Jamo
50	case r >= 0x1100 && r <= 0x115F:
51		return 2
52	// Left/right-pointing angle bracket (for compatibility)
53	case r == 0x2329 || r == 0x232A:
54		return 2
55	// CJK Radicals Supplement, Kangxi Radicals, Ideographic Description
56	// CJK Symbols, Hiragana, Katakana, Bopomofo, Hangul Compatibility Jamo
57	// Kanbun, CJK Strokes, Enclosed CJK Letters
58	case r >= 0x2E80 && r <= 0x303E:
59		return 2
60	// Hiragana, Katakana, Bopomofo, Hangul Compatibility Jamo, Kanbun
61	case r >= 0x3040 && r <= 0x33FF:
62		return 2
63	// CJK Unified Ideographs Extension A
64	case r >= 0x3400 && r <= 0x4DBF:
65		return 2
66	// CJK Unified Ideographs, Yi Syllables, Yi Radicals
67	case r >= 0x4E00 && r <= 0xA4CF:
68		return 2
69	// Hangul Jamo Extended-A
70	case r >= 0xA960 && r <= 0xA97C:
71		return 2
72	// Hangul Syllables
73	case r >= 0xAC00 && r <= 0xD7AF:
74		return 2
75	// Hangul Jamo Extended-B
76	case r >= 0xD7B0 && r <= 0xD7FF:
77		return 2
78	// CJK Compatibility Ideographs
79	case r >= 0xF900 && r <= 0xFAFF:
80		return 2
81	// Vertical Forms
82	case r >= 0xFE10 && r <= 0xFE19:
83		return 2
84	// CJK Compatibility Forms
85	case r >= 0xFE30 && r <= 0xFE6F:
86		return 2
87	// Fullwidth Forms (variation selectors, fullwidth punctuation, etc.)
88	case r >= 0xFF01 && r <= 0xFF60:
89		return 2
90	// Fullwidth Signs (cent, pound, yen, won, etc.)
91	case r >= 0xFFE0 && r <= 0xFFE6:
92		return 2
93	// Kana Supplement
94	case r >= 0x1B000 && r <= 0x1B0FF:
95		return 2
96	// Kana Extended-A
97	case r >= 0x1B100 && r <= 0x1B12F:
98		return 2
99	// Mahjong Tiles, Domino Tiles, Playing Cards
100	case r >= 0x1F000 && r <= 0x1F09F:
101		return 2
102	// Miscellaneous Symbols and Pictographs, Emoticons, Ornamental Dingbats
103	case r >= 0x1F0A0 && r <= 0x1F64F:
104		return 2
105	// Transport and Map Symbols
106	case r >= 0x1F680 && r <= 0x1F6FF:
107		return 2
108	// Supplemental Symbols and Pictographs
109	case r >= 0x1F900 && r <= 0x1F9FF:
110		return 2
111	// Symbols and Pictographs Extended-A (emoji added in recent Unicode)
112	case r >= 0x1FA70 && r <= 0x1FAFF:
113		return 2
114	// CJK Unified Ideographs Extension B and beyond
115	case r >= 0x20000 && r <= 0x2FFFF:
116		return 2
117	// CJK Unified Ideographs Extension G and beyond
118	case r >= 0x30000 && r <= 0x3FFFF:
119		return 2
120	default:
121		return 1
122	}
123}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 13

↑↓ moveenter openesc close