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)
Summary
Functions
Returns all registered commands as a list. Reads directly from ETS.
Returns a specification to start this module under a supervisor.
Looks up a command by name.
Registers a command with the given name, description, and execute function.
Registers a pre-built %Command{} struct.
Resets the registry to built-in commands only.
Starts the command registry as a named GenServer that owns an ETS table.
Removes a command by name.
Types
@type server() :: GenServer.server()
Registry server name or pid. Used as the ETS table name.
Functions
@spec all(server()) :: [Minga.Command.t()]
Returns all registered commands as a list. Reads directly from ETS.
Returns a specification to start this module under a supervisor.
See Supervisor.
@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.
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.
@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.
@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.
@spec reset(server()) :: :ok
@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)
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.