i was working on this when i stumbled on this bug, so i did bunch of different characters to see which ones cause issue, hence test has many different options. I could make it either simpler or split it, as needed.
`decode_grapheme_iterate` already computed the text of each grapheme
cluster, but `decode_grapheme_clusters` discarded it, forcing callers to
reconstruct each cluster's range by looking ahead to the next grapheme's
`byte_index`. Store it on `Grapheme` instead; it is a slice of the input
string, so no allocation is involved.
`core:text/edit` was using `Grapheme.width` -- the number of monospace
cells -- as a byte count when moving the caret by grapheme, so it landed
in the middle of a cluster for anything wider than one byte per cell. Use
`len(Grapheme.text)`, and add a test package for the translations.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Somewhere on the creation of these tables, the `0x3000-0x3000` range seemingly slipped in an additional time.
Since binary search is done on both `unicode_spaces` and `space_ranges`, i doubt this is intentional behavior, as this unsorts the tables.
string_to_proplist_property was being used with an or_return but
did not return an error. The function now returns an error when
it cannot identify a property.
This adds the functino `unicode.in_range` to search for a run in
the `Range` type used in `core/unicode/generated.odin`.
This also modifies `unicode.binary_search` so it will support searching
types other than i32 by making it support implicit parametric polymorphism.
`unicode.in_digit` has been modified to use the generated tables.
This adds a program that will generate tables for use by the `core/unicode`
package. The table generated file will be `core/unicode/generated.odin`
It may be better to incorporate this into `generate_entity_table.odin`.
This can easily be accomplised if desired.