mirror of
https://mzte.de/git/LordMZTE/dotfiles.git
synced 2024-06-09 23:09:33 +02:00
173 lines
4.9 KiB
Zig
173 lines
4.9 KiB
Zig
const std = @import("std");
|
|
const at = @import("ansi-term");
|
|
const env = @import("env.zig");
|
|
const run = @import("run.zig");
|
|
const util = @import("util.zig");
|
|
|
|
pub const std_options = struct {
|
|
pub const log_level = .debug;
|
|
pub fn logFn(
|
|
comptime msg_level: std.log.Level,
|
|
comptime scope: @TypeOf(.enum_literal),
|
|
comptime fmt: []const u8,
|
|
args: anytype,
|
|
) void {
|
|
const logfile = log_file orelse return;
|
|
|
|
if (scope != .default) {
|
|
logfile.writer().print("[{s}] ", .{@tagName(scope)}) catch return;
|
|
}
|
|
|
|
logfile.writer().writeAll(switch (msg_level) {
|
|
.err => "E: ",
|
|
.warn => "W: ",
|
|
.info => "I: ",
|
|
.debug => "D: ",
|
|
}) catch return;
|
|
|
|
logfile.writer().print(fmt ++ "\n", args) catch return;
|
|
}
|
|
};
|
|
|
|
var log_file: ?std.fs.File = null;
|
|
|
|
pub fn main() void {
|
|
log_file = createLogFile() catch null;
|
|
defer if (log_file) |lf| lf.close();
|
|
|
|
tryMain() catch |e| {
|
|
std.log.err("FATAL ERROR: {}", .{e});
|
|
std.debug.print("Encountered fatal error (check log), starting emergency shell!\n", .{});
|
|
|
|
@panic(@errorName(std.os.execveZ(
|
|
"/bin/sh",
|
|
&[_:null]?[*:0]const u8{"/bin/sh"},
|
|
&[_:null]?[*:0]const u8{},
|
|
)));
|
|
};
|
|
}
|
|
|
|
fn tryMain() !void {
|
|
var stdout = std.io.bufferedWriter(std.io.getStdOut().writer());
|
|
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
defer _ = gpa.deinit();
|
|
const alloc = gpa.allocator();
|
|
|
|
var env_map = try std.process.getEnvMap(alloc);
|
|
defer env_map.deinit();
|
|
|
|
if (env_map.get("MZTEINIT")) |_| {
|
|
try stdout.writer().writeAll("mzteinit running already, starting shell\n");
|
|
try stdout.flush();
|
|
var child = std.ChildProcess.init(&.{"fish"}, alloc);
|
|
_ = try child.spawnAndWait();
|
|
return;
|
|
} else {
|
|
try env_map.put("MZTEINIT", "1");
|
|
}
|
|
|
|
if (try env.populateEnvironment(&env_map)) {
|
|
try env.populateSysdaemonEnvironment(&env_map);
|
|
}
|
|
|
|
while (true) {
|
|
try stdout.writer().writeAll(util.ansi_clear);
|
|
|
|
const cmd = ui(&stdout) catch |e| {
|
|
std.debug.print("Error rendering the UI: {}\n", .{e});
|
|
break;
|
|
};
|
|
|
|
try stdout.writer().writeAll(util.ansi_clear);
|
|
try stdout.flush();
|
|
|
|
var exit = util.ExitMode.run;
|
|
cmd.run(alloc, &exit, &env_map) catch |e| {
|
|
try stdout.writer().print("Error running command: {}\n\n", .{e});
|
|
continue;
|
|
};
|
|
|
|
switch (exit) {
|
|
.run => {},
|
|
.immediate => return,
|
|
.delayed => {
|
|
try stdout.writer().writeAll("Goodbye!");
|
|
try stdout.flush();
|
|
std.time.sleep(2 * std.time.ns_per_s);
|
|
return;
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
fn ui(buf_writer: anytype) !run.Command {
|
|
const w = buf_writer.writer();
|
|
var style: ?at.style.Style = null;
|
|
|
|
try @import("figlet.zig").writeFiglet(w);
|
|
const uname = std.os.uname();
|
|
try updateStyle(w, .{ .foreground = .Yellow }, &style);
|
|
try w.print(
|
|
"\n {s} {s} {s}\n\n",
|
|
.{
|
|
uname.nodename,
|
|
uname.release,
|
|
uname.machine,
|
|
},
|
|
);
|
|
|
|
try updateStyle(w, .{ .font_style = .{ .bold = true } }, &style);
|
|
try w.writeAll(" What do you want to do?\n\n");
|
|
|
|
for (std.enums.values(run.Command)) |tag| {
|
|
try updateStyle(w, .{ .foreground = .Cyan }, &style);
|
|
try w.print("[{c}] ", .{tag.char()});
|
|
try updateStyle(w, .{ .foreground = .Green }, &style);
|
|
try w.print("{s}\n", .{@tagName(tag)});
|
|
}
|
|
try at.format.resetStyle(w);
|
|
style = .{};
|
|
|
|
try buf_writer.flush();
|
|
|
|
const old_termios = try std.os.tcgetattr(std.os.STDIN_FILENO);
|
|
var new_termios = old_termios;
|
|
new_termios.lflag &= ~std.os.linux.ICANON; // No line buffering
|
|
new_termios.lflag &= ~std.os.linux.ECHO; // No echoing stuff
|
|
try std.os.tcsetattr(std.os.STDIN_FILENO, .NOW, new_termios);
|
|
|
|
var cmd: ?run.Command = null;
|
|
var c: [1]u8 = undefined;
|
|
while (cmd == null) {
|
|
std.debug.assert(try std.io.getStdIn().read(&c) == 1);
|
|
cmd = run.Command.fromChar(c[0]);
|
|
if (cmd == null) {
|
|
try w.print("Unknown command '{s}'\n", .{c});
|
|
try buf_writer.flush();
|
|
}
|
|
}
|
|
try std.os.tcsetattr(std.os.STDIN_FILENO, .NOW, old_termios);
|
|
|
|
return cmd.?;
|
|
}
|
|
|
|
fn createLogFile() !std.fs.File {
|
|
var fname_buf: [128]u8 = undefined;
|
|
const fname = try std.fmt.bufPrintZ(
|
|
&fname_buf,
|
|
"/tmp/mzteinit-{}-{}.log",
|
|
.{ std.os.linux.getuid(), std.os.linux.getpid() },
|
|
);
|
|
return try std.fs.createFileAbsoluteZ(fname, .{});
|
|
}
|
|
|
|
fn updateStyle(
|
|
writer: anytype,
|
|
new_style: at.style.Style,
|
|
old_style: *?at.style.Style,
|
|
) !void {
|
|
try at.format.updateStyle(writer, new_style, old_style.*);
|
|
old_style.* = new_style;
|
|
}
|