const std = @import("std"); pub fn get_shell(allocator: std.mem.Allocator) ![]const u8 { const shell_env = std.posix.getenv("SHELL") orelse "Unknown"; var shell_path = std.mem.splitBackwards(u8, shell_env, "/"); var buf: [64]u8 = undefined; const filename = shell_path.first(); if (std.mem.eql(u8, filename, "zsh")) { 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 }); } 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, ": {s}\n", .{bash_version}); } else if (std.mem.eql(u8, filename, "bash")) { const version = try std.process.Child.run( .{ .allocator = allocator, .argv = &.{ shell_env, "--version" }, }, ); defer allocator.free(version.stdout); defer allocator.free(version.stderr); return try std.fmt.allocPrint(allocator, ": {s}\n", .{version.stdout}); } // const version = try std.process.Child.run(.{ // .allocator = allocator, // .argv = &.{ shell_env, &version_flag }, // }); // defer allocator.free(version.stdout); // defer allocator.free(version.stderr); // if (std.mem.eql(u8, "zsh", shell)) { // std.debug.print("shell: {s}\n", .{shell}); // } return try std.fmt.allocPrint(allocator, ": {s}\n", .{shell_env}); } pub fn get_terminal(buf: []u8) ![]const u8 { const term_program = std.posix.getenv("TERM_PROGRAM") orelse "Unknown"; return 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 { const zsh_version = try std.fmt.bufPrint(buf, "Unknown", .{}); const version_string = std.process.Child.run( .{ .allocator = allocator, .argv = &.{ zsh_path, "--version" }, }, ) catch { return zsh_version; }; defer allocator.free(version_string.stdout); defer allocator.free(version_string.stderr); var version = std.mem.split(u8, version_string.stdout, " "); _ = version.first(); return try std.fmt.bufPrint(buf, "{s}", .{version.next() orelse "Uknown"}); // return try std.fmt.allocPrint(allocator, "{s}", .{version.next() orelse "Unknown"}); } fn get_bash_version(allocator: std.mem.Allocator, buf: []u8, bash_path: []const u8) ![]const u8 { const version_string = try std.process.Child.run( .{ .allocator = allocator, .argv = &.{ bash_path, "--version" }, }, ); defer allocator.free(version_string.stdout); defer allocator.free(version_string.stderr); var split_lines = std.mem.split(u8, version_string.stdout, "\n"); var version_line = std.mem.split(u8, split_lines.first(), " "); var i: usize = 0; while (version_line.next()) |word| { std.debug.print("version_line: {s}", .{word}); if (i == 3) { return try std.fmt.bufPrint(buf, "{s}", .{word}); } i += 1; } return try std.fmt.bufPrint(buf, "Unknown", .{}); } pub fn get_user(buf: []u8) ![]const u8 { const user = std.posix.getenv("USER") orelse "Unknown"; return try std.fmt.bufPrint(buf, "{s}", .{user}); } pub fn get_hostname(buf: *[std.posix.HOST_NAME_MAX]u8) ![]const u8 { const hostname = try std.posix.gethostname(&buf); return try std.fmt.bufPrint(buf, hostname, .{}); } test "get_bash_version" { var buf: [8]u8 = undefined; const bash_version = try get_bash_version(std.testing.allocator, &buf, "/run/current-system/sw/bin/bash"); try std.testing.expectEqualSlices(u8, "5.2.32(1)-release", bash_version); }