# `Minga.Core.PositionEncoding`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga/core/position_encoding.ex#L1)

Converts between byte-indexed positions and external text position encodings.

Minga stores positions as `{line, byte_col}` where `byte_col` is a byte offset within the line. Some external protocols, including LSP, use UTF-16 or UTF-32 character offsets instead. This module keeps that conversion pure so Layer 0 data structures can translate ranges without depending on stateful LSP services.

# `encoding`

```elixir
@type encoding() :: :utf8 | :utf16 | :utf32
```

An external offset encoding for character positions.

# `position`

```elixir
@type position() :: {line :: non_neg_integer(), col :: non_neg_integer()}
```

A zero-indexed line and byte-column position.

# `client_supported_encodings`

```elixir
@spec client_supported_encodings() :: [String.t()]
```

Returns the supported encoding strings in client preference order.

# `from_lsp`

```elixir
@spec from_lsp(map(), String.t(), encoding()) :: position()
```

Converts an external position map back to a byte-column position.

# `negotiate`

```elixir
@spec negotiate([String.t()]) :: encoding()
```

Negotiates the best offset encoding from a supported list.

Prefers UTF-8, then UTF-16, then UTF-32. Falls back to UTF-16 when the server or external source does not advertise support.

# `to_lsp`

```elixir
@spec to_lsp(position(), String.t(), encoding()) :: map()
```

Converts a byte-column position to an external position map.

---

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