Skip to content

Instantly share code, notes, and snippets.

@kesor
Created October 19, 2025 05:37
Show Gist options
  • Save kesor/ca62a24bac3d5c7f55b3f611f6ac830d to your computer and use it in GitHub Desktop.
Save kesor/ca62a24bac3d5c7f55b3f611f6ac830d to your computer and use it in GitHub Desktop.
tmux-sessions
#!/bin/bash
fetch_tmux_sessions() {
# list session ids and names, each on a new line, ordered by session_id
tmux list-sessions -F "#{session_id} #{session_name}" | sort -n
}
# read tmux sessions into an array
mapfile -t SESSIONS < <(fetch_tmux_sessions)
declare -A KEY_SESSION_ID_MAP
declare -a SHORTCUT_KEYS=( 1 2 3 4 5 6 7 8 9 0 '!' '@' '#' '$' '%' '^' '&' '\*' '(' ')' '-' '=' \\ '`' '_' '+' '|' '~' )
FZF_LINES=""
FZF_KEYS=""
fzf_map_keys_to_sessions() {
for (( i=0; i<${#SESSIONS[@]}; i++ )); do
if [ $i -lt "${#SHORTCUT_KEYS[@]}" ]; then
session_id="${SESSIONS[$i]%% *}"
session_name="${SESSIONS[$i]#* }"
# session_id="${session_line%% *}"
# session_name="${session_line#* }"
key="${SHORTCUT_KEYS[$i]}"
KEY_SESSION_ID_MAP["$key"]="$session_id"
FZF_LINES+="$key: $session_id $session_name"$'\n'
FZF_KEYS+="$key,"
else
FZF_LINES+=" $session_id $session_name"$'\n'
fi
# i=$((i+1))
done
FZF_KEYS+="N" # new session key.
# remove trailing empty line
FZF_LINES=$(echo "$FZF_LINES" | sed '/^$/d')
}
fzf_display_sessions() {
# display sessions with fzf
echo "$FZF_LINES" | fzf --reverse \
--prompt="Select tmux session: " \
--scrollbar='' \
--expect="${FZF_KEYS}" \
--preview-window=bottom:50%:wrap:border-top \
--preview='
session_id=''{}''
session_id="${session_id#*: }"
session_id="${session_id%% *}"
tmux list-windows -t "${session_id}" -F "#{window_index}" \
| while read window; do
tmux capture-pane -t "${session_id}:${window}" -p
echo "-------"
done
'
}
handle_fzf_output() {
# Check if any selection was made
if [[ "${#FZF_OUTPUT[@]}" -le 0 ]]; then
tmux display-message "No session selected."
exit 0
fi
if [[ "${#FZF_OUTPUT[@]}" -eq 1 ]]; then
# a result has been selected using <enter>
session_id="${FZF_OUTPUT[0]#*: }"
session_id="${session_id%% *}"
else
# a result has been selected using an expected key
expected_key="${FZF_OUTPUT[0]}"
session_id="${KEY_SESSION_ID_MAP["$expected_key"]}"
fi
# Add: handle Shift-N (new session)
if [[ "$expected_key" == "N" ]]; then
read -rp "New session name: " new_session_name
if [[ -n "$new_session_name" ]]; then
tmux new-session -d -s "$new_session_name"
tmux switch-client -t "$new_session_name"
fi
exit 0
fi
echo >&2
for key in "${!KEY_SESSION_ID_MAP[@]}"; do
echo "key: $key, value: ${KEY_SESSION_ID_MAP["$key"]}" >&2
done
echo >&2
echo "expected_key: _${expected_key}_ ; session_id: _${session_id}_ ; fzf_output: _${FZF_OUTPUT[*]}_" >&2
# If a session was selected, switch to it
if [ -n "$session_id" ]; then
tmux switch-client -t "$session_id"
else
tmux display-message "No session selected."
fi
}
fzf_session_selector() {
if [ "${#SESSIONS[@]}" -le 0 ]; then
tmux display-message "No tmux sessions found."
exit 1
fi
fzf_map_keys_to_sessions
IFS=$'\n' read -r -d '' -a FZF_OUTPUT <<< "$(fzf_display_sessions)"
handle_fzf_output "$FZF_OUTPUT"
}
# Invoke the selector in a tmux popup window
if [[ "$1" == "popup" ]]; then
tmux popup -E -h 80% "$(readlink -f "${BASH_SOURCE[0]}")"
else
fzf_session_selector
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment