diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-19 13:14:52 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-19 13:14:52 -0500 |
| commit | 95e1e0be4905ff5d37b52f889f5dda65543e2b51 (patch) | |
| tree | e3a185caad1ecfba557e85c7d2c3eb66344a9f00 /dotfiles/common | |
| parent | 331d9421f1ca56afdaf0d238082f83d82103a795 (diff) | |
| download | archsetup-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-x | dotfiles/common/.local/bin/tmux-util | 39 |
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 ;; |
