wip: getting there

This commit is contained in:
Kalle Carlbark 2024-09-19 22:17:57 +02:00
parent d4933be73d
commit 9487c4abc4
No known key found for this signature in database
7 changed files with 199 additions and 173 deletions

View file

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

BIN
src/assets/tux.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
src/assets/ziggy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

25
src/linux.zig Normal file
View file

@ -0,0 +1,25 @@
const std = @import("std");
pub fn kernel_version() ![]const u8 {
var uname_buf: std.posix.utsname = undefined;
try std.posix.uname(&uname_buf);
return uname_buf.version;
}
pub fn distribution() ![]const u8 {
const os_release_path = "/etc/os-release";
var file = try std.fs.openDirAbsolute(os_release_path, .{});
defer file.close();
var buffered = std.io.bufferedReader(file.reader());
while (try buffered.reader().readUntilDelimiterOrEofAlloc(std.heap.page_allocator, '\n')) |line| {
if (std.mem.startsWith(u8, line, "PRETTY_NAME=")) {
return line[13 .. line.len - 1];
}
}
return "Uknown distro";
}

View file

@ -34,7 +34,7 @@ pub fn macosVersionAtLeast(major: i64, minor: i64, patch: i64) bool {
});
}
pub fn macos_version(allocator: std.mem.Allocator) ![]const u8 {
pub fn macos_version(buf: []u8) ![]const u8 {
const NSProcessInfo = objc.getClass("NSProcessInfo").?;
// Call a class method with no arguments that returns another objc object.
@ -42,12 +42,10 @@ pub fn macos_version(allocator: std.mem.Allocator) ![]const u8 {
const koko = info.msgSend(NSOperatingSystemVersion, "operatingSystemVersion", .{});
const buf = try std.fmt.allocPrint(allocator, ": macOS {s} {d}.{d}.{d}\n", .{ version_to_name(koko), koko.major, koko.minor, koko.patch });
return buf;
return try std.fmt.bufPrint(buf, ": macOS {s} {d}.{d}.{d}\n", .{ version_to_name(koko), koko.major, koko.minor, koko.patch });
}
pub fn macos_kernel_version(allocator: std.mem.Allocator) ![]const u8 {
pub fn get_kernel_version(buf: []u8) ![]const u8 {
var name: c.struct_utsname = undefined;
if (c.uname(&name) != 0) {
@ -57,12 +55,10 @@ pub fn macos_kernel_version(allocator: std.mem.Allocator) ![]const u8 {
const sysname = std.mem.sliceTo(name.sysname[0..], 0);
const version = std.mem.sliceTo(name.release[0..], 0);
const buf = try std.fmt.allocPrint(allocator, ": {s} {s}\n", .{ sysname, version });
return buf;
return try std.fmt.bufPrint(buf, ": {s} {s}\n", .{ sysname, version });
}
pub fn memory_info(allocator: std.mem.Allocator) ![]const u8 {
pub fn get_mem_info(buf: []u8) ![]const u8 {
var memsize: u64 = 0;
var memsize_size: usize = @sizeOf(u64);
@ -73,7 +69,7 @@ pub fn memory_info(allocator: std.mem.Allocator) ![]const u8 {
const bingb: u64 = (1024 * 1024 * 1024);
const memsize_gb: u64 = @divFloor(memsize, bingb);
return try std.fmt.allocPrint(allocator, ": {d} GiB\n", .{memsize_gb});
return try std.fmt.bufPrint(buf, ": {d} GiB\n", .{memsize_gb});
}
// Helper function to create CFString from Zig string
@ -119,7 +115,7 @@ pub fn get_vpn_info() !void {
// Convert CFStringRef to C string (null-terminated)
}
pub fn get_battery_info(allocator: std.mem.Allocator) ![]const u8 {
pub fn get_battery_info(buf: []u8) ![]const u8 {
const power_sources_info: c.CFTypeRef = c.IOPSCopyPowerSourcesInfo();
if (power_sources_info == null) {
@ -169,16 +165,16 @@ pub fn get_battery_info(allocator: std.mem.Allocator) ![]const u8 {
if (std.mem.eql(u8, power_source_state, "Battery Power")) {
if (time_to_empty_mins < 0) {
return try std.fmt.allocPrint(allocator, ": {d}%, ?m left\n", .{ percent, hours, minutes });
return try std.fmt.bufPrint(buf, ": {d}%, ?m left\n", .{ percent, hours, minutes });
} else {
return try std.fmt.allocPrint(allocator, ": {d}%, {d}h:{d}m left\n", .{ percent, hours, minutes });
return try std.fmt.bufPrint(buf, ": {d}%, {d}h:{d}m left\n", .{ percent, hours, minutes });
}
} else {
return try std.fmt.allocPrint(allocator, ": {d}%, {s}\n", .{ percent, "charging" });
return try std.fmt.bufPrint(buf, ": {d}%, {s}\n", .{ percent, "charging" });
}
}
pub fn macos_cpu_info(allocator: std.mem.Allocator) ![]const u8 {
pub fn get_cpu_info(buf: []u8) ![]const u8 {
var cpu_brand: [128]u8 = undefined;
var cpu_brand_size: usize = cpu_brand.len;
var cpu_cores: c_int = 0;
@ -193,12 +189,10 @@ pub fn macos_cpu_info(allocator: std.mem.Allocator) ![]const u8 {
}
// if (c.sysctlbyname("hw.cpufrequency", &))
const buf = try std.fmt.allocPrint(allocator, ": {s} ({d} cores)\n", .{ cpu_brand[0..cpu_brand_size], cpu_cores });
return buf;
return try std.fmt.bufPrint(buf, ": {s} ({d} cores)\n", .{ cpu_brand[0..cpu_brand_size], cpu_cores });
}
pub fn macos_uptime(allocator: std.mem.Allocator) ![]const u8 {
pub fn get_uptime(buf: []u8) ![]const u8 {
var mib: [2]c.integer_t = [_]c.integer_t{ c.CTL_KERN, c.KERN_BOOTTIME };
var boottime: c.struct_timeval = undefined;
var size: u64 = @sizeOf(c.struct_timeval);
@ -216,9 +210,7 @@ pub fn macos_uptime(allocator: std.mem.Allocator) ![]const u8 {
const hours = @divFloor(@rem(uptime_seconds, (24 * 60 * 60)), (60 * 60));
const minutes = @divFloor(@rem(uptime_seconds, (60 * 60)), 60);
const buf = try std.fmt.allocPrint(allocator, ": {d} days, {d} hours, {d} mins\n", .{ days, hours, minutes });
return buf;
return try std.fmt.bufPrint(buf, ": {d} days, {d} hours, {d} mins\n", .{ days, hours, minutes });
}
fn version_to_name(version: NSOperatingSystemVersion) []const u8 {

View file

@ -7,12 +7,12 @@ const sys = @import("sys.zig");
const log = std.log.scoped(.main);
const apple_logo = @embedFile("assets/apple-white.png");
const freebsd = @embedFile("assets/freebsd.png");
const Event = union(enum) {
key_press: vaxis.Key,
winsize: vaxis.Winsize,
const logo =
switch (builtin.target.os.tag) {
.macos => @embedFile("assets/apple-white.png"),
.freebsd => @embedFile("assets/orby.png"),
.linux => @embedFile("assets/tux.png"),
else => @embedFile("assets/ziggy.png"),
};
pub fn main() !void {
@ -24,7 +24,6 @@ pub fn main() !void {
}
}
// const stdout = std.io.getStdOut().writer();
const allocator = gpa.allocator();
var tty = try vaxis.Tty.init();
@ -36,56 +35,42 @@ pub fn main() !void {
vx.caps.unicode = .unicode;
vx.caps.kitty_graphics = true;
const battery = try macos.get_battery_info(allocator);
defer allocator.free(battery);
// _ = try macos.get_vpn_info();
// const os = try macos.macos_version(allocator);
const os = try sys.get_os_version(allocator);
defer allocator.free(os.text);
const kernel = try macos.macos_kernel_version(allocator);
defer allocator.free(kernel);
const uptime = try macos.macos_uptime(allocator);
defer allocator.free(uptime);
const cpu = try macos.macos_cpu_info(allocator);
defer allocator.free(cpu);
const current_shell = try sys.get_shell(allocator);
defer allocator.free(current_shell);
const memory = try macos.memory_info(allocator);
defer allocator.free(memory);
var term_buf: [64]u8 = undefined;
const current_terminal = try sys.get_terminal(&term_buf);
// try tty.anyWriter().writeAll("\x1bc");
// try tty.anyWriter().writeAll("\x1b[1;1H");
var battery_buf: [64]u8 = undefined;
const battery = try sys.get_battery(&battery_buf);
var os_buf: [64]u8 = undefined;
const os = try sys.get_os_version(&os_buf);
var kernel_buf: [64]u8 = undefined;
const kernel = try sys.get_kernel_version(&kernel_buf);
var uptime_buf: [64]u8 = undefined;
const uptime = try sys.get_uptime(&uptime_buf);
var cpu_buf: [64]u8 = undefined;
const cpu = try sys.get_cpu_info(&cpu_buf);
const current_shell = try sys.get_shell(allocator);
defer allocator.free(current_shell.text);
var mem_buf: [64]u8 = undefined;
const memory = try sys.get_mem_info(&mem_buf);
var buf_writer = tty.bufferedWriter();
const writer = buf_writer.writer().any();
// try writer.writeAll(vaxis.ctlseqs.unicode_set);
// defer vx.queryTerminalSend(writer) catch {};
// defer writer.writeAll(vaxis.ctlseqs.unicode_reset) catch {};
// defer tty.deinit();
const winsize: vaxis.Winsize = try vaxis.Tty.getWinsize(tty.fd);
try vx.resize(allocator, writer, winsize);
const win = vx.window();
win.clear();
// win.hideCursor();
var image: vaxis.Image = undefined;
switch (builtin.os.tag) {
.macos => {
image = try vx.loadImage(allocator, tty.anyWriter(), .{ .mem = apple_logo });
},
.freebsd => {
image = try vx.loadImage(allocator, writer, .{ .mem = freebsd });
},
else => @compileError("unsupported os"),
}
const image = try vx.loadImage(allocator, tty.anyWriter(), .{ .mem = logo });
const dims = try image.cellSize(win);
// const cursor_row = vx.state.cursor.row;
const logo_win = win.child(.{
.y_off = 2,
.x_off = 0,
@ -102,7 +87,6 @@ pub fn main() !void {
var hostname_buf: [std.posix.HOST_NAME_MAX]u8 = undefined;
const hostname = try std.posix.gethostname(&hostname_buf);
// const logo_win = win.child(.{ .y_off = 0, .x_off = 0 });
const border_locations = vaxis.Window.BorderOptions.Locations{
.top = true,
.bottom = false,
@ -130,22 +114,31 @@ pub fn main() !void {
var result: vaxis.Window.PrintResult = .{ .col = 0, .row = 0, .overflow = false };
const whoami_info = [_]vaxis.Cell.Segment{
.{ .text = user, .style = .{
.{
.text = user,
.style = .{
.fg = .{
.index = 7,
},
} },
.{ .text = "@", .style = .{
},
},
.{
.text = "@",
.style = .{
.fg = .{
.index = 15,
},
.bold = true,
} },
.{ .text = hostname, .style = .{
},
},
.{
.text = hostname,
.style = .{
.fg = .{
.index = 7,
},
} },
},
},
};
const system_info = [_]vaxis.Cell.Segment{
.{
@ -167,7 +160,7 @@ pub fn main() !void {
.bold = true,
},
},
.{ .text = kernel },
kernel,
.{
.text = " Uptime",
.style = .{
@ -177,7 +170,7 @@ pub fn main() !void {
.bold = true,
},
},
.{ .text = uptime },
uptime,
.{
.text = " CPU",
.style = .{
@ -187,7 +180,7 @@ pub fn main() !void {
.bold = true,
},
},
.{ .text = cpu },
cpu,
.{
.text = " Memory",
.style = .{
@ -197,7 +190,7 @@ pub fn main() !void {
.bold = true,
},
},
.{ .text = memory },
memory,
.{
.text = " Shell",
.style = .{
@ -207,7 +200,7 @@ pub fn main() !void {
.bold = true,
},
},
.{ .text = current_shell },
current_shell,
.{
.text = " Terminal",
.style = .{
@ -217,7 +210,7 @@ pub fn main() !void {
.bold = true,
},
},
.{ .text = current_terminal },
current_terminal,
.{
.text = " Battery",
.style = .{
@ -227,14 +220,7 @@ pub fn main() !void {
.bold = true,
},
},
.{
.text = battery,
// .style = .{
// .fg = .{
// .index = 2,
// },
// },
},
battery,
.{
.text = " ▂▂▂",
.style = .{
@ -367,80 +353,11 @@ pub fn main() !void {
.text = " ",
},
};
// const logo_text = [_]vaxis.Cell.Segment{
// .{
// .text = " hello",
// },
// };
try image.draw(logo_win, .{});
// _ = try logo_text_win.print(&logo_text, .{});
// try root.kitty_image_inline_copy(allocator, tty.anyWriter(), "/Users/kc/Sync/Images/apple-dark.png");
result = try whoami_win.print(&whoami_info, .{ .wrap = .word });
result = try info_win.print(&system_info, .{ .wrap = .word });
// printf '\e[%sA\e[9999999D' "${lines:-0}"
// try tty.anyWriter().print("\x1b[{d}A\x1b[9999999D", .{winsize.rows});
// try tty.anyWriter().writeAll("\x1b[1J");
// try logo_win.print();
// const dimensions = try koko.cellSize(win);
// const image = try vx.transmitLocalImagePath(allocator, tty.anyWriter(), "/Users/kc/Sync/Images/apple-white.png", dimensions.rows, dimensions.cols, .file, .png);
// defer vx.freeImage(tty.anyWriter(), image.id);
// try root.kitty_image_inline_copy(allocator, tty.anyWriter(), "/Users/kc/Sync/Images/apple-white.png");
// try image.draw(win, .{});
// try vx.render(tty.anyWriter());
try vx.prettyPrint(tty.anyWriter());
try buf_writer.flush();
// try vx.queryTerminalSend(tty.anyWriter());
// Clear from cursor to beginning of the screen
// Move cursor to the upper left corner of the screen
// try stdout_file.writeAll("\x1b[9B");
// try vx.enterAltScreen(tty.anyWriter());
// var img2 = try vaxis.
// const koko = try vx.loadImage(allocator, writer, .{ .path = "/Users/kc/Sync/Images/apple-white.png" });
// const koko = try vx.transmitImage(allocator, writer, &img1, .png);
// const image = [_]vaxis.Image{
// // try vx.transmitImage(allocator, writer, &img1, .png),
// try vx.loadImage(allocator, writer, .{ .path = "/Users/kc/Sync/Images/apple-white.png" }),
// // vaxis.Image.DrawOptions{ .clip_region = .{ .x = 0, .y = 0 } },
// };
// const dims = try image[0].cellSize(win);
// try vx.render(writer);
// try stdout.print("\n\n\n\n\n\n\n\n\n", .{});
// try writer.writeFile()
// try stdout.writeAll("\x1b[m");
// win.showCursor();
// std.time.sleep(10000000);
}
fn is_dark_mode(allocator: std.mem.Allocator) !bool {
const home_directory = detect_home_directory();
const dark_mode_file_path = try std.fmt.allocPrint(allocator, "{s}/.dark-mode", .{home_directory});
defer allocator.free(dark_mode_file_path);
const dark_mode = std.fs.cwd().createFile(dark_mode_file_path, .{ .exclusive = true }) catch |err|
switch (err) {
error.PathAlreadyExists => return true,
else => {
return false;
},
};
dark_mode.close();
return false;
}
fn detect_home_directory() []const u8 {
return std.posix.getenv("HOME") orelse "/tmp";
}
test "simple test" {

View file

@ -2,6 +2,7 @@ const std = @import("std");
const builtin = @import("builtin");
const vaxis = @import("vaxis");
const linux = @import("linux.zig");
const macos = @import("macos.zig");
const OSVersion = struct {
@ -16,7 +17,7 @@ const Shell = struct {
version: []const u8,
};
pub fn get_shell(allocator: std.mem.Allocator) ![]const u8 {
pub fn get_shell(allocator: std.mem.Allocator) !vaxis.Cell.Segment {
const shell_env = std.posix.getenv("SHELL") orelse "Unknown";
var shell_path = std.mem.splitBackwards(u8, shell_env, "/");
@ -26,11 +27,26 @@ pub fn get_shell(allocator: std.mem.Allocator) ![]const u8 {
const zsh_version = try get_zsh_version(allocator, &buf, shell_env);
// defer allocator.free(zsh_version);
return try std.fmt.allocPrint(allocator, ": {s} {s}\n", .{ filename, zsh_version });
return .{
.text = try std.fmt.allocPrint(
allocator,
": {s} {s}\n",
.{
filename,
zsh_version,
},
),
};
} else if (std.mem.eql(u8, filename, "bash")) {
const bash_version = try get_bash_version(allocator, &buf, shell_env);
return try std.fmt.allocPrint(allocator, ": bash {s}\n", .{bash_version});
return .{
.text = try std.fmt.allocPrint(
allocator,
": bash {s}\n",
.{bash_version},
),
};
} else if (std.mem.eql(u8, filename, "bash")) {
const version = try std.process.Child.run(
.{
@ -41,31 +57,107 @@ pub fn get_shell(allocator: std.mem.Allocator) ![]const u8 {
defer allocator.free(version.stdout);
defer allocator.free(version.stderr);
return try std.fmt.allocPrint(allocator, ": {s}\n", .{version.stdout});
return .{
.text = try std.fmt.allocPrint(
allocator,
": {s}\n",
.{version.stdout},
),
};
}
return try std.fmt.allocPrint(allocator, ": {s}\n", .{shell_env});
return .{
.text = try std.fmt.allocPrint(allocator, ": {s}\n", .{shell_env}),
};
}
pub fn get_os_version(allocator: std.mem.Allocator) !vaxis.Cell.Segment {
pub fn get_kernel_version(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.macos_version(allocator),
.text = try macos.get_kernel_version(buf),
};
},
else => return .{ .text = "" },
else => return .{ .text = try std.fmt.bufPrint(buf, "unknown", .{}) },
}
}
pub fn get_terminal(buf: []u8) ![]const u8 {
pub fn get_uptime(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_uptime(buf),
};
},
else => return .{ .text = try std.fmt.bufPrint(buf, "unknown", .{}) },
}
}
pub fn get_cpu_info(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_cpu_info(buf),
};
},
else => return .{ .text = try std.fmt.bufPrint(buf, "unknown", .{}) },
}
}
pub fn get_mem_info(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_mem_info(buf),
};
},
else => return .{ .text = try std.fmt.bufPrint(buf, "unknown", .{}) },
}
}
pub fn get_battery(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_battery_info(buf),
};
},
else => return .{ .text = "unknown" },
}
}
pub fn get_os_version(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.macos_version(buf),
};
},
.linux => {
return .{
.text = try std.fmt.bufPrint(buf, "{s} {s}", .{ try linux.kernel_version(), try linux.distribution() }),
};
},
.freebsd => {
return .{
.text = try std.fmt.bufPrint(buf, "not implemented", .{}),
};
},
else => return .{ .text = try std.fmt.bufPrint(buf, "unknown", .{}) },
}
}
pub fn get_terminal(buf: []u8) !vaxis.Cell.Segment {
const term_program = std.posix.getenv("TERM_PROGRAM") orelse "Unknown";
if (std.mem.eql(u8, term_program, "ghostty")) {
return try std.fmt.bufPrint(buf, ": {s} 󰊠\n", .{term_program});
return .{
.text = try std.fmt.bufPrint(buf, ": {s} 󰊠\n", .{term_program}),
};
}
return try std.fmt.bufPrint(buf, ": {s}\n", .{term_program});
return .{
.text = try std.fmt.bufPrint(buf, ": {s}\n", .{term_program}),
};
}
fn get_zsh_version(allocator: std.mem.Allocator, buf: []u8, zsh_path: []const u8) ![]const u8 {