mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
terminal implement clear screen and set cursor, needs tests
This commit is contained in:
@ -139,7 +139,7 @@ pub fn create(alloc: Allocator, loop: libuv.Loop) !*Window {
|
||||
|
||||
var env = try std.process.getEnvMap(alloc);
|
||||
defer env.deinit();
|
||||
try env.put("TERM", "dumb");
|
||||
try env.put("TERM", "xterm-256color");
|
||||
|
||||
var cmd: Command = .{
|
||||
.path = path,
|
||||
|
@ -8,6 +8,7 @@ const builtin = @import("builtin");
|
||||
const testing = std.testing;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ansi = @import("ansi.zig");
|
||||
const csi = @import("csi.zig");
|
||||
const Parser = @import("Parser.zig");
|
||||
const Tabstops = @import("Tabstops.zig");
|
||||
const trace = @import("../tracy/tracy.zig").trace;
|
||||
@ -127,11 +128,52 @@ pub fn appendChar(self: *Terminal, alloc: Allocator, c: u8) !void {
|
||||
switch (action_opt orelse continue) {
|
||||
.print => |p| try self.print(alloc, p),
|
||||
.execute => |code| try self.execute(alloc, code),
|
||||
.csi_dispatch => |csi| log.warn("CSI: {}", .{csi}),
|
||||
.csi_dispatch => |csi| try self.csiDispatch(alloc, csi),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn csiDispatch(
|
||||
self: *Terminal,
|
||||
alloc: Allocator,
|
||||
action: Parser.Action.CSI,
|
||||
) !void {
|
||||
switch (action.final) {
|
||||
// Set Cursor Position (TODO: docs)
|
||||
'H' => {
|
||||
switch (action.params.len) {
|
||||
0 => try self.setCursorPosition(1, 1),
|
||||
1 => try self.setCursorPosition(action.params[0], 1),
|
||||
2 => try self.setCursorPosition(action.params[0], action.params[1]),
|
||||
else => log.warn("unimplemented CSI: {}", .{csi}),
|
||||
}
|
||||
},
|
||||
|
||||
// Erase Display
|
||||
'J' => try self.eraseDisplay(alloc, switch (action.params.len) {
|
||||
0 => .below,
|
||||
1 => mode: {
|
||||
// TODO: use meta to get enum max
|
||||
if (action.params[0] > 3) {
|
||||
log.warn("invalid erase display command: {}", .{csi});
|
||||
return;
|
||||
}
|
||||
|
||||
break :mode @intToEnum(
|
||||
csi.EraseDisplayMode,
|
||||
action.params[0],
|
||||
);
|
||||
},
|
||||
else => {
|
||||
log.warn("invalid erase display command: {}", .{csi});
|
||||
return;
|
||||
},
|
||||
}),
|
||||
|
||||
else => log.warn("unimplemented CSI: {}", .{csi}),
|
||||
}
|
||||
}
|
||||
|
||||
fn print(self: *Terminal, alloc: Allocator, c: u8) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@ -171,6 +213,32 @@ pub fn bell(self: *Terminal) void {
|
||||
log.info("bell", .{});
|
||||
}
|
||||
|
||||
/// Set the cursor position. Row and column are 1-based.
|
||||
/// TODO: test
|
||||
pub fn setCursorPosition(self: *Terminal, row: usize, col: usize) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
self.cursor.x = col - 1;
|
||||
self.cursor.y = row - 1;
|
||||
}
|
||||
|
||||
/// Erase the display.
|
||||
/// TODO: test
|
||||
pub fn eraseDisplay(
|
||||
self: *Terminal,
|
||||
alloc: Allocator,
|
||||
mode: csi.EraseDisplayMode,
|
||||
) !void {
|
||||
switch (mode) {
|
||||
.complete => {
|
||||
for (self.screen.items) |*line| line.deinit(alloc);
|
||||
self.screen.clearRetainingCapacity();
|
||||
},
|
||||
else => @panic("unimplemented"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Backspace moves the cursor back a column (but not less than 0).
|
||||
pub fn backspace(self: *Terminal) void {
|
||||
const tracy = trace(@src());
|
||||
|
7
src/terminal/csi.zig
Normal file
7
src/terminal/csi.zig
Normal file
@ -0,0 +1,7 @@
|
||||
// Modes for the ED CSI command.
|
||||
pub const EraseDisplayMode = enum(u8) {
|
||||
below = 0,
|
||||
above = 1,
|
||||
complete = 2,
|
||||
scrollback = 3,
|
||||
};
|
Reference in New Issue
Block a user