Commit ccdc1b9
Danil Agafonov
·
2026-03-06 10:41:29 -0500 EST
parent 0222428
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
+64,
-0
| ... | ... | @@ -211,6 +211,70 @@ if type -q zmx | |
| 211 | 211 | end | |
| 212 | 212 | ``` | |
| 213 | 213 | ||
| 214 | + | ## session picker | |
| 215 | + | ||
| 216 | + | 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. | |
| 217 | + | ||
| 218 | + | Requires [fzf](https://github.com/junegunn/fzf). | |
| 219 | + | ||
| 220 | + | - **Enter** selects a matched session (or creates one if no sessions exist) | |
| 221 | + | - **Ctrl-N** creates a new session using the typed query, even when a fuzzy match is highlighted | |
| 222 | + | ||
| 223 | + | <details> | |
| 224 | + | <summary>bash and zsh</summary> | |
| 225 | + | ||
| 226 | + | ```bash | |
| 227 | + | zmx-select() { | |
| 228 | + | local display | |
| 229 | + | display=$(zmx list 2>/dev/null | while IFS=$'\t' read -r name pid clients created dir; do | |
| 230 | + | name=${name#session_name=} | |
| 231 | + | pid=${pid#pid=} | |
| 232 | + | clients=${clients#clients=} | |
| 233 | + | dir=${dir#started_in=} | |
| 234 | + | printf "%-20s pid:%-8s clients:%-2s %s\n" "$name" "$pid" "$clients" "$dir" | |
| 235 | + | done) | |
| 236 | + | ||
| 237 | + | local output query key selected session_name | |
| 238 | + | output=$({ [[ -n "$display" ]] && echo "$display"; } | fzf \ | |
| 239 | + | --print-query \ | |
| 240 | + | --expect=ctrl-n \ | |
| 241 | + | --height=80% \ | |
| 242 | + | --reverse \ | |
| 243 | + | --prompt="zmx> " \ | |
| 244 | + | --header="Enter: select | Ctrl-N: create new" \ | |
| 245 | + | --preview='zmx history {1}' \ | |
| 246 | + | --preview-window=right:60%:follow \ | |
| 247 | + | ) | |
| 248 | + | local rc=$? | |
| 249 | + | ||
| 250 | + | query=$(echo "$output" | sed -n '1p') | |
| 251 | + | key=$(echo "$output" | sed -n '2p') | |
| 252 | + | selected=$(echo "$output" | sed -n '3p') | |
| 253 | + | ||
| 254 | + | if [[ "$key" == "ctrl-n" && -n "$query" ]]; then | |
| 255 | + | session_name="$query" | |
| 256 | + | elif [[ $rc -eq 0 && -n "$selected" ]]; then | |
| 257 | + | session_name=$(echo "$selected" | awk '{print $1}') | |
| 258 | + | elif [[ -n "$query" ]]; then | |
| 259 | + | session_name="$query" | |
| 260 | + | else | |
| 261 | + | return 130 | |
| 262 | + | fi | |
| 263 | + | ||
| 264 | + | zmx attach "$session_name" | |
| 265 | + | } | |
| 266 | + | ``` | |
| 267 | + | ||
| 268 | + | 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. | |
| 269 | + | ||
| 270 | + | ```bash | |
| 271 | + | if command -v zmx &> /dev/null && command -v fzf &> /dev/null && [[ -z "$ZMX_SESSION" ]]; then | |
| 272 | + | zmx-select && exit | |
| 273 | + | fi | |
| 274 | + | ``` | |
| 275 | + | ||
| 276 | + | </details> | |
| 277 | + | ||
| 214 | 278 | ## session prefix | |
| 215 | 279 | ||
| 216 | 280 | 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. |