mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
CUP full implementation with tests
This commit is contained in:
@ -139,13 +139,13 @@ fn csiDispatch(
|
|||||||
action: Parser.Action.CSI,
|
action: Parser.Action.CSI,
|
||||||
) !void {
|
) !void {
|
||||||
switch (action.final) {
|
switch (action.final) {
|
||||||
// Set Cursor Position (TODO: docs)
|
// CUP - Set Cursor Position.
|
||||||
'H' => {
|
'H' => {
|
||||||
switch (action.params.len) {
|
switch (action.params.len) {
|
||||||
0 => try self.setCursorPosition(1, 1),
|
0 => try self.setCursorPosition(1, 1),
|
||||||
1 => try self.setCursorPosition(action.params[0], 1),
|
1 => try self.setCursorPosition(action.params[0], 1),
|
||||||
2 => try self.setCursorPosition(action.params[0], action.params[1]),
|
2 => try self.setCursorPosition(action.params[0], action.params[1]),
|
||||||
else => log.warn("unimplemented CSI: {}", .{csi}),
|
else => log.warn("unimplemented CSI: {}", .{action}),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ fn csiDispatch(
|
|||||||
1 => mode: {
|
1 => mode: {
|
||||||
// TODO: use meta to get enum max
|
// TODO: use meta to get enum max
|
||||||
if (action.params[0] > 3) {
|
if (action.params[0] > 3) {
|
||||||
log.warn("invalid erase display command: {}", .{csi});
|
log.warn("invalid erase display command: {}", .{action});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,12 +165,12 @@ fn csiDispatch(
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
log.warn("invalid erase display command: {}", .{csi});
|
log.warn("invalid erase display command: {}", .{action});
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
else => log.warn("unimplemented CSI: {}", .{csi}),
|
else => log.warn("unimplemented CSI: {}", .{action}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,14 +213,18 @@ pub fn bell(self: *Terminal) void {
|
|||||||
log.info("bell", .{});
|
log.info("bell", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the cursor position. Row and column are 1-based.
|
// Set Cursor Position. Move cursor to the position indicated
|
||||||
/// TODO: test
|
// by row and column (1-indexed). If column is 0, it is adjusted to 1.
|
||||||
|
// If column is greater than the right-most column it is adjusted to
|
||||||
|
// the right-most column. If row is 0, it is adjusted to 1. If row is
|
||||||
|
// greater than the bottom-most row it is adjusted to the bottom-most
|
||||||
|
// row.
|
||||||
pub fn setCursorPosition(self: *Terminal, row: usize, col: usize) !void {
|
pub fn setCursorPosition(self: *Terminal, row: usize, col: usize) !void {
|
||||||
const tracy = trace(@src());
|
const tracy = trace(@src());
|
||||||
defer tracy.end();
|
defer tracy.end();
|
||||||
|
|
||||||
self.cursor.x = col - 1;
|
self.cursor.x = @minimum(self.cols, col) -| 1;
|
||||||
self.cursor.y = row - 1;
|
self.cursor.y = @minimum(self.rows, row) -| 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Erase the display.
|
/// Erase the display.
|
||||||
@ -392,3 +396,46 @@ test "Terminal: horizontal tabs" {
|
|||||||
try t.append(testing.allocator, "\t");
|
try t.append(testing.allocator, "\t");
|
||||||
try testing.expectEqual(@as(usize, 16), t.cursor.x);
|
try testing.expectEqual(@as(usize, 16), t.cursor.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Terminal: CUP (ESC [ H)" {
|
||||||
|
var t = try init(testing.allocator, 80, 80);
|
||||||
|
defer t.deinit(testing.allocator);
|
||||||
|
|
||||||
|
// X, Y both specified
|
||||||
|
try t.append(testing.allocator, "\x1B[5;10H");
|
||||||
|
try testing.expectEqual(@as(usize, 4), t.cursor.y);
|
||||||
|
try testing.expectEqual(@as(usize, 9), t.cursor.x);
|
||||||
|
|
||||||
|
// Y only
|
||||||
|
try t.append(testing.allocator, "\x1B[5H");
|
||||||
|
try testing.expectEqual(@as(usize, 4), t.cursor.y);
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.cursor.x);
|
||||||
|
|
||||||
|
// 0, 0 default
|
||||||
|
try t.append(testing.allocator, "\x1B[H");
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.cursor.y);
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.cursor.x);
|
||||||
|
|
||||||
|
// invalid
|
||||||
|
try t.append(testing.allocator, "\x1B[1;2;3H");
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.cursor.y);
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.cursor.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Terminal: setCursorPosition" {
|
||||||
|
var t = try init(testing.allocator, 80, 80);
|
||||||
|
defer t.deinit(testing.allocator);
|
||||||
|
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.cursor.x);
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.cursor.y);
|
||||||
|
|
||||||
|
// Setting it to 0 should keep it zero (1 based)
|
||||||
|
try t.setCursorPosition(0, 0);
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.cursor.x);
|
||||||
|
try testing.expectEqual(@as(usize, 0), t.cursor.y);
|
||||||
|
|
||||||
|
// Should clamp to size
|
||||||
|
try t.setCursorPosition(81, 81);
|
||||||
|
try testing.expectEqual(@as(usize, 79), t.cursor.x);
|
||||||
|
try testing.expectEqual(@as(usize, 79), t.cursor.y);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user