Created
October 19, 2025 05:37
-
-
Save kesor/ca62a24bac3d5c7f55b3f611f6ac830d to your computer and use it in GitHub Desktop.
tmux-sessions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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