# Ghostty Module

Ghostty terminal emulator configuration for nix-darwin.

## Installation

Enable in host config:

```nix
modules.desktop.term.ghostty.enable = true;
```

On macOS, Ghostty is installed as the Nix `ghostty-bin` app bundle.
On Linux, the upstream Ghostty flake package is used.

## What This Module Provides

- **Config generation:** Main config, keybindings, and behavior.conf with PATH injection
- **macOS Terminal.app aesthetics:** Creates a Terminal profile from the same Stylix font/colors used for the host terminal theme
- **Extensible keybindings:** Other modules can add keybindings via `keybindingFiles` or `keybindingsInit`
- **PATH injection:** Ensures nix-managed commands (like Herdr/tmux) are available at startup
- **macOS legacy config cleanup:** Removes `~/Library/Application Support/com.mitchellh.ghostty/config` when present, preventing old autogenerated templates from shadowing `~/.config/ghostty/config`

## Files

| Source                            | Destination                                                  | Notes                                     |
| --------------------------------- | ------------------------------------------------------------ | ----------------------------------------- |
| `config/ghostty/config`           | `~/.config/ghostty/config`                                   | Generated (base + configInit)             |
| `config/ghostty/keybindings.conf` | `~/.config/ghostty/keybindings.conf`                         | Generated (files + init)                  |
| `config/ghostty/behavior.conf`    | `~/.config/ghostty/behavior.conf`                            | Generated (base + PATH injection)         |
| `config/ghostty/macos.conf`       | `~/.config/ghostty/macos.conf`                               | Symlinked                                 |
| `config/ghostty/ui.conf`          | `~/.config/ghostty/ui.conf`                                  | Symlinked                                 |
| activation cleanup                | `~/Library/Application Support/com.mitchellh.ghostty/config` | Removed if present so XDG stays canonical |

## Options

### `modules.desktop.term.ghostty.enable`

Enable the Ghostty module.

### `modules.desktop.term.ghostty.keybindingFiles`

List of keybinding files to concatenate into `keybindings.conf`.

Default: `[ "${configDir}/ghostty/keybindings.conf" ]`

Example (from another module):

```nix
modules.desktop.term.ghostty.keybindingFiles = [
  "${configDir}/ghostty/my-keybindings.conf"
];
```

### `modules.desktop.term.ghostty.keybindingsInit`

Inline keybinding text appended to `keybindings.conf`.

Example:

```nix
modules.desktop.term.ghostty.keybindingsInit = ''
  keybind = ctrl+shift+t=new_tab
'';
```

### `modules.desktop.term.ghostty.configInit`

Inline config text appended to the main config file.

Example:

```nix
modules.desktop.term.ghostty.configInit = ''
  font-size = 14
'';
```

### `modules.desktop.term.ghostty.macosTerminalProfileName`

Name of the generated Terminal.app profile. Default: `Ghostty Match`.

On Darwin hosts with Stylix enabled, activation creates/updates this profile and
sets it as Terminal.app's startup/default profile. It mirrors the host Stylix
monospace font, terminal font size, background, foreground, bold, cursor, and
color settings so Terminal opens with the same basic aesthetic as Ghostty.

## Extending Keybindings

Other modules (like `pi`) can add keybindings:

```nix
# Using keybindingFiles (recommended for separate files)
modules.desktop.term.ghostty.keybindingFiles = mkIf ghosttyCfg.enable [
  "${configDir}/ghostty/pi-keybindings.conf"
];

# Using keybindingsInit (for inline additions)
modules.desktop.term.ghostty.keybindingsInit = mkIf ghosttyCfg.enable ''
  keybind = alt+backspace=text:\x1b\x7f
'';
```

Use `mkBefore` to prepend or `mkAfter` to append relative to other modules.

## Startup Ownership

Ghostty should have exactly one workspace owner:

- If Herdr is enabled, Ghostty starts `~/.config/tmux/open-herdr.sh` and Herdr owns the terminal. The Herdr launcher must not fall back to tmux; otherwise a failed/exited Herdr launch can attach tmux and allow Herdr to be started inside tmux, creating `Ghostty -> Herdr helper -> tmux -> Herdr`.
- If Herdr is disabled, tmux/jmux should own startup directly. Precedence is: Herdr when enabled; otherwise jmux if enabled; otherwise plain tmux. Do not make one owner fall back into another.

## PATH Injection

Ghostty's `command` directive runs before shell profiles load (`--noprofile --norc`).
This module injects PATH into `behavior.conf` so nix-managed startup commands are found:

```
env=PATH=/Users/<user>/.nix-profile/bin:/etc/profiles/per-user/<user>/bin:...
```

## Troubleshooting

### Herdr/tmux not launched when Ghostty starts

The PATH injection and startup command should handle this. If still failing:

1. Verify `~/Library/Application Support/com.mitchellh.ghostty/config` is absent. If it exists, it can shadow the XDG config for GUI launches.
2. Verify `~/.config/ghostty/behavior.conf` contains the `env=PATH=...` line and `command = ~/.config/tmux/open-herdr.sh` when Herdr is enabled.
3. Check PATH includes `/etc/profiles/per-user/<username>/bin` and your user bins.
4. Run `hey rebuild` to regenerate configs and remove any legacy macOS config, then fully quit/reopen Ghostty.

### Keybindings not working

1. Check `~/.config/ghostty/keybindings.conf` was generated correctly
2. Verify no syntax errors in keybinding files
3. **Fully restart Ghostty** (Cmd+Q → reopen) - keybindings require full restart

### Keybindings not updating after config reload

Ghostty caches keybindings at startup for performance. While most config changes
(colors, fonts, etc.) apply with `Ctrl+Shift+,` or `ghostty +reload-config`,
**keybindings are only parsed at launch**. You must fully quit and restart Ghostty
for keybinding changes to take effect.

### SSH shows wrong TERM

The module sets `TERM=xterm-256color` when SSH is detected (ghostty terminfo isn't widely available).
