tui

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 21, 2026 License: Apache-2.0 Imports: 32 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContentHeight

func ContentHeight(totalH int) int

ContentHeight returns the usable content height (totalH - 3 for title+help).

func LoadCCXConfig added in v0.3.0

func LoadCCXConfig(path string) (*Keymap, Preferences, Shortcuts, remote.Config)

LoadCCXConfig reads the unified config file. Returns keymap, preferences, and shortcuts separately.

func SavePreferences added in v0.3.0

func SavePreferences(prefs Preferences)

SavePreferences updates the preferences section in the config file, preserving existing keymap settings and filling in missing defaults.

Types

type ActionsKeymap

type ActionsKeymap struct {
	Delete    string `yaml:"delete"`
	Move      string `yaml:"move"`
	Resume    string `yaml:"resume"`
	CopyPath  string `yaml:"copy_path"`
	Worktree  string `yaml:"worktree"`
	Kill      string `yaml:"kill"`
	Input     string `yaml:"input"`
	Jump      string `yaml:"jump"`
	URLs      string `yaml:"urls"`
	Files     string `yaml:"files"`
	Changes   string `yaml:"changes"`
	Tags      string `yaml:"tags"`
	ImportMem string `yaml:"import_mem"`
	RemoveMem string `yaml:"remove_mem"`
	Fork      string `yaml:"fork"`
	New       string `yaml:"new"`
	Remote    string `yaml:"remote"`
}

ActionsKeymap defines configurable keybindings for the actions menu.

type App

type App struct {
	// contains filtered or unexported fields
}

func NewApp

func NewApp(sessions []session.Session, cfg Config) *App

func (*App) Init

func (a *App) Init() tea.Cmd

func (*App) PickResult added in v0.3.0

func (a *App) PickResult() PickResult

PickResult returns the result captured during pick mode, or nil if the user cancelled or pick mode is disabled.

func (*App) Update

func (a *App) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (*App) View

func (a *App) View() string

type CCXConfig added in v0.3.0

type CCXConfig struct {
	Keymaps     KeymapsConfig `yaml:"keymaps,omitempty"`
	Preferences Preferences   `yaml:"preferences,omitempty"`
	Shortcuts   Shortcuts     `yaml:"shortcuts,omitempty"`
	Remote      remote.Config `yaml:"remote,omitempty"`
}

CCXConfig is the unified config file containing keybindings + preferences. Stored at ~/.config/ccx/config.yaml.

type Config

type Config struct {
	ClaudeDir    string  // path to Claude data directory (empty = ~/.claude)
	TmuxEnabled  bool    // enable tmux integration (I, J, live modal)
	TmuxAutoLive bool    // auto-enter live session in same tmux window on startup
	WorktreeDir  string  // subdirectory name for worktrees (default ".worktree")
	SearchQuery  string  // initial search filter for session list
	Keymap       *Keymap // nil = use defaults
	GroupMode    string  // initial group mode (flat|proj|tree|chain|fork)
	PreviewMode  string  // initial preview mode (conv|stats|mem|tasks)
	ViewMode     string  // initial view (sessions|config|plugins|stats)
	JumpSession  string  // session ID to open and navigate to on launch
	JumpUUID     string  // entry UUID to navigate to within the session
	PickMode     bool    // true = running under `ccx pick session`: show "Pick" action, skip prefs save
}

Config holds application configuration from CLI flags.

type ConvKeymap added in v0.3.0

type ConvKeymap struct {
	JumpToTree string `yaml:"jump_to_tree"`
	LiveToggle string `yaml:"live_toggle"`
	Edit       string `yaml:"edit"`
	Actions    string `yaml:"actions"`
	Input      string `yaml:"input"`
}

ConvKeymap defines configurable keybindings for the conversation view.

type FoldState

type FoldState struct {
	Collapsed    foldSet
	Formatted    foldSet
	Entry        session.Entry
	BlockCursor  int
	BlockStarts  []int
	BlockVisible []bool  // nil = all visible; non-nil = per-block visibility
	BlockFilter  string  // current filter expression (empty = no filter)
	HideHooks    bool    // true = suppress hook badges/details in render
	Selected     foldSet // block indices selected for copy
}

FoldState holds fold/unfold and block cursor state for previews that render structured content blocks.

func (*FoldState) GrowBlocks

func (fs *FoldState) GrowBlocks(entry session.Entry, oldBlockCount int, foldPrefs map[string]bool, fmtPrefs map[string]bool)

GrowBlocks extends fold defaults for newly-appended blocks (live tail). Uses persistent foldPrefs/fmtPrefs if available, otherwise defaults.

func (*FoldState) HandleKey

func (fs *FoldState) HandleKey(key string) foldResult

HandleKey processes fold navigation keys.

func (*FoldState) Reset

func (fs *FoldState) Reset(entry session.Entry)

Reset initializes fold state for a new entry (cold start, no preferences).

func (*FoldState) ResetWithPrefs

func (fs *FoldState) ResetWithPrefs(entry session.Entry, foldPrefs map[string]bool, fmtPrefs map[string]bool)

ResetWithPrefs initializes fold state for a new entry using persistent per-type preferences from the SplitPane. If prefs are nil, falls back to defaults.

func (*FoldState) SelectBlockAtLine

func (fs *FoldState) SelectBlockAtLine(line int)

SelectBlockAtLine moves the block cursor to the block containing the given line.

type Keymap

type Keymap struct {
	Session      SessionKeymap    `yaml:"session"`
	Actions      ActionsKeymap    `yaml:"actions"`
	Views        ViewsKeymap      `yaml:"views"`
	Conversation ConvKeymap       `yaml:"conversation"`
	Preview      PreviewKeymap    `yaml:"preview"`
	Navigation   NavigationKeymap `yaml:"navigation"`
}

Keymap holds all configurable keybindings.

func DefaultKeymap

func DefaultKeymap() Keymap

DefaultKeymap returns a Keymap with all hardcoded defaults.

func LoadKeymap

func LoadKeymap(path string) (*Keymap, error)

LoadKeymap reads a YAML config file and merges it over defaults. If the file doesn't exist, defaults are returned with no error.

func (*Keymap) TranslateNav

func (km *Keymap) TranslateNav(key string, msg tea.KeyMsg) (string, tea.KeyMsg)

TranslateNav checks if key is a navigation alias and returns the canonical key name and a synthetic tea.KeyMsg. If not an alias, returns ("", original msg).

type KeymapsConfig added in v0.3.0

type KeymapsConfig struct {
	Session    SessionKeymap    `yaml:"session,omitempty"`
	Actions    ActionsKeymap    `yaml:"actions,omitempty"`
	Views      ViewsKeymap      `yaml:"views,omitempty"`
	Navigation NavigationKeymap `yaml:"navigation,omitempty"`
}

KeymapsConfig groups all keybinding sections under one key.

type NavResult int

NavResult describes what happened after a preview navigation key press.

const (
	NavUnhandled    NavResult = iota
	NavCursorMoved            // cursor moved within bounds
	NavFoldChanged            // fold/format toggled (content changed)
	NavBoundaryUp             // cursor at top, wants to go up
	NavBoundaryDown           // cursor at bottom, wants to go down
	NavSwitchToList           // left on already-folded block
	NavScrolled               // viewport scrolled (pgup/pgdown/home/end)
)

func HandleFlatCursorNav added in v0.3.0

func HandleFlatCursorNav(cursor *int, count int, key string) NavResult

HandleFlatCursorNav processes up/down for a flat integer cursor. Returns NavBoundaryUp/Down at edges, NavCursorMoved on success.

func HandleFoldNav added in v0.3.0

func HandleFoldNav(fs *FoldState, vp *viewport.Model, key string) NavResult

HandleFoldNav processes navigation keys for a FoldState+viewport pair. Includes viewport-cursor snap: if the cursor is off-screen (e.g. after pgup/pgdown), up/down will first snap to a visible block before moving. Does NOT call any callbacks — mutates FoldState in place and returns what happened.

type NavigationKeymap struct {
	Up       []string `yaml:"up"`
	Down     []string `yaml:"down"`
	Left     []string `yaml:"left"`
	Right    []string `yaml:"right"`
	PageUp   []string `yaml:"page_up"`
	PageDown []string `yaml:"page_down"`
	Home     []string `yaml:"home"`
	End      []string `yaml:"end"`
}

NavigationKeymap defines extra keybindings that alias standard navigation keys. The standard arrow/pgup/pgdown/home/end keys always work; these are additive.

type PickResult added in v0.3.0

type PickResult interface {
	// contains filtered or unexported methods
}

PickResult is a sum-type sentinel for results returned by the TUI when launched in pick mode. Concrete implementations live alongside the entity types they represent; new entities (entries, URLs, files, …) append a new variant + one case arm in the JSON emitter.

type Preferences added in v0.3.0

type Preferences struct {
	GroupMode       string   `yaml:"group_mode,omitempty"`        // flat|proj|tree|chain|fork
	PreviewMode     string   `yaml:"preview_mode,omitempty"`      // conv|stats|mem|tasks|live
	ViewMode        string   `yaml:"view_mode,omitempty"`         // sessions|config|plugins|stats
	ConvDetailLevel int      `yaml:"conv_detail_level,omitempty"` // 0=compact,1=standard,2=verbose
	SplitRatio      int      `yaml:"split_ratio,omitempty"`       // 15-85
	WorktreeDir     string   `yaml:"worktree_dir,omitempty"`      // worktree subdirectory name
	HiddenBadges    []string `yaml:"hidden_badges,omitempty"`     // badge keys to hide: M,W,T,K,P,A,C,S,X,F
	FilterTerm      string   `yaml:"filter_term,omitempty"`       // last applied session filter
	EditorInput     bool     `yaml:"editor_input,omitempty"`      // true = open $EDITOR for live input
}

Preferences holds persisted view preferences that survive restarts.

type PreviewKeymap added in v0.3.0

type PreviewKeymap struct {
	FoldAll   string `yaml:"fold_all"`
	ExpandAll string `yaml:"expand_all"`
	Filter    string `yaml:"filter"`
	CopyMode  string `yaml:"copy_mode"`
	CopyAll   string `yaml:"copy_all"`
}

PreviewKeymap defines configurable keybindings for focused preview panes.

type SessionKeymap

type SessionKeymap struct {
	Quit         string `yaml:"quit"`
	Escape       string `yaml:"escape"`
	Open         string `yaml:"open"`
	Edit         string `yaml:"edit"`
	Actions      string `yaml:"actions"`
	Views        string `yaml:"views"`
	Refresh      string `yaml:"refresh"`
	Group        string `yaml:"group"`
	Help         string `yaml:"help"`
	Search       string `yaml:"search"`
	GlobalSearch string `yaml:"global_search"`
	Live         string `yaml:"live"`
	Select       string `yaml:"select"`
	Preview      string `yaml:"preview"`
	PreviewBack  string `yaml:"preview_back"`
	Left         string `yaml:"left"`
	Right        string `yaml:"right"`
	ResizeShrink string `yaml:"resize_shrink"`
	ResizeGrow   string `yaml:"resize_grow"`
	Command      string `yaml:"command"`
	Pick         string `yaml:"pick"` // pick mode only (ccx pick session)
}

SessionKeymap defines configurable keybindings for the session list view.

type SessionsResult added in v0.3.0

type SessionsResult struct {
	Items []session.Session
}

SessionsResult is the PickResult variant emitted by `ccx pick session`.

type ShortcutMap added in v0.3.0

type ShortcutMap map[string]string

ShortcutMap maps a key string ("1"-"9") to a command registry name.

type Shortcuts added in v0.3.0

type Shortcuts map[string]ViewShortcuts

Shortcuts maps view names to their focus-scoped shortcuts.

func DefaultShortcuts added in v0.3.0

func DefaultShortcuts() Shortcuts

DefaultShortcuts returns sensible defaults for all views.

type SplitKeyResult

type SplitKeyResult int

type SplitPane

type SplitPane struct {
	List    *list.Model
	Preview viewport.Model

	// State
	Show     bool
	Focus    bool   // true = preview focused, false = list focused
	CacheKey string // tracks last-rendered item ID to avoid redundant updates

	// Item height for mouse click calculations (delegate Height + Spacing)
	ItemHeight int

	// Optional fold support (nil = simple scroll-only preview)
	Folds *FoldState

	// BottomAlign pushes content to the bottom of viewport when shorter than viewport height.
	// Used during live tailing so new content appears at a stable bottom position.
	BottomAlign bool

	// Persistent per-type fold preferences. Survives across entry changes.
	// Updated when the user manually folds/unfolds blocks via HandleKey.
	TypeFoldPrefs map[string]bool // type → should collapse
	TypeFmtPrefs  map[string]bool // type → should format
	// contains filtered or unexported fields
}

SplitPane manages a list + viewport split layout with focus toggling.

func (*SplitPane) HandleFocusedKeys

func (sp *SplitPane) HandleFocusedKeys(key string) SplitKeyResult

HandleFocusedKeys processes keys when the preview pane is focused: "/" to start search, fold navigation, and scroll keys.

func (*SplitPane) HandleListBoundary

func (sp *SplitPane) HandleListBoundary(key string) bool

HandleListBoundary handles cursor boundary behavior. For up/down: scrolls preview when at first/last item. For pgup/pgdown: moves cursor by one page of items (instead of bubbletea's page-based navigation), snapping to first/last on edges. Returns true if the key was handled.

func (*SplitPane) HandleMouseClick

func (sp *SplitPane) HandleMouseClick(mouseX, contentY int, totalW, splitRatio int)

HandleMouseClick handles mouse click to toggle focus between list and preview.

func (*SplitPane) HandleMouseDoubleClick

func (sp *SplitPane) HandleMouseDoubleClick(mouseX int, totalW, splitRatio int) bool

HandleMouseDoubleClick handles double-click in the preview to toggle fold.

func (*SplitPane) HandleMouseScroll

func (sp *SplitPane) HandleMouseScroll(mouseX int, up bool, totalW, splitRatio int)

HandleMouseScroll handles mouse wheel events for the split pane.

func (*SplitPane) HandlePreviewScroll

func (sp *SplitPane) HandlePreviewScroll(key string) bool

HandlePreviewScroll processes scroll keys when preview is focused.

func (*SplitPane) HandleSplitKey

func (sp *SplitPane) HandleSplitKey(key string, totalW, totalH, splitRatio int, adjustRatio func(int)) SplitKeyResult

HandleSplitKey processes common split pane keys (esc, left, right, tab, shift+tab, [, ]).

func (*SplitPane) ListWidth

func (sp *SplitPane) ListWidth(totalW, splitRatio int) int

ListWidth returns the list width given total width and split ratio.

func (*SplitPane) PreviewWidth

func (sp *SplitPane) PreviewWidth(totalW, splitRatio int) int

PreviewWidth returns the preview width (totalW - listW - 1 for border).

func (*SplitPane) RefreshFoldCursor

func (sp *SplitPane) RefreshFoldCursor(totalW, splitRatio int)

RefreshFoldCursor re-renders only the block cursor markers without re-computing wrapped text. Falls back to full RefreshFoldPreview if fold state changed.

func (*SplitPane) RefreshFoldPreview

func (sp *SplitPane) RefreshFoldPreview(totalW, splitRatio int)

RefreshFoldPreview re-renders fold-aware preview content. It clamps the existing YOffset to the new content bounds and scrolls to keep the block cursor visible. Callers that need proportional scroll preservation (e.g. resize) should do so explicitly afterwards.

func (*SplitPane) Render

func (sp *SplitPane) Render(totalW, totalH, splitRatio int) string

Render draws the split layout: list | border | preview. If Show is false or dimensions too small, returns list-only view.

func (*SplitPane) Resize

func (sp *SplitPane) Resize(totalW, totalH, splitRatio int)

Resize adjusts list dimensions after terminal resize. Preserves entry identity (CacheKey) and fold state; only re-renders preview content.

func (*SplitPane) ScrollToBlock

func (sp *SplitPane) ScrollToBlock()

ScrollToBlock adjusts the preview viewport to keep the block cursor visible.

func (*SplitPane) SetPreviewContent

func (sp *SplitPane) SetPreviewContent(content string, totalW, totalH, splitRatio int)

SetPreviewContent sets the preview viewport content and resets to top.

func (*SplitPane) SyncTypePrefs

func (sp *SplitPane) SyncTypePrefs(syncFmt bool)

SyncTypePrefs merges fold/format preferences from the current FoldState into the SplitPane's persistent TypeFoldPrefs/TypeFmtPrefs maps. Only updates prefs for block types present in the current entry, preserving prefs for types not in this entry (e.g., tool_use prefs survive while viewing a text-only user message).

syncFmt controls whether format (Formatted) preferences are updated. Pass false for "left" key actions — left progressively collapses (unformat → fold → switch-to-list), and the intermediate unformat step should NOT clear the persistent format preference. Pass true for "right" (explicit format toggle) and "f"/"F" (reset all folds).

type ViewShortcuts added in v0.3.0

type ViewShortcuts struct {
	Left  ShortcutMap `yaml:"left,omitempty"`
	Right ShortcutMap `yaml:"right,omitempty"`
}

ViewShortcuts defines shortcuts for left (list) and right (preview) focus sides.

type ViewsKeymap

type ViewsKeymap struct {
	Stats   string `yaml:"stats"`
	Config  string `yaml:"config"`
	Plugins string `yaml:"plugins"`
}

ViewsKeymap defines configurable keybindings for the views menu.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL