MingaEditor.State.Launchpad (Minga v0.1.0)

Copy Markdown View Source

State for the zero-buffers launchpad surface (#2689).

Created when the workspace enters the empty state (last buffer closed or no-file startup) and cleared when any buffer opens. Session and recents data are snapshotted once at entry so the render builder stays pure and frame builds never touch the filesystem.

This module owns focus movement; activation semantics live in the commands layer so both frontends behave identically.

Summary

Functions

Disarms a pending gg chord.

Sets focus to a specific item id when it exists.

Ordered focusable item ids: resume, recents, then actions.

Moves focus by one step or to an edge.

Builds launchpad state by snapshotting session and recent-file data.

Handles a g keypress for the gg go-to-first chord.

The id for the recent file at 1-based position i.

The recent-file path for an item id, or nil.

The resume item id.

Types

t()

@type t() :: %MingaEditor.State.Launchpad{
  crashed?: boolean(),
  focused_id: String.t() | nil,
  pending_g?: boolean(),
  recents: [String.t()],
  session_file_count: non_neg_integer()
}

Functions

clear_pending_g(lp)

@spec clear_pending_g(t()) :: t()

Disarms a pending gg chord.

focus(lp, id)

@spec focus(t(), String.t()) :: t()

Sets focus to a specific item id when it exists.

item_ids(lp)

@spec item_ids(t()) :: [String.t()]

Ordered focusable item ids: resume, recents, then actions.

On a first run (no session, no recents) the tutorial is promoted to the front: it renders as the "Get started" hero card with a RET chip, so it must also hold the initial focus for Enter-on-launch to honor that chip.

move_focus(lp, direction)

@spec move_focus(t(), :next | :prev | :first | :last) :: t()

Moves focus by one step or to an edge.

new(opts \\ [])

@spec new(keyword()) :: t()

Builds launchpad state by snapshotting session and recent-file data.

:session_dir scopes the session read (threaded from the editor's session options so tests stay hermetic). :session_file_count, :crashed?, and :recents override the reads entirely for tests.

press_g(lp)

@spec press_g(t()) :: t()

Handles a g keypress for the gg go-to-first chord.

The first g arms the pending state; the second moves focus to the first item. Any other key must call clear_pending_g/1.

recent_id(i)

@spec recent_id(pos_integer()) :: String.t()

The id for the recent file at 1-based position i.

recent_path(launchpad, arg2)

@spec recent_path(t(), String.t()) :: String.t() | nil

The recent-file path for an item id, or nil.

resume_id()

@spec resume_id() :: String.t()

The resume item id.