# `MingaEditor.FoldMap.VisibleLines`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/fold_map/visible_lines.ex#L1)

Computes the mapping from screen rows to buffer lines for a fold-aware
viewport.

Given a fold map, the first visible buffer line, and the number of
screen rows, produces a list describing what to render at each row.
The content stage uses this to skip folded lines and show fold summaries.

# `line_entry`

```elixir
@type line_entry() :: {non_neg_integer(), :normal | {:fold_start, pos_integer()}}
```

What to render at a screen row.

- `{buf_line, :normal}` — render the buffer line normally
- `{buf_line, {:fold_start, hidden_count}}` — render the buffer line
  with a fold summary suffix showing how many lines are hidden

# `buffer_range`

```elixir
@spec buffer_range([line_entry()]) :: {non_neg_integer(), non_neg_integer()} | nil
```

Returns the buffer line range needed to fetch all visible lines.

This is used to request the right slice from the buffer. Returns
`{first_buf_line, last_buf_line}` (inclusive). The caller should
fetch lines from first to last and index into them.

# `compute`

```elixir
@spec compute(
  MingaEditor.FoldMap.t(),
  non_neg_integer(),
  pos_integer(),
  non_neg_integer()
) ::
  [line_entry()] | nil
```

Computes the list of visible line entries for a viewport.

`first_buf_line` is the first buffer line to show (typically from
viewport scrolling). `visible_rows` is the number of screen rows.
`total_lines` is the total line count in the buffer.

Returns a list of `line_entry()` tuples, one per screen row (up to
`visible_rows`). Folded regions are skipped; fold start lines include
the hidden count.

When the fold map is empty, returns nil to signal the caller to use
the existing (faster) sequential path.

---

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