aboutsummaryrefslogtreecommitdiff
path: root/tests/tmux-util/fake-tmux
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-19 12:31:17 -0500
committerCraig Jennings <c@cjennings.net>2026-05-19 12:31:17 -0500
commit924fec1f00e7ef5e497575488701e8c9eb2606f0 (patch)
tree9c0df313352ab01bd608fd408871ef7de418a39c /tests/tmux-util/fake-tmux
parent5d8d9df7d1b95c1a6a7bf25ddf57652c86f110b3 (diff)
downloadarchsetup-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-xtests/tmux-util/fake-tmux65
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"