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

ETS-backed registry of popup rules.

Rules are stored in a named ETS table and looked up when a buffer is
opened. The registry is ordered by priority (higher priority wins) and
insertion order as tiebreaker (later registrations win).

The table uses `read_concurrency: true` because rule lookups happen on
every buffer open, while registrations only happen at startup and when
the user reloads config.

Every public function has a default-arg version that uses the global
`@table` and an explicit-table version for tests that create private
instances. This follows the same pattern as `Minga.Config.Advice`.

## Usage

    Minga.Popup.Registry.register(Minga.Popup.Rule.new("*Warnings*", side: :bottom))
    Minga.Popup.Registry.match("*Warnings*")
    #=> {:ok, %Popup.Rule{pattern: "*Warnings*", ...}}

    Popup.Registry.match("*Messages*")
    #=> :none

## Test usage (private instance)

    table = Minga.Popup.Registry.init(:test_popup_registry)
    Minga.Popup.Registry.register(rule, table)
    assert {:ok, _} = Minga.Popup.Registry.match("*Warnings*", table)

# `clear`

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

Removes all registered rules. Used during config reload.

# `clear`

```elixir
@spec clear(atom()) :: :ok
```

# `init`

```elixir
@spec init() :: atom()
```

Creates the ETS table. Called once during application startup.

Accepts an optional table name for testing. Returns the table name.
Safe to call multiple times; returns the existing table if it exists.

# `init`

```elixir
@spec init(atom()) :: atom()
```

# `list`

```elixir
@spec list() :: [Minga.Popup.Rule.t()]
```

Returns all registered rules, ordered by priority (highest first).

# `list`

```elixir
@spec list(atom()) :: [Minga.Popup.Rule.t()]
```

# `match`

```elixir
@spec match(String.t()) :: {:ok, Minga.Popup.Rule.t()} | :none
```

Finds the highest-priority rule matching the given buffer name.

Walks rules in priority order (highest first, with later registrations
winning ties at the same priority). Returns `{:ok, rule}` for the first
match, or `:none` if no rule matches.

# `match`

```elixir
@spec match(String.t(), atom()) :: {:ok, Minga.Popup.Rule.t()} | :none
```

# `register`

```elixir
@spec register(Minga.Popup.Rule.t()) :: :ok
```

Registers a popup rule.

If a rule with the same pattern already exists, it is replaced. The key
is `{-priority, sequence}` so that higher priority rules sort first, with
later registrations winning ties.

# `register`

```elixir
@spec register(Minga.Popup.Rule.t(), atom()) :: :ok
```

# `unregister`

```elixir
@spec unregister(Regex.t() | String.t()) :: :ok
```

Removes all rules matching the given pattern.

Used when user config overrides a built-in rule: the old rule is
cleared before the new one is registered.

# `unregister`

```elixir
@spec unregister(Regex.t() | String.t(), atom()) :: :ok
```

---

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