mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
terminal2: zwjs in selectionString
This commit is contained in:
@ -5810,6 +5810,7 @@ test "Screen: selectionString empty with soft wrap" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// X
|
||||||
test "Screen: selectionString with zero width joiner" {
|
test "Screen: selectionString with zero width joiner" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
@ -884,15 +884,23 @@ pub fn selectionString(
|
|||||||
self.pages.cols;
|
self.pages.cols;
|
||||||
|
|
||||||
const cells = cells_ptr[start_x..end_x];
|
const cells = cells_ptr[start_x..end_x];
|
||||||
for (cells) |cell| {
|
for (cells) |*cell| {
|
||||||
if (!cell.hasText()) continue;
|
if (!cell.hasText()) continue;
|
||||||
const char = if (cell.content.codepoint > 0) cell.content.codepoint else ' ';
|
|
||||||
|
|
||||||
var buf: [4]u8 = undefined;
|
var buf: [4]u8 = undefined;
|
||||||
const encode_len = try std.unicode.utf8Encode(char, &buf);
|
{
|
||||||
try strbuilder.appendSlice(buf[0..encode_len]);
|
const char = if (cell.content.codepoint > 0) cell.content.codepoint else ' ';
|
||||||
|
const encode_len = try std.unicode.utf8Encode(char, &buf);
|
||||||
|
try strbuilder.appendSlice(buf[0..encode_len]);
|
||||||
|
}
|
||||||
|
if (cell.hasGrapheme()) {
|
||||||
|
const cps = chunk.page.data.lookupGrapheme(cell).?;
|
||||||
|
for (cps) |cp| {
|
||||||
|
const encode_len = try std.unicode.utf8Encode(cp, &buf);
|
||||||
|
try strbuilder.appendSlice(buf[0..encode_len]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO: graphemes
|
|
||||||
|
|
||||||
if (row_count < rows.len - 1 and
|
if (row_count < rows.len - 1 and
|
||||||
(!row.wrap or sel_ordered.rectangle))
|
(!row.wrap or sel_ordered.rectangle))
|
||||||
@ -1508,7 +1516,24 @@ pub fn testWriteString(self: *Screen, text: []const u8) !void {
|
|||||||
|
|
||||||
const width: usize = if (c <= 0xFF) 1 else @intCast(unicode.table.get(c).width);
|
const width: usize = if (c <= 0xFF) 1 else @intCast(unicode.table.get(c).width);
|
||||||
if (width == 0) {
|
if (width == 0) {
|
||||||
@panic("zero-width todo");
|
const cell = cell: {
|
||||||
|
var cell = self.cursorCellLeft(1);
|
||||||
|
switch (cell.wide) {
|
||||||
|
.narrow => {},
|
||||||
|
.wide => {},
|
||||||
|
.spacer_head => unreachable,
|
||||||
|
.spacer_tail => cell = self.cursorCellLeft(2),
|
||||||
|
}
|
||||||
|
|
||||||
|
break :cell cell;
|
||||||
|
};
|
||||||
|
|
||||||
|
try self.cursor.page_pin.page.data.appendGrapheme(
|
||||||
|
self.cursor.page_row,
|
||||||
|
cell,
|
||||||
|
c,
|
||||||
|
);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.cursor.pending_wrap) {
|
if (self.cursor.pending_wrap) {
|
||||||
@ -5341,3 +5366,36 @@ test "Screen: selectionString empty with soft wrap" {
|
|||||||
try testing.expectEqualStrings(expected, contents);
|
try testing.expectEqualStrings(expected, contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Screen: selectionString with zero width joiner" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var s = try init(alloc, 10, 1, 0);
|
||||||
|
defer s.deinit();
|
||||||
|
const str = "👨"; // this has a ZWJ
|
||||||
|
try s.testWriteString(str);
|
||||||
|
|
||||||
|
// Integrity check
|
||||||
|
{
|
||||||
|
const pin = s.pages.pin(.{ .screen = .{ .y = 0, .x = 0 } }).?;
|
||||||
|
const cell = pin.rowAndCell().cell;
|
||||||
|
try testing.expectEqual(@as(u21, 0x1F468), cell.content.codepoint);
|
||||||
|
try testing.expectEqual(Cell.Wide.wide, cell.wide);
|
||||||
|
const cps = pin.page.data.lookupGrapheme(cell).?;
|
||||||
|
try testing.expectEqual(@as(usize, 1), cps.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The real test
|
||||||
|
{
|
||||||
|
const sel = Selection.init(
|
||||||
|
s.pages.pin(.{ .screen = .{ .x = 0, .y = 0 } }).?,
|
||||||
|
s.pages.pin(.{ .screen = .{ .x = 1, .y = 0 } }).?,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
const contents = try s.selectionString(alloc, sel, true);
|
||||||
|
defer alloc.free(contents);
|
||||||
|
const expected = "👨";
|
||||||
|
try testing.expectEqualStrings(expected, contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user