test very long emoji

This commit is contained in:
Mitchell Hashimoto
2022-09-06 14:21:07 -07:00
parent f40eb3663a
commit 3754de3b95

View File

@ -1497,6 +1497,8 @@ pub fn testWriteString(self: *Screen, text: []const u8) !void {
// Get our row
var row = self.getRow(.{ .active = y });
// NOTE: graphemes are currently disabled
if (false) {
// If we have a previous cell, we check if we're part of a grapheme.
if (grapheme.cell) |prev_cell| {
const grapheme_break = brk: {
@ -1523,6 +1525,21 @@ pub fn testWriteString(self: *Screen, text: []const u8) !void {
continue;
}
}
}
const width = utf8proc.charwidth(c);
//log.warn("c={x} width={}", .{ c, width });
// Zero-width are attached as grapheme data.
// NOTE: if/when grapheme clustering is ever enabled (above) this
// is not necessary
if (width == 0) {
if (grapheme.cell != null) {
try row.attachGrapheme(grapheme.x, c);
}
continue;
}
// If we're writing past the end, we need to soft wrap.
if (x == self.cols) {
@ -1537,7 +1554,6 @@ pub fn testWriteString(self: *Screen, text: []const u8) !void {
}
// If our character is double-width, handle it.
const width = utf8proc.charwidth(c);
assert(width == 1 or width == 2);
switch (width) {
1 => {
@ -1768,9 +1784,40 @@ test "Screen: write graphemes" {
buf_idx += try std.unicode.utf8Encode(0x1F44D, buf[buf_idx..]); // Thumbs up plain
buf_idx += try std.unicode.utf8Encode(0x1F3FD, buf[buf_idx..]); // Medium skin tone
// Note the assertions below are NOT the correct way to handle graphemes
// in general, but they're "correct" for historical purposes for terminals.
// For terminals, all double-wide codepoints are counted as part of the
// width.
try s.testWriteString(buf[0..buf_idx]);
try testing.expect(s.rowsWritten() == 2);
try testing.expectEqual(@as(usize, 2), s.cursor.x);
}
test "Screen: write long emoji" {
const testing = std.testing;
const alloc = testing.allocator;
var s = try init(alloc, 5, 30, 0);
defer s.deinit();
// Sanity check that our test helpers work
var buf: [32]u8 = undefined;
var buf_idx: usize = 0;
buf_idx += try std.unicode.utf8Encode(0x1F9D4, buf[buf_idx..]); // man: beard
buf_idx += try std.unicode.utf8Encode(0x1F3FB, buf[buf_idx..]); // light skin tone (Fitz 1-2)
buf_idx += try std.unicode.utf8Encode(0x200D, buf[buf_idx..]); // ZWJ
buf_idx += try std.unicode.utf8Encode(0x2642, buf[buf_idx..]); // male sign
buf_idx += try std.unicode.utf8Encode(0xFE0F, buf[buf_idx..]); // emoji representation
// Note the assertions below are NOT the correct way to handle graphemes
// in general, but they're "correct" for historical purposes for terminals.
// For terminals, all double-wide codepoints are counted as part of the
// width.
try s.testWriteString(buf[0..buf_idx]);
try testing.expect(s.rowsWritten() == 1);
try testing.expectEqual(@as(usize, 4), s.cursor.x);
try testing.expectEqual(@as(usize, 5), s.cursor.x);
}
test "Screen: scrolling" {