From 7b7f5a5dcfb168aa64aaa0e08f609a747e41a3aa Mon Sep 17 00:00:00 2001 From: Mathias Schneider Date: Wed, 15 Apr 2026 22:00:59 +0200 Subject: [PATCH] tmuxifier --- term/.bashrc | 4 + term/.config/fish/config.fish | 6 + term/.config/tmux/README.md | 353 ++++++++++++++++++++++ term/.config/tmux/layouts/demo.session.sh | 23 ++ term/.config/tmux/tmux.conf | 7 +- 5 files changed, 391 insertions(+), 2 deletions(-) create mode 100644 term/.config/tmux/README.md create mode 100644 term/.config/tmux/layouts/demo.session.sh diff --git a/term/.bashrc b/term/.bashrc index f8c12b4..713f4ef 100644 --- a/term/.bashrc +++ b/term/.bashrc @@ -9,3 +9,7 @@ alias ls='ls --color=auto' alias grep='grep --color=auto' PS1='[\u@\h \W]\$ ' export PATH="$HOME/.local/bin:$PATH" + +# Tmuxifier +export PATH="$HOME/.tmuxifier/bin:$PATH" +eval "$(tmuxifier init -)" diff --git a/term/.config/fish/config.fish b/term/.config/fish/config.fish index c1da968..a29c635 100644 --- a/term/.config/fish/config.fish +++ b/term/.config/fish/config.fish @@ -122,3 +122,9 @@ alias zi=__zoxide_zi # # zoxide init fish | source fish_add_path -m $HOME/.local/bin + +# Tmuxifier +if test -d $HOME/.tmuxifier + fish_add_path -m $HOME/.tmuxifier/bin + tmuxifier init - | source +end diff --git a/term/.config/tmux/README.md b/term/.config/tmux/README.md new file mode 100644 index 0000000..6536393 --- /dev/null +++ b/term/.config/tmux/README.md @@ -0,0 +1,353 @@ +# Tmuxifier Session Templates + +This directory contains reusable tmux session and window layouts managed by [tmuxifier](https://github.com/jimeh/tmuxifier). + +## Installation + +### 1. Install tmuxifier + +```bash +git clone https://github.com/jimeh/tmuxifier.git ~/.tmuxifier +``` + +### 2. Add to tmux (via TPM) + +The `tmux.conf` in this directory already includes the tmuxifier plugin. After starting tmux, press `prefix + I` to install it via TPM. + +### 3. Add to your shell + +The fish config (`~/.config/fish/config.fish`) in this repo already includes tmuxifier initialization. Restart fish or run: + +```fish +source ~/.config/fish/config.fish +``` + +### 4. Verify installation + +```fish +which tmuxifier +# Should output: ~/.tmuxifier/bin/tmuxifier + +tmuxifier help +# Should show tmuxifier commands +``` + +## Quick Start + +After installing tmuxifier, create and load sessions: + +```bash +# Create a new session layout +tmuxifier new-session my-project + +# Load a session +tmuxifier load-session my-project # or: t s my-project + +# Edit an existing session +tmuxifier edit-session my-project # or: t es my-project + +# Create a window layout (for use within existing sessions) +tmuxifier new-window my-window +tmuxifier load-window my-window # or: t lw my-window +``` + +## Directory Structure + +``` +tmuxifier/ +├── layouts/ +│ ├── *.session.sh # Full session definitions +│ └── *.window.sh # Window-only definitions +``` + +## Session Template Reference + +### Basic Structure + +```bash +# Set a custom session root path (must be called before initialize_session) +session_root "~/projects/my-project" + +# Create session with specified name if it does not already exist +if initialize_session "my-project"; then + + # Create windows + new_window "editor" + new_window "server" + new_window "logs" + + # Select the default active window + select_window "editor" + + # Run commands in the selected window + run_cmd "cd ~/projects/my-project" + + # Send keys (like typing) to the pane + send_keys "nvim ." C-m + + # Finalize session creation and switch/attach to it + finalize_and_go_to_session +fi +``` + +### Commands Reference + +#### Session Commands + +| Command | Description | +|---------|-------------| +| `session_root "path"` | Set root directory for session (must be first) | +| `initialize_session "name"` | Create session if it doesn't exist | +| `finalize_and_go_to_session` | Complete creation and attach to session | +| `select_window "name"` | Set active window | + +#### Window Commands + +| Command | Description | +|---------|-------------| +| `new_window "name"` | Create a new window | +| `select_window "name"` | Switch to existing window | +| `run_cmd "command"` | Execute command in current pane | +| `send_keys "keys"` | Send key sequence to pane | +| `send_text "text"` | Send raw text to pane | +| `split_h [percent]` | Horizontal split (default 50%) | +| `split_v [percent]` | Vertical split (default 50%) | +| `select_pane [target]` | Select pane (up, down, left, right, left-or-up, right-or-down) | + +#### Pane Target Options + +For `select_pane`: +- `up`, `down`, `left`, `right` - Navigate to adjacent pane +- `left-or-up`, `right-or-down` - Prefer first direction, fall back to second + +### Key Modifiers + +| Symbol | Meaning | +|--------|---------| +| `C-m` | Enter/Return key | +| `C-c` | Ctrl+C | +| `C-d` | Ctrl+D (EOF) | +| `M-m` | Alt/Meta+m | +| `C-\\` | Ctrl+\\ | + +## Example Templates + +Understanding the pane system is key. Here's a visual breakdown: + +``` +┌─────────────────────────────────────────────────────┐ +│ Window: "editor" │ +│ ┌─────────────────────┬───────────────────────────┐ │ +│ │ Pane 1 (40%) │ Pane 2 (60%) │ │ +│ │ nvim │ npm run dev │ │ +│ │ ├───────────────────────────┤ │ +│ │ │ Pane 3 (50% of pane 2) │ │ +│ │ │ npm run test │ │ +│ └─────────────────────┴───────────────────────────┘ │ +└─────────────────────────────────────────────────────┘ +``` + +### Example 1: Two Panes Side by Side + +```bash +session_root "~/projects/app" + +if initialize_session "app"; then + new_window "editor" + + # Split horizontally (40% left, 60% right) + split_h 40 + + # Run command in first pane (left side) + run_cmd "cd ~/projects/app && nvim" + + # Move to second pane (right side) and split vertically + select_pane right + split_v 50 + + # Run commands in the new panes + run_cmd "npm run dev" + select_pane right + run_cmd "npm run test" + + select_window "editor" + finalize_and_go_to_session +fi +``` + +### Example 2: Three Panes with Nested Split + +```bash +session_root "~/projects/app" + +if initialize_session "app"; then + new_window "editor" + + # Create three panes: top (20%), bottom-left (40%), bottom-right (40%) + split_v 20 # horizontal split at 20% + run_cmd "htop" # top pane: system monitor + + select_pane down # move to bottom + split_h 50 # vertical split bottom into left/right + run_cmd "npm run dev" # bottom-left + select_pane right + run_cmd "npm run test" # bottom-right + + select_window "editor" + finalize_and_go_to_session +fi +``` + +``` +Resulting layout: +┌─────────────────────────────────────┐ +│ htop (20%) │ +├──────────────┬──────────────────────┤ +│ npm run dev │ npm run test │ +│ (40%) │ (40%) │ +└──────────────┴──────────────────────┘ +``` + +### Example 3: Multiple Windows with Panes + +```bash +session_root "~/projects/webapp" + +if initialize_session "webapp"; then + # Window 1: Main workspace with panes + new_window "editor" + split_h 50 + run_cmd "cd ~/projects/webapp && nvim" + select_pane right + run_cmd "cd ~/projects/webapp && npm run dev" + + # Window 2: Server with logs + new_window "server" + split_v 30 + run_cmd "cd ~/projects/webapp && python -m http.server 8000" + select_pane right + run_cmd "cd ~/projects/webapp && tail -f logs/app.log" + + # Window 3: Database + new_window "database" + run_cmd "docker compose up db" + + # Start on editor window + select_window "editor" + finalize_and_go_to_session +fi +``` + +### Example 4: Practical Development Setup + +```bash +session_root "~/projects/api" + +if initialize_session "api"; then + new_window "code" + split_h 60 + run_cmd "cd ~/projects/api && nvim" + select_pane right + split_v 50 + run_cmd "cd ~/projects/api && uvicorn main:app --reload" + select_pane right + run_cmd "cd ~/projects/api && tail -f logs/api.log" + + new_window "tests" + split_h 50 + run_cmd "cd ~/projects/api && pytest -v" + select_pane right + run_cmd "cd ~/projects/api && pytest --cov" + + new_window "shell" + run_cmd "cd ~/projects/api" + + select_window "code" + finalize_and_go_to_session +fi +``` + +### Example 5: Simple Window Layout (No Panes) + +```bash +session_root "~/projects/webapp" + +if initialize_session "webapp"; then + # Each window has a single pane + new_window "editor" + run_cmd "cd ~/projects/webapp && nvim" + + new_window "server" + run_cmd "cd ~/projects/webapp && npm run dev" + + new_window "database" + run_cmd "docker compose up db" + + new_window "logs" + run_cmd "cd ~/projects/webapp && tail -f logs/app.log" + + select_window "editor" + finalize_and_go_to_session +fi +``` + +## Shell Integration + +### Aliases + +Add these to your shell config for convenience: + +```bash +# Bash/Zsh (.bashrc or .zshrc) +alias t='tmuxifier' +alias ts='tmuxifier load-session' +alias tes='tmuxifier edit-session' +alias tns='tmuxifier new-session' +alias tlw='tmuxifier load-window' + +# Fish (.config/fish/config.fish or conf.d/) +alias t 'tmuxifier' +alias ts 'tmuxifier load-session' +alias tes 'tmuxifier edit-session' +``` + +### Usage Without Tmux Prefix + +If you want to load sessions from outside tmux (in a regular terminal): + +```bash +# Run this in a plain terminal, NOT inside tmux +tmuxifier load-session my-project +``` + +## Tips + +1. **Exit before loading**: Make sure you're not inside tmux when running `load-session` +2. **Auto-starting services**: Use `run_cmd` with background processes (`&`) for long-running services +3. **Docker containers**: Commands like `docker compose up -d` work well in dedicated windows +4. **Custom layouts path**: Set `TMUXIFIER_LAYOUT_PATH` to use a different directory + +```bash +export TMUXIFIER_LAYOUT_PATH="$HOME/.config/tmux/layouts" +``` + +## Troubleshooting + +**"unknown command" when running tmuxifier?** +- tmuxifier is not installed. Run: `git clone https://github.com/jimeh/tmuxifier.git ~/.tmuxifier` +- Restart your shell: `source ~/.config/fish/config.fish` +- Verify: `which tmuxifier` + +**Session won't load?** +- Make sure you're NOT inside tmux when running `load-session` +- Make sure tmuxifier is initialized in your shell config +- Check that you have tmux installed: `tmux -V` +- Verify the layout file exists: `ls ~/.tmuxifier/layouts/` + +**TPM plugin not working?** +- Inside tmux, press `prefix + I` (capital I) to install plugins +- `prefix` is `Ctrl+Space` by default in this config + +**Commands not running?** +- Use `run_cmd` for single commands, not `send_keys` +- For interactive commands, consider using `send_keys` instead diff --git a/term/.config/tmux/layouts/demo.session.sh b/term/.config/tmux/layouts/demo.session.sh new file mode 100644 index 0000000..3e959ba --- /dev/null +++ b/term/.config/tmux/layouts/demo.session.sh @@ -0,0 +1,23 @@ +# Example session: demo +# Usage: tmuxifier load-session demo +# Edit: tmuxifier edit-session demo + +session_root "$HOME" + +if initialize_session "demo"; then + new_window "editor" + new_window "server" + new_window "shell" + + select_window "editor" + run_cmd "cd ~ && nvim ." + + select_window "server" + run_cmd "echo 'Server ready'" + + select_window "shell" + run_cmd "echo 'Shell ready'" + + select_window "editor" + finalize_and_go_to_session +fi diff --git a/term/.config/tmux/tmux.conf b/term/.config/tmux/tmux.conf index 22e5a0b..ce4c845 100644 --- a/term/.config/tmux/tmux.conf +++ b/term/.config/tmux/tmux.conf @@ -1,6 +1,5 @@ # ── General ─────────────────────────────────────────────────────────────────── - set -g default-terminal "tmux-256color" set -ag terminal-overrides ",xterm-256color:RGB" @@ -31,7 +30,7 @@ bind k select-pane -U bind l select-pane -R -# ── Plugins ─────────────────────────────────────────────────────────────────── +# ── Plugins ──────────────────────────────────────────────────────────────────── # Auto-bootstrap TPM if not installed if "test ! -d ~/.config/tmux/plugins/tpm" \ @@ -40,12 +39,16 @@ if "test ! -d ~/.config/tmux/plugins/tpm" \ set -g @plugin 'tmux-plugins/tpm' set -g @plugin 'tmux-plugins/tmux-sensible' set -g @plugin 'sindrip/tmux-nvim-navigator' +set -g @plugin 'jimeh/tmuxifier' # Catppuccin theme set -g @plugin 'catppuccin/tmux' set -g @catppuccin_flavor "mocha" set -g @catppuccin_window_status_style "rounded" +# Tmuxifier environment +set-environment -g TMUXIFIER_LAYOUT_PATH "$HOME/.tmuxifier/layouts" + # ── Initialize TPM (must be last line before status bar) ──────────────────────