Skip to main content

SidebarState

Struct SidebarState 

Source
pub struct SidebarState {
    pub open: bool,
    pub position: SidebarPosition,
    pub orientation: SidebarOrientation,
    pub focused: bool,
    pub scroll: u16,
    pub max_scroll: u16,
    pub cache: Option<((PathBuf, SidebarMode), SidebarSections)>,
    pub mode: SidebarMode,
}
Expand description

Pure sidebar state. Use Self::new (or the Default impl below) to get the initial state that matches the previous App::new_at behaviour (open + unfocused + zero scroll + cold cache) — the #[derive(Default)] Copilot would normally synthesise here would set open = false, which contradicts both the doc above and new(). The hand-written Default keeps the contract single-sourced.

Fields§

§open: bool

true when the sidebar is visible. On a narrow terminal the renderer no longer hides it (pre-#188 behaviour) but stacks it under the table instead — see Self::resolve_layout. Closing the panel (open = false) is the only way to reclaim the full width for the table.

§position: SidebarPosition

Which side the sidebar sits on in the side-by-side layout (issue #188). Seeded from [tui] sidebar_position at App construction, toggled live by Self::toggle_position (H). Ignored by the stacked layout (sidebar always at the bottom).

§orientation: SidebarOrientation

How the sidebar is arranged relative to the table (issue #188). Defaults to SidebarOrientation::Auto (width-driven); cycled by Self::cycle_orientation (V). Runtime-only — not persisted to .gwm.toml, unlike position.

§focused: bool

true when keyboard navigation (j / k) targets the sidebar (scrolling Recent Commits) instead of the worktree list. Invariant: focused is false whenever open is false.

§scroll: u16

First-visible line index of the Recent Commits section. Bumped by Self::scroll_down / Self::scroll_up; reset to 0 by Self::on_navigation.

§max_scroll: u16

Upper bound for scroll, republished by the renderer every frame against the actual rendered Recent Commits height. Used by Self::scroll_down to clamp so the panel content can never be pushed entirely off-screen.

§cache: Option<((PathBuf, SidebarMode), SidebarSections)>

Cached pre-rendered sections keyed by the selected worktree’s path and the active mode (issue #34). None = cold cache (the renderer will rebuild and store). Invalidated on selection change (Self::on_navigation), worktree list mutation (App::refresh calls Self::invalidate), filter narrowing (App::filter_push_char / filter_pop_char), and mode toggle (Self::cycle_mode). Two-tuple key so a re-toggle re-shells git stash list / git log rather than serving stale content for the other mode.

§mode: SidebarMode

Active preview mode. Defaults to SidebarMode::Commits so the pre-#34 sidebar behaviour is unchanged until the user presses s. Toggled by Self::cycle_mode.

Implementations§

Source§

impl SidebarState

Source

pub fn new() -> Self

Source

pub fn resolve_layout(&self, width: u16) -> ResolvedSidebarLayout

Resolve the concrete layout for a frame of width columns from the current visibility, orientation, and position. Pure and ratatui-free so the width contract is unit-testable:

  • closed → ResolvedSidebarLayout::Hidden;
  • Auto → side-by-side at width >= SIDEBAR_MIN_WIDTH, else stacked;
  • SideBySide / Stacked → that layout regardless of width.

In a side-by-side result sidebar_left mirrors Self::position.

Source

pub fn cycle_orientation(&mut self)

Cycle the orientation Auto → SideBySide → Stacked → Auto (issue #188, V). The cache survives — orientation changes the frame geometry, not the previewed git content.

Source

pub fn toggle_position(&mut self)

Flip the side-by-side position left ↔ right (issue #188, H). The cache survives for the same reason as Self::cycle_orientation.

Source

pub fn cycle_mode(&mut self)

Cycle the preview mode (issue #34). Pre-#34 the sidebar only ever showed git log + git status; now s flips between Commits and Stashes. The scroll offset resets to 0 because the new content has its own length and the previous offset becomes meaningless. The cache is invalidated because the key (path + mode) changes — the new mode re-shells the right git command on the next frame.

Source

pub fn on_navigation(&mut self)

Navigation-driven reset: drop the scroll back to the top AND invalidate the cache so the new selection’s preview renders fresh. Paired with App::refresh_link() inside App::on_navigation to collapse the pre-extraction sidebar_scroll = 0; invalidate_sidebar_cache(); refresh_link(); triple that the App body repeated 4+ times across next / prev / first / last.

Deliberately does NOT touch open, focused, or max_scroll: navigation moves selection within the existing layout; visibility is a separate concern owned by the toggle methods, and max_scroll is owned by the renderer (a stale value resets itself on the next frame anyway).

Source

pub fn invalidate(&mut self)

Standalone cache flush. Used outside the navigation path — App::refresh after the worktrees list mutates, and the filter push_char / pop_char wrappers that re-narrow the visible set without moving the cursor. Scroll state survives so a user scrolled halfway through the preview keeps their viewport.

Source

pub fn scroll_down(&mut self)

Scroll the Recent Commits viewport down by one line, clamped at max_scroll. The clamp is the load-bearing invariant — without it, j on a focused sidebar would walk the content entirely off the bottom of the panel.

Source

pub fn scroll_up(&mut self)

Scroll the Recent Commits viewport up by one line, saturating at 0. Matches k-on-sidebar; safe to call from scroll == 0.

Source

pub fn toggle_open(&mut self)

Flip open. When closing, also drops focused — a hidden sidebar can never hold the navigation focus, so the worktree list takes back j / k automatically. Status-bar copy is the App orchestrator’s concern.

Source

pub fn toggle_focus(&mut self)

Flip focused. No-op when the sidebar is closed — focus cannot move to a hidden panel. Matches the Tab keybinding semantics.

Source

pub fn focus_table(&mut self)

Direct-focus the worktree table (issue #217, 1). Releases the sidebar’s navigation focus so j / k walk the worktree list. The sidebar stays open — 1 is about where the cursor is, not visibility (that’s v / Self::toggle_open).

Source

pub fn focus_panel(&mut self)

Direct-focus the status (sidebar) pane (issue #217, 2). Opens the sidebar if it was closed and moves the navigation focus onto it, so a single keystroke both reveals and targets the pane.

Trait Implementations§

Source§

impl Debug for SidebarState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for SidebarState

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.