mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
terminal2: selectionString with wide spacer head
This commit is contained in:
@ -5759,6 +5759,7 @@ test "Screen: selectionString wide char" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// X
|
||||||
test "Screen: selectionString wide char with header" {
|
test "Screen: selectionString wide char with header" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
@ -5779,6 +5780,7 @@ test "Screen: selectionString wide char with header" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// X
|
||||||
// https://github.com/mitchellh/ghostty/issues/289
|
// https://github.com/mitchellh/ghostty/issues/289
|
||||||
test "Screen: selectionString empty with soft wrap" {
|
test "Screen: selectionString empty with soft wrap" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
@ -852,7 +852,18 @@ pub fn selectionString(
|
|||||||
const sel_end = end: {
|
const sel_end = end: {
|
||||||
var end = sel.end();
|
var end = sel.end();
|
||||||
const cell = end.rowAndCell().cell;
|
const cell = end.rowAndCell().cell;
|
||||||
if (cell.wide == .spacer_tail) end.x -= 1;
|
switch (cell.wide) {
|
||||||
|
.narrow, .wide => {},
|
||||||
|
|
||||||
|
// We can omit the tail
|
||||||
|
.spacer_tail => end.x -= 1,
|
||||||
|
|
||||||
|
// With the head we want to include the wrapped wide character.
|
||||||
|
.spacer_head => if (end.down(1)) |p| {
|
||||||
|
end = p;
|
||||||
|
end.x = 0;
|
||||||
|
},
|
||||||
|
}
|
||||||
break :end end;
|
break :end end;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5277,3 +5288,56 @@ test "Screen: selectionString wide char" {
|
|||||||
try testing.expectEqualStrings(expected, contents);
|
try testing.expectEqualStrings(expected, contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Screen: selectionString wide char with header" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var s = try init(alloc, 5, 3, 0);
|
||||||
|
defer s.deinit();
|
||||||
|
const str = "1ABC⚡";
|
||||||
|
try s.testWriteString(str);
|
||||||
|
|
||||||
|
{
|
||||||
|
const sel = Selection.init(
|
||||||
|
s.pages.pin(.{ .screen = .{ .x = 0, .y = 0 } }).?,
|
||||||
|
s.pages.pin(.{ .screen = .{ .x = 4, .y = 0 } }).?,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
const contents = try s.selectionString(alloc, sel, true);
|
||||||
|
defer alloc.free(contents);
|
||||||
|
const expected = str;
|
||||||
|
try testing.expectEqualStrings(expected, contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/mitchellh/ghostty/issues/289
|
||||||
|
test "Screen: selectionString empty with soft wrap" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var s = try init(alloc, 5, 2, 0);
|
||||||
|
defer s.deinit();
|
||||||
|
|
||||||
|
// Let me describe the situation that caused this because this
|
||||||
|
// test is not obvious. By writing an emoji below, we introduce
|
||||||
|
// one cell with the emoji and one cell as a "wide char spacer".
|
||||||
|
// We then soft wrap the line by writing spaces.
|
||||||
|
//
|
||||||
|
// By selecting only the tail, we'd select nothing and we had
|
||||||
|
// a logic error that would cause a crash.
|
||||||
|
try s.testWriteString("👨");
|
||||||
|
try s.testWriteString(" ");
|
||||||
|
|
||||||
|
{
|
||||||
|
const sel = Selection.init(
|
||||||
|
s.pages.pin(.{ .screen = .{ .x = 1, .y = 0 } }).?,
|
||||||
|
s.pages.pin(.{ .screen = .{ .x = 2, .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