diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-19 12:31:17 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-19 12:31:17 -0500 |
| commit | 924fec1f00e7ef5e497575488701e8c9eb2606f0 (patch) | |
| tree | 9c0df313352ab01bd608fd408871ef7de418a39c /tests/tmux-util/fake-tmux | |
| parent | 5d8d9df7d1b95c1a6a7bf25ddf57652c86f110b3 (diff) | |
| download | archsetup-924fec1f00e7ef5e497575488701e8c9eb2606f0.tar.gz archsetup-924fec1f00e7ef5e497575488701e8c9eb2606f0.zip | |
feat(tmux-util): add ls subcommand
tmux-util ls is an opinionated replacement for `tmux ls` with columns for state (attached/detached), name, idle time (humanized), window count, and the current pane's cwd (tilde-fied if it sits under $HOME).
The cwd query goes through `tmux display -p -t <session> '#{pane_current_path}'`, which returns the cwd of the active pane of the active window. That's close enough to "what the session is about" for a one-line summary.
Idle calculation reads `date +%s` by default and accepts an override via the TMUX_UTIL_NOW env var so tests can pin "now" to a known epoch.
12 new tests cover Normal cases (attached / detached, multiple sessions) and Boundary cases (no sessions, idle exactly at minute / hour / day boundaries, $HOME tilde). One existing dispatch test got reworked because the original stub target (`ls`) is no longer unimplemented. Total suite is 26 tests, all green.
The fake-tmux harness picked up two things along the way: real format-string parsing for `list-sessions -F` and a new handler for `display -p`. The state file format extended to include activity epoch, window count, and cwd, with sensible defaults for older 3-tuple test inputs so the reap tests keep passing untouched.
Diffstat (limited to 'tests/tmux-util/fake-tmux')
| -rwxr-xr-x | tests/tmux-util/fake-tmux | 65 |
1 files changed, 50 insertions, 15 deletions
diff --git a/tests/tmux-util/fake-tmux b/tests/tmux-util/fake-tmux index f6217bb..ba2d5cc 100755 --- a/tests/tmux-util/fake-tmux +++ b/tests/tmux-util/fake-tmux @@ -1,9 +1,11 @@ -#!/bin/sh +#!/bin/bash # Fake tmux for testing tmux-util. # # State file: $FAKE_TMUX_DIR/sessions.txt -# One line per session, space-separated: <name> <attached> <pids_csv> [last_activity_epoch] +# One line per session, space-separated: +# <name> <attached> <pids_csv> [<activity_epoch> [<windows> [<cwd>]]] # pids_csv is a comma-separated list of pane PIDs (or '-' for none) +# cwd cannot contain spaces in test data. # # Log file: $FAKE_TMUX_DIR/calls.log # Each invocation appended as a single line: tmux <args> @@ -19,19 +21,36 @@ printf 'tmux %s\n' "$*" >> "$LOG" cmd="$1" shift -# Helper: read state file, ignoring blank lines read_state() { [ -f "$STATE" ] || return 0 grep -v '^[[:space:]]*$' "$STATE" || true } +# Render a tmux format string against one session's fields. +# Args: format, name, attached, activity, windows, cwd +render_format() { + local out="$1" name="$2" attached="$3" activity="$4" windows="$5" cwd="$6" + out="${out//\#\{session_name\}/$name}" + out="${out//\#\{session_attached\}/$attached}" + out="${out//\#\{session_activity\}/$activity}" + out="${out//\#\{session_windows\}/$windows}" + out="${out//\#\{pane_current_path\}/$cwd}" + echo "$out" +} + case "$cmd" in list-sessions) - # Format string is ignored; we always emit "<name> <attached>" because - # that's the only format tmux-util uses against list-sessions. - read_state | while IFS=' ' read -r name attached pids _rest; do + fmt="" + while [ "$#" -gt 0 ]; do + case "$1" in + -F) shift; fmt="${1:-}"; shift ;; + *) shift ;; + esac + done + [ -n "$fmt" ] || fmt='#{session_name} #{session_attached}' + read_state | while IFS=' ' read -r name attached pids activity windows cwd; do [ -n "$name" ] || continue - echo "$name $attached" + render_format "$fmt" "$name" "$attached" "${activity:-0}" "${windows:-1}" "${cwd:-/tmp}" done ;; list-panes) @@ -51,6 +70,25 @@ case "$cmd" in fi done ;; + display) + fmt="" + target="" + while [ "$#" -gt 0 ]; do + case "$1" in + -p) shift ;; + -t) shift; target="$1"; shift ;; + *) fmt="$1"; shift ;; + esac + done + while IFS=' ' read -r name attached pids activity windows cwd; do + [ -n "$name" ] || continue + if [ "$name" = "$target" ]; then + render_format "$fmt" "$name" "$attached" "${activity:-0}" "${windows:-1}" "${cwd:-/tmp}" + exit 0 + fi + done < "$STATE" + exit 1 + ;; has-session) session="" while [ "$#" -gt 0 ]; do @@ -76,14 +114,11 @@ case "$cmd" in done tmp="$STATE.tmp" : > "$tmp" - while IFS=' ' read -r name attached pids rest; do - [ -n "$name" ] || continue - if [ "$name" != "$session" ]; then - if [ -n "$rest" ]; then - printf '%s %s %s %s\n' "$name" "$attached" "$pids" "$rest" >> "$tmp" - else - printf '%s %s %s\n' "$name" "$attached" "$pids" >> "$tmp" - fi + while IFS= read -r line; do + [ -n "$line" ] || continue + first="${line%% *}" + if [ "$first" != "$session" ]; then + printf '%s\n' "$line" >> "$tmp" fi done < "$STATE" mv "$tmp" "$STATE" |
