Help us shape the future of Go! Take the 2026 Go Developer Survey

tui

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package tui renders an interactive picker for the pick subcommand. It shows a foldable repository tree with live token tallies, per-file compression modes, and a file preview, and returns the user's selection.

Index

Constants

This section is empty.

Variables

View Source
var ThemePresets = []ThemePreset{
	{
		ID: "catppuccin-mocha", Name: "Catppuccin Mocha", Family: "Catppuccin", Variant: "Mocha", Dark: true,
		Border: lipgloss.Color("#cba6f7"), Title: lipgloss.Color("#89b4fa"), Muted: lipgloss.Color("#6c7086"),
		CursorBg: lipgloss.Color("#313244"), CursorFg: lipgloss.Color("#cdd6f4"), Selected: lipgloss.Color("#89b4fa"),
		Notice: lipgloss.Color("#a6e3a1"), ModeFull: lipgloss.Color("#a6e3a1"), ModeSig: lipgloss.Color("#f9e2af"), ModeSkip: lipgloss.Color("#f38ba8"),
		Highlight: hlPalette("#cba6f7", "#a6e3a1", "#fab387", "#6c7086", "#f9e2af"),
		Syntax:    semanticPalette("#cba6f7", "#a6e3a1", "#fab387", "#6c7086", "#f9e2af", "#89b4fa", "#eba0ac", "#89dceb", "#6c7086"),
	},
	{
		ID: "tokyo-night", Name: "Tokyo Night", Family: "Tokyo Night", Variant: "Night", Dark: true,
		Border: lipgloss.Color("#7aa2f7"), Title: lipgloss.Color("#7dcfff"), Muted: lipgloss.Color("#565f89"),
		CursorBg: lipgloss.Color("#2ac3de"), CursorFg: lipgloss.Color("#1a1b26"), Selected: lipgloss.Color("#7aa2f7"),
		Notice: lipgloss.Color("#9ece6a"), ModeFull: lipgloss.Color("#9ece6a"), ModeSig: lipgloss.Color("#e0af68"), ModeSkip: lipgloss.Color("#f7768e"),
		Highlight: hlPalette("#bb9af7", "#9ece6a", "#ff9e64", "#565f89", "#7dcfff"),
		Syntax:    semanticPalette("#bb9af7", "#9ece6a", "#ff9e64", "#565f89", "#7dcfff", "#7aa2f7", "#73daca", "#89ddff", "#565f89"),
	},
	{
		ID: "dracula", Name: "Dracula", Family: "Dracula", Variant: "Dracula", Dark: true,
		Border: lipgloss.Color("#bd93f9"), Title: lipgloss.Color("#8be9fd"), Muted: lipgloss.Color("#6272a4"),
		CursorBg: lipgloss.Color("#44475a"), CursorFg: lipgloss.Color("#f8f8f2"), Selected: lipgloss.Color("#ff79c6"),
		Notice: lipgloss.Color("#50fa7b"), ModeFull: lipgloss.Color("#50fa7b"), ModeSig: lipgloss.Color("#f1fa8c"), ModeSkip: lipgloss.Color("#ff5555"),
		Highlight: hlPalette("#ff79c6", "#f1fa8c", "#bd93f9", "#6272a4", "#8be9fd"),
		Syntax:    semanticPalette("#ff79c6", "#f1fa8c", "#bd93f9", "#6272a4", "#8be9fd", "#50fa7b", "#ffb86c", "#ff79c6", "#6272a4"),
	},
	{
		ID: "gruvbox-dark", Name: "Gruvbox Dark", Family: "Gruvbox", Variant: "Dark", Dark: true,
		Border: lipgloss.Color("#d3869b"), Title: lipgloss.Color("#83a598"), Muted: lipgloss.Color("#928374"),
		CursorBg: lipgloss.Color("#3c3836"), CursorFg: lipgloss.Color("#ebdbb2"), Selected: lipgloss.Color("#83a598"),
		Notice: lipgloss.Color("#b8bb26"), ModeFull: lipgloss.Color("#b8bb26"), ModeSig: lipgloss.Color("#fabd2f"), ModeSkip: lipgloss.Color("#fb4934"),
		Highlight: hlPalette("#fb4934", "#b8bb26", "#d3869b", "#928374", "#fabd2f"),
		Syntax:    semanticPalette("#fb4934", "#b8bb26", "#d3869b", "#928374", "#fabd2f", "#83a598", "#8ec07c", "#fe8019", "#928374"),
	},
	{
		ID: "nord", Name: "Nord", Family: "Nord", Variant: "Nord", Dark: true,
		Border: lipgloss.Color("#88c0d0"), Title: lipgloss.Color("#81a1c1"), Muted: lipgloss.Color("#4c566a"),
		CursorBg: lipgloss.Color("#3b4252"), CursorFg: lipgloss.Color("#eceff4"), Selected: lipgloss.Color("#88c0d0"),
		Notice: lipgloss.Color("#a3be8c"), ModeFull: lipgloss.Color("#a3be8c"), ModeSig: lipgloss.Color("#ebcb8b"), ModeSkip: lipgloss.Color("#bf616a"),
		Highlight: hlPalette("#81a1c1", "#a3be8c", "#b48ead", "#4c566a", "#88c0d0"),
		Syntax:    semanticPalette("#81a1c1", "#a3be8c", "#b48ead", "#4c566a", "#88c0d0", "#88c0d0", "#8fbcbb", "#81a1c1", "#4c566a"),
	},
	{
		ID: "rose-pine", Name: "Rose Pine", Family: "Rosé Pine", Variant: "Main", Dark: true,
		Border: lipgloss.Color("#c4a7e7"), Title: lipgloss.Color("#e0def4"), Muted: lipgloss.Color("#6e6a86"),
		CursorBg: lipgloss.Color("#ebbcba"), CursorFg: lipgloss.Color("#191724"), Selected: lipgloss.Color("#31748f"),
		Notice: lipgloss.Color("#9ccfd8"), ModeFull: lipgloss.Color("#9ccfd8"), ModeSig: lipgloss.Color("#f6c177"), ModeSkip: lipgloss.Color("#eb6f92"),
		Highlight: hlPalette("#c4a7e7", "#9ccfd8", "#f6c177", "#6e6a86", "#ebbcba"),
		Syntax:    semanticPalette("#c4a7e7", "#9ccfd8", "#f6c177", "#6e6a86", "#ebbcba", "#31748f", "#c4a7e7", "#9ccfd8", "#6e6a86"),
	},
	{
		ID: "classic", Name: "Classic (Default)", Family: "Classic", Variant: "Default", Dark: true,
		Border: lipgloss.Color("62"), Title: lipgloss.Color("12"), Muted: lipgloss.Color("245"),
		CursorBg: lipgloss.Color("236"), CursorFg: lipgloss.Color("15"), Selected: lipgloss.Color("12"),
		Notice: lipgloss.Color("10"), ModeFull: lipgloss.Color("10"), ModeSig: lipgloss.Color("11"), ModeSkip: lipgloss.Color("9"),

		Highlight: highlight.Palette{Keyword: "\033[1;34m", String: "\033[32m", Number: "\033[36m", Comment: "\033[2m", TypeName: "\033[35m"},
	},
}

ThemePresets lists every selectable theme in the interactive t menu. The Classic/Default entry reproduces the original ANSI palette.

Functions

This section is empty.

Types

type CompressMode

type CompressMode string

CompressMode is the per-node output mode: full content, signatures only, or skip entirely.

const (
	// ModeFull includes the file's full content.
	ModeFull CompressMode = "full"
	// ModeSignatures includes only the tree-sitter signature summary.
	ModeSignatures CompressMode = "signatures"
	// ModeSkip excludes the node from the output.
	ModeSkip CompressMode = "skip"
)

type DeltaCommit

type DeltaCommit struct {
	Short   string
	Subject string
	Checked bool
}

DeltaCommit is one selectable commit shown in the delta modal.

type DeltaInfo

type DeltaInfo struct {
	RootDir    string
	FromHash   string
	FromMsg    string
	HeadHash   string
	HeadMsg    string
	Commits    []DeltaCommit // newest first; Checked selects how far back to go
	Files      []string      // changed files from FromHash..HEAD
	FilesToken int           // token estimate for the full-content strategy
	PatchToken int           // token estimate for the raw-patch strategy
	PatchLines int           // approximate line count of the raw patch
}

DeltaInfo carries the git delta state the picker shows in its delta modal. It is nil (or DeltaInfo.Available is false) when the directory is not a git repository or no dump baseline has been recorded.

type DeltaSelection

type DeltaSelection struct {
	Strategy  DeltaStrategy
	From      string
	To        string
	Clipboard bool
}

DeltaSelection describes a delta dump the user confirmed in the modal.

type DeltaStrategy

type DeltaStrategy int

DeltaStrategy selects how a delta dump is rendered.

const (
	// DeltaFull dumps the full content of the changed files.
	DeltaFull DeltaStrategy = iota
	// DeltaPatch dumps the raw unified diff in a context_update block.
	DeltaPatch
)

type ErrMsg

type ErrMsg struct {
	Err error
}

ErrMsg wraps a fatal scan error.

type Glyphs

type Glyphs struct {
	FolderClosed string
	FolderOpen   string
	File         string
	Warning      string
	CheckFull    string
	CheckPartial string
	CheckNone    string
	Cursor       string
	Relevant     string
	Success      string
	Refresh      string
	ModeFull     string
	ModeSigns    string
	ModeSkip     string

	TreePipe   string
	TreeMiddle string
	TreeLast   string
	TreeSpace  string

	Theme  string
	Delta  string
	Prompt string
	Help   string
}

Glyphs holds the decorative symbols used by the picker. Two variants exist: Nerd Fonts (rich, Unicode) and ASCII (fallback for plain terminals). The ASCII fallback is selected with --no-nerd-fonts.

func NewASCIIGlyphs

func NewASCIIGlyphs() Glyphs

NewASCIIGlyphs returns a plain ASCII fallback glyph set.

func NewNerdFontGlyphs

func NewNerdFontGlyphs() Glyphs

NewNerdFontGlyphs returns the Nerd Font glyph set.

type Item

type Item struct {
	// Path is the file's path relative to the scanned root.
	Path string
	// IsDir marks a directory for the structure skeleton. BuildTree forces a
	// KindDir leaf so empty directories render as folders, not files. Files
	// never set it.
	IsDir bool
	// Content is the full (redacted) content, used for the preview pane.
	Content []byte
	// SigContent is the signature-only summary when available.
	SigContent []byte
	// TokensFull and TokensSig are the token counts of the two variants.
	TokensFull int
	TokensSig  int
	// ApproxTokens is a byte-based estimate shown as "~n tok" until the exact
	// count lands. Skeleton items carry it; enriched items do not.
	ApproxTokens int
	// SecretCount is the number of secrets detected in the file.
	SecretCount int
	Hidden      bool
	GitIgnored  bool
	// RankScore is the git relevance score.
	RankScore float64
	// ModeReason explains the automatic mode recommendation when available.
	ModeReason   string
	TestAffinity float64
	// PreferredMode is the git-history-backed mode preference for this file.
	// Empty means no preference; BuildTree falls back to the default full.
	PreferredMode CompressMode
}

Item is one selectable file with all data the picker needs.

type NodeKind

type NodeKind int

NodeKind identifies whether a tree node is a file or a directory.

const (
	// KindFile is a regular file leaf.
	KindFile NodeKind = iota
	// KindDir is a directory that may contain children.
	KindDir
)

type NodesMsg

type NodesMsg struct {
	Items  []Item
	Remove []string
}

NodesMsg is a batch of file items produced by the background walk. Items upsert into the skeleton tree; Remove lists skeleton paths the full walk later rejected, so the picker can drop files that will never enrich.

type Options

type Options struct {
	Budget            int
	Style             string
	UseNerd           bool
	Highlight         bool
	Theme             string
	UITheme           string
	UserThemes        []ThemePreset
	HighlightMaxBytes int
	WindowTitle       string
	ProjectPath       string
	OnThemeChange     func(string) error
	Prompt            string
	SelectionTuning   selection.Tuning
	OnCopy            func([]Selection) error
	OnCopyPrompt      func([]Selection, string) error
	OnGenerateCopy    func([]Selection, string) error

	// OnGenerate renders the current selection without exiting the picker
	// (pressing g). It mirrors OnCopy but writes the document instead of the
	// clipboard.
	OnGenerate func([]Selection) error
	// OnGeneratePrompt is the prompt-aware variant used by the TUI directive
	// builder. When nil, OnGenerate is used for backward compatibility.
	OnGeneratePrompt func([]Selection, string) error

	// Delta is the git delta state shown in the delta modal (pressing d).
	// When nil the modal shows "not available" messaging. OnDelta is invoked
	// when the user confirms a delta dump.
	Delta   *DeltaInfo
	OnDelta func(DeltaSelection) error

	// OnRescan starts a fresh background scan and returns its stream
	// (pressing r). When nil the picker reports rescan as unavailable.
	OnRescan func() (Stream, error)
}

Options configures the picker.

type PaneFocus

type PaneFocus int

PaneFocus identifies which pane currently owns keyboard input.

const (
	FocusTree PaneFocus = iota
	FocusPreview
)

type ProgressMsg

type ProgressMsg struct {
	Files     int
	Dirs      int
	Processed int
	Skipped   int
	Done      bool
}

ProgressMsg reports scan progress for the footer.

type PromptPreset

type PromptPreset struct {
	Name string
	Text string
}

PromptPreset is a reusable task directive available from the prompt modal.

type Result

type Result struct {
	// Selections is the user's file selection and modes, empty when the
	// session ended via a delta dump or with nothing selected.
	Selections []Selection
	// DeltaDone reports that the session ended by performing a delta dump,
	// whose output replaces any picker selection.
	DeltaDone bool
}

Result carries the picker's outcome.

func Run

func Run(items []Item, opts Options) (Result, error)

Run displays the picker for items and returns the picker's result. The picker takes over its own screen via the alternate buffer and restores the terminal on exit.

func RunStreaming

func RunStreaming(skeleton []Item, opts Options, stream Stream) (Result, error)

RunStreaming is the progressive variant of Run: it opens the picker immediately on a structure-only skeleton and merges items streamed over scan's channels as the background walk enriches them.

type SelectState

type SelectState int

SelectState describes the checkbox state of a node.

const (
	// Unselected means no descendant is selected.
	Unselected SelectState = iota
	// Partial means some descendants are selected.
	Partial
	// Selected means all descendants are selected.
	Selected
)

type Selection

type Selection struct {
	Path string
	Mode CompressMode
}

Selection pairs a selected path with its output mode.

type StatusColors added in v1.3.0

type StatusColors struct {
	Info    lipgloss.Color
	Success lipgloss.Color
	Warning lipgloss.Color
	Error   lipgloss.Color
}

StatusColors keeps operational status separate from syntax and UI accents.

type Stream

type Stream struct {
	// Nodes carries batches of enriched items that upsert into the skeleton
	// tree passed to RunStreaming.
	Nodes <-chan NodesMsg
	// Progress carries scan statistics for the footer.
	Progress <-chan ProgressMsg
	// Err carries a fatal scan error, after which no more messages arrive.
	Err <-chan error
}

Stream carries progressive scan data into the picker. Producers fill the channels in the background; the picker consumes them via tea.Cmd. All channels are closed once the scan finishes (after a final ProgressMsg with Done true is sent).

type ThemePreset

type ThemePreset struct {
	// ID is the stable persisted identity; Name remains the display label.
	ID          string
	Name        string
	Family      string
	Variant     string
	Description string
	Dark        bool
	// FollowTerminal marks a palette that intentionally uses the terminal's
	// ANSI colors instead of fixed RGB values.
	FollowTerminal bool

	Border   lipgloss.Color
	Title    lipgloss.Color
	Muted    lipgloss.Color
	CursorBg lipgloss.Color
	CursorFg lipgloss.Color
	Selected lipgloss.Color
	Notice   lipgloss.Color
	ModeFull lipgloss.Color
	ModeSig  lipgloss.Color
	ModeSkip lipgloss.Color
	// Highlight is retained for compatibility with legacy RenderLine callers.
	Highlight highlight.Palette
	// Syntax is the theme-independent semantic palette for cached previews.
	Syntax highlight.SyntaxPalette

	UI     UIColors
	Status StatusColors
}

ThemePreset is an instance-local color palette. Applying a preset rebuilds the model's own styles; it never mutates package-level state.

func LoadUserThemes added in v1.3.0

func LoadUserThemes(path string) ([]ThemePreset, error)

LoadUserThemes loads and validates custom picker themes from a TOML file. Inheriting themes are resolved against built-ins and earlier definitions.

type TreeNode

type TreeNode struct {
	Name     string
	Path     string // Relative slash-separated path; "" for the root.
	Kind     NodeKind
	Children []*TreeNode
	Parent   *TreeNode
	Expanded bool // Folder open/closed.

	SelectState SelectState
	Mode        CompressMode // Effective mode, default full.
	// PreferredMode is the mode smart select should fall back to for this
	// file, derived from git commit history. Empty means "no preference".
	PreferredMode CompressMode

	// TokensFull and TokensSig aggregate descendant token counts. For files
	// they come straight from the item; for directories they are the sum of
	// all descendants.
	TokensFull       int
	TokensSig        int
	ActiveTokens     int // Cached active tokens for O(1) lookup
	FileCountVal     int // Cached file count for O(1) lookup
	SelectedCountVal int // Cached selected file count for O(1) lookup
	SecretCount      int
	RankScore        float64
	ModeReason       string
	TestAffinity     float64
	// ApproxTokens is a byte-based token estimate shown with a "~" until the
	// exact count arrives via the scan stream. Zero once TokensFull is known.
	ApproxTokens int

	// Content and SigContent are the file's two renderings (only set on file
	// nodes). They are nil on directories.
	Content    []byte
	SigContent []byte

	// Filtered marks whether the node is hidden by the active fuzzy filter.
	Filtered   bool
	Hidden     bool
	GitIgnored bool
}

TreeNode is one node in the picker's foldable repository tree.

func BuildTree

func BuildTree(items []Item) *TreeNode

BuildTree assembles a repository tree from flat file items. Directories are created implicitly and sorted before files at each level. The returned root has Name "." and Kind KindDir with Expanded true.

func (*TreeNode) ClearSelection

func (n *TreeNode) ClearSelection()

ClearSelection deselects every file.

func (*TreeNode) CollapseAll

func (n *TreeNode) CollapseAll()

CollapseAll collapses every directory in the subtree. The root's own state is left untouched.

func (*TreeNode) CycleMode

func (n *TreeNode) CycleMode()

CycleMode advances the effective mode FULL -> SIGS -> SKIP -> FULL and applies it to the whole subtree, so a directory set to a mode propagates to every file beneath it.

func (*TreeNode) ExpandAll

func (n *TreeNode) ExpandAll()

ExpandAll expands every directory in the subtree. The root's own state is left untouched.

func (*TreeNode) FileCount

func (n *TreeNode) FileCount() int

FileCount returns the cached file count under n in O(1) time.

func (*TreeNode) Preview

func (n *TreeNode) Preview() []byte

Preview returns the preview text for a file: its signature summary when the mode is signatures and one is available, otherwise the full content.

func (*TreeNode) SelectByRank

func (n *TreeNode) SelectByRank(budget int, prompt string, tunings ...selection.Tuning) int

SelectByRank delegates smart selection to the shared utility optimizer. Budget zero means unlimited; otherwise the optimizer considers full, signature, and skipped variants together. The prompt conditions path-relevance scoring so smart selection respects the active task directive. Returns the selected file count.

func (*TreeNode) SelectedCount

func (n *TreeNode) SelectedCount() int

SelectedCount returns the cached selected file count under n in O(1) time.

func (*TreeNode) Selections

func (n *TreeNode) Selections() []Selection

Selections returns the chosen files in presentation order, each with its active mode. Files under skipped directories are omitted.

func (*TreeNode) Toggle

func (n *TreeNode) Toggle()

Toggle flips the node's selection. Files flip between selected and not; directories recursively select or deselect all descendants. Selection bubbles up to parents as Partial/Selected.

func (*TreeNode) TotalActiveTokens

func (n *TreeNode) TotalActiveTokens() int

TotalActiveTokens returns the cached active tokens for n in O(1) time.

func (*TreeNode) TreePrefix

func (n *TreeNode) TreePrefix(g Glyphs) string

TreePrefix computes the hierarchical guide lines prefix (e.g. "│ ├── ") for node rendering in the explorer view.

func (*TreeNode) VisibleRows

func (n *TreeNode) VisibleRows(filter string) []*TreeNode

VisibleRows returns the flattened, currently expanded nodes in display order. When filter is non-empty only matching nodes and their ancestors are included.

func (*TreeNode) VisibleRowsWithOptions

func (n *TreeNode) VisibleRowsWithOptions(filter string, showHidden, showGitIgnored bool) []*TreeNode

VisibleRowsWithOptions flattens the tree while applying fuzzy and presentation-visibility filters.

type UIColors added in v1.3.0

type UIColors struct {
	Background   lipgloss.Color
	Surface      lipgloss.Color
	SurfaceAlt   lipgloss.Color
	Text         lipgloss.Color
	TextMuted    lipgloss.Color
	TextSubtle   lipgloss.Color
	Accent       lipgloss.Color
	AccentSoft   lipgloss.Color
	Border       lipgloss.Color
	BorderActive lipgloss.Color
	CursorBg     lipgloss.Color
	CursorFg     lipgloss.Color
	SelectionBg  lipgloss.Color
	SelectionFg  lipgloss.Color
	TreeGuide    lipgloss.Color
	Scrollbar    lipgloss.Color
	ModeFull     lipgloss.Color
	ModeSig      lipgloss.Color
	ModeSkip     lipgloss.Color
}

UIColors describes the semantic roles consumed by TUI renderers. Legacy preset fields remain supported and are normalized into this structure.

Jump to

Keyboard shortcuts

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