Skip to content

Instantly share code, notes, and snippets.

@tott
Created October 31, 2025 15:39
Show Gist options
  • Select an option

  • Save tott/5371bc0b20cb9543f007dfabc30dbb2e to your computer and use it in GitHub Desktop.

Select an option

Save tott/5371bc0b20cb9543f007dfabc30dbb2e to your computer and use it in GitHub Desktop.
Create tmux snapshot of layout / scripts in current window to be used with tmuxp as configuration. This is a bit better in this use case than tmuxp freeze
#!/bin/bash
# Enhanced tmux Layout Snapshot Script
# Captures the current tmux window layout with better command detection
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Default output file
OUTPUT_FILE=".tmuxp.yml"
# Check if we're in a tmux session
if [ -z "$TMUX" ]; then
echo -e "${RED}Error: Not running inside a tmux session${NC}"
exit 1
fi
# Parse command line arguments
while getopts "o:h" opt; do
case $opt in
o)
OUTPUT_FILE="$OPTARG"
;;
h)
echo "Usage: $0 [-o output_file]"
echo " -o: Output file path (default: .tmuxp.yml)"
echo " -h: Show this help message"
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
esac
done
echo -e "${YELLOW}Capturing tmux layout...${NC}"
# Get session information
SESSION_NAME=$(/usr/bin/tmux display-message -p "#{session_name}")
WINDOW_INDEX=$(/usr/bin/tmux display-message -p "#{window_index}")
WINDOW_NAME=$(/usr/bin/tmux display-message -p "#{window_name}")
WINDOW_LAYOUT=$(/usr/bin/tmux display-message -p "#{window_layout}")
SESSION_PATH=$(/usr/bin/tmux display-message -p "#{pane_current_path}")
echo -e "${GREEN}Session: ${NC}$SESSION_NAME"
echo -e "${GREEN}Window: ${NC}$WINDOW_NAME (index: $WINDOW_INDEX)"
echo -e "${GREEN}Layout: ${NC}$WINDOW_LAYOUT"
echo ""
# Function to get the actual command running in a pane
get_pane_command() {
local pane_pid=$1
local pane_cmd=$2
# Try to get the full command line from ps
if [ -n "$pane_pid" ]; then
# Get child processes
local child_pids=$(pgrep -P "$pane_pid" 2>/dev/null || echo "")
if [ -n "$child_pids" ]; then
# Get the command of the first child process
local full_cmd=$(ps -o args= -p $(echo "$child_pids" | head -1) 2>/dev/null || echo "")
if [ -n "$full_cmd" ]; then
echo "$full_cmd"
return
fi
fi
fi
# Fallback to the pane command
echo "$pane_cmd"
}
# Start building the YAML file
cat > "$OUTPUT_FILE" <<EOF
session_name: $SESSION_NAME
start_directory: $SESSION_PATH
windows:
- window_name: $WINDOW_NAME
layout: $WINDOW_LAYOUT
start_directory: $SESSION_PATH
panes:
EOF
echo -e "${BLUE}Pane commands detected:${NC}"
# Get pane information and add to YAML
/usr/bin/tmux list-panes -F "#{pane_index}|#{pane_pid}|#{pane_current_command}|#{pane_current_path}" | while IFS='|' read -r pane_index pane_pid pane_cmd pane_path; do
# Get the full command
full_cmd=$(get_pane_command "$pane_pid" "$pane_cmd")
# Clean up the command (remove leading/trailing whitespace)
shell_command=$(echo "$full_cmd" | xargs)
echo -e " ${GREEN}Pane $pane_index:${NC} $shell_command"
# Add pane to YAML with proper escaping for special characters
cat >> "$OUTPUT_FILE" <<EOF
- start_directory: $pane_path
shell_command: $shell_command
EOF
done
echo ""
echo -e "${GREEN}✓ Layout snapshot saved to: ${NC}$OUTPUT_FILE"
echo ""
echo -e "${YELLOW}Next steps:${NC}"
echo -e " 1. Review the generated file: ${GREEN}cat $OUTPUT_FILE${NC}"
echo -e " 2. Edit any commands that need adjustment"
echo -e " 3. Test the layout: ${GREEN}tmuxp load $OUTPUT_FILE${NC}"
echo ""
echo -e "${YELLOW}Common adjustments needed:${NC}"
echo -e " - Long-running watchers: ${BLUE}./vendor/bin/sail npm run dev${NC}"
echo -e " - Log tails: ${BLUE}tail -f storage/logs/laravel.log${NC}"
echo -e " - Editor files: ${BLUE}nvim README.md${NC}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment