const linux = std.os.linux; const std = @import("std"); const STDIN_FILENO = std.os.STDIN_FILENO; const RawMode = @This(); const tcflag_t = linux.tcflag_t; const tcgetattr = std.os.tcgetattr; const tcsetattr = std.os.tcsetattr; const termios = std.os.termios; orig: termios, pub fn init() !RawMode { const orig = try tcgetattr(STDIN_FILENO); const self = RawMode{ .orig = orig }; errdefer self.deinit(); var raw = orig; raw.iflag &= ~@as(tcflag_t, linux.BRKINT | linux.ICRNL | linux.INPCK | linux.ISTRIP | linux.IXON); raw.lflag &= ~@as(tcflag_t, linux.ECHO | linux.ICANON | linux.IEXTEN | linux.ISIG); raw.oflag &= ~@as(tcflag_t, linux.OPOST); raw.cflag |= linux.CS8; raw.cc[linux.V.MIN] = 0; raw.cc[linux.V.TIME] = 1; try tcsetattr(STDIN_FILENO, .FLUSH, raw); return self; } pub fn deinit(self: RawMode) void { tcsetattr(STDIN_FILENO, .FLUSH, self.orig) catch |err| { std.log.err("Failed to reset termios: {}", .{err}); }; }