Ordered list of open tabs with an active tab pointer.
The tab bar is the primary navigation structure. Each tab (file or agent) carries a context snapshot of per-tab editor state. Buffer processes live in a shared pool, not inside individual tabs.
Invariants
- There is always at least one tab.
active_idalways refers to an existing tab.- Tab ids are unique and monotonically increasing.
Summary
Functions
Returns the active tab.
Returns the index of the active tab (0-based).
Returns the active workspace.
Returns the active workspace id, derived from the active tab.
Adds a new tab after the active tab and makes it active.
Adds an agent workspace and returns {updated_tab_bar, workspace}.
Returns true if any tab has its attention flag set.
Returns the number of tabs.
Returns the progressive disclosure tier (0-3) based on agent workspace count.
Drops snapshotted extension-owned feature state from every tab context.
Drops snapshotted feature state owned by a source from every tab context.
Returns all tabs matching the given kind.
Returns the first tab matching the given kind, or nil.
Returns the remote agent tab for a server/session id pair.
Returns the agent tab whose session matches the given pid, or nil.
Finds the file tab in a workspace that represents the given file reference.
Returns an agent tab that has no session assigned, or nil.
Returns the workspace matching a remote server/session id pair.
Returns the workspace matching the given session pid, or nil.
Returns the tab with the given id, or nil.
Returns the workspace with the given id, or nil.
Returns true if any agent workspaces exist.
Returns true if a tab with the given id exists.
Inserts a new tab next to the active tab without switching to it.
Keeps only the tab with the given id. Returns unchanged when the tab is not present.
Returns the most recently used tab of the given kind that is NOT the active tab. Useful for "switch back to previous file/agent" commands.
Moves the active tab one visible slot left within its workspace.
Moves the active tab one visible slot right within its workspace.
Moves the tab with the given id one visible slot left within its workspace.
Moves the tab with the given id one visible slot right within its workspace.
Moves a tab to a different workspace.
Creates a tab bar with a single initial tab and the manual workspace.
Switches to the next visible file tab in the active workspace, wrapping around.
Switches to the next agent workspace, wrapping around. No-op if no agent workspaces exist.
Cycles to the next tab of the given kind, wrapping around. If the active tab is already of that kind, jumps to the next one. If the active tab is a different kind, jumps to the first of the requested kind. Returns unchanged if no tabs of that kind exist.
Pins the tab with the given id. Returns unchanged when the tab is missing.
Switches to the previous visible file tab in the active workspace, wrapping around.
Switches to the previous agent workspace, wrapping around. No-op if no agent workspaces exist.
Returns remote workspaces for a server.
Removes the tab with the given id.
Removes a workspace and migrates its tabs to the manual workspace (group_id 0).
Reorders a visible file tab within its workspace by zero-based visible index.
Replaces restored workspaces and recalculates the next workspace id.
Removes a dead buffer pid from all tab context snapshots.
Sets the attention flag on the tab matching the given session pid.
Updates all workspaces and projected tabs for a remote server to the given connection status.
Switches the active tab to the one with the given id.
Switches to the given workspace by activating its first tab.
Synchronizes any agent-tab projection from workspace-owned lifecycle and remote metadata.
Returns the tab at the given 1-based position index, or nil.
Returns all tabs belonging to the given workspace.
Toggles the pinned state of the active tab.
Unpins the tab with the given id. Returns unchanged when the tab is missing.
Updates the context of the tab with the given id.
Updates the label of the tab with the given id.
Applies fun to the tab with id, replacing it in the list.
Updates a workspace by applying fun to it.
Returns visible file tabs for the active workspace.
Returns visible file tabs for the given workspace id. Agent chat tabs are excluded.
Types
@type t() :: %MingaEditor.State.TabBar{ active_id: MingaEditor.State.Tab.id(), next_id: MingaEditor.State.Tab.id(), next_workspace_id: pos_integer(), tabs: [MingaEditor.State.Tab.t()], workspaces: [MingaEditor.State.Workspace.t()] }
Tab bar state.
Functions
@spec active(t()) :: MingaEditor.State.Tab.t() | nil
Returns the active tab.
@spec active_index(t()) :: non_neg_integer()
Returns the index of the active tab (0-based).
@spec active_workspace(t()) :: MingaEditor.State.Workspace.t() | nil
Returns the active workspace.
Derived from the active tab's group_id, not stored separately. The active workspace is always the workspace of the tab you're looking at.
@spec active_workspace_id(t()) :: non_neg_integer()
Returns the active workspace id, derived from the active tab.
@spec add(t(), MingaEditor.State.Tab.kind(), String.t()) :: {t(), MingaEditor.State.Tab.t()}
Adds a new tab after the active tab and makes it active.
Returns {updated_tab_bar, new_tab} so the caller can use the tab's id.
@spec add_workspace(t(), String.t(), pid() | nil) :: {t(), MingaEditor.State.Workspace.t()}
Adds an agent workspace and returns {updated_tab_bar, workspace}.
The workspace is appended to the workspaces list. The session pid
is stored so we can track which agent owns the workspace.
Returns true if any tab has its attention flag set.
@spec count(t()) :: pos_integer()
Returns the number of tabs.
@spec disclosure_tier(t()) :: 0 | 1 | 2 | 3
Returns the progressive disclosure tier (0-3) based on agent workspace count.
Drops snapshotted extension-owned feature state from every tab context.
@spec drop_feature_state_source(t(), MingaEditor.FeatureState.source()) :: t()
Drops snapshotted feature state owned by a source from every tab context.
@spec filter_by_kind(t(), MingaEditor.State.Tab.kind()) :: [MingaEditor.State.Tab.t()]
Returns all tabs matching the given kind.
@spec find_by_kind(t(), MingaEditor.State.Tab.kind()) :: MingaEditor.State.Tab.t() | nil
Returns the first tab matching the given kind, or nil.
@spec find_by_remote_session(t(), String.t(), String.t()) :: MingaEditor.State.Tab.t() | nil
Returns the remote agent tab for a server/session id pair.
@spec find_by_session(t(), pid()) :: MingaEditor.State.Tab.t() | nil
Returns the agent tab whose session matches the given pid, or nil.
@spec find_file_tab_in_workspace(t(), non_neg_integer(), Minga.FileRef.t()) :: MingaEditor.State.Tab.t() | nil
Finds the file tab in a workspace that represents the given file reference.
@spec find_sessionless_agent(t()) :: MingaEditor.State.Tab.t() | nil
Returns an agent tab that has no session assigned, or nil.
Used by start_agent_session to find the correct tab to bind a
new session to, avoiding ambiguity when multiple agent tabs exist.
Falls back to the active tab if it's an agent tab.
@spec find_workspace_by_remote_session(t(), String.t(), String.t()) :: MingaEditor.State.Workspace.t() | nil
Returns the workspace matching a remote server/session id pair.
@spec find_workspace_by_session(t(), pid()) :: MingaEditor.State.Workspace.t() | nil
Returns the workspace matching the given session pid, or nil.
@spec get(t(), MingaEditor.State.Tab.id()) :: MingaEditor.State.Tab.t() | nil
Returns the tab with the given id, or nil.
@spec get_workspace(t(), non_neg_integer()) :: MingaEditor.State.Workspace.t() | nil
Returns the workspace with the given id, or nil.
Returns true if any agent workspaces exist.
@spec has_tab?(t(), MingaEditor.State.Tab.id()) :: boolean()
Returns true if a tab with the given id exists.
@spec insert(t(), MingaEditor.State.Tab.kind(), String.t()) :: {t(), MingaEditor.State.Tab.t()}
Inserts a new tab next to the active tab without switching to it.
Returns {updated_tab_bar, new_tab}. The caller is responsible for
calling switch_to/2 or EditorState.switch_tab/2 to activate it.
This is the primitive that add/3 and EditorState.add_buffer/2 build on.
@spec keep_only(t(), MingaEditor.State.Tab.id()) :: t()
Keeps only the tab with the given id. Returns unchanged when the tab is not present.
@spec most_recent_of_kind(t(), MingaEditor.State.Tab.kind()) :: MingaEditor.State.Tab.t() | nil
Returns the most recently used tab of the given kind that is NOT the active tab. Useful for "switch back to previous file/agent" commands.
Tabs are searched right-to-left from the active position (wrapping), so the nearest neighbor of the requested kind is returned.
Moves the active tab one visible slot left within its workspace.
Moves the active tab one visible slot right within its workspace.
@spec move_tab_left(t(), MingaEditor.State.Tab.id()) :: t()
Moves the tab with the given id one visible slot left within its workspace.
@spec move_tab_right(t(), MingaEditor.State.Tab.id()) :: t()
Moves the tab with the given id one visible slot right within its workspace.
@spec move_tab_to_workspace(t(), MingaEditor.State.Tab.id(), non_neg_integer()) :: t()
Moves a tab to a different workspace.
@spec new(MingaEditor.State.Tab.t(), String.t() | nil) :: t()
Creates a tab bar with a single initial tab and the manual workspace.
Switches to the next visible file tab in the active workspace, wrapping around.
Switches to the next agent workspace, wrapping around. No-op if no agent workspaces exist.
@spec next_of_kind(t(), MingaEditor.State.Tab.kind()) :: t()
Cycles to the next tab of the given kind, wrapping around. If the active tab is already of that kind, jumps to the next one. If the active tab is a different kind, jumps to the first of the requested kind. Returns unchanged if no tabs of that kind exist.
@spec pin_tab(t(), MingaEditor.State.Tab.id()) :: t()
Pins the tab with the given id. Returns unchanged when the tab is missing.
Switches to the previous visible file tab in the active workspace, wrapping around.
Switches to the previous agent workspace, wrapping around. No-op if no agent workspaces exist.
@spec remote_workspaces_for_server(t(), String.t()) :: [ MingaEditor.State.Workspace.t() ]
Returns remote workspaces for a server.
@spec remove(t(), MingaEditor.State.Tab.id()) :: {:ok, t()} | :last_tab
Removes the tab with the given id.
If the removed tab was active, switches to the nearest neighbor (prefer
right, then left). Returns {:ok, updated_tab_bar} or :last_tab if
this is the only tab (can't remove the last one).
@spec remove_workspace(t(), non_neg_integer()) :: t()
Removes a workspace and migrates its tabs to the manual workspace (group_id 0).
Cannot remove the manual workspace.
@spec reorder_tab(t(), MingaEditor.State.Tab.id(), non_neg_integer()) :: t()
Reorders a visible file tab within its workspace by zero-based visible index.
@spec restore_workspaces(t(), [MingaEditor.State.Workspace.t()], String.t() | nil) :: t()
Replaces restored workspaces and recalculates the next workspace id.
Removes a dead buffer pid from all tab context snapshots.
Sets the attention flag on the tab matching the given session pid.
@spec set_remote_connection_status( t(), String.t(), MingaEditor.State.Tab.connection_status() ) :: t()
Updates all workspaces and projected tabs for a remote server to the given connection status.
@spec switch_to(t(), MingaEditor.State.Tab.id()) :: t()
Switches the active tab to the one with the given id.
@spec switch_to_workspace(t(), non_neg_integer()) :: t()
Switches to the given workspace by activating its first tab.
Returns unchanged if the workspace doesn't exist or has no tabs.
@spec sync_workspace_agent_tab_projection(t(), non_neg_integer()) :: t()
@spec sync_workspace_agent_tab_projection(t(), MingaEditor.State.Workspace.t()) :: t()
Synchronizes any agent-tab projection from workspace-owned lifecycle and remote metadata.
@spec tab_at(t(), pos_integer()) :: MingaEditor.State.Tab.t() | nil
Returns the tab at the given 1-based position index, or nil.
@spec tabs_in_workspace(t(), non_neg_integer()) :: [MingaEditor.State.Tab.t()]
Returns all tabs belonging to the given workspace.
Toggles the pinned state of the active tab.
@spec unpin_tab(t(), MingaEditor.State.Tab.id()) :: t()
Unpins the tab with the given id. Returns unchanged when the tab is missing.
@spec update_context( t(), MingaEditor.State.Tab.id(), MingaEditor.State.Tab.context() | MingaEditor.State.Tab.legacy_context() ) :: t()
Updates the context of the tab with the given id.
@spec update_label(t(), MingaEditor.State.Tab.id(), String.t()) :: t()
Updates the label of the tab with the given id.
@spec update_tab(t(), MingaEditor.State.Tab.id(), (MingaEditor.State.Tab.t() -> MingaEditor.State.Tab.t())) :: t()
Applies fun to the tab with id, replacing it in the list.
Returns the updated tab bar. If no tab matches, returns unchanged.
@spec update_workspace(t(), non_neg_integer(), (MingaEditor.State.Workspace.t() -> MingaEditor.State.Workspace.t())) :: t()
Updates a workspace by applying fun to it.
Returns unchanged tab bar if no workspace matches.
@spec visible_file_tabs(t()) :: [MingaEditor.State.Tab.t()]
Returns visible file tabs for the active workspace.
@spec visible_file_tabs(t(), non_neg_integer()) :: [MingaEditor.State.Tab.t()]
Returns visible file tabs for the given workspace id. Agent chat tabs are excluded.