Last active
March 21, 2026 15:26
-
-
Save hoangtrung99/7043116174078a904068dc7d2a7a3fad to your computer and use it in GitHub Desktop.
Tmux full setup script - 11 plugins, catppuccin mocha, context-aware status bar, popup help
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 | |
| # ═══════════════════════════════════════════════════════════════ | |
| # Tmux Setup Script - Automated installation & configuration | |
| # ═══════════════════════════════════════════════════════════════ | |
| # | |
| # USAGE: | |
| # curl -fsSL <gist-raw-url> | bash | |
| # OR: bash setup-tmux.sh | |
| # | |
| # WHAT THIS DOES: | |
| # 1. Install tmux (brew/apt) | |
| # 2. Install TPM (Tmux Plugin Manager) | |
| # 3. Write ~/.tmux.conf with 11 plugins + custom status bar | |
| # 4. Create popup help file + terminal cheatsheet | |
| # 5. Install all plugins via TPM | |
| # | |
| # PLUGINS INCLUDED: | |
| # Core: tpm, sensible, yank, resurrect, continuum | |
| # Navigation: vim-tmux-navigator | |
| # Productivity: thumbs (quick copy), menus, fzf, floax (floating pane) | |
| # Theme: catppuccin mocha | |
| # | |
| # KEY BINDINGS: | |
| # C-b ? Popup cheatsheet | |
| # C-b Space Thumbs quick copy | |
| # C-b F Fuzzy find (fzf) | |
| # C-b p Floating pane | |
| # C-b \ Context menus | |
| # C-b C-s Save session | |
| # C-b C-r Restore session | |
| # C-b r Reload config | |
| # C-h/j/k/l Navigate panes (no prefix) | |
| # | |
| # STATUS BAR: | |
| # Normal: shows session name + help hints + time | |
| # PREFIX: turns orange, shows available commands | |
| # COPY: turns red, shows copy-mode keys | |
| # | |
| # ═══════════════════════════════════════════════════════════════ | |
| set -e | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| CYAN='\033[0;36m' | |
| RED='\033[0;31m' | |
| NC='\033[0m' | |
| info() { echo -e "${CYAN}[INFO]${NC} $1"; } | |
| ok() { echo -e "${GREEN}[OK]${NC} $1"; } | |
| warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } | |
| fail() { echo -e "${RED}[FAIL]${NC} $1"; exit 1; } | |
| # ─── Step 1: Install tmux ─── | |
| install_tmux() { | |
| if command -v tmux &>/dev/null; then | |
| ok "tmux already installed: $(tmux -V)" | |
| return | |
| fi | |
| info "Installing tmux..." | |
| if [[ "$(uname)" == "Darwin" ]]; then | |
| if ! command -v brew &>/dev/null; then | |
| fail "Homebrew not found. Install from https://brew.sh" | |
| fi | |
| brew install tmux | |
| elif command -v apt-get &>/dev/null; then | |
| sudo apt-get update && sudo apt-get install -y tmux | |
| elif command -v dnf &>/dev/null; then | |
| sudo dnf install -y tmux | |
| elif command -v pacman &>/dev/null; then | |
| sudo pacman -S --noconfirm tmux | |
| else | |
| fail "Cannot detect package manager. Install tmux manually." | |
| fi | |
| ok "tmux installed: $(tmux -V)" | |
| } | |
| # ─── Step 2: Install dependencies ─── | |
| install_deps() { | |
| # fzf (required for tmux-fzf) | |
| if ! command -v fzf &>/dev/null; then | |
| info "Installing fzf..." | |
| if [[ "$(uname)" == "Darwin" ]]; then | |
| brew install fzf | |
| elif command -v apt-get &>/dev/null; then | |
| sudo apt-get install -y fzf | |
| fi | |
| ok "fzf installed" | |
| else | |
| ok "fzf already installed" | |
| fi | |
| # cargo (required for tmux-thumbs) | |
| if ! command -v cargo &>/dev/null; then | |
| info "Installing Rust/Cargo (for tmux-thumbs)..." | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y | |
| source "$HOME/.cargo/env" 2>/dev/null || true | |
| ok "Cargo installed" | |
| else | |
| ok "Cargo already installed" | |
| fi | |
| } | |
| # ─── Step 3: Install TPM ─── | |
| install_tpm() { | |
| if [ -d "$HOME/.tmux/plugins/tpm" ]; then | |
| ok "TPM already installed" | |
| return | |
| fi | |
| info "Installing TPM (Tmux Plugin Manager)..." | |
| git clone https://github.com/tmux-plugins/tpm "$HOME/.tmux/plugins/tpm" | |
| ok "TPM installed" | |
| } | |
| # ─── Step 4: Write ~/.tmux.conf ─── | |
| write_tmux_conf() { | |
| if [ -f "$HOME/.tmux.conf" ]; then | |
| cp "$HOME/.tmux.conf" "$HOME/.tmux.conf.bak.$(date +%s)" | |
| warn "Existing .tmux.conf backed up" | |
| fi | |
| info "Writing ~/.tmux.conf..." | |
| cat > "$HOME/.tmux.conf" << 'TMUXCONF' | |
| # ~/.tmux.conf | |
| # ─── Plugin Manager ─── | |
| set -g @plugin 'tmux-plugins/tpm' | |
| # ─── Core Plugins ─── | |
| set -g @plugin 'tmux-plugins/tmux-sensible' | |
| set -g @plugin 'tmux-plugins/tmux-yank' | |
| set -g @plugin 'tmux-plugins/tmux-resurrect' | |
| set -g @plugin 'tmux-plugins/tmux-continuum' | |
| set -g @plugin 'christoomey/vim-tmux-navigator' | |
| set -g @plugin 'fcsonline/tmux-thumbs' | |
| set -g @plugin 'jaclu/tmux-menus' | |
| # ─── New Plugins ─── | |
| set -g @plugin 'sainnhe/tmux-fzf' | |
| set -g @plugin 'omerxx/tmux-floax' | |
| # ─── Theme: Catppuccin Mocha ─── | |
| set -g @plugin 'catppuccin/tmux' | |
| set -g @catppuccin_flavor 'mocha' | |
| # ─── Plugin Config ─── | |
| set -g @continuum-restore 'on' | |
| set -g @floax-bind 'p' | |
| set -g @menus_show_key_hints 'Yes' | |
| set -g @floax-session-name 'scratch' | |
| # ─── Base Config ─── | |
| set -g mouse on | |
| set -g base-index 1 | |
| set -g pane-base-index 1 | |
| set -g mode-keys vi | |
| set -g history-limit 50000 | |
| set -sg escape-time 0 | |
| set -g renumber-windows on | |
| set -g allow-rename off | |
| set -g automatic-rename off | |
| set -g default-terminal "tmux-256color" | |
| set -ag terminal-overrides ",xterm-256color:RGB" | |
| # ─── Custom Keybindings ─── | |
| bind '"' split-window -v -c "#{pane_current_path}" | |
| bind % split-window -h -c "#{pane_current_path}" | |
| bind r source-file ~/.tmux.conf \; display "Config reloaded!" | |
| bind ? display-popup -w 60 -h 30 -E "cat ~/.tmux-help.txt && read -n 1" | |
| bind C-y copy-mode \; send-keys -X history-top \; send-keys -X begin-selection \; send-keys -X history-bottom \; send-keys -X copy-pipe-and-cancel "pbcopy" | |
| # ─── TPM Init ─── | |
| run '~/.tmux/plugins/tpm/tpm' | |
| # ─── Floax Menu Override ─── | |
| # Use tmux's native display-menu instead of the plugin's menu wrapper. | |
| unbind P | |
| bind P if-shell -F '#{==:#{session_name},#{@floax-session-name}}' \ | |
| 'display-menu -T "FloaX" \ | |
| "size down" - "run-shell \"~/.tmux/plugins/tmux-floax/scripts/zoom-options.sh in\"" \ | |
| "size up" + "run-shell \"~/.tmux/plugins/tmux-floax/scripts/zoom-options.sh out\"" \ | |
| "full screen" f "run-shell \"~/.tmux/plugins/tmux-floax/scripts/zoom-options.sh full\"" \ | |
| "reset size" r "run-shell \"~/.tmux/plugins/tmux-floax/scripts/zoom-options.sh reset\"" \ | |
| "embed in session" e "run-shell \"~/.tmux/plugins/tmux-floax/scripts/embed.sh embed\""' \ | |
| 'display-menu -T "FloaX" \ | |
| "pop current window" p "run-shell \"~/.tmux/plugins/tmux-floax/scripts/embed.sh pop\""' | |
| # ─── Status Bar (after TPM to override catppuccin) ─── | |
| set -g status-left-length 40 | |
| set -g status-right-length 120 | |
| # Mode indicator: PREFIX (orange) | COPY (red) | Session (blue) | |
| set -g status-left '#{?client_prefix,#[bg=#fab387 fg=#1e1e2e bold] PREFIX ,#{?pane_in_mode,#[bg=#f38ba8 fg=#1e1e2e bold] COPY ,#[bg=#89b4fa fg=#1e1e2e bold] #S }}#[bg=default fg=default] ' | |
| # Context-aware hints | |
| set -g status-right '#{?client_prefix,#[fg=#a6adc8] c:win · d:detach · ?:help ,#{?pane_in_mode,#[fg=#a6adc8] v:sel · y:yank · q:quit ,#[fg=#585b70] ?:help · Spc:copy · F:fzf }}#[fg=#89b4fa] %H:%M ' | |
| # Fix catppuccin using #T (pane title) instead of #W (window name) | |
| set -g window-status-format "#[fg=#11111b,bg=#{@thm_overlay_2}] #I #[fg=#cdd6f4,bg=#{@thm_surface_0}] #W " | |
| set -g window-status-current-format "#[fg=#11111b,bg=#{@thm_mauve}] #I #[fg=#cdd6f4,bg=#{@thm_surface_1}] #W " | |
| TMUXCONF | |
| ok "~/.tmux.conf written" | |
| } | |
| # ─── Step 5: Create help files ─── | |
| write_help_files() { | |
| info "Creating help files..." | |
| # Popup help (C-b ?) | |
| cat > "$HOME/.tmux-help.txt" << 'HELPFILE' | |
| TMUX QUICK REFERENCE | |
| ───────────────────────────────────────────── | |
| SESSION WINDOW | |
| C-b d detach C-b c new window | |
| C-b s list sessions C-b n/p next/prev | |
| C-b $ rename C-b 1-9 jump to | |
| C-b , rename | |
| C-b & close | |
| PANE COPY (vi mode) | |
| C-b % split | C-b [ enter | |
| C-b " split - v select | |
| C-b z zoom y yank | |
| C-b x close / search | |
| C-h/j/k/l navigate q quit | |
| PLUGINS | |
| C-b Space thumbs copy C-b p float pane | |
| C-b \ menus C-b F fzf find | |
| C-b C-s save session C-b r reload conf | |
| C-b C-r restore C-b I install plugins | |
| C-b C-y copy pane to clipboard | |
| ───────────────────────────────────────────── | |
| Press any key to close | |
| HELPFILE | |
| # Terminal cheatsheet on startup (bash + zsh compatible) | |
| cat > "$HOME/.tmux-cheatsheet.sh" << 'CHEATSHEET' | |
| #!/bin/sh | |
| # Tmux Cheatsheet - hiển thị khi mở terminal | |
| # Tắt: export TMUX_CHEATSHEET=off | |
| _tmux_cheatsheet() { | |
| [ "$TMUX_CHEATSHEET" = "off" ] && return | |
| local b=$'\e[1m' c=$'\e[36m' y=$'\e[33m' r=$'\e[0m' | |
| echo "${c}${b} ┌─────────────────────────────────────────────────────┐${r}" | |
| echo "${c}${b} │ TMUX CHEATSHEET │${r}" | |
| echo "${c}${b} └─────────────────────────────────────────────────────┘${r}" | |
| echo | |
| echo "${y}${b} SESSION WINDOW PANE${r}" | |
| printf ' %-20s%-20s%s\n' \ | |
| 'C-b d detach' 'C-b c new' 'C-b % split |' \ | |
| 'C-b s list' 'C-b n next' 'C-b " split -' \ | |
| 'C-b $ rename' 'C-b 1-9 jump' 'C-b z zoom' \ | |
| '' 'C-b , rename' 'C-b x close' | |
| echo | |
| echo "${y}${b} NAVIGATE COPY${r}" | |
| printf ' %-28s%s\n' \ | |
| 'C-h/j/k/l move panes' 'C-b Space thumbs (quick)' \ | |
| '(no prefix needed)' 'C-b y copy line' \ | |
| '' 'C-b [ copy mode' | |
| echo | |
| echo "${y}${b} SAVE/RESTORE MENU${r}" | |
| printf ' %-28s%s\n' \ | |
| 'C-b C-s save session' 'C-b \ main menu' \ | |
| 'C-b C-r restore' 'right-click context menu' | |
| echo | |
| } | |
| _tmux_cheatsheet | |
| unset -f _tmux_cheatsheet | |
| CHEATSHEET | |
| chmod +x "$HOME/.tmux-cheatsheet.sh" | |
| ok "Help files created" | |
| } | |
| # ─── Step 6: Add cheatsheet to shell ─── | |
| setup_shell_cheatsheet() { | |
| local rc="$HOME/.zshrc" | |
| [ ! -f "$rc" ] && rc="$HOME/.bashrc" | |
| [ ! -f "$rc" ] && { warn "No .zshrc or .bashrc found, skipping cheatsheet auto-display"; return; } | |
| if grep -q "tmux-cheatsheet" "$rc" 2>/dev/null; then | |
| ok "Cheatsheet already in shell rc" | |
| return | |
| fi | |
| info "Adding cheatsheet to $rc..." | |
| echo '' >> "$rc" | |
| echo '# Tmux cheatsheet on terminal open (set TMUX_CHEATSHEET=off to disable)' >> "$rc" | |
| echo 'source ~/.tmux-cheatsheet.sh' >> "$rc" | |
| ok "Cheatsheet added to $rc" | |
| } | |
| # ─── Step 7: Install plugins ─── | |
| install_plugins() { | |
| info "Installing tmux plugins via TPM..." | |
| "$HOME/.tmux/plugins/tpm/bin/install_plugins" 2>&1 | |
| ok "All plugins installed" | |
| # Reload config if tmux is running | |
| if tmux list-sessions &>/dev/null; then | |
| tmux source-file "$HOME/.tmux.conf" 2>/dev/null | |
| ok "Tmux config reloaded" | |
| fi | |
| } | |
| # ─── Main ─── | |
| main() { | |
| echo "" | |
| echo -e "${CYAN}═══════════════════════════════════════════════════${NC}" | |
| echo -e "${CYAN} Tmux Setup - Full Installation ${NC}" | |
| echo -e "${CYAN}═══════════════════════════════════════════════════${NC}" | |
| echo "" | |
| install_tmux | |
| install_deps | |
| install_tpm | |
| write_tmux_conf | |
| write_help_files | |
| setup_shell_cheatsheet | |
| install_plugins | |
| echo "" | |
| echo -e "${GREEN}═══════════════════════════════════════════════════${NC}" | |
| echo -e "${GREEN} Setup complete!${NC}" | |
| echo -e "${GREEN}═══════════════════════════════════════════════════${NC}" | |
| echo "" | |
| echo " Start tmux: tmux new -s main" | |
| echo " Popup help: C-b ?" | |
| echo " Floating pane: C-b p" | |
| echo " Fuzzy find: C-b F" | |
| echo " Quick copy: C-b Space" | |
| echo " Save session: C-b C-s" | |
| echo " Restore session: C-b C-r" | |
| echo "" | |
| echo " Disable cheatsheet: export TMUX_CHEATSHEET=off" | |
| echo "" | |
| } | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment