# `Minga.Command.Registry`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga/command/registry.ex#L1)

ETS-backed registry for named editor commands.

Commands are stored by name (atom) in an ETS table with
`read_concurrency: true` for lock-free lookups on the hot path
(every keystroke dispatches through this registry).

## Built-in commands

At startup, the registry aggregates commands from all modules that
implement `Minga.Command.Provider`. Each provider declares its
commands via `__commands__/0`. Adding a new command means adding
one entry in the sub-module that implements it. Zero changes here.

## Extension commands

Extensions register commands at runtime via `register/4` or
`Minga.Config.command/3`. Both paths write to the same ETS table,
so extension commands are immediately dispatchable through the same
`MingaEditor.Commands.execute/2` lookup.

## Usage

    {:ok, _pid} = Minga.Command.Registry.start_link(name: MyRegistry)
    {:ok, cmd} = Minga.Command.Registry.lookup(MyRegistry, :save)

# `server`

```elixir
@type server() :: GenServer.server()
```

Registry server name or pid. Used as the ETS table name.

# `all`

```elixir
@spec all(server()) :: [Minga.Command.t()]
```

Returns all registered commands as a list.
Reads directly from ETS.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `lookup`

```elixir
@spec lookup(server(), atom()) :: {:ok, Minga.Command.t()} | :error
```

Looks up a command by name.

Returns `{:ok, command}` if found, `:error` otherwise.
Reads directly from ETS (no GenServer call) for lock-free concurrency.

# `register`

```elixir
@spec register(server(), atom(), String.t(), function()) :: :ok
```

Registers a command with the given name, description, and execute function.

If a command with the same name already exists it is overwritten.
Writes go through the GenServer to ensure ETS table ownership is respected.

This is the primary API for extensions to register commands at runtime.
Built-in commands are registered via the `Minga.Command.Provider` behaviour.

# `register_command`

```elixir
@spec register_command(server(), Minga.Command.t()) :: :ok
```

Registers a pre-built `%Command{}` struct.

Used by `Extension.Supervisor` to register commands declared via the
extension DSL (`command/3` macro), where the full struct (including
`requires_buffer`, `scope`, etc.) is built by the framework.

# `reset`

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

Resets the registry to built-in commands only.

Removes all user-registered commands and re-registers the defaults
from all Provider modules. Used by hot reload to clear stale user
commands before re-evaluating config.

# `reset`

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

# `start_link`

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

Starts the command registry as a named GenServer that owns an ETS table.

## Options

* `:name` — the name to register under (default: `Elixir.Minga.Command.Registry`)

# `unregister`

```elixir
@spec unregister(server(), atom()) :: :ok
```

Removes a command by name.

Used by `Extension.Supervisor` to deregister commands when an extension
is stopped, preventing stale entries from pointing at purged modules.
No-op if the command doesn't exist.

---

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