# seela

A simple tmux session manager. Lets you fuzzy-find your projects,
and handles the window/pane layout based on your config.

## How to build

You can build using cargo

```bash
cargo build --release
```

## Usage

Run the binary

```bash
seela
```

Or specify a custom config path:

```bash
seela --config path/to/config.toml
```

### Tmux Integration

You can use `seela` in tmux like this

```tmux
bind g display-popup -w 80% -h 80% -E "seela"
```

## Configuration

`seela` looks for a config file in the following order:

1. `--config` flag
2. `$SEELA_CONFIG_HOME/config.toml`
3. `$XDG_CONFIG_HOME/seela/config.toml`
4. `~/.config/seela/config.toml`

Example `config.toml`:

```toml
[folders]
search_dirs = ["~/projects", "~/work"]
exclude_paths = ["~/projects/archive"]
force_include = ["~/special-project"]

[fzf]
preview = true
preview_command = "tree -C -L 2 {}"
fzf_opts = "--height 40% --layout=reverse"

[tmux]
# Time to wait for tmux to stabilize before sending commands (ms)
startup_delay_ms = 1000
# Delay between keys and minor actions (ms)
key_delay_ms = 100
# Delay after major actions like Enter or C-c (ms)
action_delay_ms = 200
```

> [!TIP]
> If your `exec` commands are not running correctly (e.g., being sent before the
> shell is ready), try increasing the values in the `[tmux]` section.
> Different operating systems, shells, and hardware may require different
> timings to ensure commands are processed correctly.


### Layout Configuration

You can configure your tmux session's layout.
Based on the path of the project or its type.

#### Default Session

`default_session` is for projects that do not match any path or type.

```toml
[default_session]
windows = ["editor", "terminal"]
window_focus = "editor"
```

#### Custom Sessions

You can also define `custom_sessions`
Which can match a project based on the path or type.

The projects will math the session based on this order:

1. Exact Path
2. Type Match
3. Partial Path Match (The closest match will be chosen)
4. Default Session

```toml
[[custom_sessions]]
name = "Rust Development"
types = ["rust"]  # Match projects of type 'rust'
windows = ["editor", "bacon"]
window_focus = "editor"

[[custom_sessions]]
name = "Web Development"
paths = ["~/projects/web"] # Match by path prefix
types = ["web"]            # OR match by project type
windows = ["editor", "server", "logs"]
```

#### Project Types

You can define your types like this.

```toml
[[project_types]]
name = "rust"
files = ["Cargo.toml"]

[[project_types]]
name = "web"
files = ["tsconfig.json", "package.json", "node_modules"]
```

#### Window Layouts

```toml
[[windows]]
name = "editor"
[[windows.panes]]
exec = ["nvim"]
```

#### Deeply Nested Panes

The panes are nest-able Use `split = "vertical"` for side-by-side panes
and `split = "horizontal"` for top-to-bottom panes.

The `split` property on a "parent" pane tells `seela` how to lay out its
"children". You can use the `ratio` property (a float) to define proportional
sizes for panes. If omitted, panes share the available space equally.

```toml
[[windows]]
name = "dev"

[[windows.panes]]
split = "vertical"  # The children below will be side-by-side

  [[windows.panes.panes]]
  exec = ["nvim"]
  ratio = 0.7       # 70% width

  [[windows.panes.panes]]
  split = "horizontal"
  ratio = 0.3       # 30% width

    [[windows.panes.panes.panes]]
    exec = ["ls -la"]
    ratio = 0.4      # 40% height of the 30% width

    [[windows.panes.panes.panes]]
    exec = ["git status"]
    ratio = 0.6      # 60% height of the 30% width
```

#### Special Operators

You can use special operators in the `exec` list to control command execution:

- **`@run <command>`**: Executes the command in the pane with several
  environment variables set:
  - `SEELA_SESSION_PATH`: Absolute path to the project.
  - `SEELA_SESSION_NAME`: Name of the tmux session.
  - `SEELA_WINDOW_NAME`: Name of the current window.
  - `SEELA_PANE_ID`: Unique ID of the current pane.
- **`@confirm <command>`**: Prompts for confirmation (`Run "command"? [Y/n]`)
  before executing.
- **`@wait <seconds>`**: Pauses execution for the specified number of seconds.
- **`@wait-milli <ms>`** (alias **`@wait-ms`**): Pauses execution for the
  specified number of milliseconds.
- **`@send-key <key>`** (alias **`@sk`**): Sends a raw key or key sequence to
  the pane (e.g., `Enter`, `Space`, `C-c`, `C-l`).

> [!NOTE]
> All panes need to be initialized before you you are attached to the session.
> This means using high `@wait` will make the app just stall for that period.

## TODO

- [x] Implement TOML config loading (`src/config.rs`)
- [x] Recursive project discovery (look for `.git` folders)
- [x] `fzf` integration for project selection
- [x] Basic tmux session opening
- [x] Complex window/pane layout support
- [x] Different layouts based on project paths
- [x] Custom and inbuilt types and layout based on the type
