repos / zmx

session persistence for terminal processes
git clone https://github.com/neurosnap/zmx.git

commit
68dfbef
parent
314974e
author
Josh Bainbridge
date
2026-01-01 17:52:22 -0500 EST
feat: add new short list option via flag

Listing just the session names, without extra information, could be
useful for external tools or processes that need to do operations based
on the session names.

Add a new --short option to the list subcommand to list only session
names without extra information.
3 files changed,  +12, -6
M CHANGELOG.md
+1, -0
1@@ -8,6 +8,7 @@ Use spec: https://common-changelog.org/
2 
3 - New flag `--vt` for `zmx [hi]story` which prints raw ansi escape codes for terminal session
4 - New flag `--html` for `zmx [hi]story` which prints html representation of terminal session
5+- New list flag `zmx [l]ist [--list]` that lists all session names with no extra information
6 
7 ### Fixed
8 
M README.md
+1, -1
1@@ -57,7 +57,7 @@ Commands:
2   [a]ttach <name> [command...]   Attach to session, creating session if needed
3   [r]un <name> [command...]      Send command without attaching, creating session if needed
4   [d]etach                       Detach all clients from current session  (ctrl+\ for current client)
5-  [l]ist                         List active sessions
6+  [l]ist [--short]               List active sessions
7   [k]ill <name>                  Kill a session and all attached clients
8   [hi]story <name> [--vt|--html] Output session scrollback (--vt or --html for escape sequences)
9   [v]ersion                      Show version information
M src/main.zig
+10, -5
 1@@ -339,7 +339,7 @@ pub fn main() !void {
 2     defer log_system.deinit();
 3 
 4     const cmd = args.next() orelse {
 5-        return list(&cfg);
 6+        return list(&cfg, false);
 7     };
 8 
 9     if (std.mem.eql(u8, cmd, "version") or std.mem.eql(u8, cmd, "v") or std.mem.eql(u8, cmd, "-v") or std.mem.eql(u8, cmd, "--version")) {
10@@ -347,7 +347,8 @@ pub fn main() !void {
11     } else if (std.mem.eql(u8, cmd, "help") or std.mem.eql(u8, cmd, "h") or std.mem.eql(u8, cmd, "-h")) {
12         return help();
13     } else if (std.mem.eql(u8, cmd, "list") or std.mem.eql(u8, cmd, "l")) {
14-        return list(&cfg);
15+        const short = if (args.next()) |arg| std.mem.eql(u8, arg, "--short") else false;
16+        return list(&cfg, short);
17     } else if (std.mem.eql(u8, cmd, "detach") or std.mem.eql(u8, cmd, "d")) {
18         return detachAll(&cfg);
19     } else if (std.mem.eql(u8, cmd, "kill") or std.mem.eql(u8, cmd, "k")) {
20@@ -461,7 +462,7 @@ fn help() !void {
21         \\  [a]ttach <name> [command...]  Attach to session, creating session if needed
22         \\  [r]un <name> [command...]     Send command without attaching, creating session if needed
23         \\  [d]etach                      Detach all clients from current session (ctrl+\ for current client)
24-        \\  [l]ist                        List active sessions
25+        \\  [l]ist [--short]              List active sessions
26         \\  [k]ill <name>                 Kill a session and all attached clients
27         \\  [hi]story <name> [--vt|--html] Output session scrollback (--vt or --html for escape sequences)
28         \\  [v]ersion                     Show version information
29@@ -488,7 +489,7 @@ const SessionEntry = struct {
30     }
31 };
32 
33-fn list(cfg: *Cfg) !void {
34+fn list(cfg: *Cfg, short: bool) !void {
35     var gpa = std.heap.GeneralPurposeAllocator(.{}){};
36     defer _ = gpa.deinit();
37     const alloc = gpa.allocator();
38@@ -554,6 +555,7 @@ fn list(cfg: *Cfg) !void {
39     }
40 
41     if (sessions.items.len == 0) {
42+        if (short) return;
43         try w.interface.print("no sessions found in {s}\n", .{cfg.socket_dir});
44         try w.interface.flush();
45         return;
46@@ -562,7 +564,10 @@ fn list(cfg: *Cfg) !void {
47     std.mem.sort(SessionEntry, sessions.items, {}, SessionEntry.lessThan);
48 
49     for (sessions.items) |session| {
50-        if (session.is_error) {
51+        if (short) {
52+            if (session.is_error) continue;
53+            try w.interface.print("{s}\n", .{session.name});
54+        } else if (session.is_error) {
55             try w.interface.print("session_name={s}\tstatus={s}\t(cleaning up)\n", .{ session.name, session.error_name.? });
56         } else {
57             try w.interface.print("session_name={s}\tpid={d}\tclients={d}", .{ session.name, session.pid.?, session.clients_len.? });