diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 26bccde42..8ceebc289 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -2892,6 +2892,7 @@ test "Terminal: print right margin outside" { } } +// X test "Terminal: print right margin outside wrap" { var t = try init(testing.allocator, 10, 5); defer t.deinit(testing.allocator); @@ -2909,6 +2910,7 @@ test "Terminal: print right margin outside wrap" { } } +// X test "Terminal: linefeed and carriage return" { var t = try init(testing.allocator, 80, 80); defer t.deinit(testing.allocator); @@ -2927,6 +2929,7 @@ test "Terminal: linefeed and carriage return" { } } +// X test "Terminal: linefeed unsets pending wrap" { var t = try init(testing.allocator, 5, 80); defer t.deinit(testing.allocator); @@ -2938,6 +2941,7 @@ test "Terminal: linefeed unsets pending wrap" { try testing.expect(t.screen.cursor.pending_wrap == false); } +// X test "Terminal: linefeed mode automatic carriage return" { var t = try init(testing.allocator, 10, 10); defer t.deinit(testing.allocator); @@ -2954,6 +2958,7 @@ test "Terminal: linefeed mode automatic carriage return" { } } +// X test "Terminal: carriage return unsets pending wrap" { var t = try init(testing.allocator, 5, 80); defer t.deinit(testing.allocator); @@ -2965,6 +2970,7 @@ test "Terminal: carriage return unsets pending wrap" { try testing.expect(t.screen.cursor.pending_wrap == false); } +// X test "Terminal: carriage return origin mode moves to left margin" { var t = try init(testing.allocator, 5, 80); defer t.deinit(testing.allocator); @@ -2976,6 +2982,7 @@ test "Terminal: carriage return origin mode moves to left margin" { try testing.expectEqual(@as(usize, 2), t.screen.cursor.x); } +// X test "Terminal: carriage return left of left margin moves to zero" { var t = try init(testing.allocator, 5, 80); defer t.deinit(testing.allocator); @@ -2986,6 +2993,7 @@ test "Terminal: carriage return left of left margin moves to zero" { try testing.expectEqual(@as(usize, 0), t.screen.cursor.x); } +// X test "Terminal: carriage return right of left margin moves to left margin" { var t = try init(testing.allocator, 5, 80); defer t.deinit(testing.allocator); diff --git a/src/terminal/new/Terminal.zig b/src/terminal/new/Terminal.zig index d441c37e6..07f400978 100644 --- a/src/terminal/new/Terminal.zig +++ b/src/terminal/new/Terminal.zig @@ -202,9 +202,8 @@ pub fn printString(self: *Terminal, str: []const u8) !void { while (it.nextCodepoint()) |cp| { switch (cp) { '\n' => { - @panic("TODO: newline"); - // self.carriageReturn(); - // try self.linefeed(); + self.carriageReturn(); + try self.linefeed(); }, else => try self.print(cp), @@ -411,6 +410,26 @@ fn printWrap(self: *Terminal) !void { self.screen.cursor.page_row.flags.wrap_continuation = true; } +/// Carriage return moves the cursor to the first column. +pub fn carriageReturn(self: *Terminal) void { + // Always reset pending wrap state + self.screen.cursor.pending_wrap = false; + + // In origin mode we always move to the left margin + self.screen.cursorHorizontalAbsolute(if (self.modes.get(.origin)) + self.scrolling_region.left + else if (self.screen.cursor.x >= self.scrolling_region.left) + self.scrolling_region.left + else + 0); +} + +/// Linefeed moves the cursor to the next line. +pub fn linefeed(self: *Terminal) !void { + try self.index(); + if (self.modes.get(.linefeed)) self.carriageReturn(); +} + /// Move the cursor to the next line in the scrolling region, possibly scrolling. /// /// If the cursor is outside of the scrolling region: move the cursor one line @@ -827,3 +846,90 @@ test "Terminal: print right margin outside wrap" { try testing.expectEqualStrings("123456789X\n Y", str); } } + +test "Terminal: linefeed and carriage return" { + var t = try init(testing.allocator, 80, 80); + defer t.deinit(testing.allocator); + + // Basic grid writing + for ("hello") |c| try t.print(c); + t.carriageReturn(); + try t.linefeed(); + for ("world") |c| try t.print(c); + try testing.expectEqual(@as(usize, 1), t.screen.cursor.y); + try testing.expectEqual(@as(usize, 5), t.screen.cursor.x); + { + const str = try t.plainString(testing.allocator); + defer testing.allocator.free(str); + try testing.expectEqualStrings("hello\nworld", str); + } +} + +test "Terminal: linefeed unsets pending wrap" { + var t = try init(testing.allocator, 5, 80); + defer t.deinit(testing.allocator); + + // Basic grid writing + for ("hello") |c| try t.print(c); + try testing.expect(t.screen.cursor.pending_wrap == true); + try t.linefeed(); + try testing.expect(t.screen.cursor.pending_wrap == false); +} + +test "Terminal: linefeed mode automatic carriage return" { + var t = try init(testing.allocator, 10, 10); + defer t.deinit(testing.allocator); + + // Basic grid writing + t.modes.set(.linefeed, true); + try t.printString("123456"); + try t.linefeed(); + try t.print('X'); + { + const str = try t.plainString(testing.allocator); + defer testing.allocator.free(str); + try testing.expectEqualStrings("123456\nX", str); + } +} + +test "Terminal: carriage return unsets pending wrap" { + var t = try init(testing.allocator, 5, 80); + defer t.deinit(testing.allocator); + + // Basic grid writing + for ("hello") |c| try t.print(c); + try testing.expect(t.screen.cursor.pending_wrap == true); + t.carriageReturn(); + try testing.expect(t.screen.cursor.pending_wrap == false); +} + +test "Terminal: carriage return origin mode moves to left margin" { + var t = try init(testing.allocator, 5, 80); + defer t.deinit(testing.allocator); + + t.modes.set(.origin, true); + t.screen.cursor.x = 0; + t.scrolling_region.left = 2; + t.carriageReturn(); + try testing.expectEqual(@as(usize, 2), t.screen.cursor.x); +} + +test "Terminal: carriage return left of left margin moves to zero" { + var t = try init(testing.allocator, 5, 80); + defer t.deinit(testing.allocator); + + t.screen.cursor.x = 1; + t.scrolling_region.left = 2; + t.carriageReturn(); + try testing.expectEqual(@as(usize, 0), t.screen.cursor.x); +} + +test "Terminal: carriage return right of left margin moves to left margin" { + var t = try init(testing.allocator, 5, 80); + defer t.deinit(testing.allocator); + + t.screen.cursor.x = 3; + t.scrolling_region.left = 2; + t.carriageReturn(); + try testing.expectEqual(@as(usize, 2), t.screen.cursor.x); +}