Documentation
¶
Index ¶
- Constants
- Variables
- func Hints(bindings ...key.Binding) string
- func NewSpinner(color bool) spinner.Model
- type HelpModel
- type PagerModel
- func (m PagerModel) ClearSearch() PagerModel
- func (m PagerModel) GotoBottom() PagerModel
- func (m PagerModel) GotoTop() PagerModel
- func (m PagerModel) Init() tea.Cmd
- func (m PagerModel) Ready() bool
- func (m PagerModel) ResetSearch() PagerModel
- func (m PagerModel) ScrollPercent() float64
- func (m PagerModel) SearchActive() bool
- func (m PagerModel) Searching() bool
- func (m PagerModel) SetContent(raw string) PagerModel
- func (m PagerModel) SetContentFollowingTail(raw string) PagerModel
- func (m PagerModel) SetSize(width, height int) PagerModel
- func (m PagerModel) Update(msg tea.Msg) (PagerModel, tea.Cmd)
- func (m PagerModel) View(status string) tea.View
- func (m PagerModel) WithBorder(c color.Color) PagerModel
- func (m PagerModel) WithContent(raw string) PagerModel
- func (m PagerModel) WithKeys(keys ...key.Binding) PagerModel
- func (m PagerModel) WithReflow(reflow func(width int) string) PagerModel
- type PreviewModel
- type SelectModel
- func (m SelectModel) Done() bool
- func (m SelectModel) Init() tea.Cmd
- func (m SelectModel) Selected() int
- func (m SelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m SelectModel) View() tea.View
- func (m SelectModel) WithChildren(children []string) SelectModel
- func (m SelectModel) WithCursor(i int) SelectModel
- func (m SelectModel) WithHeight(rows int) SelectModel
- func (m SelectModel) WithIcons(icons []string) SelectModel
- func (m SelectModel) WithItemStyleFunc(fn func(i int) lipgloss.Style) SelectModel
- func (m SelectModel) WithKeys(keys ...key.Binding) SelectModel
- func (m SelectModel) WithNote(note string) SelectModel
- type Tabs
- type TokenModel
Constants ¶
const ( // PreviewFrameWidth is how many columns the frame steals from the box's // outer width before content. Callers subtract it from the pane width to get // the column count content must wrap to (e.g. glamour word-wrap width). PreviewFrameWidth = previewBorderSize + previewPaddingX // PreviewFrameHeight is the rows the frame consumes, so callers can size the // box to leave room for surrounding chrome. PreviewFrameHeight = previewBorderSize // top+bottom border )
previewFramePadding is the columns/rows lipgloss border + horizontal padding add around the content. The border costs 1 cell on each side (2 cols, 2 rows) and the padding adds 1 col on each side (2 cols).
PagerFooterHeight is the number of rows PagerModel reserves below the viewport for its footer (one blank separator row + the help/status line). Callers use it to decide whether content fits on one screen without paging.
Variables ¶
var ( KeyEnter = key.NewBinding(key.WithKeys("enter")) KeyEsc = key.NewBinding(key.WithKeys("esc")) KeyCtrlC = key.NewBinding(key.WithKeys("ctrl+c")) KeyYes = key.NewBinding(key.WithKeys("y", "Y")) KeyNo = key.NewBinding(key.WithKeys("n", "N")) KeyTab = key.NewBinding(key.WithKeys("tab")) KeyShiftTab = key.NewBinding(key.WithKeys("shift+tab")) KeySpace = key.NewBinding(key.WithKeys(" ", "space")) // List/viewport movement. k/j accompany the arrows for vim-style navigation. KeyUp = key.NewBinding(key.WithKeys("up", "k")) KeyDown = key.NewBinding(key.WithKeys("down", "j")) KeyPageUp = key.NewBinding(key.WithKeys("pgup")) KeyPageDown = key.NewBinding(key.WithKeys("pgdown")) KeyTop = key.NewBinding(key.WithKeys("g", "home")) KeyBottom = key.NewBinding(key.WithKeys("G", "end")) // Search "/" prompt editing. History recall is arrow-only (not KeyUp/KeyDown) // so k/j are typed into the pattern as literal text instead of recalling. KeyBackspace = key.NewBinding(key.WithKeys("backspace")) KeyHistPrev = key.NewBinding(key.WithKeys("up")) KeyHistNext = key.NewBinding(key.WithKeys("down")) // Pager committed-search navigation. KeySearchNext = key.NewBinding(key.WithKeys("n")) KeySearchPrev = key.NewBinding(key.WithKeys("N")) // Run picker: jump the status filter back to "all statuses". The forward // cycle reuses BindStatus below (it is also a footer entry). KeyStatusClear = key.NewBinding(key.WithKeys("S")) )
Dispatch bindings. These carry no help text — they never appear in a footer, they only classify a key press. Movement is split per-direction because up and down (etc.) trigger different actions; the grouped display bindings below layer the combined "↑/↓" hint label on top of the same keystrokes.
var ( BindSelect = key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "select")) BindSearch = key.NewBinding(key.WithKeys("/"), key.WithHelp("/", "search")) BindRefresh = key.NewBinding(key.WithKeys("r"), key.WithHelp("r", "refresh")) BindStatus = key.NewBinding(key.WithKeys("s"), key.WithHelp("s", "status")) BindHelp = key.NewBinding(key.WithKeys("?"), key.WithHelp("?", "help")) BindQuit = key.NewBinding(key.WithKeys("q"), key.WithHelp("q", "quit")) )
Footer bindings that also serve as dispatch bindings: single-key actions whose help label matches what they do, so one binding covers both roles.
var ( BindBack = key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "back")) BindQuitEsc = key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "quit")) BindMove = grouped("↑/↓", "move", KeyUp, KeyDown) BindScroll = grouped("↑/↓", "scroll", KeyUp, KeyDown) BindTopBottom = grouped("g/G", "top/bottom", KeyTop, KeyBottom) BindPage = grouped("f/b", "page", KeyPageUp, KeyPageDown) )
Footer-only display bindings. The two esc variants exist because esc reads as "back" in pickers/pagers that pop a level and "quit" in the ones that exit; the grouped movement bindings reuse the dispatch keystrokes above so the key strings stay defined in exactly one place.
Functions ¶
func Hints ¶
Hints renders a one-line, muted footer for the given key bindings using the shared house style. Use it for standalone footers a host draws itself (a theme picker, a token prompt); components that own their footer store the bindings and render them internally.
func NewSpinner ¶
Types ¶
type HelpModel ¶
type HelpModel struct {
// contains filtered or unexported fields
}
HelpModel is a scrollable full-screen help overlay: markdown rendered in a frame (a PagerModel, so it scrolls and offers the less-style "/" search), meant to be embedded in another program that opens it on "?" and dismisses it on esc/q. Unlike MarkdownViewportModel — which is its own program and quits on esc/q — HelpModel records the dismissal via Dismissed() so the host can route back to whatever it was showing rather than exiting.
Content is produced by a render callback so the markdown re-wraps to the live terminal width on resize. Build with NewHelp; the zero value is not usable.
func NewHelp ¶
NewHelp returns a help overlay that displays the markdown produced by render. render is given the column width the content must fit into and is re-invoked on every resize so the markdown re-wraps.
func (HelpModel) Dismissed ¶
Dismissed reports whether the user closed the overlay (esc/q). The host checks this after Update to decide whether to route back to its previous view.
func (HelpModel) Reopen ¶
Reopen clears the dismissed flag, drops any prior search, and scrolls to the top, readying the overlay for a fresh open.
func (HelpModel) Searching ¶
Searching reports whether the "/" search prompt is open, so the host can let esc/ctrl+c reach the prompt (cancel) instead of treating them as its own keys.
func (HelpModel) SetSize ¶
SetSize applies a terminal size to the underlying pager, re-wrapping the content to the new width.
type PagerModel ¶
type PagerModel struct {
// contains filtered or unexported fields
}
PagerModel is a scrollable full-screen pager with less-style search built in. It wraps a viewport, owns the search engine, and renders a footer showing the scroll position, key hints and search state. It handles scrolling (↑/↓, page keys via the viewport), jump-to-top/bottom (g/G, home/end) and the whole "/" search interaction (typing, up/down to recall recent patterns, n/N navigation, match highlighting, scroll-to-match).
It deliberately does NOT handle the lifecycle keys (q, esc, ctrl+c): those mean different things to different hosts — quit here, go back to a picker there — so the embedding model owns them. The typical host loop is:
if !pager.Searching() {
switch key {
case "ctrl+c", "q": quit
case "esc":
if pager.SearchActive() { pager = pager.ClearSearch(); return }
quit / go back
}
}
pager, cmd = pager.Update(msg)
Guarding on Searching() first is important: while the "/" prompt is open those keys are text to be typed (or the prompt's own cancel/commit), not lifecycle actions, so they must fall through to Update.
Build with NewPager; the zero value is not usable. Content is supplied with SetContent / SetContentFollowingTail, or recomputed per width by a WithReflow callback on resize.
func NewPager ¶
func NewPager() PagerModel
NewPager returns an empty pager. Chain WithKeys / WithReflow / WithContent to configure it before use.
func (PagerModel) ClearSearch ¶
func (m PagerModel) ClearSearch() PagerModel
ClearSearch dismisses the committed search, dropping its highlights, and leaves the viewport scrolled where it is.
func (PagerModel) GotoBottom ¶
func (m PagerModel) GotoBottom() PagerModel
GotoBottom scrolls to the bottom of the content.
func (PagerModel) GotoTop ¶
func (m PagerModel) GotoTop() PagerModel
GotoTop scrolls to the top of the content.
func (PagerModel) Init ¶
func (m PagerModel) Init() tea.Cmd
func (PagerModel) Ready ¶
func (m PagerModel) Ready() bool
Ready reports whether a terminal size has been seen, so the pager can render.
func (PagerModel) ResetSearch ¶
func (m PagerModel) ResetSearch() PagerModel
ResetSearch clears the committed search (query, matches, prompt) and re-applies plain content, while preserving the in-memory recall history. Use it when opening fresh content that should start unsearched but still offer previous patterns for recall at the "/" prompt.
func (PagerModel) ScrollPercent ¶
func (m PagerModel) ScrollPercent() float64
ScrollPercent is the viewport's scroll position in the range [0, 1].
func (PagerModel) SearchActive ¶
func (m PagerModel) SearchActive() bool
SearchActive reports whether a committed search is present to dismiss (a query with matches, or a not-found notice). Hosts use it to decide whether Esc should clear the search or fall through to their own quit/back action.
func (PagerModel) Searching ¶
func (m PagerModel) Searching() bool
Searching reports whether the "/" input prompt is currently active.
func (PagerModel) SetContent ¶
func (m PagerModel) SetContent(raw string) PagerModel
SetContent replaces the paged content, preserving the scroll position, and re-applies any active search highlight.
func (PagerModel) SetContentFollowingTail ¶
func (m PagerModel) SetContentFollowingTail(raw string) PagerModel
SetContentFollowingTail is like SetContent but keeps the view pinned to the bottom when it was already there, so streamed output that a reader is watching live keeps scrolling while a reader who has scrolled up to read is left alone.
func (PagerModel) SetSize ¶
func (m PagerModel) SetSize(width, height int) PagerModel
SetSize applies a terminal size, sizing the viewport (reserving the footer), re-wrapping via the reflow callback when set, and re-applying search highlights. It is equivalent to feeding the pager a tea.WindowSizeMsg.
func (PagerModel) Update ¶
func (m PagerModel) Update(msg tea.Msg) (PagerModel, tea.Cmd)
Update handles scrolling, jump keys and the whole "/" search interaction. It leaves q/esc/ctrl+c untouched (except while the search prompt is open, where esc/enter cancel/commit the pattern) so the host can bind them. See PagerModel.
func (PagerModel) View ¶
func (m PagerModel) View(status string) tea.View
View renders the viewport above the footer, on the alternate screen. status is an optional, already-styled segment shown at the left of the footer before the search state (e.g. a "streaming…" indicator); pass "" for none. It returns an empty view until a terminal size is known.
func (PagerModel) WithBorder ¶
func (m PagerModel) WithBorder(c color.Color) PagerModel
WithBorder frames the viewport in a rounded border of the given color, offset from the text by a right pad. Use it to lift an overlay (e.g. the help view) off the content behind it. The border is drawn inside the pager's width, so the content re-wraps to the reduced interior — callers pass the full terminal size as usual. Unset (the default) renders flush, with no border.
func (PagerModel) WithContent ¶
func (m PagerModel) WithContent(raw string) PagerModel
WithContent seeds the initial content. It is rendered once a size is known.
func (PagerModel) WithKeys ¶
func (m PagerModel) WithKeys(keys ...key.Binding) PagerModel
WithKeys sets the footer key bindings (e.g. BindScroll, BindSearch, BindQuit). They are rendered as a muted, " · "-joined hint line at the right of the footer.
func (PagerModel) WithReflow ¶
func (m PagerModel) WithReflow(reflow func(width int) string) PagerModel
WithReflow installs a callback that recomputes the content for a given width, invoked on every resize. Use it for content that must be re-wrapped to the terminal width (rendered markdown). Content that should merely soft-wrap needs no reflow; set it with SetContent instead.
type PreviewModel ¶
type PreviewModel struct {
// contains filtered or unexported fields
}
PreviewModel is a display-only pane that frames pre-rendered content inside a bordered box. It does no rendering of its own — callers supply already-styled content (e.g. glamour-rendered markdown) and the box size, and PreviewModel only draws the frame. It is used as the right-hand pane of the theme picker to show sample markdown rendered in the highlighted theme.
PreviewModel is not a standalone bubbletea program: it has no Update loop and View returns a plain string so a parent model can compose it horizontally with other panes.
func NewPreviewModel ¶
func NewPreviewModel() PreviewModel
NewPreviewModel returns an empty preview pane.
func (PreviewModel) ContentHeight ¶
func (m PreviewModel) ContentHeight() int
ContentHeight is the row count available for content inside the frame. Callers use it to vertically place content (e.g. to center a loading placeholder).
func (PreviewModel) ContentWidth ¶
func (m PreviewModel) ContentWidth() int
ContentWidth is the column count available for content inside the frame. Callers wrap their content (e.g. via glamour) to this width.
func (PreviewModel) View ¶
func (m PreviewModel) View() string
View renders the bordered content box as a plain string for a parent model to place. Returns "" until a size has been set.
func (PreviewModel) WithContent ¶
func (m PreviewModel) WithContent(content string) PreviewModel
WithContent returns a copy of the pane displaying content. Content is assumed to be pre-wrapped to ContentWidth(); anything wider is clipped by the box.
func (PreviewModel) WithSize ¶
func (m PreviewModel) WithSize(width, height int) PreviewModel
WithSize returns a copy of the pane sized to the given outer width and height (in terminal cells), border and padding included.
type SelectModel ¶
type SelectModel struct {
// contains filtered or unexported fields
}
SelectModel is a single-choice picker rendered as a vertical list with a cursor (›) marking the focused option. ↑/↓ or k/j move; Enter confirms; Esc/Ctrl+C cancels. When the option list is taller than the available height the list scrolls to keep the cursor visible (see WithHeight).
func NewSelectModel ¶
func NewSelectModel(prompt string, options []string) SelectModel
func (SelectModel) Done ¶
func (m SelectModel) Done() bool
Done reports whether the user has confirmed a selection.
func (SelectModel) Init ¶
func (m SelectModel) Init() tea.Cmd
func (SelectModel) Selected ¶
func (m SelectModel) Selected() int
Selected returns the index chosen by the user. Only valid when Done().
func (SelectModel) View ¶
func (m SelectModel) View() tea.View
func (SelectModel) WithChildren ¶
func (m SelectModel) WithChildren(children []string) SelectModel
WithChildren attaches an optional nested sub-entry to each option. children is parallel to the options; an empty string means "no child" for that row. A child renders as a muted, non-selectable "└ value" line indented beneath its option (e.g. a branch name under a trigger), keeping a long attribute off the option's own row. Children are meant for short lists shown in full; the list still scrolls by option when it overflows, but the window is sized to show every option and its children together, so a caller relying on children should leave enough height for them.
func (SelectModel) WithCursor ¶
func (m SelectModel) WithCursor(i int) SelectModel
WithCursor returns a copy of the model with the initial cursor positioned at index i, clamped to the available options. Use this to pre-select a default choice.
func (SelectModel) WithHeight ¶
func (m SelectModel) WithHeight(rows int) SelectModel
WithHeight sets the number of terminal rows available to the picker. When the option list is taller than this, the list scrolls to keep the cursor visible and a position indicator ("(3–12 of 40)") is appended to the hint. Zero (the default) imposes no limit and renders every option.
func (SelectModel) WithIcons ¶
func (m SelectModel) WithIcons(icons []string) SelectModel
WithIcons attaches an optional status icon to each option. icons is parallel to the options passed to NewSelectModel; an empty string means "no icon" for that row. Each icon is rendered in a fixed column before the label and is emitted verbatim — already styled by the caller if color is wanted — outside the cursor/selection styling, so a status color survives even on the highlighted or chosen row. Rows align one column further in when any option carries an icon.
func (SelectModel) WithItemStyleFunc ¶
func (m SelectModel) WithItemStyleFunc(fn func(i int) lipgloss.Style) SelectModel
WithItemStyleFunc returns a copy whose option labels are styled per-index by fn. The returned style applies to the label text (not the icon or cursor arrow); on the cursor row the accent foreground is layered on top so the highlighted row still stands out while keeping fn's other attributes (e.g. italic). Use it to give a special row a distinct look.
func (SelectModel) WithKeys ¶
func (m SelectModel) WithKeys(keys ...key.Binding) SelectModel
WithKeys returns a copy of the model with custom footer key bindings, replacing the default (move / select / quit) hint line.
func (SelectModel) WithNote ¶
func (m SelectModel) WithNote(note string) SelectModel
WithNote returns a copy of the model with an informational note rendered between the title and the options (e.g. a run's config error). An empty note renders nothing. The note is emitted verbatim — style it in the caller if color is wanted — and may span multiple lines, which are reserved for when the option list scrolls.
type Tabs ¶
type Tabs struct {
// contains filtered or unexported fields
}
Tabs is a horizontal tab bar seamed into a rounded-bordered window: the active tab's label reads as continuous with the body below it. It owns the active-tab index and the switch keys (←/→, tab/shift+tab); the host supplies the labels and, per frame, the active tab's body content (Tabs draws only the chrome, not the body — the host decides what each tab shows). Enter/esc and body navigation are left to the host.
func (Tabs) Next ¶
Next / Prev return a copy with the following / preceding tab active, wrapping at the ends.
type TokenModel ¶
type TokenModel struct {
// contains filtered or unexported fields
}
func NewTokenModel ¶
func NewTokenModel() TokenModel
func (TokenModel) Init ¶
func (m TokenModel) Init() tea.Cmd
func (TokenModel) Token ¶
func (m TokenModel) Token() string
func (TokenModel) View ¶
func (m TokenModel) View() tea.View