Skip to content

philmard/mygrid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⊞  mygrid

One Ghostty window → one tmux session → a ragged grid where each row is a repo.
Single-Cmd chords jump-and-zoom to any terminal; Cmd+0 shows the whole overview.

The model · Install · Usage · Profiles · Status bar

mygrid demo - mygrid tap countries building a two-row ragged grid

The model

OVERVIEW  (Cmd+0)  ──►  TERMINAL N  (Cmd+1 … Cmd+9, jumps AND zooms)
   the full ragged grid          one pane filling the screen
[ 1 · web ] | [ 2 · web ]                row 1  (repo: web)
[ 3 · app ] | [ 4 · app ] | [ 5 · app ]  row 2  (repo: app)
[ 6 · api ] | [ 7 · api ]                row 3  (repo: api)

Numbers are positional (reading order, top→bottom then left→right) and reflow whenever you add/remove panes — exactly the dynamic behavior you wanted.

Note on Cmd+N: the numbers you see are reading-order positions, which are NOT the same as tmux's internal pane_index after arbitrary splits. So Cmd+N is routed through tmux-gotopane, which always resolves N to the pane whose visible title is N · repo. (This is why the binds are run-shell 'tmux-gotopane N' rather than select-pane -t N.)

Requirements

  • macOS — the Cmd/Opt keybinds are Mac-specific.
  • Ghostty — the terminal the keybinds drive.
  • tmuxinstall.sh installs it via Homebrew if it's missing.
  • zsh — pane commands run in your interactive shell, and install.sh adds ~/bin to ~/.zshrc.

Install

The quickest path is the bundled installer:

./install.sh

It installs tmux (via Homebrew if missing), copies the scripts to ~/bin and ensures it's on PATH, installs ~/.tmux.conf, and appends the Ghostty keybinds to your active Ghostty config (detecting config vs config.ghostty).

Manual install

  1. Scripts — put mygrid, tmux-renumber, and tmux-gotopane on your PATH:

    mkdir -p ~/bin
    cp bin/mygrid bin/tmux-renumber bin/tmux-gotopane ~/bin/
    chmod +x ~/bin/mygrid ~/bin/tmux-renumber ~/bin/tmux-gotopane
    # ensure ~/bin is on PATH (add to ~/.zshrc if needed):
    echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc
  2. tmux:

    brew install tmux
    cp tmux.conf ~/.tmux.conf
  3. Ghostty — append the keybinds to your active config, then fully quit and reopen Ghostty:

    cat ghostty-config.txt >> "$HOME/Library/Application Support/com.mitchellh.ghostty/config"

What it changes / uninstall

install.sh is idempotent and backs up anything it replaces. It touches only:

  • ~/bin/ — copies in mygrid and the tmux-* helper scripts.
  • ~/.zshrc — appends a PATH line for ~/bin (only if missing).
  • ~/.tmux.conf — installs this repo's config (your old one is saved to ~/.tmux.conf.bak).
  • ~/.config/mygrid/profiles/ — seeds example.conf on a fresh setup.
  • Your Ghostty config — appends the keybinds between # >>> mygrid keybinds >>> markers.

To uninstall: delete ~/bin/mygrid and the ~/bin/tmux-* scripts, remove the marked keybind block from your Ghostty config, restore ~/.tmux.conf.bak (or remove ~/.tmux.conf), and drop the ~/bin PATH line from ~/.zshrc. Nothing is installed system-wide.

Use

Build a layout (each token is a row; count[:path]):

mygrid 2,3,2
mygrid 2:~/code/web,3:~/code/app,2:~/code/api

Or use named profiles (see below) — one row per profile:

mygrid web api

Then, with a single Cmd chord:

Key Action
Cmd+1..9 jump to terminal N and zoom it fullscreen
Cmd+0 overview — un-zoom to the full ragged grid
Opt+1..9 focus terminal N without zooming (overview)
Cmd+Shift+A add a pane to the current row, then renumber
Cmd+Shift+R add a new row (new repo), then renumber
Cmd+W close current pane (no confirm), then renumber
Cmd+Shift+X close current pane (confirm), then renumber
Cmd+Shift+N force a renumber/relabel pass
Cmd+Shift+= rebalance row heights
*Cmd+Shift+* rebalance column widths within each row

(The same actions exist under the tmux prefix Ctrl-A if you ever want them manually: Ctrl-A then a, r, x, n, =, |, or a digit.)

After adding/removing rows you may want Cmd+Shift+= to even the row heights.

Profiles

A profile is a named row definition: a directory plus the panes (and their startup commands) for one row. mygrid <name> [name...] builds one row per profile, in order.

Profiles live in ~/.config/mygrid/profiles/<name>.conf (override the location with $MYGRID_PROFILES). Format:

# ~/.config/mygrid/profiles/web.conf
dir  = ~/dev/web-client  # directory every pane in this row opens in
pane = yarn dev:prod     # left pane  — runs on startup
pane = claude            # middle pane
pane = gl                # right pane
# ~/.config/mygrid/profiles/api.conf
dir   = ~/dev/api-server
count = 3                # 3 plain shells, no startup commands
  • Each pane = <command> adds one pane (left→right). The command runs in your normal interactive shell (via tmux send-keys), so ~/.zshrc aliases and functions like gl work, and the pane stays open as a shell after the command finishes. pane = (empty) is a plain shell.
  • count = N is shorthand for N plain shells; it's used only when there are no pane = lines.
  • The profile name is independent of the directory, so web~/dev/web-client.
  • mygrid with no args (or an unknown name) lists the profiles you have.
  • Mix freely: mygrid web api is two rows; add more names for more rows.

profiles/example.conf in this repo is a documented template; install.sh seeds it into ~/.config/mygrid/profiles/ on a fresh setup.

Status bar

The bottom line shows, on the left:

web │ 1 [2] 3 │ ⊞ OVERVIEW
  • web — the profile of the row you're focused on (only that row, never the whole spec). Ad-hoc rows show the row's directory name instead.
  • 1 [2] 3 — that row's panes by their global reading-order numbers; the focused one is bracketed and highlighted in the accent color.
  • ⊞ OVERVIEW / ⛶ ZOOMED — whether you're seeing the full grid or a single zoomed pane (ZOOMED is accent/bold as a reminder that other panes exist off-screen).

It updates instantly on focus changes via a pane-focus-in hook running tmux-statusmap (no polling). Pane border titles use the same one-name rule: 2 · web, not 2 · web-client · web. The default window list is hidden — mygrid keeps everything in one window, so it never said anything.

Personal colors (~/.tmux.conf.local)

The repo ships neutral colors only — pulling it never rethemes your setup. Personalize in ~/.tmux.conf.local, sourced at the very end of tmux.conf and never written by install.sh, so it survives every pull/reinstall:

# ~/.tmux.conf.local — example matched to Ghostty's "Django Reborn Again"
set -g @grid_accent_bg "#ffcc00"             # accent: focused-pane border,
set -g @grid_accent_fg "#051f14"             #   map highlight, ZOOMED badge
set -g status-style "bg=#245032,fg=#dadedc"  # status bar background/text

The @grid_accent_* pair is one knob for everything accent-colored; any other tmux option (border styles, the bar, whatever) can be overridden there too.

Attention flags

monitor-activity and monitor-bell are on, so a pane that prints output while unfocused (a Claude permission prompt, a failed command) gets flagged in the status line — your cue for which terminal to check, even before you open the overview.

Notes / limits

  • Ragged widths: each row divides its own width among its panes, so a 2-pane row is wider per-pane than a 3-pane row. tmux's automatic layouts can't do this on their own, which is why mygrid builds rows manually.
  • Cmd+Shift+A splits the active pane, so the new pane takes its width from that pane — the row may look slightly uneven. It stays in the same row.
  • Clicking links: mouse on (below) makes tmux capture the mouse, so a plain Cmd+click no longer reaches Ghostty's link handler. Hold Shift while clicking (Shift+click or Cmd+Shift+click) to bypass tmux's mouse grab and open the link — Ghostty's mouse-shift-capture = false default makes this work. (Turn off set -g mouse on in tmux.conf if you'd rather have plain Cmd+click back at the cost of scroll / click-to-focus / drag-resize.)
  • Mouse: mouse on gives you trackpad scrollback, click-to-focus a pane, and drag-to-resize borders.
  • Persistence: the tmux session survives closing Ghostty (quitting Ghostty does not end the tmux server). Reopen and run mygrid (no args) or mygrid <same spec> to re-attach, or tmux attach -t dev. To switch to a different layout you must end the old session first: tmux kill-session -t dev && mygrid <new spec>. Running mygrid <different spec> while a session exists refuses (rather than silently attaching to the old layout) and tells you this — mygrid records the spec that built the session in the @mygrid_spec option to detect the mismatch.
  • Change the session name with MYGRID_SESSION=foo mygrid 2,2.

About

Ragged tmux grid for Ghostty - one row per repo, as many panes as you want. Single-Cmd chords jump-and-zoom to any pane; Cmd+0 shows the whole grid.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages