mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-08-04 06:36:24 +00:00
Add grapheme break properties when generating wcwidth data
This commit is contained in:
parent
41a3519ebb
commit
dc625c5e0c
3 changed files with 5692 additions and 15 deletions
|
|
@ -71,6 +71,7 @@ flag_codepoints = frozenset(range(0x1F1E6, 0x1F1E6 + 26))
|
|||
marks = set(emoji_skin_tone_modifiers) | flag_codepoints
|
||||
not_assigned = set(range(0, sys.maxunicode))
|
||||
property_maps: dict[str, set[int]] = defaultdict(set)
|
||||
grapheme_segmentation_maps: dict[str, set[int]] = defaultdict(set)
|
||||
|
||||
|
||||
def parse_prop_list() -> None:
|
||||
|
|
@ -259,6 +260,12 @@ def parse_eaw() -> None:
|
|||
doublewidth |= set(range(0x30000, 0x3FFFD + 1)) - seen
|
||||
|
||||
|
||||
def parse_grapheme_segmentation() -> None:
|
||||
for line in get_data('ucd/auxiliary/GraphemeBreakProperty.txt'):
|
||||
chars, category = split_two(line)
|
||||
grapheme_segmentation_maps[category] |= chars
|
||||
|
||||
|
||||
def get_ranges(items: list[int]) -> Generator[Union[int, tuple[int, int]], None, None]:
|
||||
items.sort()
|
||||
for k, g in groupby(enumerate(items), lambda m: m[0]-m[1]):
|
||||
|
|
@ -362,21 +369,6 @@ def category_test(
|
|||
p('\treturn false;\n}\n')
|
||||
|
||||
|
||||
def codepoint_to_mark_map(p: Callable[..., None], mark_map: list[int]) -> dict[int, int]:
|
||||
p('\tswitch(c) { // {{{')
|
||||
rmap = {c: m for m, c in enumerate(mark_map)}
|
||||
for spec in get_ranges(mark_map):
|
||||
if isinstance(spec, tuple):
|
||||
s = rmap[spec[0]]
|
||||
cases = ' '.join(f'case {i}:' for i in range(spec[0], spec[1]+1))
|
||||
p(f'\t\t{cases} return {s} + c - {spec[0]};')
|
||||
else:
|
||||
p(f'\t\tcase {spec}: return {rmap[spec]};')
|
||||
p('default: return 0;')
|
||||
p('\t} // }}}')
|
||||
return rmap
|
||||
|
||||
|
||||
def classes_to_regex(classes: Iterable[str], exclude: str = '', for_go: bool = True) -> Iterable[str]:
|
||||
chars: set[int] = set()
|
||||
for c in classes:
|
||||
|
|
@ -451,6 +443,47 @@ def gen_names() -> None:
|
|||
print(cp, *words, end=end, file=f)
|
||||
|
||||
|
||||
def gen_grapheme_segmentation() -> None:
|
||||
with create_header('kitty/grapheme-segmentation-data.h') as p, open('tools/wcswidth/grapheme-segmentation-data.go', 'w') as gof:
|
||||
gp = partial(print, file=gof)
|
||||
p('typedef enum GraphemeBreakProperty {') # }
|
||||
p(' None,')
|
||||
gp('package wcswidth\n\n')
|
||||
gp('type GraphemeBreakProperty uint8\n')
|
||||
gp('const (') # )
|
||||
gp('None = iota') # )
|
||||
for category in grapheme_segmentation_maps:
|
||||
p(f' {category},')
|
||||
gp(f' {category}')
|
||||
p('} GraphemeBreakProperty;')
|
||||
p('')
|
||||
gp(')')
|
||||
gp('')
|
||||
p('static inline GraphemeBreakProperty')
|
||||
p('grapheme_break_property(const char_type c) {') # }
|
||||
p('\tswitch(c) {') # }
|
||||
gp('func GraphemeBreakPropertyFor(code rune) GraphemeBreakProperty {') # }
|
||||
gp('\tswitch code {') # }
|
||||
for category, codepoints in grapheme_segmentation_maps.items():
|
||||
p(f'\t\t // {category} ({len(codepoints)} codepoints ''{{''{')
|
||||
gp(f'\t\t // {category} ({len(codepoints)} codepoints ''{{''{')
|
||||
for spec in get_ranges(list(codepoints)):
|
||||
write_case(spec, p)
|
||||
p(f'\t\t\treturn {category};')
|
||||
write_case(spec, p, for_go=True)
|
||||
p(f'\t\t\treturn {category}')
|
||||
p('\t\t // }}''}')
|
||||
p('')
|
||||
gp('\t\t // }}''}')
|
||||
gp('')
|
||||
p('\t}') # }
|
||||
gp('\t}') # }
|
||||
p('\treturn None;') # }
|
||||
gp('\treturn None') # }
|
||||
p('}')
|
||||
gp('}')
|
||||
|
||||
|
||||
def gen_wcwidth() -> None:
|
||||
seen: set[int] = set()
|
||||
non_printing = class_maps['Cc'] | class_maps['Cf'] | class_maps['Cs']
|
||||
|
|
@ -569,11 +602,13 @@ def main(args: list[str]=sys.argv) -> None:
|
|||
parse_prop_list()
|
||||
parse_emoji()
|
||||
parse_eaw()
|
||||
parse_grapheme_segmentation()
|
||||
gen_ucd()
|
||||
gen_wcwidth()
|
||||
gen_emoji()
|
||||
gen_names()
|
||||
gen_rowcolumn_diacritics()
|
||||
gen_grapheme_segmentation()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
5576
kitty/grapheme-segmentation-data.h
Normal file
5576
kitty/grapheme-segmentation-data.h
Normal file
File diff suppressed because one or more lines are too long
66
tools/wcswidth/grapheme-segmentation-data.go
Normal file
66
tools/wcswidth/grapheme-segmentation-data.go
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
package wcswidth
|
||||
|
||||
|
||||
type GraphemeBreakProperty uint8
|
||||
|
||||
const (
|
||||
None = iota
|
||||
Prepend
|
||||
CR
|
||||
LF
|
||||
Control
|
||||
Extend
|
||||
Regional_Indicator
|
||||
SpacingMark
|
||||
L
|
||||
V
|
||||
T
|
||||
LV
|
||||
LVT
|
||||
ZWJ
|
||||
)
|
||||
|
||||
func GraphemeBreakPropertyFor(code rune) GraphemeBreakProperty {
|
||||
switch code {
|
||||
// Prepend (28 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// CR (1 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// LF (1 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// Control (3893 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// Extend (2198 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// Regional_Indicator (26 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// SpacingMark (378 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// L (125 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// V (100 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// T (137 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// LV (399 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// LVT (10773 codepoints {{{
|
||||
// }}}
|
||||
|
||||
// ZWJ (1 codepoints {{{
|
||||
// }}}
|
||||
|
||||
}
|
||||
return None
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue