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

A named editor command.

Commands are the bridge between key sequences (via the keymap trie)
and editor state mutations. Each command has a name (for registry
lookup), a human-readable description (for which-key display), and
an execute function that maps editor state → new editor state.

## Scopeable commands

Commands that toggle buffer-local options can declare an `option_toggle`.
When invoked from a keybinding, scopeable commands apply to the current
buffer (fast path). When invoked from the command palette, the palette
presents a scope picker ("This Buffer" / "All Buffers") so the user can
choose where the change applies.

The `option_toggle` field is either:

* an atom (e.g. `:wrap`) for boolean toggles
* a `{atom, function}` tuple (e.g. `{:line_numbers, fn :hybrid -> :absolute end}`)
  for non-boolean cycling

## Buffer requirement

Commands that only make sense with an active buffer set
`requires_buffer: true`. The dispatch layer skips these commands
(returning state unchanged) when no buffer is active.

## Example

    %Minga.Command{
      name: :save,
      description: "Save the current file",
      execute: fn state -> MingaEditor.Commands.BufferManagement.execute(state, :save) end,
      requires_buffer: true
    }

    # Scopeable toggle:
    %Minga.Command{
      name: :toggle_wrap,
      description: "Toggle word wrap",
      execute: fn state -> MingaEditor.Commands.BufferManagement.execute(state, :toggle_wrap) end,
      requires_buffer: true,
      option_toggle: :wrap
    }

# `option_toggle`

```elixir
@type option_toggle() :: atom() | {atom(), (term() -&gt; term())}
```

Descriptor for commands that toggle buffer-local options.

An atom for boolean toggles, or `{atom, function}` for custom cycling.

# `t`

```elixir
@type t() :: %Minga.Command{
  description: String.t(),
  execute: function(),
  name: atom(),
  option_toggle: option_toggle() | nil,
  requires_buffer: boolean(),
  scope: atom() | nil
}
```

An editor command struct.

* `name`            — atom identifier used for registry lookup and keymap binding
* `description`     — human-readable label shown in which-key popups
* `execute`         — function applied to the editor state, returns new state
* `requires_buffer` — when true, command is skipped if no buffer is active
* `option_toggle`   — option to toggle: atom for boolean flip, `{atom, fun}` for custom cycling
* `scope`           — keymap scope required for this command to run (e.g. `:agent`); `nil` means any scope

# `all_commands`

```elixir
@spec all_commands() :: [t()]
```

Returns all registered commands as a list.

# `compute_new_value`

```elixir
@spec compute_new_value(t(), term()) :: term()
```

Computes the new value for a scopeable command given the current value.

Atom toggles negate the boolean. Tuple toggles call the cycling function.

# `lookup`

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

Looks up a command by name. Returns `{:ok, command}` or `:error`.

# `option_name`

```elixir
@spec option_name(t()) :: atom() | nil
```

Extracts the option name from an `option_toggle` field.

# `parse`

```elixir
@spec parse(String.t()) :: Minga.Command.Parser.parsed()
```

Parses a command-line string into a structured command invocation.

# `register`

```elixir
@spec register(atom(), String.t(), (term() -&gt; term())) :: :ok
```

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

# `reset_registry`

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

Resets the registry to built-in commands (discards user/extension commands).

# `scopeable?`

```elixir
@spec scopeable?(t()) :: boolean()
```

Returns true if this command toggles a buffer-local option.

---

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