const std = @import("std"); const os = std.os; const io = std.io; const fs = std.fs; const mem = std.mem; const heap = std.heap; const fmt = std.fmt; pub fn main() !void { var gpa = heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); var term = try Terminal.init(allocator); defer term.deinit(); // var info = try Terminal.Info.init(allocator); // defer info.deinit(); // var seq = Terminal.Info.Sequence.init(allocator, &info); // defer seq.deinit(); // try seq.cursorLeft(); try term.print("poopoo", .{}); try term.cursorLeft(); try term.cursorLeft(); try term.print("ee", .{}); // try seq.writeOut(term.tty.writer()); //io.AnyWriter{ .context = &term.tty, .writeFn = &fs.File.write }); } pub const Terminal = struct { tty: fs.File, original_termios: os.linux.termios, info: Info, allocator: mem.Allocator, pub fn init(allocator: mem.Allocator) !Terminal { var term = Terminal{ .tty = try fs.openFileAbsolute("/dev/tty", .{ .mode = .read_write }), .original_termios = undefined, .info = try Info.init(allocator), .allocator = allocator, }; errdefer term.tty.close(); errdefer term.info.deinit(); term.uncook(); return term; } pub fn deinit(self: *Terminal) void { self.cook(); self.tty.close(); self.info.deinit(); } // pub fn poll(self: *Terminal) void {} fn uncook(self: *Terminal) void { _ = os.linux.tcgetattr(self.tty.handle, &self.original_termios); var raw = self.original_termios; raw.lflag.ECHO = false; raw.lflag.ICANON = false; raw.lflag.ISIG = false; raw.lflag.IEXTEN = false; raw.iflag.IXON = false; raw.iflag.ICRNL = false; raw.iflag.BRKINT = false; raw.iflag.INPCK = false; raw.iflag.ISTRIP = false; raw.oflag.OPOST = false; raw.cc[@intFromEnum(os.linux.V.TIME)] = 0; raw.cc[@intFromEnum(os.linux.V.MIN)] = 1; _ = os.linux.tcsetattr(self.tty.handle, .FLUSH, &raw); } fn cook(self: *Terminal) void { _ = os.linux.tcsetattr(self.tty.handle, .FLUSH, &self.original_termios); } pub fn print(self: *Terminal, comptime format: []const u8, args: anytype) !void { const formatted = try fmt.allocPrint(self.allocator, format, args); defer self.allocator.free(formatted); try self.tty.writeAll(formatted); } pub fn cursorLeft(self: *Terminal) !void { try self.info.writeString(.cursor_left, self.tty.writer()); // try self.info.cursorLeft(self.tty.writer()); } pub const Info = @import("terminfo.zig"); pub const SpecialKey = enum(u16) { home, end, page_up, page_down, delete, backspace, arrow_left, arrow_right, arrow_up, arrow_down, }; };