repos / zmx

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

commit
ccdc1b9
parent
0222428
author
Danil Agafonov
date
2026-03-06 10:41:29 -0500 EST
docs: add session picker recipe using fzf (#75)

Add a shell function that fuzzy-finds and attaches to zmx sessions,
previews scrollback history, or creates new ones. Includes a Ctrl-N
keybinding to force session creation when a fuzzy match is highlighted.
Particularly useful for remote SSH workflows.
1 files changed,  +64, -0
M README.md
+64, -0
 1@@ -211,6 +211,70 @@ if type -q zmx
 2 end
 3 ```
 4 
 5+## session picker
 6+
 7+You can add an interactive session picker to your shell that lets you fuzzy-find existing sessions, preview their scrollback history, or create new ones — all from a single prompt. This is especially useful for remote SSH workflows: add it to your shell startup so that connecting to a machine immediately presents the picker.
 8+
 9+Requires [fzf](https://github.com/junegunn/fzf).
10+
11+- **Enter** selects a matched session (or creates one if no sessions exist)
12+- **Ctrl-N** creates a new session using the typed query, even when a fuzzy match is highlighted
13+
14+<details>
15+<summary>bash and zsh</summary>
16+
17+```bash
18+zmx-select() {
19+  local display
20+  display=$(zmx list 2>/dev/null | while IFS=$'\t' read -r name pid clients created dir; do
21+    name=${name#session_name=}
22+    pid=${pid#pid=}
23+    clients=${clients#clients=}
24+    dir=${dir#started_in=}
25+    printf "%-20s  pid:%-8s  clients:%-2s  %s\n" "$name" "$pid" "$clients" "$dir"
26+  done)
27+
28+  local output query key selected session_name
29+  output=$({ [[ -n "$display" ]] && echo "$display"; } | fzf \
30+    --print-query \
31+    --expect=ctrl-n \
32+    --height=80% \
33+    --reverse \
34+    --prompt="zmx> " \
35+    --header="Enter: select | Ctrl-N: create new" \
36+    --preview='zmx history {1}' \
37+    --preview-window=right:60%:follow \
38+  )
39+  local rc=$?
40+
41+  query=$(echo "$output" | sed -n '1p')
42+  key=$(echo "$output" | sed -n '2p')
43+  selected=$(echo "$output" | sed -n '3p')
44+
45+  if [[ "$key" == "ctrl-n" && -n "$query" ]]; then
46+    session_name="$query"
47+  elif [[ $rc -eq 0 && -n "$selected" ]]; then
48+    session_name=$(echo "$selected" | awk '{print $1}')
49+  elif [[ -n "$query" ]]; then
50+    session_name="$query"
51+  else
52+    return 130
53+  fi
54+
55+  zmx attach "$session_name"
56+}
57+```
58+
59+You can call `zmx-select` manually, bind it to a key, or auto-launch it on shell startup when outside a zmx session. With `&& exit`, the normal flow becomes: connect via SSH → pick a session → work → detach or exit the session → SSH disconnects automatically. Cancelling the picker with **Ctrl-C** drops you into a regular shell as an escape hatch.
60+
61+```bash
62+if command -v zmx &> /dev/null && command -v fzf &> /dev/null && [[ -z "$ZMX_SESSION" ]]; then
63+  zmx-select && exit
64+fi
65+```
66+
67+</details>
68+
69 ## session prefix
70 
71 We allow users to set an environment variable `ZMX_SESSION_PREFIX` which will prefix the name of the session for all commands. This means if that variable is set, every command that accepts a session will be prefixed with it.