Add session manager for tmux.

This will open a tmux session for each monitor.
Add helper script for tmux actions.
This commit is contained in:
2025-09-22 15:26:42 +02:00
parent c4df56cb47
commit 8e563fec51
8 changed files with 622 additions and 11 deletions

42
tmux/move-window.sh Executable file
View File

@@ -0,0 +1,42 @@
#!/bin/bash
# Tmux window mover with fzf
# Allows moving current window to another session
# Get current session and window
current_session=$(tmux display-message -p '#S')
current_window=$(tmux display-message -p '#I')
current_window_name=$(tmux display-message -p '#W')
# Get list of all sessions with window count
sessions=$(tmux list-sessions -F '#{session_name}: #{session_windows} windows' | grep -v "^${current_session}:")
# If no other sessions, offer to create one
if [ -z "$sessions" ]; then
echo "No other sessions available. Create a new session? (y/n)"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
echo "Enter new session name:"
read -r new_session
if [ ! -z "$new_session" ]; then
tmux new-session -d -s "$new_session"
tmux move-window -t "${new_session}:"
tmux switch-client -t "$new_session"
fi
fi
exit 0
fi
# Select target session with fzf
target_session=$(echo "$sessions" | fzf --header="Move window '${current_window_name}' to session:" --preview='tmux list-windows -t {1} -F "#{window_index}: #{window_name} [#{window_panes} panes]"' | cut -d: -f1)
# If a session was selected, move the window
if [ ! -z "$target_session" ]; then
# Move window to target session
tmux move-window -t "${target_session}:"
# Switch to the target session
tmux switch-client -t "$target_session"
echo "Moved window '${current_window_name}' to session '${target_session}'"
fi

193
tmux/tmux-fzf-menu.sh Executable file
View File

@@ -0,0 +1,193 @@
#!/bin/bash
# Advanced tmux operations menu using fzf
# Provides a unified interface for various tmux operations
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Main menu options
show_menu() {
echo "Session: Switch to session"
echo "Window: Switch to window"
echo "Move Window: Move current window to another session"
echo "Move Pane: Move current pane to another window"
echo "Swap Window: Swap current window with another"
echo "Rename Window: Rename current window"
echo "Rename Session: Rename current session"
echo "Kill Window: Kill a window"
echo "Kill Session: Kill a session"
echo "New Session: Create new session"
echo "Link Window: Link window from another session"
echo "Unlink Window: Unlink current window"
}
# Function to switch session
switch_session() {
tmux list-sessions -F '#{session_name}: #{session_windows} windows#{?session_attached, (attached),}' | \
fzf --header='Switch to session:' \
--preview='tmux list-windows -t {1} -F "#{window_index}: #{window_name} [#{window_panes} panes]"' | \
cut -d: -f1 | \
xargs -I {} tmux switch-client -t {}
}
# Function to switch window
switch_window() {
tmux list-windows -a -F '#{session_name}:#{window_index}: #{window_name}' | \
fzf --header='Switch to window:' \
--preview='tmux list-panes -t {1} -F "Pane #{pane_index}: #{pane_current_command}"' | \
cut -d: -f1,2 | \
xargs -I {} tmux switch-client -t {}
}
# Function to move current window
move_window() {
current_window=$(tmux display-message -p '#W')
target=$(tmux list-sessions -F '#{session_name}' | \
fzf --header="Move window '${current_window}' to session:" \
--preview='tmux list-windows -t {} -F "#{window_index}: #{window_name}"')
if [ ! -z "$target" ]; then
tmux move-window -t "${target}:"
tmux switch-client -t "$target"
fi
}
# Function to move current pane
move_pane() {
target=$(tmux list-windows -a -F '#{session_name}:#{window_index}: #{window_name}' | \
fzf --header='Move pane to window:' \
--preview='tmux list-panes -t {1} -F "Pane #{pane_index}: #{pane_current_command}"')
if [ ! -z "$target" ]; then
window_target=$(echo "$target" | cut -d: -f1,2)
tmux join-pane -t "$window_target"
fi
}
# Function to swap windows
swap_window() {
target=$(tmux list-windows -F '#{window_index}: #{window_name}' | \
fzf --header='Swap current window with:')
if [ ! -z "$target" ]; then
window_idx=$(echo "$target" | cut -d: -f1)
tmux swap-window -t "$window_idx"
fi
}
# Function to rename window
rename_window() {
echo -n "New window name: "
read -r new_name
if [ ! -z "$new_name" ]; then
tmux rename-window "$new_name"
fi
}
# Function to rename session
rename_session() {
echo -n "New session name: "
read -r new_name
if [ ! -z "$new_name" ]; then
tmux rename-session "$new_name"
fi
}
# Function to kill window
kill_window() {
target=$(tmux list-windows -a -F '#{session_name}:#{window_index}: #{window_name}' | \
fzf --header='Kill window:' --multi \
--preview='tmux list-panes -t {1} -F "Pane #{pane_index}: #{pane_current_command}"')
if [ ! -z "$target" ]; then
echo "$target" | while IFS= read -r window; do
window_target=$(echo "$window" | cut -d: -f1,2)
tmux kill-window -t "$window_target"
done
fi
}
# Function to kill session
kill_session() {
target=$(tmux list-sessions -F '#{session_name}: #{session_windows} windows#{?session_attached, (attached),}' | \
fzf --header='Kill session:' --multi \
--preview='tmux list-windows -t {1} -F "#{window_index}: #{window_name}"')
if [ ! -z "$target" ]; then
echo "$target" | while IFS= read -r session; do
session_name=$(echo "$session" | cut -d: -f1)
tmux kill-session -t "$session_name"
done
fi
}
# Function to create new session
new_session() {
echo -n "New session name: "
read -r session_name
if [ ! -z "$session_name" ]; then
tmux new-session -d -s "$session_name"
tmux switch-client -t "$session_name"
fi
}
# Function to link window from another session
link_window() {
target=$(tmux list-windows -a -F '#{session_name}:#{window_index}: #{window_name}' | \
fzf --header='Link window:' \
--preview='tmux list-panes -t {1} -F "Pane #{pane_index}: #{pane_current_command}"')
if [ ! -z "$target" ]; then
source_window=$(echo "$target" | cut -d' ' -f1)
tmux link-window -s "$source_window"
fi
}
# Function to unlink current window
unlink_window() {
tmux unlink-window
echo "Current window unlinked"
}
# Main execution
if [ "$1" == "--menu" ] || [ -z "$1" ]; then
# Show interactive menu
selection=$(show_menu | fzf --header='Tmux Operations:' | cut -d: -f1)
case "$selection" in
"Session") switch_session ;;
"Window") switch_window ;;
"Move Window") move_window ;;
"Move Pane") move_pane ;;
"Swap Window") swap_window ;;
"Rename Window") rename_window ;;
"Rename Session") rename_session ;;
"Kill Window") kill_window ;;
"Kill Session") kill_session ;;
"New Session") new_session ;;
"Link Window") link_window ;;
"Unlink Window") unlink_window ;;
esac
else
# Direct command execution
case "$1" in
session) switch_session ;;
window) switch_window ;;
move-window) move_window ;;
move-pane) move_pane ;;
swap-window) swap_window ;;
rename-window) rename_window ;;
rename-session) rename_session ;;
kill-window) kill_window ;;
kill-session) kill_session ;;
new-session) new_session ;;
link-window) link_window ;;
unlink-window) unlink_window ;;
*) echo "Unknown command: $1" ;;
esac
fi

View File

@@ -108,4 +108,19 @@ bind w display-popup -E "tmux list-windows -F '#{window_index}: #{window_name}'
bind f display-popup -E "fd --type f --hidden --follow --exclude .git | fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}' | xargs -I {} tmux new-window 'vim {}'"
# Quick directory navigation
bind g display-popup -E "fd --type d --hidden --follow --exclude .git | fzf --preview 'tree -C {} | head -200' | xargs -I {} tmux send-keys 'cd {}' Enter"
bind g display-popup -E "fd --type d --hidden --follow --exclude .git | fzf --preview 'tree -C {} | head -200' | xargs -I {} tmux send-keys 'cd {}' Enter"
# Move window to another session with fzf
bind m display-popup -E "bash ~/.config/tmux/move-window.sh"
# Swap windows with fzf
bind M display-popup -E "tmux list-windows -F '#{window_index}: #{window_name}' | fzf --header='Swap current window with:' | cut -d: -f1 | xargs -I {} tmux swap-window -t {}"
# Move pane to another window with fzf
bind p display-popup -E "tmux list-windows -F '#{window_index}: #{window_name}' | fzf --header='Move pane to window:' | cut -d: -f1 | xargs -I {} tmux join-pane -t :{}"
# Break pane into new window
bind B break-pane -d
# Comprehensive tmux operations menu with fzf
bind Space display-popup -E -w 80% -h 80% "bash ~/.config/tmux/tmux-fzf-menu.sh --menu"