# `MingaEditor.Workspace.State`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/workspace/state.ex#L1)

Core editing context that exists regardless of presentation.

A workspace is the editing state that gets saved/restored when
switching tabs. It works identically whether rendered as a tab in
the traditional editor, a card on The Board, or running headless
without any UI.

This struct formalizes the `@per_tab_fields` boundary from
`MingaEditor.State`: every field here is snapshotted per tab and
restored on tab switch.

# `document_highlight`

```elixir
@type document_highlight() :: Minga.LSP.DocumentHighlight.t()
```

A document highlight range from the LSP server.

# `t`

```elixir
@type t() :: %MingaEditor.Workspace.State{
  agent_ui: MingaEditor.Agent.UIState.t(),
  buffers: MingaEditor.State.Buffers.t(),
  completion: Minga.Editing.Completion.t() | nil,
  completion_trigger: MingaEditor.CompletionTrigger.t(),
  document_highlights: [document_highlight()] | nil,
  editing: MingaEditor.VimState.t(),
  file_tree: MingaEditor.State.FileTree.t(),
  highlight: MingaEditor.State.Highlighting.t(),
  injection_ranges: %{
    required(pid()) =&gt; [Minga.Language.Highlight.InjectionRange.t()]
  },
  keymap_scope: Minga.Keymap.Scope.scope_name(),
  lsp_pending: %{required(reference()) =&gt; atom() | tuple()},
  mouse: MingaEditor.State.Mouse.t(),
  pending_conflict: {pid(), String.t()} | nil,
  search: MingaEditor.State.Search.t(),
  viewport: MingaEditor.Viewport.t(),
  windows: MingaEditor.State.Windows.t()
}
```

# `active_window_struct`

```elixir
@spec active_window_struct(t()) :: MingaEditor.Window.t() | nil
```

Returns the active window struct, or nil.

# `clear_completion`

```elixir
@spec clear_completion(t(), MingaEditor.CompletionTrigger.t()) :: t()
```

Clears completion and resets the trigger bridge.

# `field_names`

```elixir
@spec field_names() :: [atom()]
```

Returns the list of field names (for snapshot/restore compatibility).

# `invalidate_all_windows`

```elixir
@spec invalidate_all_windows(t()) :: t()
```

Invalidates render caches for all windows.

Call when the screen layout changes (file tree toggle, agent panel toggle)
because cached draws contain baked-in absolute coordinates that become
wrong when column offsets shift.

# `scope_for_active_window`

```elixir
@spec scope_for_active_window(t()) :: atom()
```

Returns the appropriate keymap scope for the active window's content type.

# `scope_for_content`

```elixir
@spec scope_for_content(
  MingaEditor.Window.Content.t(),
  Minga.Keymap.Scope.scope_name()
) ::
  Minga.Keymap.Scope.scope_name()
```

Derives the keymap scope from a window's content type.

Agent chat windows always use `:agent` scope. Buffer windows use
`:editor` when coming from `:agent` scope, and preserve the current
scope otherwise.

# `set_agent_ui`

```elixir
@spec set_agent_ui(t(), MingaEditor.Agent.UIState.t()) :: t()
```

Updates the agent UI state.

# `set_buffers`

```elixir
@spec set_buffers(t(), MingaEditor.State.Buffers.t()) :: t()
```

Replaces the buffers sub-struct.

# `set_completion`

```elixir
@spec set_completion(t(), Minga.Editing.Completion.t() | nil) :: t()
```

Updates the completion state.

# `set_completion_trigger`

```elixir
@spec set_completion_trigger(t(), MingaEditor.CompletionTrigger.t()) :: t()
```

Updates the completion trigger bridge.

# `set_document_highlights`

```elixir
@spec set_document_highlights(t(), [document_highlight()] | nil) :: t()
```

Updates the document highlights from LSP.

# `set_editing`

```elixir
@spec set_editing(t(), MingaEditor.VimState.t()) :: t()
```

Replaces the editing (VimState) sub-struct.

# `set_highlight`

```elixir
@spec set_highlight(t(), MingaEditor.State.Highlighting.t()) :: t()
```

Updates the highlighting sub-struct.

# `set_injection_ranges`

```elixir
@spec set_injection_ranges(t(), %{
  required(pid()) =&gt; [Minga.Language.Highlight.InjectionRange.t()]
}) ::
  t()
```

Updates the injection ranges map.

# `set_keymap_scope`

```elixir
@spec set_keymap_scope(t(), Minga.Keymap.Scope.scope_name()) :: t()
```

Sets the keymap scope.

# `set_lsp_pending`

```elixir
@spec set_lsp_pending(t(), %{required(reference()) =&gt; atom() | tuple()}) :: t()
```

Updates the LSP pending requests map.

# `set_mouse`

```elixir
@spec set_mouse(t(), MingaEditor.State.Mouse.t()) :: t()
```

Updates the mouse sub-struct.

# `set_pending_conflict`

```elixir
@spec set_pending_conflict(t(), {pid(), String.t()} | nil) :: t()
```

Sets the pending conflict state.

# `set_search`

```elixir
@spec set_search(t(), MingaEditor.State.Search.t()) :: t()
```

Updates the search sub-struct.

# `set_viewport`

```elixir
@spec set_viewport(t(), MingaEditor.Viewport.t()) :: t()
```

Sets the viewport dimensions.

# `set_windows`

```elixir
@spec set_windows(t(), MingaEditor.State.Windows.t()) :: t()
```

Replaces the windows sub-struct.

# `split?`

```elixir
@spec split?(t()) :: boolean()
```

Returns true if the workspace has more than one window.

# `switch_buffer`

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

Switches to the buffer at `idx`, making it active for the current window.

Pure workspace operation: updates Buffers and syncs the active window.

# `sync_active_window_buffer`

```elixir
@spec sync_active_window_buffer(t()) :: t()
```

Syncs the active window's buffer reference with `buffers.active`.

Call after any operation that changes `buffers.active` to keep the
window tree consistent. No-op when windows aren't initialized.

# `transition_mode`

```elixir
@spec transition_mode(t(), atom(), term()) :: t()
```

Transitions the editing model to a new mode.

# `update_editing`

```elixir
@spec update_editing(t(), (MingaEditor.VimState.t() -&gt; MingaEditor.VimState.t())) ::
  t()
```

Updates the editing (VimState) sub-struct.

# `update_highlight`

```elixir
@spec update_highlight(t(), (MingaEditor.State.Highlighting.t() -&gt;
                         MingaEditor.State.Highlighting.t())) ::
  t()
```

Updates the highlighting sub-struct via a mapper function.

# `update_search`

```elixir
@spec update_search(t(), (MingaEditor.State.Search.t() -&gt;
                      MingaEditor.State.Search.t())) :: t()
```

Updates the search sub-struct via a mapper function.

# `update_window`

```elixir
@spec update_window(t(), MingaEditor.Window.id(), (MingaEditor.Window.t() -&gt;
                                               MingaEditor.Window.t())) ::
  t()
```

Updates the window struct for the given window id via a mapper function.

---

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