# Tmux Configuration

This directory contains the tmux configuration, reusable tmuxifier layouts, and
session persistence settings.

## Session Persistence

The configuration uses tmux-resurrect and tmux-continuum to save sessions every
15 minutes and restore the latest saved session when tmux starts. Sessions save
window and pane layouts, working directories, and pane contents. Running
programs are restored only when supported by tmux-resurrect; their live process
state cannot survive a shutdown.

After starting tmux, install the configured plugins with:

```text
Ctrl-Space I
```

`Ctrl-Space` is the configured tmux prefix. You can also save or restore
manually with:

```text
Ctrl-Space Ctrl-S  Save the current tmux state
Ctrl-Space Ctrl-R  Restore the last saved state
```

# 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
