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);
|
var env = try std.process.getEnvMap(alloc);
|
||||||
defer env.deinit();
|
defer env.deinit();
|
||||||
try env.put("TERM", "dumb");
|
try env.put("TERM", "xterm-256color");
|
||||||
|
|
||||||
var cmd: Command = .{
|
var cmd: Command = .{
|
||||||
.path = path,
|
.path = path,
|
||||||
|
@ -8,6 +8,7 @@ const builtin = @import("builtin");
|
|||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const ansi = @import("ansi.zig");
|
const ansi = @import("ansi.zig");
|
||||||
|
const csi = @import("csi.zig");
|
||||||
const Parser = @import("Parser.zig");
|
const Parser = @import("Parser.zig");
|
||||||
const Tabstops = @import("Tabstops.zig");
|
const Tabstops = @import("Tabstops.zig");
|
||||||
const trace = @import("../tracy/tracy.zig").trace;
|
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) {
|
switch (action_opt orelse continue) {
|
||||||
.print => |p| try self.print(alloc, p),
|
.print => |p| try self.print(alloc, p),
|
||||||
.execute => |code| try self.execute(alloc, code),
|
.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 {
|
fn print(self: *Terminal, alloc: Allocator, c: u8) !void {
|
||||||
const tracy = trace(@src());
|
const tracy = trace(@src());
|
||||||
defer tracy.end();
|
defer tracy.end();
|
||||||
@ -171,6 +213,32 @@ pub fn bell(self: *Terminal) void {
|
|||||||
log.info("bell", .{});
|
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).
|
/// Backspace moves the cursor back a column (but not less than 0).
|
||||||
pub fn backspace(self: *Terminal) void {
|
pub fn backspace(self: *Terminal) void {
|
||||||
const tracy = trace(@src());
|
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