diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index b56193020..4120e48c9 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -3267,9 +3267,14 @@ pub fn eraseLine( break :left .{ 0, x + 1 }; }, - // Note that it seems like complete should reset the soft-wrap - // state of the line but in xterm it does not. - .complete => .{ 0, self.cols }, + .complete => complete: { + // Xterm preserves this flag for EL2, but it also doesn't reflow + // rows when resizing. Since we do, the erased row must no longer + // continue onto the next row. + self.screens.active.cursorResetWrap(); + + break :complete .{ 0, self.cols }; + }, else => { log.err("unimplemented erase line mode: {}", .{mode}); @@ -13596,6 +13601,35 @@ test "Terminal: eraseLine complete preserves background sgr" { } } +test "Terminal: eraseLine complete resets wrap" { + const alloc = testing.allocator; + const io_impl = testing.io; + var t = try init(io_impl, alloc, .{ .rows = 5, .cols = 5 }); + defer t.deinit(alloc); + + for ("ABCDE123") |c| try t.print(c); + { + const list_cell = t.screens.active.pages.getCell(.{ .active = .{ .x = 0, .y = 0 } }).?; + try testing.expect(list_cell.row.wrap); + } + + t.setCursorPos(1, 1); + t.eraseLine(.complete, false); + + { + const list_cell = t.screens.active.pages.getCell(.{ .active = .{ .x = 0, .y = 0 } }).?; + try testing.expect(!list_cell.row.wrap); + } + try t.print('X'); + try t.resize(alloc, .{ .rows = 5, .cols = 10 }); + + { + const str = try t.plainString(testing.allocator); + defer testing.allocator.free(str); + try testing.expectEqualStrings("X\n123", str); + } +} + test "Terminal: eraseLine complete protected attributes respected with iso" { const alloc = testing.allocator; const io_impl = testing.io;