Created
August 29, 2025 13:24
-
-
Save Micka33/dd77056a95268436b7b2cd063b5c9ff7 to your computer and use it in GitHub Desktop.
A simple TMUX script to run (`bin/rails s`, `bin/vite dev` and `sidekiq` in 3 separate top panes and have a bottom pane with a shell)
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
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| # PS4='+ ${BASH_SOURCE}:${LINENO}:${FUNCNAME[0]:-main}() ' | |
| # set -x | |
| # -- Add to your ~/.tmux.conf -- | |
| # set -g mouse on | |
| # or run | |
| # echo "set -g mouse on" >> ~/.tmux.conf | |
| # --- Config (override via env if needed) --- | |
| BOTTOM_PERCENT="${BOTTOM_PERCENT:-60%}" # bottom row height percentage | |
| RIGHT_PERCENT="${RIGHT_PERCENT:-35%}" # top right column width percentage (eg: takes 35% of the top row) | |
| MIDDLE_PERCENT="${MIDDLE_PERCENT:-15%}" # top middle column width percentage (eg: takes 15% of the width left in the left column) | |
| SESSION_NAME="${SESSION_NAME:-$(basename "$PWD")}" | |
| # --- Commands to run --- | |
| CMD_LEFT_PANE="${CMD_LEFT_PANE:-bin/rails s}" | |
| CMD_MIDDLE_PANE="${CMD_MIDDLE_PANE:-bin/vite dev}" | |
| CMD_RIGHT_PANE="${CMD_RIGHT_PANE:-sidekiq}" # or "bundle exec sidekiq" | |
| require_tmux() { | |
| if ! command -v tmux >/dev/null 2>&1; then | |
| echo "tmux is required. Install with: brew install tmux" >&2 | |
| exit 1 | |
| fi | |
| } | |
| # Build layout in a specific target window (format: <session>:<window-index>) | |
| # and start commands. This function runs tmux commands server-side; it doesn't | |
| # depend on the interactive client being attached. | |
| build_layout_in_window() { | |
| local TARGET="$1" | |
| # Ensure we are operating on the right window | |
| tmux select-window -t "$TARGET" | |
| # Start from a single pane: kill all other panes in that window | |
| # (safe even if there's only one) | |
| tmux kill-pane -a -t "$TARGET" || true | |
| # Capture the top pane id (the only pane right now) | |
| local P_TOP | |
| P_TOP="$(tmux display-message -p -t "$TARGET" '#{pane_id}')" | |
| # Create bottom free shell | |
| tmux split-window -v -l "$BOTTOM_PERCENT" -t "$TARGET" | |
| # Go back to the captured TOP pane explicitly | |
| tmux select-pane -t "$P_TOP" | |
| # Split TOP into three columns: left (P_TOP), new right (P_RIGHT1), | |
| # then split the left again to create the middle (P_MID) | |
| tmux split-window -h -l "$RIGHT_PERCENT" -t "$P_TOP" | |
| local P_RIGHT | |
| P_RIGHT="$(tmux display-message -p -t "$TARGET" '#{pane_id}')" | |
| tmux split-window -h -l "$MIDDLE_PERCENT" -t "$P_TOP" | |
| local P_MID | |
| P_MID="$(tmux display-message -p -t "$TARGET" '#{pane_id}')" | |
| local P_LEFT="$P_TOP" | |
| # Fire up commands in precise panes | |
| tmux send-keys -t "$P_LEFT" "$CMD_LEFT_PANE" C-m | |
| tmux send-keys -t "$P_MID" "$CMD_MIDDLE_PANE" C-m | |
| tmux send-keys -t "$P_RIGHT" "$CMD_RIGHT_PANE" C-m | |
| # Put focus on the bottom shell (the one that was created by split-window -v) | |
| # Easiest: select the last pane (bottom) by direction from any top pane | |
| tmux select-pane -t "$P_LEFT" | |
| tmux select-pane -D -t "$TARGET" 2>/dev/null || true | |
| } | |
| main() { | |
| require_tmux | |
| if [ -n "${TMUX-}" ]; then | |
| # Already inside tmux: operate on the current window | |
| local CUR_SESSION CUR_INDEX TARGET | |
| CUR_SESSION="$(tmux display-message -p '#S')" | |
| CUR_INDEX="$(tmux display-message -p '#I')" | |
| TARGET="${CUR_SESSION}:${CUR_INDEX}" | |
| build_layout_in_window "$TARGET" | |
| else | |
| # Not in tmux: create or reuse a session (no new iTerm2 window is spawned) | |
| if ! tmux has-session -t "$SESSION_NAME" 2>/dev/null; then | |
| tmux new-session -d -s "$SESSION_NAME" -n dev | |
| fi | |
| # Build in window 0 of that session | |
| build_layout_in_window "${SESSION_NAME}:0" | |
| # Attach in THIS terminal window | |
| tmux attach -t "$SESSION_NAME" | |
| fi | |
| } | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage :
Move to your Rails folder and run the script above.