Minga.Command.Registry (Minga v0.1.0)

Copy Markdown View Source

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

Types

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

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

server()

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

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

Functions

all(server)

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

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

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

lookup(server, name)

@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(server, name, description, execute)

@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(server, cmd)

@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()

@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(server)

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

start_link(opts \\ [])

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

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

Options

unregister(server, name)

@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.