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
↓ nina-57059505.tar.gzatlas at this save
files changed4 files
VERSION+1 −1build.zig.zon+1 −1src/exec.zig+46 −0src/output.zig+2 −2build.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 allowssrc/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 }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 {