aboutsummaryrefslogtreecommitdiff
path: root/dotfiles/common
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-19 13:14:52 -0500
committerCraig Jennings <c@cjennings.net>2026-05-19 13:14:52 -0500
commit95e1e0be4905ff5d37b52f889f5dda65543e2b51 (patch)
treee3a185caad1ecfba557e85c7d2c3eb66344a9f00 /dotfiles/common
parent331d9421f1ca56afdaf0d238082f83d82103a795 (diff)
downloadarchsetup-95e1e0be4905ff5d37b52f889f5dda65543e2b51.tar.gz
archsetup-95e1e0be4905ff5d37b52f889f5dda65543e2b51.zip
feat(tmux-util): add pick subcommand (fzf session switcher)
tmux-util pick lists every session ("attached"/"detached" plus name), pipes it through fzf, and attaches or switch-clients to the chosen one (matching the go subcommand's inside-vs-outside-tmux discipline). If the user cancels fzf (Ctrl-C, Esc, empty selection), the pipeline returns empty and pick exits 0 without touching tmux state. The new fake-fzf testing fake is driven by env vars: - FAKE_FZF_CHOICE_LINE=<N>: return the Nth line of stdin as the selection - FAKE_FZF_CHOICE=<string>: return the literal string (ignores stdin) - (neither): exit 130 to simulate cancel 4 new tests cover Normal cases (pick second line, inside/outside tmux behavior) and Boundary cases (no sessions, user cancellation). Total suite: 43 tests, all green.
Diffstat (limited to 'dotfiles/common')
-rwxr-xr-xdotfiles/common/.local/bin/tmux-util39
1 files changed, 38 insertions, 1 deletions
diff --git a/dotfiles/common/.local/bin/tmux-util b/dotfiles/common/.local/bin/tmux-util
index 5e0ce85..4669b03 100755
--- a/dotfiles/common/.local/bin/tmux-util
+++ b/dotfiles/common/.local/bin/tmux-util
@@ -36,6 +36,40 @@ EOF
}
# -----------------------------------------------------------------------------
+# pick
+# -----------------------------------------------------------------------------
+
+cmd_pick() {
+ local sessions
+ sessions=$(tmux list-sessions \
+ -F '#{session_attached} #{session_name}' 2>/dev/null || true)
+ if [ -z "$sessions" ]; then
+ echo "No tmux sessions to pick from."
+ return 0
+ fi
+
+ # Format for fzf: "<state> <name>" — name is the second field of the
+ # selection line, which we recover after fzf returns.
+ local choice
+ choice=$(echo "$sessions" | awk '{
+ state = ($1 == "1") ? "attached" : "detached"
+ printf "%-9s %s\n", state, $2
+ }' | fzf --header="Pick a tmux session" | awk '{print $2}')
+
+ if [ -z "$choice" ]; then
+ # User cancelled (Ctrl-C or Esc); fzf exits 130, the pipeline
+ # returns empty.
+ return 0
+ fi
+
+ if [ -n "${TMUX:-}" ]; then
+ tmux switch-client -t "$choice"
+ else
+ tmux attach-session -t "$choice"
+ fi
+}
+
+# -----------------------------------------------------------------------------
# find
# -----------------------------------------------------------------------------
@@ -204,7 +238,10 @@ main() {
find)
cmd_find "$@"
;;
- pick|rename)
+ pick)
+ cmd_pick "$@"
+ ;;
+ rename)
echo "tmux-util: subcommand '$sub' is not implemented yet" >&2
return 2
;;