570595053bdd

try + develop: branded PS1 prompt and exit instruction (v3.1.4)

time
2026-06-10 19:39 UTC · 4 months ago
machine
koh2
parent
b32f051a7897
4 files VERSION+1 −1build.zig.zon+1 −1src/exec.zig+46 −0src/output.zig+2 −2
VERSION+1 −1
@@ -1 +1 @@1-3.1.31+3.1.4

view file

build.zig.zon+1 −1
@@ -9,7 +9,7 @@99     .name = .nina,1010     // This is a [Semantic Version](https://semver.org/).1111     // In a future version of Zig it will be used for package deduplication.12-    .version = "3.1.3",12+    .version = "3.1.4",1313     // Together with name, this represents a globally unique package1414     // identifier. This field is generated by the Zig toolchain when the1515     // package is first created, and then *never changes*. This allows

view file

src/exec.zig+46 −0
@@ -74,6 +74,7 @@7474     var env = try base_env.clone(gpa);7575     defer env.deinit();7676     try env.put("PS1", ps1);77+    try env.put("NINA_PS1", ps1);7778 7879     var child = std.process.spawn(io, .{7980         .argv = argv,@@ -97,6 +98,35 @@9798     };9899 }99100 101+fn createInteractiveShellRc(gpa: std.mem.Allocator, io: std.Io) ![]u8 {102+    const out = try captureLocal(gpa, io, &.{ "mktemp", "/tmp/nina-shell-rc.XXXXXX" });103+    defer gpa.free(out);104+105+    const path = std.mem.trim(u8, out, " \t\r\n");106+    if (path.len == 0) return error.FileNotFound;107+    const owned_path = try gpa.dupe(u8, path);108+    errdefer gpa.free(owned_path);109+110+    const file = std.Io.Dir.createFile(.cwd(), io, owned_path, .{}) catch {111+        errors.error_info.setMessage("could not write shell prompt setup", .{});112+        return error.FileNotFound;113+    };114+    errdefer file.close(io);115+116+    const content =117+        \\PS1="${NINA_PS1:-$PS1}"118+        \\trap 'exit 130' INT119+        \\120+    ;121+    file.writePositionalAll(io, content, 0) catch {122+        errors.error_info.setMessage("could not write shell prompt setup", .{});123+        return error.FileNotFound;124+    };125+    file.close(io);126+127+    return owned_path;128+}129+100130 // Stream a local process with inherited stdio (no SSH routing — for nix commands).101131 pub fn streamLocal(io: std.Io, cmd: []const []const u8) !u8 {102132     output.flush();@@ -821,6 +851,14 @@821851     defer gpa.free(ref);822852     const ps1 = try std.fmt.allocPrint(gpa, "(nina: {s}) -> ", .{pkg});823853     defer gpa.free(ps1);854+    if (machine.local) {855+        const rc_path = try createInteractiveShellRc(gpa, io);856+        defer {857+            std.Io.Dir.deleteFile(.cwd(), io, rc_path) catch {};858+            gpa.free(rc_path);859+        }860+        return streamEnv(io, machine, gpa, &.{ "nix", "shell", ref, "--command", "bash", "--rcfile", rc_path, "-i" }, base_env, ps1);861+    }824862     return streamEnv(io, machine, gpa, &.{ "nix", "shell", ref }, base_env, ps1);825863 }826864 @@ -836,6 +874,14 @@836874     if (run_cmd) |cmd| {837875         // sh -c so a multi-word command isn't treated as a single executable name.838876         return stream(io, machine, gpa, &.{ "nix", "develop", "--command", "sh", "-c", cmd });877+    }878+    if (machine.local) {879+        const rc_path = try createInteractiveShellRc(gpa, io);880+        defer {881+            std.Io.Dir.deleteFile(.cwd(), io, rc_path) catch {};882+            gpa.free(rc_path);883+        }884+        return streamEnv(io, machine, gpa, &.{ "nix", "develop", "--command", "bash", "--rcfile", rc_path, "-i" }, base_env, "(nina: dev) -> ");839885     }840886     return streamEnv(io, machine, gpa, &.{ "nix", "develop" }, base_env, "(nina: dev) -> ");841887 }

view file

src/output.zig+2 −2
@@ -424,7 +424,7 @@424424         if (i > 0) p("  ", .{});425425         p("{s}", .{pkg});426426     }427-    p("\n\n   {s}-> type 'exit' to return{s}\n\n", .{ c(DIM), c(RESET) });427+    p("\n\n   {s}-> press Ctrl+C or type 'exit' to return{s}\n\n", .{ c(DIM), c(RESET) });428428 }429429 430430 pub fn developDone() void {@@ -601,7 +601,7 @@601601 }602602 603603 pub fn tryExitHint() void {604-    p("   {s}-> type 'exit' to return{s}\n", .{ c(DIM), c(RESET) });604+    p("   {s}-> press Ctrl+C or type 'exit' to return{s}\n", .{ c(DIM), c(RESET) });605605 }606606 607607 pub fn tryDone() void {

view file