# `Minga.Config.Hooks`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga/config/hooks.ex#L1)

Registry for lifecycle hooks.

Hooks are functions registered for specific editor events (save, open,
mode change). When an event fires, all registered hooks run asynchronously
under `Minga.Eval.TaskSupervisor`, so a slow or crashing hook never blocks
editing.

Hooks subscribes to the `Minga.Events` bus on startup. When a bus event
arrives (e.g. `:buffer_saved`), it maps the topic to the corresponding
hook event (`:after_save`) and fires all registered hooks. Direct
invocation via `run/2` is still supported for backward compatibility.

## Supported events

| Event            | Arguments                  | Fires when                |
|------------------|----------------------------|---------------------------|
| `:after_save`    | `[buffer_pid, file_path]`  | After a successful save   |
| `:after_open`    | `[buffer_pid, file_path]`  | After opening a file      |
| `:on_mode_change`| `[old_mode, new_mode]`     | When the editor mode changes |

## Example

    Minga.Config.Hooks.register(:after_save, fn _buf, path ->
      System.cmd("mix", ["format", path])
    end)

# `event`

```elixir
@type event() :: :after_save | :after_open | :on_mode_change
```

Valid event names.

# `state`

```elixir
@type state() :: %{required(event()) =&gt; [function()]}
```

Hook state: event name → list of hook functions.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `register`

```elixir
@spec register(event(), function()) :: :ok | {:error, String.t()}
```

Registers a hook function for an event.

Hooks fire in registration order. Returns `:ok` or `{:error, reason}`.

# `register`

```elixir
@spec register(GenServer.server(), event(), function()) :: :ok | {:error, String.t()}
```

# `reset`

```elixir
@spec reset() :: :ok
```

Removes all registered hooks.

# `reset`

```elixir
@spec reset(GenServer.server()) :: :ok
```

# `run`

```elixir
@spec run(event(), [term()]) :: :ok
```

Fires all hooks for an event asynchronously.

Each hook runs in a separate Task under `Minga.Eval.TaskSupervisor`.
Crashes are logged but don't propagate. This is a fire-and-forget cast:
it returns `:ok` immediately before hooks are dispatched. Prefer
broadcasting through `Minga.Events` over calling this directly.

# `run`

```elixir
@spec run(GenServer.server(), event(), [term()]) :: :ok
```

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Starts the hooks registry and subscribes to the event bus.

# `valid_events`

```elixir
@spec valid_events() :: [event()]
```

Returns the list of valid event names.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
