From 490fd008e29420e5b317fd5ef7526f3cc92ba2eb Mon Sep 17 00:00:00 2001 From: Jose Colon Rodriguez Date: Sat, 17 Feb 2024 11:31:52 -0400 Subject: display_width tweaks --- src/display_width.zig | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'src/display_width.zig') diff --git a/src/display_width.zig b/src/display_width.zig index aed0ef1..2ac7093 100644 --- a/src/display_width.zig +++ b/src/display_width.zig @@ -42,17 +42,10 @@ fn isAsciiOnly(str: []const u8) bool { pub fn strWidth(str: []const u8) usize { var total: isize = 0; + // ASCII fast path if (isAsciiOnly(str)) { - for (str) |b| { - // Backspace and delete - if (b == 0x8 or b == 0x7f) { - total -= 1; - } else if (b >= 0x20) { - total += 1; - } - } - - return if (total > 0) @intCast(total) else 0; + for (str) |b| total += codePointWidth(b); + return @intCast(@max(0, total)); } var giter = GraphemeIterator.init(str); @@ -72,14 +65,17 @@ pub fn strWidth(str: []const u8) usize { } // Only adding width of first non-zero-width code point. - if (gc_total == 0) gc_total = w; + if (gc_total == 0) { + gc_total = w; + break; + } } } total += gc_total; } - return if (total > 0) @intCast(total) else 0; + return @intCast(@max(0, total)); } test "display_width Width" { @@ -147,4 +143,14 @@ test "display_width Width" { // The following passes but as a mere coincidence. const kannada_2 = "\u{0cb0}\u{0cbc}\u{0ccd}\u{0c9a}"; try testing.expectEqual(@as(usize, 2), strWidth(kannada_2)); + + // From Rust https://github.com/jameslanska/unicode-display-width + try testing.expectEqual(@as(usize, 15), strWidth("πŸ”₯πŸ—‘πŸ©πŸ‘©πŸ»β€πŸš€β°πŸ’ƒπŸΌπŸ”¦πŸ‘πŸ»")); + try testing.expectEqual(@as(usize, 2), strWidth("πŸ¦€")); + try testing.expectEqual(@as(usize, 2), strWidth("πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§")); + try testing.expectEqual(@as(usize, 2), strWidth("πŸ‘©β€πŸ”¬")); + try testing.expectEqual(@as(usize, 9), strWidth("sane text")); + try testing.expectEqual(@as(usize, 9), strWidth("αΊ’ΜŒΓ‘Μ²lΝ”ΜΜžΜ„Μ‘ΝŒgΜ–Μ˜Μ˜Μ”Μ”Ν’ΝžΝoΜͺΜ”TΜ’Μ™Μ«ΜˆΜΝžeΜ¬ΝˆΝ•ΝŒΜΝ‘x̺̍ṭ̓̓ͅ")); + try testing.expectEqual(@as(usize, 17), strWidth("μŠ¬λΌλ°” μš°ν¬λΌμ΄λ‚˜")); + try testing.expectEqual(@as(usize, 1), strWidth("\u{378}")); } -- cgit v1.2.3