# `MingaEditor.Shell.Traditional.Modeline`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/shell/traditional/modeline.ex#L1)

Doom Emacs-style modeline rendering.

Renders the colored status line at row N-2. Takes a data map and viewport
width; returns a list of draw tuples and a list of clickable regions. Has
no dependency on the GenServer or any mutable state, just a pure
`data → {draws, click_regions}` transformation.

Click regions are `{col_start, col_end, command}` tuples attached to
segments at render time, matching how Doom Emacs embeds `local-map` text
properties and Neovim embeds `%@ClickHandler@` markers. The mouse handler
looks up the command for a clicked column without reverse-engineering the
layout.

# `click_region`

```elixir
@type click_region() ::
  {col_start :: non_neg_integer(), col_end :: non_neg_integer(),
   command :: atom()}
```

A clickable region: column range mapping to a command.

# `git_diff_summary`

```elixir
@type git_diff_summary() ::
  {non_neg_integer(), non_neg_integer(), non_neg_integer()} | nil
```

Git diff summary: {added, modified, deleted} line counts.

# `lsp_status`

```elixir
@type lsp_status() :: :ready | :initializing | :starting | :error | :none
```

LSP connection status for the modeline indicator.

# `modeline_data`

```elixir
@type modeline_data() :: %{
  :mode =&gt; Minga.Mode.mode(),
  :mode_state =&gt; Minga.Mode.state() | nil,
  :file_name =&gt; String.t(),
  :filetype =&gt; atom(),
  :dirty_marker =&gt; String.t(),
  :cursor_line =&gt; non_neg_integer(),
  :cursor_col =&gt; non_neg_integer(),
  :line_count =&gt; non_neg_integer(),
  :buf_index =&gt; pos_integer(),
  :buf_count =&gt; non_neg_integer(),
  :macro_recording =&gt; {true, String.t()} | false,
  optional(:agent_status) =&gt; MingaEditor.State.Agent.status(),
  optional(:agent_theme_colors) =&gt; MingaEditor.UI.Theme.Agent.t() | nil,
  optional(:mode_override) =&gt; String.t() | nil,
  optional(:lsp_status) =&gt; lsp_status(),
  optional(:parser_status) =&gt; parser_status(),
  optional(:git_branch) =&gt; String.t() | nil,
  optional(:git_diff_summary) =&gt; git_diff_summary(),
  optional(:diagnostic_counts) =&gt;
    {non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer()}
    | nil
}
```

Data for rendering the modeline.

# `parser_status`

```elixir
@type parser_status() :: :available | :unavailable | :restarting
```

Parser availability status for the modeline indicator.

# `cursor_shape`

```elixir
@spec cursor_shape(Minga.Mode.mode() | MingaEditor.VimState.t()) ::
  MingaEditor.Frontend.Protocol.cursor_shape()
```

Returns the cursor shape for the given mode.

Accepts either a bare mode atom or the full vim state map. When the
vim state is passed, `pending: :replace` in normal mode produces
an underline cursor (matching Vim's `r` feedback).

# `render`

```elixir
@spec render(
  non_neg_integer(),
  pos_integer(),
  modeline_data(),
  MingaEditor.UI.Theme.t(),
  non_neg_integer()
) :: {[MingaEditor.DisplayList.draw()], [click_region()]}
```

Renders the modeline at the given row using the provided data.

Returns `{draw_commands, click_regions}` where click_regions is a list of
`{col_start, col_end, command_atom}` tuples for mouse hit-testing.

---

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