A window is a viewport into a buffer.
Each window holds a reference to a buffer process and its own independent viewport (scroll position and dimensions). Multiple windows can reference the same buffer; edits in one are visible in all.
render_cache contains only bounded input-domain observations. Durable
render state is owned by MingaEditor.Renderer.State.
Summary
Functions
Returns the editor-owned authoritative-scroll request counter (#2652).
Folds all available ranges.
Folds the range containing the given buffer line.
Folds the outermost range containing the given buffer line and every nested range.
Returns true if this window has any active folds.
Records that an authoritative BEAM-initiated viewport jump must discard any frontend-held local scroll offset, even if the committed top is unchanged (#2652).
Records the committed viewport top of a frontend-reported free-scroll (#2661).
Creates a new window with the given id, buffer, and viewport dimensions.
Creates a new window with the given id, buffer, viewport dimensions, and cursor position.
Creates a new semantic agent chat window.
Creates a new window showing the zero-buffers launchpad surface (#2689).
Finds the next textobject position of the given type after (row, col).
Commits bounded viewport/cursor input metadata from a synchronous render.
Returns true if this window is a popup (has popup metadata attached).
Finds the previous textobject position of the given type before (row, col).
Records a wheel/trackpad scroll event so the render pipeline can tell a scroll gesture is in progress.
Remembers the buffer cursor last observed while this window was active.
Updates the viewport dimensions for this window, marking all lines dirty.
Scrolls the window horizontally by display columns.
Scrolls the window's viewport by delta lines and updates pinned state.
Sets the window cursor.
Updates the document symbols available for this window.
Updates the available fold ranges (from a provider). Preserves existing folds that still exist in the new ranges.
Sets whether the window should stay pinned to the bottom while content streams.
Updates textobject positions available for this window.
Stores the computed viewport for this window.
Switches the window from the launchpad back to a buffer.
Switches the window to the zero-buffers launchpad surface (#2689).
Toggles the fold at the given buffer line using the window's available fold ranges.
Unfolds all folds.
Unfolds the range containing the given buffer line.
Unfolds any folds that contain the given lines (used by search auto-unfold).
Unfolds every active fold inside the outermost range containing the given buffer line.
Types
@type id() :: pos_integer()
Unique identifier for a window.
@type t() :: %MingaEditor.Window{ authoritative_scroll_seq: non_neg_integer(), content: MingaEditor.Window.Content.t(), cursor: Minga.Buffer.position(), document_symbols: [Minga.Language.Symbol.t()], fold_map: MingaEditor.FoldMap.t(), fold_ranges: [Minga.Editing.Fold.Range.t()], id: id(), pinned: boolean(), popup_meta: MingaEditor.UI.Popup.Active.t() | nil, render_cache: MingaEditor.Window.RenderCache.t(), scroll_detach_cursor: Minga.Buffer.position() | nil, scroll_echo_top: integer() | nil, scroll_velocity: MingaEditor.Window.ScrollVelocity.t(), textobject_positions: %{ required(atom()) => [{non_neg_integer(), non_neg_integer()}] }, viewport: MingaEditor.Viewport.t() }
Functions
@spec authoritative_scroll_seq(t()) :: non_neg_integer()
Returns the editor-owned authoritative-scroll request counter (#2652).
Folds all available ranges.
@spec fold_at(t(), non_neg_integer()) :: t()
Folds the range containing the given buffer line.
@spec fold_recursive_at(t(), non_neg_integer()) :: t()
Folds the outermost range containing the given buffer line and every nested range.
Returns true if this window has any active folds.
Records that an authoritative BEAM-initiated viewport jump must discard any frontend-held local scroll offset, even if the committed top is unchanged (#2652).
Command handlers call this on the live window (editor process): at dispatch
for the always-authoritative viewport commands, and from the success branches
of failable jumps (search hits, mark jumps, bracket match, LSP goto). The
MingaEditor.Commands @authoritative_scroll_commands comment documents the
policy and is the source of truth for the command set.
It is an editor-owned, top-level Window field (never in the render cache), a
monotonic request counter incremented once per authoritative jump. Like
scroll_echo_top, only the editor writes it, on the live window, so the async
render writeback (which copies back only the render cache) cannot clobber it.
settle_scroll_seq/1 consumes it: the render cache remembers the last request
count it settled against and advances scroll_seq whenever this counter moved
past that baseline. Because the baseline (in the render cache) is overwritten to
the observed counter every settle rather than the counter being cleared here, a
single increment produces exactly one bump per rendered lineage and cannot latch
(see MingaEditor.Window.RenderCache.settle_scroll_seq/4). This closes the
same-top gap that the settle-time top comparison alone cannot see (a zz while
already centered, a search hit already on screen).
Records the committed viewport top of a frontend-reported free-scroll (#2661).
Set by the mouse-wheel/trackpad input path to the top it just committed. It is
an editor-owned, top-level Window field (never in the render cache) so the
async render writeback cannot clobber a newer value: only the input path ever
writes it, on the live window. It is deliberately sticky — never cleared. A
later wheel overwrites it; settle_scroll_seq/1 treats a viewport top equal to
this value as an echo of the frontend's own report, so it does not advance
scroll_seq (the "echo-loop guard": no re-anchor storm during a wheel/trackpad scroll gesture).
@spec new(id(), pid(), pos_integer(), pos_integer()) :: t()
Creates a new window with the given id, buffer, and viewport dimensions.
@spec new(id(), pid(), pos_integer(), pos_integer(), Minga.Buffer.position()) :: t()
Creates a new window with the given id, buffer, viewport dimensions, and cursor position.
@spec new_agent_chat(id(), pos_integer(), pos_integer()) :: t()
Creates a new semantic agent chat window.
@spec new_empty_state(id(), pos_integer(), pos_integer()) :: t()
Creates a new window showing the zero-buffers launchpad surface (#2689).
@spec next_textobject(t(), atom(), {non_neg_integer(), non_neg_integer()}) :: {non_neg_integer(), non_neg_integer()} | nil
Finds the next textobject position of the given type after (row, col).
@spec observe_render(t(), MingaEditor.Viewport.t(), non_neg_integer()) :: t()
Commits bounded viewport/cursor input metadata from a synchronous render.
Returns true if this window is a popup (has popup metadata attached).
@spec prev_textobject(t(), atom(), {non_neg_integer(), non_neg_integer()}) :: {non_neg_integer(), non_neg_integer()} | nil
Finds the previous textobject position of the given type before (row, col).
@spec record_scroll_event(t(), integer(), Minga.Buffer.position()) :: t()
Records a wheel/trackpad scroll event so the render pipeline can tell a scroll gesture is in progress.
Advances the scroll-rate estimator (scroll_follow_cursor?/3 reads its tier to
suppress cursor re-anchoring mid-gesture) and marks scroll_detach_cursor at
the cursor position at gesture start, so the viewport stays put until the cursor
actually moves.
@spec remember_cursor(t(), Minga.Buffer.position()) :: t()
Remembers the buffer cursor last observed while this window was active.
@spec resize(t(), non_neg_integer(), non_neg_integer()) :: t()
Updates the viewport dimensions for this window, marking all lines dirty.
@spec scroll_follow_cursor?(t(), Minga.Buffer.position(), integer()) :: {t(), boolean()}
Scrolls the window horizontally by display columns.
@spec scroll_velocity_tier(t(), integer()) :: MingaEditor.Window.ScrollVelocity.tier()
@spec scroll_viewport(t(), integer(), non_neg_integer()) :: t()
Scrolls the window's viewport by delta lines and updates pinned state.
Scrolling up always unpins. Scrolling down re-pins only when the viewport
reaches the bottom. total_lines is the buffer's line count.
Returns the updated window.
@spec set_cursor(t(), Minga.Buffer.position()) :: t()
Sets the window cursor.
@spec set_document_symbols(t(), [Minga.Language.Symbol.t()]) :: t()
Updates the document symbols available for this window.
@spec set_fold_ranges(t(), [Minga.Editing.Fold.Range.t()]) :: t()
Updates the available fold ranges (from a provider). Preserves existing folds that still exist in the new ranges.
Sets whether the window should stay pinned to the bottom while content streams.
Updates textobject positions available for this window.
@spec set_viewport(t(), MingaEditor.Viewport.t()) :: t()
Stores the computed viewport for this window.
Switches the window from the launchpad back to a buffer.
Switches the window to the zero-buffers launchpad surface (#2689).
The window stays open (the window tree never drops its last leaf); only its content changes, mirroring how agent chat panes host non-buffer content. Any cached buffer rendering is invalidated.
@spec toggle_fold(t(), non_neg_integer()) :: t()
Toggles the fold at the given buffer line using the window's available fold ranges.
Unfolds all folds.
@spec unfold_at(t(), non_neg_integer()) :: t()
Unfolds the range containing the given buffer line.
@spec unfold_containing(t(), [non_neg_integer()]) :: t()
Unfolds any folds that contain the given lines (used by search auto-unfold).
@spec unfold_recursive_at(t(), non_neg_integer()) :: t()
Unfolds every active fold inside the outermost range containing the given buffer line.