summaryrefslogtreecommitdiff
path: root/src/display_width.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/display_width.zig')
-rw-r--r--src/display_width.zig30
1 files changed, 18 insertions, 12 deletions
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 {
42pub fn strWidth(str: []const u8) usize { 42pub fn strWidth(str: []const u8) usize {
43 var total: isize = 0; 43 var total: isize = 0;
44 44
45 // ASCII fast path
45 if (isAsciiOnly(str)) { 46 if (isAsciiOnly(str)) {
46 for (str) |b| { 47 for (str) |b| total += codePointWidth(b);
47 // Backspace and delete 48 return @intCast(@max(0, total));
48 if (b == 0x8 or b == 0x7f) {
49 total -= 1;
50 } else if (b >= 0x20) {
51 total += 1;
52 }
53 }
54
55 return if (total > 0) @intCast(total) else 0;
56 } 49 }
57 50
58 var giter = GraphemeIterator.init(str); 51 var giter = GraphemeIterator.init(str);
@@ -72,14 +65,17 @@ pub fn strWidth(str: []const u8) usize {
72 } 65 }
73 66
74 // Only adding width of first non-zero-width code point. 67 // Only adding width of first non-zero-width code point.
75 if (gc_total == 0) gc_total = w; 68 if (gc_total == 0) {
69 gc_total = w;
70 break;
71 }
76 } 72 }
77 } 73 }
78 74
79 total += gc_total; 75 total += gc_total;
80 } 76 }
81 77
82 return if (total > 0) @intCast(total) else 0; 78 return @intCast(@max(0, total));
83} 79}
84 80
85test "display_width Width" { 81test "display_width Width" {
@@ -147,4 +143,14 @@ test "display_width Width" {
147 // The following passes but as a mere coincidence. 143 // The following passes but as a mere coincidence.
148 const kannada_2 = "\u{0cb0}\u{0cbc}\u{0ccd}\u{0c9a}"; 144 const kannada_2 = "\u{0cb0}\u{0cbc}\u{0ccd}\u{0c9a}";
149 try testing.expectEqual(@as(usize, 2), strWidth(kannada_2)); 145 try testing.expectEqual(@as(usize, 2), strWidth(kannada_2));
146
147 // From Rust https://github.com/jameslanska/unicode-display-width
148 try testing.expectEqual(@as(usize, 15), strWidth("πŸ”₯πŸ—‘πŸ©πŸ‘©πŸ»β€πŸš€β°πŸ’ƒπŸΌπŸ”¦πŸ‘πŸ»"));
149 try testing.expectEqual(@as(usize, 2), strWidth("πŸ¦€"));
150 try testing.expectEqual(@as(usize, 2), strWidth("πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§"));
151 try testing.expectEqual(@as(usize, 2), strWidth("πŸ‘©β€πŸ”¬"));
152 try testing.expectEqual(@as(usize, 9), strWidth("sane text"));
153 try testing.expectEqual(@as(usize, 9), strWidth("αΊ’ΜŒΓ‘Μ²lΝ”ΜΜžΜ„Μ‘ΝŒgΜ–Μ˜Μ˜Μ”Μ”Ν’ΝžΝoΜͺΜ”TΜ’Μ™Μ«ΜˆΜΝžeΜ¬ΝˆΝ•ΝŒΜΝ‘x̺̍ṭ̓̓ͅ"));
154 try testing.expectEqual(@as(usize, 17), strWidth("μŠ¬λΌλ°” μš°ν¬λΌμ΄λ‚˜"));
155 try testing.expectEqual(@as(usize, 1), strWidth("\u{378}"));
150} 156}