# `Minga.Editing.Completion.Session`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga/editing/completion/session.ex#L1)

Pure lifecycle authority for one completion interaction.

Every request, batch, selection, and resolve operation carries the stable session, provider, and item identity needed to reject late work after supersession or teardown.

# `provider_request`

```elixir
@type provider_request() :: {client :: pid(), request_ref :: reference()}
```

Provider request identity and cancellation target.

# `resolve`

```elixir
@type resolve() :: %{
  identity: resolve_identity(),
  client: pid(),
  timer: reference() | nil,
  request_ref: reference() | nil
}
```

Resolve work owned by this session.

# `resolve_identity`

```elixir
@type resolve_identity() ::
  {reference(), Minga.Editing.Completion.Item.provider_id(),
   Minga.Editing.Completion.Item.id()}
```

Stable resolve identity for one selected item.

# `selection_origin`

```elixir
@type selection_origin() :: :automatic | :user
```

Whether ranking or explicit user navigation owns the current selection.

# `t`

```elixir
@type t() :: %Minga.Editing.Completion.Session{
  batches: %{
    required(Minga.Editing.Completion.Item.provider_id()) =&gt;
      Minga.Editing.Completion.ProviderBatch.t()
  },
  buffer: pid(),
  buffer_version: non_neg_integer(),
  debounce_timer: reference() | nil,
  dismissed?: boolean(),
  generation: non_neg_integer(),
  id: reference(),
  index: Minga.Editing.Completion.Index.t(),
  previewed_item_id: Minga.Editing.Completion.Item.id() | nil,
  provider_order: [Minga.Editing.Completion.Item.provider_id()],
  provider_requests: %{
    required(Minga.Editing.Completion.Item.provider_id()) =&gt; provider_request()
  },
  resolve: resolve() | nil,
  selected_item_id: Minga.Editing.Completion.Item.id() | nil,
  selection_origin: selection_origin(),
  trigger_position: {non_neg_integer(), non_neg_integer()}
}
```

# `accept_batch`

```elixir
@spec accept_batch(t(), Minga.Editing.Completion.ProviderBatch.t()) ::
  {:ok, t()} | :stale
```

Accepts a batch only when it exactly matches the live provider request identity.

# `activate`

```elixir
@spec activate(t(), {non_neg_integer(), non_neg_integer()}) :: t()
```

Moves a debounced session into provider-request ownership.

# `begin_resolve`

```elixir
@spec begin_resolve(t(), Minga.Editing.Completion.Item.id(), pid(), reference() | nil) ::
  {:ok, t()} | :stale
```

Starts debounced resolve work for the current stable item identity.

# `clear_resolve`

```elixir
@spec clear_resolve(t()) :: {t(), provider_request() | nil, reference() | nil}
```

Clears resolve ownership and returns its cancellation target and timer.

# `continue_locally`

```elixir
@spec continue_locally(t(), non_neg_integer()) :: t()
```

Advances the session snapshot after local filtering sends no provider request.

# `current?`

```elixir
@spec current?(t(), reference(), non_neg_integer(), pid(), non_neg_integer()) ::
  boolean()
```

Returns whether a response still belongs to this exact session and buffer snapshot.

# `fail_request`

```elixir
@spec fail_request(t(), Minga.Editing.Completion.Item.provider_id(), reference()) ::
  {:ok, t()} | :stale
```

Clears one failed provider request only when its request identity is still current.

# `fail_resolve`

```elixir
@spec fail_resolve(t(), resolve_identity(), reference()) :: {:ok, t()} | :stale
```

Clears a failed resolve only when its stable identity and request ref are current.

# `find_item`

```elixir
@spec find_item(t(), Minga.Editing.Completion.Item.id()) ::
  Minga.Editing.Completion.Item.t() | nil
```

Finds one item by stable identity.

# `incomplete_providers`

```elixir
@spec incomplete_providers(t()) :: [
  {Minga.Editing.Completion.Item.provider_id(), pid()}
]
```

Returns incomplete providers that require an LSP trigger-kind-3 refresh.

# `index`

```elixir
@spec index(t()) :: Minga.Editing.Completion.Index.t()
```

Returns the provider-aware normalized index owned by this session.

# `items`

```elixir
@spec items(t()) :: [Minga.Editing.Completion.Item.t()]
```

Returns every candidate in deterministic provider and sort order.

# `new`

```elixir
@spec new(
  reference(),
  non_neg_integer(),
  pid(),
  non_neg_integer(),
  {non_neg_integer(), non_neg_integer()}
) :: t()
```

Creates a completion session around one exact buffer snapshot.

# `preview`

```elixir
@spec preview(t(), Minga.Editing.Completion.Item.id() | nil) :: t()
```

Marks a locally previewed item so teardown can clear that ownership explicitly.

# `put_debounce_timer`

```elixir
@spec put_debounce_timer(t(), reference() | nil) :: t()
```

Installs the debounce timer owned by this session.

# `register_requests`

```elixir
@spec register_requests(t(), [
  {Minga.Editing.Completion.Item.provider_id(), pid(), reference()}
]) :: t()
```

Registers one independently cancellable request per provider.

# `resolve_current?`

```elixir
@spec resolve_current?(t(), resolve_identity(), reference()) :: boolean()
```

Returns whether an exact resolve identity and request ref remain active.

# `resolve_item`

```elixir
@spec resolve_item(t(), resolve_identity(), reference(), String.t()) ::
  {:ok, t()} | :stale
```

Applies resolved documentation only to the exact live resolve identity and request.

# `retrigger`

```elixir
@spec retrigger(t(), non_neg_integer(), non_neg_integer(), [
  {Minga.Editing.Completion.Item.provider_id(), pid(), reference()}
]) :: t()
```

Advances an existing session for trigger-kind-3 requests while retaining complete batches.

# `retrigger_providers`

```elixir
@spec retrigger_providers(t()) :: [
  {Minga.Editing.Completion.Item.provider_id(), pid()}
]
```

Returns providers whose incomplete batch or pending request must refresh after input.

# `select`

```elixir
@spec select(t(), Minga.Editing.Completion.Item.id() | nil) :: t()
```

Records an explicit user selection by stable identity. Unknown or stale identities are ignored.

# `teardown`

```elixir
@spec teardown(t()) :: {t(), [provider_request()], [reference()]}
```

Returns cancellation targets and timers while clearing every owned lifecycle value.

# `track_resolve`

```elixir
@spec track_resolve(t(), resolve_identity(), reference()) :: {:ok, t()} | :stale
```

Records the independently cancellable request ref for the active resolve.

---

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