Documentation
¶
Overview ¶
Package terminu draws and drives a terminal UI the way terminu design (tdp) says, on top of Bubble Tea v1.
Index ¶
- Constants
- Variables
- func Center(s string, w int) string
- func Clipboard(text string)
- func Composite(base, top []string, x, y, width int) []string
- func Cut(s string, from, to int) string
- func Dim(line string) string
- func DimLines(lines []string) []string
- func EmptyState(w, h int, fact, hint string) []string
- func EnvName(app, name string) string
- func Escape(s string) string
- func Filter(items []string, typed string) []int
- func Fit(s string, w int) string
- func FitLeft(s string, w int) string
- func HexText(c Color) string
- func IconWidth() int
- func KeyName(msg tea.KeyMsg) string
- func LoadingFrame() string
- func MarkLabel(key, label string) string
- func Matches(text, typed string) bool
- func Pad(s string, w int) string
- func Pad2(lines []string, w, h int) []string
- func PadLeft(s string, w int) string
- func PowerlineWidth() int
- func Reading(lines ...string) []string
- func Repeat(s string, n int) string
- func SetIconWidth(icon, powerline int)
- func StripStyles(s string) string
- func Truncate(s string, w int) string
- func TruncateLeft(s string, w int) string
- func TruncateMiddle(s string, w int) string
- func Upper(text string) string
- func Width(s string) int
- func Wrap(s string, w int) []string
- type Action
- type App
- func (a *App) AddScreen(s *Screen) *Screen
- func (a *App) Checks(c Checks) tea.Cmd
- func (a *App) CloseAll() tea.Cmd
- func (a *App) ClosePopup(b PopupBody) tea.Cmd
- func (a *App) CloseTop(n int) tea.Cmd
- func (a *App) Confirm(ask Ask, accept func() tea.Cmd) tea.Cmd
- func (a *App) Error(title, message string) tea.Cmd
- func (a *App) ErrorAbout(title, subject, message string) tea.Cmd
- func (a *App) Find(f *Finder) tea.Cmd
- func (a *App) Focus(p *Panel) tea.Cmd
- func (a *App) Form(f *Form) tea.Cmd
- func (a *App) Frame() []string
- func (a *App) Init() tea.Cmd
- func (a *App) LoadChecks(c *Checks) tea.Cmd
- func (a *App) LoadSelect(s *Select) tea.Cmd
- func (a *App) Log(kind ToastKind, text string)
- func (a *App) Menu(title string, sections ...MenuSection) tea.Cmd
- func (a *App) MenuAbout(title, subject string, sections ...MenuSection) tea.Cmd
- func (a *App) MoveAside(path string, err error, fresh func() tea.Cmd) tea.Cmd
- func (a *App) Number(in NumberInput) tea.Cmd
- func (a *App) Open(in Input) tea.Cmd
- func (a *App) OpenTerminal(t *Terminal) tea.Cmd
- func (a *App) Password(in PasswordInput) tea.Cmd
- func (a *App) PickColor(c ColorPicker) tea.Cmd
- func (a *App) PickDate(d DatePicker) tea.Cmd
- func (a *App) PickFile(p FilePicker) tea.Cmd
- func (a *App) PlaySplash(s Splash) tea.Cmd
- func (a *App) Popup(p Popup) tea.Cmd
- func (a *App) Reorder(r Reorder) tea.Cmd
- func (a *App) Run() error
- func (a *App) Screen() *Screen
- func (a *App) Select(s Select) tea.Cmd
- func (a *App) ShowScreen(s *Screen) tea.Cmd
- func (a *App) Size() (w, h int)
- func (a *App) Text(in TextInput) tea.Cmd
- func (a *App) Textarea(t Textarea) tea.Cmd
- func (a *App) Tick(d time.Duration, fn func(time.Time) tea.Msg) tea.Cmd
- func (a *App) Toast(kind ToastKind, text string) tea.Cmd
- func (a *App) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (a *App) View() string
- func (a *App) Viewer(v *Viewer) tea.Cmd
- type Ask
- type Body
- type Capsule
- type Checks
- type Color
- type ColorPicker
- type Column
- type CoreKey
- type DatePicker
- type Failure
- type Field
- type FilePicker
- type FilePreview
- type Finder
- type FinderItem
- type Form
- type FormButton
- type FormField
- type FormResult
- type Input
- type KeyHint
- type KeyRow
- type KeySection
- type List
- func (l *List) Actions() []Action
- func (l *List) ClearFilter()
- func (l *List) ClearMarks()
- func (l *List) Current() (Row, bool)
- func (l *List) Draw(w, h int, focused bool) []string
- func (l *List) Drop()
- func (l *List) Empty() bool
- func (l *List) Filtering() bool
- func (l *List) Focus()
- func (l *List) HasItem() bool
- func (l *List) Hold() bool
- func (l *List) Holding() bool
- func (l *List) Key(key string, msg tea.KeyMsg) (bool, tea.Cmd)
- func (l *List) Marked() []string
- func (l *List) MoveHeld(down bool)
- func (l *List) MoveKeys() []KeyRow
- func (l *List) OpenFilter()
- func (l *List) Rows() []Row
- func (l *List) Scroll() string
- func (l *List) Select(id string) bool
- func (l *List) SetMarked(ids []string)
- func (l *List) SetRows(rows []Row)
- func (l *List) SortBy(keys ...SortKey)
- func (l *List) Sorting() []SortKey
- func (l *List) ToggleMark()
- func (l *List) Typing() bool
- type MenuSection
- type Mode
- type ModeKey
- type NumberInput
- type Pager
- func (t *Pager) Append(lines ...string)
- func (t *Pager) Draw(w, h int, focused bool) []string
- func (t *Pager) Empty() bool
- func (t *Pager) HasItem() bool
- func (t *Pager) Key(key string, _ tea.KeyMsg) (bool, tea.Cmd)
- func (t *Pager) Lines() []string
- func (t *Pager) MoveKeys() []KeyRow
- func (t *Pager) Scroll() string
- func (t *Pager) SetLines(lines []string)
- type Panel
- type PasswordInput
- type Popup
- type PopupBody
- type PreviewFS
- type PreviewFile
- type ProbeResult
- type RGB
- type Rect
- type Reorder
- type Row
- type Scope
- type Screen
- type Select
- type Selection
- type Slider
- type SortKey
- type Span
- type Splash
- type Style
- type Terminal
- func (t *Terminal) Draw(w, h int, focused bool) []string
- func (t *Terminal) Empty() bool
- func (t *Terminal) Enter()
- func (t *Terminal) Exited() bool
- func (t *Terminal) HasItem() bool
- func (t *Terminal) Hide(a *App) tea.Cmd
- func (t *Terminal) Inside() bool
- func (t *Terminal) Key(string, tea.KeyMsg) (bool, tea.Cmd)
- func (t *Terminal) Mode() string
- func (t *Terminal) MoveKeys() []KeyRow
- func (t *Terminal) Running() bool
- func (t *Terminal) Scroll() string
- func (t *Terminal) Spoke() bool
- func (t *Terminal) Start() tea.Cmd
- func (t *Terminal) Stop()
- type TerminalKey
- type TextInput
- type TextMatch
- type Textarea
- type ToastKind
- type Values
- func (v *Values) Actions() []Action
- func (v *Values) Current() *Field
- func (v *Values) Draw(w, h int, focused bool) []string
- func (v *Values) Empty() bool
- func (v *Values) EnterHint() string
- func (v *Values) HasItem() bool
- func (v *Values) Key(key string, _ tea.KeyMsg) (bool, tea.Cmd)
- func (v *Values) MoveKeys() []KeyRow
- func (v *Values) Scroll() string
- type Viewer
- type ViewerKey
Constants ¶
const ( FamilyIconWidth = "TERMINU__ICON_WIDTH" FamilyPowerlineWidth = "TERMINU__POWERLINE_WIDTH" )
The variables a family app sets for what runs in its PTY (tdp E2, E5).
const ( RemoteIconWidth = "LC_TERMINU_ICON_WIDTH" RemotePowerlineWidth = "LC_TERMINU_POWERLINE_WIDTH" )
The variables an app with ssh sends to the remote end when it connects, for the family app that runs there: OpenSSH passes on only LANG and LC_* (tdp E2, E5). Sending them is that app's; Probe reads them.
Variables ¶
var ( Base = Hex("#1e1e2e") // text on blocks, the unfilled side of a capsule join, what dimming fades to Blue = Hex("#89b4fa") // focus: frames, keys you can press now, the screen chips Surface2 = Hex("#585b70") // not usable: unfocused frames, disabled rows Lavender = Hex("#b4befe") // being edited, the user's footprint Sapphire = Hex("#74c7ec") // the last layer colour Green = Hex("#a6e3a1") // in effect: the chosen value, live sessions, progress Yellow = Hex("#f9e2af") // a mode Peach = Hex("#fab387") // a warning Red = Hex("#f38ba8") // an error Overlay0 = Hex("#6c7086") // quiet text: descriptions, hint words, separators Text = Hex("#cdd6f4") // ordinary text Subtext1 = Hex("#bac2de") // the panel cursor block Surface1 = Hex("#45475a") // an unfocused button )
The family colours, catppuccin-mocha (components/color). Each meaning has one colour (Principle P4); the comment is what tdp uses it for.
var ErrEmpty = errors.New("can't be empty")
ErrEmpty is a ready "may not be empty" check. The input names the value before it: "Name can't be empty" (components/input/README).
Functions ¶
func Clipboard ¶ added in v0.2.0
func Clipboard(text string)
Clipboard puts text on the terminal's clipboard (OSC 52), as a viewer's selection mode copies by default (components/dialog/note). It is sent with the next frame.
func Composite ¶
Composite lays the lines of top over base, top's first cell at column x and row y. Whatever falls off the screen is cut; it never panics, however big top is (tdp E5). base is changed in place and returned; every line keeps base's width.
func Cut ¶
Cut keeps the cells [from, to) of one line. Escape sequences are kept so the styles stay right, and the result ends with a style reset. A wide character cut in half becomes spaces, so the result is always exactly as wide as the part of [from, to) the line covers.
func Dim ¶
Dim redraws one drawn line dimmed: every foreground and background colour in its SGR sequences fades toward Base, always written as 24-bit, and text with no colour of its own gets dim(Text). Bold, reverse, cursor movement and the text itself are left as they are.
func EmptyState ¶
EmptyState draws an empty panel's two sentences, the fact and the hint naming keys, both in Overlay0 (layout/screen); keys written as [A] in the hint stay as they are.
func EnvName ¶
EnvName is the name of an environment variable app reads, tdp E2: EnvName("filu", "icon width") is "FILU__ICON_WIDTH".
func Escape ¶ added in v0.4.0
Escape is text as a name or a short text is drawn (components, control characters): each control character (C0, DEL, C1), Tab, \n and ESC too, by its name in Red (\t, \n, \x1b, as a pasted one in an input), nothing read as a style or a line break, nothing dropped. The lib draws every name and short text an app gives it this way; an app drawing text from outside itself (on a Canvas, in a popup of its own) uses it too.
func Filter ¶
Filter returns the indexes of the items that match typed, in their order: a filter never reorders.
func IconWidth ¶
func IconWidth() int
IconWidth is how many cells a Nerd Font icon takes on this terminal.
func KeyName ¶
KeyName is the name of the key in msg as tdp writes it (Rules M5): the keycap name in upper camel case (Enter, Esc, Tab, Space, Backspace, Delete, Home, End, PgUp, PgDn), arrows as ↑ ↓ ← →, a letter as typed (q, A), modifiers joined with "-" and Ctrl's letter in upper case (Ctrl-C, Alt-t, Shift-Tab, Alt-Esc). A paste has no name: it is "".
func LoadingFrame ¶ added in v0.2.0
func LoadingFrame() string
LoadingFrame is the loading icon as it is now, for a row of the app's own that is loading (a transfer in a work list): the same icon, turning with the lib's. App.Spinning keeps it turning (components/layout/popup).
func MarkLabel ¶
MarkLabel writes a hotkey into its label the way Rules M5 says. A letter that is in the label, in either case, goes in place of the first one, written as the key is pressed ("[r]ename", "[n]ew", "D[e]lete", "Ex[P]ort": Shift-P); one that is not goes in front ("[x] Reset"). A modifier key goes in place of the letter it ends with the same way ("[Alt-t]erm"), several letters in place at the start ("[go]to"), a digit, a core key or a symbol always in front ("[3] Favorites", "[Enter] Edit", "[/] Search"). The label keeps its own case. A label that already shows its key, and a row with no key, are left as they are.
func Matches ¶
Matches reports whether text matches what was typed in a filter (components/input/finder, matching): every space-separated word must appear in text as typed, in one piece, ignoring case; the words may come in any order. Nothing typed matches everything.
func PowerlineWidth ¶
func PowerlineWidth() int
PowerlineWidth is how many cells a powerline symbol takes on this terminal.
func Reading ¶ added in v0.4.0
Reading is lines of reading content (a log, a program's output) as a terminal draws them, the way the lib's viewer and Pager draw theirs (components, control characters): a line with \n in it is two rows, a \r inside a line leaves its last state, the \r of a CRLF goes, colour codes colour, a tab is input_tab_width spaces, any other control character or escape sequence is its name in Red. For a body of the app's own that shows what is read (a container's log behind a prefix, folded): each string it gives back is one row's text, to fold or cut as the app does; Width, Truncate and Cut measure it right.
func SetIconWidth ¶
func SetIconWidth(icon, powerline int)
SetIconWidth sets how many cells a Nerd Font icon takes, and a powerline symbol. Probe sets them; tests and apps that already know may set them.
func Truncate ¶
Truncate fits one line in w cells, cutting from the end and adding "…" when it had to cut. The result may be narrower than w when a wide character would straddle the cut.
func TruncateLeft ¶
TruncateLeft fits one line in w cells, cutting from the front and putting "…" first: for paths and for a value whose end matters.
func TruncateMiddle ¶ added in v0.2.0
TruncateMiddle fits one line in w cells, cutting from the middle and putting "…" there: for a value whose two ends both matter, a pod's name with its deployment in front and what tells it apart at the end ("demo-app…66-gm72n"). The end keeps the extra cell of an odd split. The result may be narrower than w when a wide character would straddle a cut.
func Upper ¶
Upper writes text in upper case for a capsule, a title, a header or a section title (components, "Uppercase"), leaving the letters in a hotkey marker as they are: "[m]anage" becomes "[m]ANAGE".
func Width ¶
Width is how many cells s takes on the screen: its widest line, escape sequences ignored.
func Wrap ¶
Wrap breaks plain text into lines of at most w cells (components, wrapping): at spaces and on either side of a wide character; inside a word only when it is longer than a line, cut by cells, a wide character never cut in half. Line breaks in s are kept. The text is only shown, so the space it breaks at is not drawn (the textarea and the viewer use foldAt).
Types ¶
type Action ¶
type Action struct {
// Key is the hotkey as KeyName writes it ("r", "D", "Alt-t", "go",
// "Enter", "/"); "" for none. It may not take a core key or a movement
// letter (Rules K1, K12); "Enter" is the panel's Enter action.
Key string
// Label is the action's name ("Rename"); the hotkey marker is added
// where Rules M5 puts it.
Label string
// Desc is one line: what it does to what.
Desc string
Scope Scope
// Hint is the word after the key in the panel's bottom-border hint
// ("logs" for Enter:logs); "" keeps the action out of the hint.
Hint string
// Ask, when set, asks first (Rules F6): every time.
Ask *Ask
// AskFor, when set, is asked when the action runs, after Hidden and
// Disabled, for the question it asks then (the name of the item under the
// cursor); nil asks nothing (a step that turns out to need no asking). It
// wins over Ask. Run from a menu, the confirm opens over the menu, so Esc
// on it goes back to the menu (Rules T1).
AskFor func() *Ask
// Hidden reports that its object does not exist now: the row is not
// shown at all (Rules M6).
Hidden func() bool
// Disabled reports that it cannot run now: the row is shown in the
// disabled colour, the cursor skips it and its hotkey does nothing.
Disabled func() bool
// Run from a menu, an action that opens a popup keeps the menu under it,
// to come back to (Rules T1, F4); one that opens nothing has done the
// menu's work, and the menu closes. A confirm before it is only a door:
// Esc on it goes back to the menu, and once it is accepted what the action
// does decides.
//
// Clear makes what it opens clear the menu, and the popups under it, as
// it opens (T1: the item is gone, a shell, another screen, a drill-down).
Clear bool
// Stay keeps the menu it runs from open even when it opens nothing.
Stay bool
// Detail marks a row whose Enter opens its full text over the menu (a
// worklist, Rules F1): the menu stays and its hint is Enter:detail
// (components/dialog/menu).
Detail bool
// EnterHint is the word after Enter in a menu's hint while the cursor is
// on this row ("cancel" on a work list's transfer, which asks first with
// the row's full text); "" is run, or detail with Detail
// (components/dialog/menu, work lists).
EnterHint string
// Live, when set, gives the row's label and description each time the
// menu is drawn: a work list's progress and state change while it is open
// (components/dialog/menu). The row keeps the width it had when the menu
// opened.
Live func() (label, desc string)
// ToDetails, on a panel's "Enter" action only, says whether Enter on the
// item under the cursor also sends the focus to the panel's Details: the
// one place Enter changes panels, whether and on which items being the
// app's call (Rules K3).
ToDetails func() bool
// Do runs it.
Do func() tea.Cmd
}
Action is something the user can do. One registration gives the Space menu row, the global operation popup row, the key reference row, the hotkey and the hint, so they cannot drift apart (Rules M3).
type App ¶
type App struct {
// Name is the app's name, for its environment variables (Rules E2).
Name string
// Quit is the quit flow (Rules K9): nil leaves at once, an Ask confirms
// first. A second Ctrl-C during the flow always leaves.
Quit *Ask
// QuitDesc is the Quit row's description in the global operation popup.
QuitDesc string
// QuitFlow, when set, is the quit flow itself, in place of Quit (Rules
// K9: the app's): q and Ctrl-C run it, a menu of the app's own to choose
// how to leave, say. While the popup it opens is open, a second Ctrl-C
// leaves at once, as in any quit flow.
QuitFlow func() tea.Cmd
// Global are the global operations besides switching screens and
// quitting (Principle P3); their hotkeys work on panels too (Rules M4).
Global []Action
// Status is the statusbar for w cells (layout/screen); nil for none. It
// is spans, in the app's colours (Overlay0 words, a Lavender value...):
// a value from outside (a path) has its control characters drawn by
// name (components, control characters). Cut at w.
Status func(w int) []Span
// Canvas, when set, is a screen the app draws itself, whole: a full-screen
// lock screen. The lib draws it instead of its screens, chips and footer,
// h lines of w cells, and puts its popups and toasts over it, so confirm,
// toast and every kind of input work there as anywhere (Rules E8).
Canvas func(w, h int) []string
// CanvasKey gets every key on the Canvas while no popup is open and
// reports whether it took it. Of what it leaves only Ctrl-C does
// something, the quit flow (Rules K9: App.Quit decides); no Space menu,
// no ?, no q: the screen is the app's.
CanvasKey func(key string, msg tea.KeyMsg) (bool, tea.Cmd)
// HideSecretsInPreview is the user's setting hide_secrets_in_preview,
// read from the app's settings file (tdp E3): a file preview shows only
// the first line of a private key, and nothing of a file only its owner
// may read (components/input/file-picker).
HideSecretsInPreview bool
// InputTabWidth is the user's setting input_tab_width: how many spaces
// Tab puts in a textarea, and the spaces a tab in any text is drawn as;
// 4 when unset (components/input/textarea, Rules E3).
InputTabWidth int
// ToastLines caps how many lines a toast has, the last one kept ending in
// "…"; 0 for no cap (components/dialog/toast: the app's choice).
ToastLines int
// Spinning reports that a loading icon of the app's own is on the screen
// (LoadingFrame in a row), so the lib keeps drawing it turning.
Spinning func() bool
// Progress is a long job's progress, 0 to 1, for the bar under the
// screen chips; ok false when there is none.
Progress func() (frac float64, ok bool)
// ShiftTab makes Shift-Tab go to the previous panel (Rules K2: the app's
// choice).
ShiftTab bool
// OnMsg gets the messages the lib does not handle itself.
OnMsg func(tea.Msg) tea.Cmd
// OnResize runs when the terminal changes size, after the lib has laid
// the screen out again: the place to change what depends on the width
// (which columns a list shows; Rules L1).
OnResize func(w, h int) tea.Cmd
// ForceNarrow draws every screen narrow (for showing the narrow layout).
ForceNarrow bool
// Start runs when the program starts.
Start func() tea.Cmd
// Splash is the family's easter egg, opened with V on a panel (Rules S).
// Every app has one: Run refuses an app without it.
Splash Splash
// MinWidth and MinHeight are the app's least size (Rules L1): 80 × 40 when
// unset, the most they may be. On a smaller terminal only the app's name
// and "needs a terminal of at least W×H" are drawn, in the middle; every
// key is ignored, the PTY's too, but Ctrl-C pressed twice, which leaves.
// What the app was showing comes back as the terminal grows.
MinWidth, MinHeight int
// CoreKeys are core keys of the app's own (Rules K1): each means the same
// on every panel and popup, but on a typing row, in a PTY and in a mode;
// no hotkey may take one.
CoreKeys []CoreKey
// contains filtered or unexported fields
}
App is the whole terminal UI: screens of panels, the popups over them, the footer. It is a Bubble Tea model.
func (*App) AddScreen ¶
AddScreen adds a screen. It panics when a panel registers a key that is not the app's to take (Rules K1, K12): that is a mistake in the program.
func (*App) CloseAll ¶ added in v0.2.0
CloseAll closes every popup, the lib's and the app's, each playing its own closing at the same time (Rules F2), as when what was done ends the whole stack (Rules T1; a long session started from a viewer). A confirm or an input closed this way is cancelled (OnCancel).
func (*App) ClosePopup ¶ added in v0.1.9
ClosePopup closes the popup b is the inside of, and every popup over it.
func (*App) CloseTop ¶ added in v0.2.0
CloseTop closes the n popups on top, the lowest of them animating, as the last step of a flow ends the steps under it (Rules T1); a step that has been answered is not cancelled.
func (*App) Confirm ¶
Confirm asks ask; accept runs when the user answers Enter. The popup under it stays (Rules T1, a short confirm).
func (*App) Error ¶
Error opens an error popup over the top popup (components/dialog/note): an action failed.
func (*App) ErrorAbout ¶ added in v0.2.0
ErrorAbout is Error naming what failed: subject goes after ": " in the title, kept as it is, RENAME FAILED: notes.md (components/dialog/note).
func (*App) Focus ¶ added in v0.2.0
Focus moves the focus to p, on whichever screen it is, switching to that screen. The app does it where the user expects the focus to move: after what they pressed, never on something that happened in the background (a load done, a job ended; Rules K3). A panel on no screen is left alone.
func (*App) Form ¶
Form opens a form. It panics on a field with more than five options: those go in a select or a checkbox popup (components/dialog/form); on a form with both Submit and SubmitLong; and on a button with not one of Submit, SubmitLong, Run and Open: mistakes in the program.
func (*App) LoadChecks ¶ added in v0.2.0
LoadChecks opens a checkbox popup whose options are still coming, as LoadSelect does: keep the pointer and append to Options (and Checked) while Loading is true.
func (*App) LoadSelect ¶ added in v0.2.0
LoadSelect opens a select whose options are still coming: keep the pointer and append to Options while Loading is true. Meanwhile the title has the loading icon and the popup is as wide as it can be, its width not known when it opens (Rules F7).
func (*App) Log ¶ added in v0.4.0
Log writes to the App Log: in kind's level (Info INFO, Success OK, Warning WARN, Error ERR), at the App's time. Every toast and error popup is logged by itself; the app logs the actions it does and their results and what it does in the background (moving its files, defaults it made at the start, the details of what it could not reach). It may be called from any goroutine; the screen shows it with the next frame.
func (*App) Menu ¶
func (a *App) Menu(title string, sections ...MenuSection) tea.Cmd
Menu opens a menu of sections (Rules M8); running a row closes the menu and everything under it.
func (*App) MenuAbout ¶ added in v0.2.0
func (a *App) MenuAbout(title, subject string, sections ...MenuSection) tea.Cmd
MenuAbout is Menu for one thing: subject goes after ": " in the title, kept as it is, OPEN WITH: notes.md (components, upper case).
func (*App) MoveAside ¶ added in v0.4.0
MoveAside asks what to do with a file of the app's own it cannot read (Rules E3, when it cannot be read): its settings, its state or its data, whatever the reason (a bad format, a broken file, no permission). The confirm, MOVE ASIDE, names the path and why:
- Enter (move) renames the file to <name>.bak (.bak.1, .bak.2… when that is taken: never over another), logs it and runs fresh, where the app starts a new one in the same place (its defaults for settings, empty state or data) and goes on.
- Esc (quit) leaves the app: Run returns the path and the reason, for main to write to stderr as it does any error of Run.
A cache that cannot be read is not asked about: throw it away and build it again. Something outside the app that cannot be reached (a cluster, the network) is not the app's own: the app goes on and says so where it shows it (layout/panel, loading and errors).
func (*App) Number ¶
func (a *App) Number(in NumberInput) tea.Cmd
Number opens a number input popup.
func (*App) OpenTerminal ¶
OpenTerminal opens a terminal popup with t in it, starting it if it has not started (components/dialog/terminal).
func (*App) Password ¶
func (a *App) Password(in PasswordInput) tea.Cmd
Password opens a password input popup.
func (*App) PickColor ¶
func (a *App) PickColor(c ColorPicker) tea.Cmd
PickColor opens a color picker.
func (*App) PickDate ¶
func (a *App) PickDate(d DatePicker) tea.Cmd
PickDate opens a date (or date and time) picker.
func (*App) PlaySplash ¶ added in v0.2.0
PlaySplash plays s over the whole screen now, from its first frame, as V does with the app's own (Rules S): a splash the app shows of its own accord, a mark being designed, say. Any key closes it.
func (*App) Popup ¶ added in v0.1.9
Popup opens p over what is on top. It panics when p.Body is nil or not comparable: that is a mistake in the program.
func (*App) Run ¶
Run asks the terminal how wide an icon is and what its colours are, then runs the app in the alternate screen. When the user leaves on MoveAside's Esc it returns the path that cannot be read and why, for main to write to stderr (Rules E3).
func (*App) ShowScreen ¶ added in v0.2.0
ShowScreen switches to s, as its chip's key does (Rules K3: when the user expects it).
func (*App) Tick ¶ added in v0.3.0
Tick is tea.Tick on the App's clock. A timer of the app's own made with it (a debounce, a message that goes after a while) waits, under a test that drives the App, until the test moves the time on (tdptest); one made with tea.Tick runs on the real clock there too.
func (*App) Toast ¶
Toast shows a short message from the bottom (components/dialog/toast); a second one replaces the first and starts its time again.
type Ask ¶
type Ask struct {
Title string // the action's name, after the shield glyph: "Delete"
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
Question string // the last line: "Delete web-a8k2?"
Verb string // Enter:<verb> in the hint: "delete"
Details []string // what to read before answering, above the question
Warn []int // which lines of Details are warnings (Peach)
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
}
Ask is a confirm popup (components/dialog/confirm): Enter accepts, Esc cancels.
type Body ¶
type Body interface {
// Draw returns h lines of exactly w cells: the inside of the frame.
Draw(w, h int, focused bool) []string
// Key handles a key the panel did not take; it reports whether it did
// something with it. Movement keys arrive here.
Key(key string, msg tea.KeyMsg) (bool, tea.Cmd)
// HasItem reports whether the cursor is on an item, so that item
// operations apply (Rules M2).
HasItem() bool
// Scroll is the scroll position for the bottom border after the last
// Draw ("3 of 40", "1-20 of 120"), "" when everything fits.
Scroll() string
// MoveKeys are the movement keys that work here, for the key
// reference's move section (Rules K6).
MoveKeys() []KeyRow
}
Body is what is inside a panel's frame. The lib has List, Values and Text; an app that draws its own content implements Body itself.
type Checks ¶
type Checks struct {
Title, Glyph string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
Options []string
Checked []bool
// Cursor is the option the cursor starts on, scrolled into sight; the
// app decides (components/input/checkbox). 0, the first, by default.
Cursor int
// Surface2, the tick too, but the cursor stops on it and Space flips it
// like any other; what it means is the app's (components/input/checkbox).
Unavailable func(i int) bool
// Loading, for a checkbox popup opened with LoadChecks, is true while
// Options are still coming; Checked may be shorter than Options.
Loading bool
// Done gets the new set. It is not called when nothing changed.
Done func([]bool) tea.Cmd
// Commit, when set, writes a changed value back when Enter takes it, on
// the update loop, before Done: an error keeps the popup open with the
// value in it and opens an error popup over it, "RENAME FAILED"
// (components/layout/popup, the action failing; Rules F4).
Commit func([]bool) error
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
}
Checks picks several values (components/input/checkbox, the checkbox popup): Space checks a row on screen only, Enter writes the whole set back.
type Color ¶
Color is a colour or no colour (the terminal's own).
func LayerColor ¶
LayerColor is the colour of the popup at layer k, the bottom one being 1; layer 4 and up are Sapphire. A toast is always layer 1.
type ColorPicker ¶
type ColorPicker struct {
Title, Glyph string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
// Value is the colour now; one not Set is no colour yet (the theme's
// own): old shows none and no swatch, new starts from #000000, and Choose
// always counts as a change (components/input/color-picker).
Value Color
// Done gets the new colour. It is not called when it did not change.
Done func(Color) tea.Cmd
// Commit, when set, writes a changed value back when Enter takes it, on
// the update loop, before Done: an error keeps the popup open with the
// value in it and opens an error popup over it, "RENAME FAILED"
// (components/layout/popup, the action failing; Rules F4).
Commit func(Color) error
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
}
ColorPicker picks a colour (components/input/color-picker): old and new side by side, the red, green and blue channels each chosen from a select.
type Column ¶
type Column struct {
// Title is the column's header. A list of one column whose Title is ""
// has no header.
Title string
// Number marks a number column: right-aligned and sorted by value (9
// before 10). Text columns are left-aligned and sorted as text.
Number bool
// Flex did let the column give up room first when the panel is narrow. It
// does nothing since tdp v0.8.0: mark a long column Shrink.
Flex bool
// Shrink marks a column of long values (a name, a URL, a line of text):
// the shrinkable columns share the width the others leave, cut each its
// own way when too long, down to MinWidth (12 cells when unset). The
// other columns, short values (a state, a number, a date), keep the width
// of their widest value (layout/panel).
Shrink bool
MinWidth int
// Drop is when the column is taken away, whole and its header with it,
// when the columns do not fit even with the shrinkable ones at their
// MinWidth: 1 first, then 2 and on; 0 never (the name). As the panel
// grows they come back in order, and the shrinkable ones grow back
// (layout/panel).
Drop int
// Path cuts the column's values from the front ("…/.ssh/id_ed25519").
Path bool
// Middle cuts the column's values in the middle, for a value whose two
// ends both matter ("demo-app…66-gm72n").
Middle bool
}
Column is one column of a List (layout/panel, ordinary lists).
type DatePicker ¶
type DatePicker struct {
Title, Glyph string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
// Value is the value now; zero for none.
Value time.Time
// Time adds the hour and the minute (five minutes a step).
Time bool
// Min and Max limit the dates; zero for no limit.
Min, Max time.Time
// SundayFirst starts a week on Sunday instead of Monday.
SundayFirst bool
// Done gets the new value. It is not called when it did not change.
Done func(time.Time) tea.Cmd
// Commit, when set, writes a changed value back when Enter takes it, on
// the update loop, before Done: an error keeps the popup open with the
// value in it and opens an error popup over it, "RENAME FAILED"
// (components/layout/popup, the action failing; Rules F4).
Commit func(time.Time) error
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
}
DatePicker picks a date, or a date and a time (components/input/datetime-picker).
type Failure ¶
type Failure struct {
Fact, Hint string
}
Failure is what a panel shows when its content could not be had (layout/panel, loading and errors): a fact in Red and a hint naming a key.
type Field ¶
type Field struct {
Label string
// Value is the value as shown (components/input/README, how a value is
// shown); Empty is what an empty value means, shown in grey ("not set").
// A control character in it, ESC too, is drawn by its name (Escape).
Value func() string
// Styled, when set, is how the value is shown in colours of the app's own
// (a swatch, ColorSpans; a state in Green): each piece's text drawn as
// Value's is. Value stays what the value is.
Styled func() []Span
Empty string
// Path cuts a value too long from the front: "…/.ssh/id_ed25519".
Path bool
// Options make the field a radio drawn in place: Selected is the chosen
// one. With Multi it is a group of checkboxes: Checked says which.
Options []string
Selected int
Multi bool
Checked []bool
// OptionUnavailable reports a checkbox option that is not available:
// drawn in Surface2, the tick too, but stopped on and flipped like any
// other (components/input/checkbox).
Disabled func() bool
// Err marks the field's value as wrong: its label turns Red.
Err func() bool
// Edit is what Enter does on a field that is not drawn in place: open its
// input popup.
Edit func() tea.Cmd
// OnChange runs when a radio or checkbox changes in place; it takes
// effect at once (there is no submit).
OnChange func() tea.Cmd
// Desc, when set, says what the row means, for the "what each row is"
// section first in the panel's key reference: the label is a word or
// two (layout/panel, components/dialog/note). Whether a panel has the
// section is the app's: it has it when a field has a Desc.
Desc string
}
Field is one value of a Values panel (layout/panel, one value per row).
type FilePicker ¶
type FilePicker struct {
// Title is the field's name: the title writes the directory after it
// ("IDENTITY FILE · ~/.ssh").
Title, Glyph string
// Root is the directory the list opens in: a start, not a boundary.
Root string
// Value is the file now, if any: the cursor starts on it, in Green.
Value string
// Dirs picks a directory (components/input/file-picker, choosing a
// directory). Open it at the directory now (Root = Value): the cursor
// starts on ".", in Green.
Dirs bool
// Icon is a row's icon and its colour, the app's choice (a file type's
// colour); a folder or a file glyph in Text when unset.
Icon func(path string, dir bool) (string, Color)
// Done gets the chosen file (or directory). It is not called when it did
// not change.
Done func(path string) tea.Cmd
// Commit, when set, writes a changed value back when Enter takes it, on
// the update loop, before Done: an error keeps the popup open with the
// value in it and opens an error popup over it, "RENAME FAILED"
// (components/layout/popup, the action failing; Rules F4).
Commit func(path string) error
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
}
FilePicker picks a file (components/input/file-picker): a finder over a directory, Enter going into a directory or choosing a file. With Dirs it picks a directory instead: only directories are listed, and Enter on the first row, ". (this directory)", chooses the one listed.
type FilePreview ¶ added in v0.2.0
type FilePreview struct {
Path string
// Line is a text file's line to start near: a search's hit.
Line int
// FS is where it reads: the local disk when nil.
FS PreviewFS
// Icon is a tree entry's icon and its colour, as a FilePicker's.
Icon func(path string, dir bool) (string, Color)
// Info puts TYPE, SIZE, MODIFIED and MODE under the preview, after a
// separator.
Info bool
// EmptyFact and EmptyHint are what it says with no Path.
EmptyFact, EmptyHint string
// contains filtered or unexported fields
}
FilePreview is a panel's body that shows a file or a directory as a file-picker's preview does: a tree, a text file in colour with line numbers, an image, a PDF, hex; with Info, its four facts under it (components/input/file-picker). As a details panel it follows its list's cursor: set Path in the list's OnMove (layout/panel, details). It takes no keys and does not scroll, as a preview does not.
func (*FilePreview) Draw ¶ added in v0.2.0
func (p *FilePreview) Draw(w, h int, _ bool) []string
Draw draws the preview in w × h, one cell from the frame on either side.
func (*FilePreview) Empty ¶ added in v0.2.0
func (p *FilePreview) Empty() bool
Empty reports whether there is nothing to show, for the panel's loading and failure.
func (*FilePreview) HasItem ¶ added in v0.2.0
func (p *FilePreview) HasItem() bool
HasItem is false: a preview has no item of its own.
func (*FilePreview) MoveKeys ¶ added in v0.2.0
func (p *FilePreview) MoveKeys() []KeyRow
MoveKeys are none.
func (*FilePreview) Scroll ¶ added in v0.2.0
func (p *FilePreview) Scroll() string
Scroll is "": a preview does not scroll.
type Finder ¶
type Finder struct {
Title, Glyph string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
// Verb is what Enter on the list does, for the hint ("open").
Verb string
Items []FinderItem
Loading bool
// Preview is the row under the cursor: a title (its name, or where it
// is) and the lines to show.
Preview func(FinderItem) (title string, lines []string)
// Files says the items are files and directories, their IDs the paths:
// the preview shows them as a file-picker does, with their facts under
// it (components/input/file-picker), instead of Preview.
Files bool
// FS is where Files reads the paths: the local disk when nil.
FS PreviewFS
// Search, when set, is a search the app runs itself (a search tool, a
// remote host), answering a batch at a time: it gets the typed words each
// time they change and puts what it finds in Items as it comes, Loading
// meanwhile; the list is then Items as they are, not filtered again. It
// must not wait for the search: typing goes on while it runs
// (components/input/finder).
Search func(typed string) tea.Cmd
Done func(FinderItem) tea.Cmd
}
Finder is a list with a search that goes somewhere (components/input/finder): type to narrow the list, Enter on a row to go there, the row under the cursor previewed beside it. Keep the pointer: rows may keep arriving — append to Items while Loading is true.
type FinderItem ¶
type FinderItem struct {
ID string // the app's own key for it
Text string // shown, and matched unless Match is set
// Match, when set, is what the typed words are matched against instead
// of Text: the item's other content, a file's text (components/input/finder:
// what is matched is the app's choice).
Match string
// Icon, when set, goes before the text in IconColor (a file's type).
Icon string
IconColor Color
// Line, with Files, is a text file's line a search found: the preview
// starts near it.
Line int
}
FinderItem is one row of a Finder.
type Form ¶
type Form struct {
Title, Glyph string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
// Name is the form in the discard question: "Discard changes to New host?"
Name string
Fields []*FormField
// Button is the main submit button's text: what the form does ("Save").
// ButtonSubject is the name it acts on, kept as it is after the verb on
// the button and in the hint: "Overwrite KBU.svg", "Enter:overwrite
// KBU.svg" (components/dialog/form, hint).
Button, ButtonSubject string
// Buttons are the action area's other buttons, row by row from the top,
// each row on the right. The main submit goes at the end of the last
// row, the bottom right; an empty last row puts it on a row of its own.
Buttons [][]*FormButton
// Focus, when set, is the field the form opens on.
Focus *FormField
// Submit does what the form is for once every Check passes. An error
// opens an error popup over the form, which stays; otherwise the form
// closes and the command runs.
Submit func() (tea.Cmd, error)
// SubmitLong is a Submit that takes long ("Connect"), in its place: it
// runs off the update loop, the loading icon after the title and Enter
// on its button doing nothing until it ends. ctx ends when the form
// closes first; what it returns then is dropped (components/dialog/form).
SubmitLong func(ctx context.Context) (tea.Cmd, error)
// OnCancel runs when it closes without being submitted: Esc, its discard
// confirm, or the popup it is over closing it, as an Ask's and an input's
// do (Rules F6).
OnCancel func() tea.Cmd
}
Form is several values filled in and submitted together (components/dialog/form): Enter on a field opens its input popup, options are chosen on the form, the button submits.
type FormButton ¶ added in v0.1.7
type FormButton struct {
// Label is what it does ("Overwrite"); Subject the name it acts on, kept
// as it is, as the form's ButtonSubject.
Label, Subject string
// Submit makes it another submit ("Save As"): it checks the whole form
// as the main one does, and the form closes once it is done. SubmitLong
// is one that takes long, as the form's.
Submit func() (tea.Cmd, error)
SubmitLong func(ctx context.Context) (tea.Cmd, error)
// Run makes it an action that keeps the form open ("Test"). It checks
// Needs first, the fields it needs (their Check); then it runs off the
// update loop, the loading icon after the title and Enter on it doing
// nothing until it ends. ctx ends when the form closes first; its result
// is then dropped, Apply too.
Needs []*FormField
Run func(ctx context.Context) FormResult
// Open makes it an action that opens a popup over the form, on the update
// loop, the form staying under it: a terminal popup (OpenTerminal) that
// copies a key to the host, say. Back, when set, runs as the popup it
// opened closes and the form is on top again: where the app reads what
// was done there into the fields; true counts as a change to the form.
Open func() tea.Cmd
Back func() (changed bool)
}
FormButton is a button of a form's action area besides the main submit (components/dialog/form): another submit, or an action that keeps the form open. It has one of Submit, SubmitLong, Run and Open.
type FormField ¶
type FormField struct {
Label string
// Stacked puts the label on a row of its own and the value under it, as
// wide as the inside: for long values (a URL, a path, a command).
Stacked bool
// Value is the value as shown (components/input/README, how a value is
// shown); Empty is what an empty value means, in grey ("not set").
Value func() string
// Styled, when set, is how the value is shown in colours of the app's
// own (a swatch, ColorSpans): each piece's text drawn as Value's is
// (Escape). Value stays what the value is.
Styled func() []Span
Empty string
// Path cuts a value too long from the front: "…/.ssh/id_ed25519".
Path bool
// Edit makes the input popup Enter opens, when it opens: it starts from
// the value then.
Edit func() Input
// Options make the field a radio drawn on the form, at most five
// (Selected is the chosen one); with Multi, a group of checkboxes
// (Checked says which).
Options []string
Selected int
Multi bool
Checked []bool
// OptionDisabled reports an option that cannot be chosen now: drawn in
// the disabled colour and skipped (components/dialog/form).
OptionDisabled func(i int) bool
// OptionUnavailable reports a checkbox option that is not available:
// drawn in Surface2, the tick too, but stopped on and flipped like any
// other (components/input/checkbox).
Disabled func() bool
// Check is the whole form's rule for this field (required, depends on
// another field, a name taken), run when the form is submitted: what is
// wrong, or "".
Check func() string
}
FormField is one field of a Form (components/dialog/form).
type FormResult ¶ added in v0.1.7
type FormResult struct {
Toast string
Info bool
Lines []string
Err error
// Apply, when set, runs on the update loop as it ends, before the result
// shows: where the action writes a value into a field, which then counts
// as changed.
Apply func()
}
FormResult is what came of a form's action (components/dialog/form): Err opens an error popup, the focus on the button so that Enter tries again; else Lines open a note to read; else Toast says it in one sentence, a Success toast, or Info when Info is set: which one a thing done is, is the app's (components/dialog/toast).
type Input ¶
type Input interface {
// contains filtered or unexported methods
}
Input is an input popup to open on its own (App.Open) or from a form's field: TextInput, PasswordInput, NumberInput, Select, Checks, and the rest.
type KeyHint ¶
type KeyHint struct {
Key, Desc string
}
KeyHint is one "key:what" pair of a hint or the footer (Rules M5).
type KeySection ¶
KeySection is a titled section of a key reference ("terminal").
type List ¶
type List struct {
Columns []Column
// Marks keeps a column for marks in front of every row (Principle P3,
// batches of marked items).
Marks bool
// Draggable keeps that column too, for the swap glyph of the row held in
// a Drag mode (layout/panel): Hold, MoveHeld, Drop.
Draggable bool
// Filterable lets / open a panel filter on the list.
Filterable bool
// EmptyFact and EmptyHint are what an empty list says (layout/screen,
// empty states); keys in the hint written in brackets.
EmptyFact, EmptyHint string
// Location, when set, is the list's location row: where the user is (a
// directory, a remote path, the level drilled into), in Lavender on the
// panel's first row, cut from the front. It is only shown: the cursor
// does not stop on it and the scroll position does not count it
// (layout/panel, location row). Whether a list has one is the app's.
Location string
// OnMove runs when the cursor comes to another row, by a key or not, the
// first time included: before the frame is drawn, so a details panel
// shows that row in the same frame (layout/panel, details). It does not
// run while no row is under the cursor.
OnMove func(Row) tea.Cmd
// contains filtered or unexported fields
}
List is a panel body with one item per row: a header, a cursor, marks, a panel filter (layout/panel).
func (*List) Draw ¶
Draw draws the list in w × h: the location row, the filter's typing row, the header, the rows.
func (*List) Drop ¶ added in v0.1.6
func (l *List) Drop()
Drop puts the held row down where it is; its own mark shows again.
func (*List) Focus ¶
func (l *List) Focus()
Focus is called when the panel gets the focus: a list with a filter set goes straight back to its typing row.
func (*List) Hold ¶ added in v0.1.6
Hold picks up the row under the cursor in the panel's Drag mode (layout/panel): it is drawn as the cursor in the mode's colour, Yellow, with the swap glyph in its mark column, until Drop. It reports whether there was a row. The Drag mode and its keys are the app's (Panel.EnterMode).
func (*List) MoveHeld ¶ added in v0.1.6
MoveHeld swaps the held row with the next or the previous row shown, the cursor going with it. Past the ends it wraps: the last moved down goes to the top and the others move down one (Rules K12). It moves the rows themselves: a sorted list shows no move, so the app leaves the sort first.
func (*List) MoveKeys ¶
MoveKeys are the list's movement keys; none when nothing is shown, nothing to move to (Rules M6).
func (*List) OpenFilter ¶
func (l *List) OpenFilter()
OpenFilter puts a typing row at the top of the list, or goes back to it to type on (layout/panel, panel filter).
func (*List) Select ¶
Select puts the cursor on the row with this ID, the next frame scrolling it into sight, and reports whether it is shown. After the app adds an item (New, Copy, Import), it selects it (Rules K3); a row the panel filter hides is not shown, so the app clears the filter first if it wants it seen.
func (*List) SetMarked ¶ added in v0.2.0
SetMarked marks the rows with these IDs and unmarks the others, the rows the panel filter hides too.
func (*List) SetRows ¶
SetRows replaces the list's rows, keeping the cursor on the same row when it is still there.
func (*List) SortBy ¶
SortBy sorts the list by keys, first key first: numbers by value, text as text (layout/panel). nil keeps the rows' order. Rows the keys cannot tell apart go by their IDs, so the same rows come out in the same order however they were set: a list must keep one order every time it is opened or fetched again, and data with no order of its own (a kubeconfig's contexts) is sorted by name.
func (*List) ToggleMark ¶
func (l *List) ToggleMark()
ToggleMark marks or unmarks the row under the cursor.
type MenuSection ¶
MenuSection is a group of a menu's rows under a title. A menu of one group needs none; in a menu of more, every group has one, the first too (Rules M8).
type Mode ¶
type Mode struct {
Name string // shown at the right of the top border: one word
// Keys are the mode's own keys: the only ones that work besides the
// core keys of K11. They are listed in its key reference and the footer.
Keys []ModeKey
// Exit is the verb Esc does in the footer ("cancel" for Esc:cancel).
Exit string
// Pause suspends Tab and the digits in the mode; pressing them then says
// to leave the mode first.
Pause bool
// OnExit runs when Esc leaves the mode, to go back to the state before it.
OnExit func() tea.Cmd
}
Mode is a temporary state of a panel in which some keys mean something of their own and Esc leaves (Rules K11).
type ModeKey ¶
type ModeKey struct {
// Key is how it is written in the footer and the key reference ("j|k");
// Keys are the keys it takes, Key itself when empty.
Key string
Keys []string
Desc string
NoFooter bool
// Do runs it, with the key pressed.
Do func(key string) tea.Cmd
}
ModeKey is one of a mode's keys.
type NumberInput ¶
type NumberInput struct {
Title, Glyph, Prompt, Verb string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
// Name is the value's name in its errors ("Port must be 1-65535"); left
// unset, the title names it.
Name string
Old string
// Suggest is a value the app proposes when there is no Old, as on a
// TextInput.
Suggest string
Min, Max float64
Negative bool // "-" may be typed
Decimal bool // "." may be typed
// Optional lets the value be empty: an empty one is not checked against
// the range and is written back empty; what it means the form or panel
// says in grey (components/input/number). Otherwise empty is an error.
Optional bool
// Unit is what the number counts, the whole word ("seconds"), in grey on
// a row of its own under the value (components/input/number).
Unit string
Check func(string) error
Done func(string) tea.Cmd
// Stay keeps it open under what Done opens: a step of a flow (current
// PIN, new PIN, confirm PIN), each step a popup of its own, Esc on the
// next one coming back here (Rules F1, F4). The app ends the flow with
// CloseTop when its last step is done (T1).
Stay bool
// Commit, when set, writes a changed value back when Enter takes it, on
// the update loop, before Done: an error keeps the popup open with the
// value in it and opens an error popup over it, "RENAME FAILED"
// (components/layout/popup, the action failing; Rules F4).
Commit func(string) error
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
// Unchanged, when set, runs when Enter takes the value it opened with, so
// nothing is written back and Done is not called: a step of a flow ends
// the flow (CloseTop), a page waiting for an answer gets the value it
// offered (Rules K3, F6).
Unchanged func() tea.Cmd
}
NumberInput is a number (components/input/number).
type Pager ¶
type Pager struct {
Follow bool
// EmptyFact and EmptyHint are what it says with no lines.
EmptyFact, EmptyHint string
// contains filtered or unexported fields
}
Pager is a panel body that shows lines with no cursor: a preview, a log. When Follow is set, new lines keep it at the bottom as long as it was there (streaming content). Its lines are reading content, drawn as a terminal draws them (components, control characters): \n starts another line, a \r in one leaves its last state, SGR colours it, a tab is spaces, any other control character is its name in Red.
func (*Pager) HasItem ¶
HasItem is false: a text has no items (Rules K3: Enter works on the whole panel).
func (*Pager) MoveKeys ¶
MoveKeys are the scrolling keys; none when every line fits, nothing to scroll (Rules M6).
type Panel ¶
type Panel struct {
// Label is the panel's name after its [N]. With tabs it is the first
// tab's name: a panel has no other name (layout/panel, tabs).
Label string
// Name, when set, is the name of the one thing the panel shows, kept as it
// is after the label, upper case, and ": " ([2] PODS: nginx-7d4f); with no
// Label it is the whole label ([1] prod-web-01). The Space menu and the
// key reference write it so too (components, upper case).
Name string
// Tabs are the panel's other tabs, after the label's own. Tab is the
// current one, 0 being the label's; h/l switch tabs and call OnTab.
Tabs []string
Tab int
OnTab func(tab int) tea.Cmd
Body Body
// Actions are the panel's item and panel operations; a "Enter" key is
// what Enter does here (Rules K3).
Actions []Action
// Details is the panel that shows the item under this panel's cursor
// (components/layout/panel, details): the "Enter" action may send the
// focus there (Action.ToDetails).
Details *Panel
// Stream marks streaming content, which is not dimmed when unfocused
// (Rules T2).
Stream bool
// Loading puts the loading icon after the capsule chain; LoadingText is
// what an empty panel says meanwhile ("loading pods…").
Loading bool
LoadingText string
// Fail, when set and the panel has nothing to show, is shown in its middle.
Fail *Failure
// OnEsc is the app's "one level up" for Esc on this panel (Rules K4); it
// reports whether there was one.
OnEsc func() tea.Cmd
// HintPressableOnly leaves what cannot run now out of the bottom-border
// hint (Rules M6: the app's choice); otherwise it is listed in the
// disabled colour, as in the Space menu and ?.
HintPressableOnly bool
// OtherKeys are sections of its ? about another surface that has no key
// reference of its own (Rules M6: a PTY, a grid), after the panel's own.
OtherKeys []KeySection
// contains filtered or unexported fields
}
Panel is a region of a screen with its own cursor and content (Principle "Panel"). It is numbered by its place in its screen, from [1].
type PasswordInput ¶
type PasswordInput struct {
Title, Glyph, Prompt, Verb string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
// Name is the value's name in its errors when the title is not
// ("Password" on a "Log in"); left unset, the title names it.
Name string
// Set says a password exists now: eight grey dots stand for it.
Set bool
// Unlock is the unlock look: one ● per character, a cell apart, centred
// (a PIN), and no prompt row: the title says what to type (UNLOCK,
// CURRENT PIN); otherwise one • per character from the left.
Unlock bool
MaxLen int
Check func(string) error
// PausedUntil, when set, is asked when the popup opens and after each
// Enter: until the time it gives, the popup takes no value, the error row
// counting down each second ("try again in 27 s") and every key but Esc
// swallowed (a PIN wrong too many times; components/layout/popup, the
// error row).
PausedUntil func() time.Time
// Done gets the new password; "" with clear true when it was removed.
Done func(value string, clear bool) tea.Cmd
// Stay keeps it open under what Done opens: a step of a flow (current
// PIN, new PIN, confirm PIN), each step a popup of its own, Esc on the
// next one coming back here (Rules F1, F4). The app ends the flow with
// CloseTop when its last step is done (T1).
Stay bool
// Commit, when set, writes a changed value back when Enter takes it, on
// the update loop, before Done: an error keeps the popup open with the
// value in it and opens an error popup over it, "RENAME FAILED"
// (components/layout/popup, the action failing; Rules F4).
Commit func(value string, clear bool) error
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
// Unchanged, when set, runs when Enter takes the value it opened with, so
// nothing is written back and Done is not called: a step of a flow ends
// the flow (CloseTop), a page waiting for an answer gets the value it
// offered (Rules K3, F6).
Unchanged func() tea.Cmd
}
PasswordInput is a masked input (components/input/password).
type Popup ¶ added in v0.1.9
type Popup struct {
// Title is what the popup is for, upper case on the frame; Subject is
// the one thing it acts on, kept as it is after ": " ("DRAW: kamonu";
// components/layout/popup). Glyph goes before the title.
Title, Glyph, Subject string
Body PopupBody
}
Popup is a popup of the app's own, for what none of the lib's popups holds (a grid to draw on). The app draws what is inside the frame and handles its keys; the lib draws the frame with the title and the hint in the layer colour, dims what is under it, opens and closes it with the animation (Rules F2, F8), and puts its own popups over it: a confirm, an input, an error popup, the key reference.
type PopupBody ¶ added in v0.1.9
type PopupBody interface {
// Size is the inside on a sw × sh screen: w cells from frame line to
// frame line, h rows between the blank rows above and below. It is asked
// when the popup opens and when the terminal changes size; the lib makes
// it wide enough for the title and the hint, and no bigger than the
// screen allows (Rules F7).
Size(sw, sh int) (w, h int)
// Draw returns h lines of w cells; layer is the popup's colour. The cell
// at either end is the blank margin, which only a full-row cursor covers
// (components/layout/popup).
Draw(w, h int, layer Color) []string
// Key handles a key while the popup is on top and reports whether it
// did. The lib does the keys it leaves: Esc closes the popup, ? opens its
// key reference, q starts the quit flow (Rules K1). Ctrl-C never comes
// here: it is always the quit flow (K9).
Key(key string, msg tea.KeyMsg) (bool, tea.Cmd)
// Hint is the hint on the bottom frame line now (Rules M5).
Hint() []KeyHint
// Keys is its key reference: only its own keys, Esc among them (Rules K6).
Keys() []KeySection
}
PopupBody is the inside of a popup of the app's own. It must be comparable, a pointer most often: ClosePopup finds the popup by it.
A body may also have QuitNote() string: what quitting now would lose ("Changes to kamonu are not saved."), "" for nothing. The quit flow's confirm puts it last, in Peach, and asks first even when App.Quit is nil (Rules K9: the quit flow is the app's).
A body that scrolls may also have Scroll() string: its scroll position ("3 of 40", "1-20 of 120"), "" when everything fits. The lib draws it on the right of the bottom frame line in the layer colour and, when the popup opens, makes it wide enough for it and the whole hint (components/layout/popup, when the content does not fit).
type PreviewFS ¶ added in v0.2.0
type PreviewFS interface {
Open(name string) (PreviewFile, error)
Stat(name string) (fs.FileInfo, error)
// Lstat does not follow a link, ReadLink says where one points: a link's
// TYPE is "link → <target>".
Lstat(name string) (fs.FileInfo, error)
ReadLink(name string) (string, error)
ReadDir(name string) ([]fs.FileInfo, error)
}
PreviewFS is where a file preview reads: the local disk when nil, or a file system the app gives, such as a remote host's over SFTP, so its files get the same preview, tree and facts (components/input/file-picker, the preview). Paths are the app's own, slash-separated as SFTP's are.
type PreviewFile ¶ added in v0.2.0
PreviewFile is an open file of a PreviewFS: read from its start, or at an offset (a PDF, a zip).
type ProbeResult ¶
type ProbeResult struct {
IconCells int // cells a Nerd Font icon takes
PowerlineCells int // cells a powerline symbol takes
// IconFrom and PowerlineFrom say where each came from: the variable's
// name, "probe", or "default".
IconFrom, PowerlineFrom string
Palette int // how many of the 16 colours the terminal reported (OSC 4)
}
ProbeResult is what Probe found out about the terminal.
func Probe ¶
func Probe(app string) ProbeResult
Probe finds out, before Bubble Tea takes the terminal, how many cells an icon and a powerline symbol take (tdp E5) and the terminal's 16 colours (components/color, dimming). Each width comes from the app's variable (<APP>__ICON_WIDTH, <APP>__POWERLINE_WIDTH), then the family's (TERMINU__ICON_WIDTH, TERMINU__POWERLINE_WIDTH), then the one brought over ssh (LC_TERMINU_ICON_WIDTH, LC_TERMINU_POWERLINE_WIDTH), then asking the terminal where the cursor ended up after printing one (CPR, unix only). The palette is asked for with OSC 4 at the same time; colours the terminal does not report stay xterm's. Probe sets the lib's widths and palette and reports what it found.
type Reorder ¶ added in v0.1.6
type Reorder struct {
Title, Glyph string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
Options []string
// Done gets the new order: the options' indexes as they now stand
// ([2 0 1]: the third first). It is not called when the order did not
// change.
Done func(order []int) tea.Cmd
// Commit, when set, writes a changed value back when Enter takes it, on
// the update loop, before Done: an error keeps the popup open with the
// value in it and opens an error popup over it, "RENAME FAILED"
// (components/layout/popup, the action failing; Rules F4).
Commit func(order []int) error
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
}
Reorder puts a set of items in an order by hand (components/input/reorder): the panel's Drag mode in a popup. D picks up the item under the cursor, j|k move it, Enter drops it; Enter with nothing held writes the order back.
type Row ¶
type Row struct {
ID string // what marks are kept by; the row's place when empty
// Cells are the row's text, one per column: a control character in one,
// ESC too, is drawn by its name (Escape; layout/panel). The filter and
// sorting go by them.
Cells []string
// Styled, when set for a cell, is how it is drawn in colours of the app's
// own: each piece's text drawn as a cell's is. The cell's text stays in
// Cells.
Styled [][]Span
// Sort, when set, are the values sorted by instead of the cells (an age
// shown as "3d" sorted by seconds).
Sort []string
// SortGroup keeps rows apart when the list is sorted: the lower group
// first, sorting only within each (a file manager's directories before its
// files); no title is drawn between them (layout/panel). The rows of one
// group keep their order when the list is not sorted.
SortGroup int
// Group is the title of the group the row is in (layout/panel, groups).
// A group's rows stay together, the groups in the order they first
// appear, sorted within; the rows are drawn two cells further in, under
// a title the cursor skips. A group with no row shown has no title.
Group string
}
Row is one item of a List.
type Screen ¶
type Screen struct {
// Name is the screen's chip and its row in the global operation popup
// ("Panels"); Key is its global hotkey ("P"). Desc is that row's
// description.
Name, Key, Desc string
Panels []*Panel
// Layout places the panels in the panel area, one Rect each; nil puts
// them side by side in equal widths. How a screen is laid out is the
// app's (Rules L1).
Layout func(w, h int) []Rect
// NarrowBelow is the width under which only the focused panel is drawn,
// across the whole width (layout/screen, narrow); at most 80.
NarrowBelow int
// contains filtered or unexported fields
}
Screen is a set of panels shown together (Principle "Screen"). A screen's panels are numbered from [1] by their order (Rules K1).
type Select ¶
type Select struct {
Title, Glyph string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
Options []string
// Keys, when set, are the options' hotkeys (Rules M5); "" for none.
Keys []string
// Selected is the value now; -1 for none.
Selected int
// Loading, for a select opened with LoadSelect, is true while Options
// are still coming.
Loading bool
// Done gets the chosen option. It is not called when the value did not
// change.
Done func(int) tea.Cmd
// Commit, when set, writes a changed value back when Enter takes it, on
// the update loop, before Done: an error keeps the popup open with the
// value in it and opens an error popup over it, "RENAME FAILED"
// (components/layout/popup, the action failing; Rules F4).
Commit func(int) error
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
}
Select picks one value from a list (components/input/select).
type Selection ¶
type Selection struct {
Key string // "v"
Name string // the mode's name on the frame: "Visual"
CopyKey string // "y" when unset
// Copy takes the text copied. Unset, it goes on the terminal's
// clipboard and a Success toast says so (components/dialog/note).
Copy func(text string) tea.Cmd
}
Selection is a viewer's selection mode: Key brings the cursor out at the start of the first line in sight, Key again starts the selection where it is, the cursor moves through the text (h|j|k|l, w|b|e, 0|$), CopyKey hands the selected text to Copy and leaves; Esc leaves.
type Slider ¶
type Slider struct {
Title, Glyph string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
Bottom, Top float64
// Step is the distance between two numbers: (Top − Bottom) / 10 when 0.
Step float64
Value float64
// Done gets the new number. It is not called when it did not change.
Done func(float64) tea.Cmd
}
Slider is a number in a range, shown as a track (components/input/slider). It has no keys of its own: Enter opens a select of the numbers from Bottom to Top, Step apart.
type Span ¶ added in v0.4.0
Span is a piece of text in a style of the app's own, for the places an app colours text it gives the lib (a list's cell, a value, the statusbar): the text is drawn as any name or short text, a control character in it by its name (Escape); the style is the app's.
func ColorSpans ¶ added in v0.4.0
ColorSpans is a colour as a value on a form or a panel shows it, for Styled: a small swatch and its hex (components/input/color-picker).
type Splash ¶
Splash draws frame n (from 0) of the family's easter egg in w × h cells (Rules S). done reports that the reveal is over; the last frame then stays until a key. NewSplash makes the one Rules S5 describes.
func NewSplash ¶
NewSplash is the family's splash (Rules S5): the mark in icon, the app's docs/icon.svg, cell for cell, and under it the app's name (its command's), its version as `<app> version` prints it and a one-line intro, then the family's author and the hint. The text is designed with the mark: a name, version or intro wider than the mark (50 columns) is an error.
icon is read as S5 describes it: a 250 × 250 viewBox of 10 × 10 rects, the U frame in #205090 and the letters in #f2b753 within rows 3–21. The letters are revealed one at a time: each XML comment starts the next one, so the svg lists them in the order of the app's name with a comment before each (`<!-- K -->`). Without comments all the gold is one letter.
type Style ¶
Style is what a piece of text is drawn with. The zero Style draws the text as it is.
type Terminal ¶
type Terminal struct {
// Title is what runs, in capitals ("SHELL", "ALTERM"); Subject what it
// runs on, as it is ("myhost"): the popup's title reads "ALTERM: myhost".
Title, Subject string
// Command is the program and its arguments: the user's shell ($SHELL)
// when empty.
Command []string
Dir string
// Env is added to the app's environment. TERMINU__ICON_WIDTH and
// TERMINU__POWERLINE_WIDTH are always set to the app's own (tdp E5).
Env []string
// Ends makes the exit key end the program ("Alt-Esc:exit"); otherwise
// leaving keeps it running ("Alt-Esc:leave").
Ends bool
// Keys are the app's own keys in the PTY, shown after the exit key.
Keys []TerminalKey
// Interactive marks a terminal the user types commands of their own in
// (a shell, an ssh session, kubectl exec), not one the app opens to run
// one program for one thing ($EDITOR, sudo asking for a password). It
// has the two modes of components/dialog/terminal, which every other PTY
// leaves to its program, PgUp too:
// - History, on PgUp: j|k, u|d, gg|G, PgUp|PgDn scroll back through
// what went off the top, Esc goes back to the live screen, any other
// key leaves the mode and goes to the program. While the program
// fills the whole screen (vim, less, htop: the alternate screen),
// PgUp is the program's and the hint leaves PgUp:history out.
// - The selection, on Alt-v (the family's v, with Alt to get out of
// the program): the screen holds still, what the program prints
// meanwhile waiting; the cursor starts at the first line in sight
// and goes up into the history too; v starts selecting, y copies,
// Esc leaves. Copy takes the text; unset, it goes on the terminal's
// clipboard with a Success toast.
Interactive bool
// AllKeys, while set, hands every key to the program but the exit key
// and the app's own Keys (the one that takes them back): the user gave
// them all away (sshu's locked cell, a family app running inside). The
// selection is the program's then and PgUp|PgDn go to it, the innermost
// PTY scrolling its own history (components/dialog/terminal).
AllKeys bool
// ExitKey is the key that takes the focus out (Rules K10), Alt-Esc when
// unset; the app may change it while the program runs, and the hint and
// the footer show it as it is. Alt-Esc always asks first; another asks
// when ExitAsks.
ExitKey string
ExitAsks bool
// Copy takes what the selection copies (Interactive); unset, it goes on
// the terminal's clipboard with a Success toast.
Copy func(text string) tea.Cmd
// NotReady, while it reports true, keeps the ordinary keys from the
// program (it is still connecting); Ctrl-C and the exit key still work.
NotReady func() bool
// OnExit runs when the program ends.
OnExit func(err error) tea.Cmd
// OnFirstOutput runs when the program first prints something after
// Start: an ssh that has connected, to end the panel's loading and
// NotReady (Rules K10, F7).
OnFirstOutput func() tea.Cmd
// contains filtered or unexported fields
}
Terminal is a program running in a PTY (components/dialog/terminal): a shell, an editor, a remote session. Put it in a panel as the panel's Body, or open it in a terminal popup (App.OpenTerminal). While the focus is in it every key goes to the program, but the exit key and the app's own keys (Rules K10).
func (*Terminal) Empty ¶ added in v0.2.1
Empty reports a program started that has printed nothing yet: the panel's LoadingText shows in its middle meanwhile (layout/panel, loading).
func (*Terminal) Enter ¶
func (t *Terminal) Enter()
Enter puts the focus in a terminal in a panel: keys go to the program until the exit key.
func (*Terminal) Hide ¶
Hide takes the focus out and leaves the program running: its popup closes, a terminal in a panel lets the panel's keys work again. For an app's own exit key, such as one that hides a terminal popup.
func (*Terminal) Key ¶
Key does nothing: while the focus is in the terminal the app sends it every key; outside it the panel's own keys apply.
func (*Terminal) Spoke ¶ added in v0.2.0
Spoke reports whether the program has printed anything since Start.
type TerminalKey ¶
type TerminalKey struct {
// Key is how it is written in the footer and the hint ("Alt-←|→|↑|↓");
// Keys are the keys it takes, Key itself when empty, as a ModeKey's
// (Rules M5).
Key string
Keys []string
Desc string
Do func() tea.Cmd
// DoKey, when set, runs instead of Do, with the key pressed.
DoKey func(key string) tea.Cmd
}
TerminalKey is one of the app's own keys in a PTY (Rules K10).
type TextInput ¶
type TextInput struct {
Title string // what the popup is for, in its title ("Rename")
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
Glyph string // its title glyph: the app's choice
// Prompt is one line saying what to type ("New name for assets").
Prompt string
// Verb is what Enter does, for the hint ("rename").
Verb string
// Name is the value's name in its errors when the title says what the
// popup does rather than what the value is called: "Name can't have
// control characters" on a "Save as" (components/input/README). Left
// unset, the title names it.
Name string
// Old is the value now: offered in grey from the cursor on, Tab takes it
// (components/input/README, the grey suggestion).
Old string
// Suggest, when there is no Old, is a value the app proposes for a new
// thing ("assets.zip"), offered in grey as Old is; Enter with nothing
// touched takes it, checked and written back as any value
// (components/input/README, a suggested value).
Suggest string
// MaxLen, when set, is the most characters the value can have; the
// popup's width is then known when it opens.
MaxLen int
// Check is the value's own rules: an error is written on the error row
// and the value is not written back.
Check func(string) error
// Search marks a value that is only searched for, never used: control
// characters in it are drawn, not held back on Enter, as on a finder's
// typing row (components/input/README, pasted control characters).
Search bool
// Done gets the new value. It is not called when the value did not change.
Done func(string) tea.Cmd
// Stay keeps it open under what Done opens: a step of a flow (current
// PIN, new PIN, confirm PIN), each step a popup of its own, Esc on the
// next one coming back here (Rules F1, F4). The app ends the flow with
// CloseTop when its last step is done (T1).
Stay bool
// Commit, when set, writes a changed value back when Enter takes it, on
// the update loop, before Done: an error keeps the popup open with the
// value in it and opens an error popup over it, "RENAME FAILED"
// (components/layout/popup, the action failing; Rules F4).
Commit func(string) error
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
// Unchanged, when set, runs when Enter takes the value it opened with, so
// nothing is written back and Done is not called: a step of a flow ends
// the flow (CloseTop), a page waiting for an answer gets the value it
// offered (Rules K3, F6).
Unchanged func() tea.Cmd
}
TextInput is a one-line text input popup (components/input/text): a prompt, the value, an error row.
type TextMatch ¶ added in v0.2.0
type TextMatch struct{ Line, From, To int }
TextMatch is a stretch of a viewer's line: its characters From to To, To not in, counted as the selection mode's cursor counts them.
type Textarea ¶
type Textarea struct {
Title, Glyph string
// Subject is the one thing it acts on, kept as it is after ": " in the
// title: "EDIT: filu" (components/layout/popup).
Subject string
// Name is the text's name in its errors when the title is not ("Notes"
// on an "Edit"); left unset, the title names it (components/input/README).
Name string
Old string
// Check, when set, judges a changed text on Enter: an error keeps it
// open and is written in the error row, as on a one-line input (Rules K3).
Check func(string) error
// Done gets the new text. It is not called when it did not change.
Done func(string) tea.Cmd
// Commit, when set, writes a changed value back when Enter takes it, on
// the update loop, before Done: an error keeps the popup open with the
// value in it and opens an error popup over it, "RENAME FAILED"
// (components/layout/popup, the action failing; Rules F4).
Commit func(string) error
// OnCancel runs when it closes with no answer: Esc, or the popup it is
// over closing it, so whoever waits for the answer (a web page's prompt,
// ssh's askpass) hears it was cancelled (Rules F6).
OnCancel func() tea.Cmd
}
Textarea is multi-line text (components/input/textarea): it opens writing, with the value there and the cursor at its end; Esc moves to the moving state, where Enter saves.
type ToastKind ¶
type ToastKind int
ToastKind is what a toast says (components/dialog/toast): which one goes with the meaning of its colour.
type Values ¶
type Values struct {
Fields []*Field
// Header, when set, is the table header over the labels and the values.
Header [2]string
// OnMove runs when the cursor comes to another place, by a key or not,
// the first time included: the field, and the option in it (-1 for a
// field not drawn in place). It runs before the frame is drawn, so a
// details panel follows in the same frame (layout/panel, details).
OnMove func(f *Field, option int) tea.Cmd
// EmptyFact and EmptyHint are what it says with no fields, in Overlay0, as
// a list does (layout/screen, the empty state).
EmptyFact, EmptyHint string
// contains filtered or unexported fields
}
Values is a panel body with one value per row: a settings screen (layout/panel). It moves like a form; a value takes effect when it is set.
func (*Values) Actions ¶ added in v0.2.0
Actions are the panel's own item operation: what Enter does on the item under the cursor, so the Space menu and ? have it as the hint does (Rules M3, K6); in the disabled colour on a field that cannot be used now (M6).
func (*Values) EnterHint ¶
EnterHint is what Enter does on the item under the cursor, for the panel's hint: edit a value, choose a radio option, toggle a checkbox.
type Viewer ¶
type Viewer struct {
// Title is what it shows, in capitals ("YAML"); Subject is the thing
// itself, as it is ("pod/nginx"): the title reads "YAML — pod/nginx".
Title, Subject string
Glyph string
Lines []string
Loading bool
// Lang is the language its lines are coloured in, as the file preview
// colours a text file (components/dialog/note): a chroma lexer's name or
// alias ("yaml", "json"), a file name to judge by ("deploy.yaml"), or a
// content type ("application/json"). Unset or not known: plain text, in
// Text (an App Log).
Lang string
// Tabs, when set, follow the title (components/layout/popup); h/l switch
// them and OnTab fills Lines for the new one.
Tabs []string
Tab int
OnTab func(tab int) tea.Cmd
// Keys are the viewer's own hotkeys, first in its hint.
Keys []ViewerKey
// Select is its selection mode (Rules K11): every viewer has one
// (components/dialog/note). Unset, it is v, Visual, y copying to the
// terminal's clipboard with a Success toast.
Select *Selection
// NoWrap keeps a line too long on its row, cut with "…" at the end, for
// content that lines up (columns side by side, a table); lines fold by
// default (components/dialog/note).
NoWrap bool
// NoNumbers leaves out the line numbers, for a table the app lays out
// itself, where they mean nothing (components/dialog/note).
NoNumbers bool
// Hits are what a search the app runs found (its own / and n|N): each
// underlined in its own colours, Hits[Current] drawn as the cursor block,
// "you are here" (components/dialog/note, the viewer's search; FindText
// finds them). No new colour: Yellow is the selection's.
Hits []TextMatch
Current int
// contains filtered or unexported fields
}
Viewer is a note to read (components/dialog/note): a YAML view, a log, a file. Its lines are numbered on the left and a long one folds onto the rows under it. It scrolls, may have keys of its own and a selection mode, and closes with Esc only. Keep the pointer: lines may keep arriving while Loading is true.
func (*Viewer) FindText ¶ added in v0.2.0
FindText is every place q is in the lines, in either case, for the app's search (Hits).
Source Files
¶
- action.go
- app.go
- applog.go
- apppopup.go
- clipboard.go
- clock.go
- color.go
- colorpicker.go
- confirm.go
- corekeys.go
- datetime.go
- editor.go
- filepicker.go
- filepreview.go
- finder.go
- form.go
- frame.go
- input.go
- keys.go
- list.go
- match.go
- menu.go
- moveaside.go
- note.go
- output.go
- pager.go
- panel.go
- popup.go
- preview.go
- previewfs.go
- probe.go
- probe_unix.go
- reorder.go
- slider.go
- splash.go
- terminal.go
- terminal_unix.go
- text.go
- textarea.go
- toast.go
- values.go
- viewer.go
- vt.go
- width.go
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
minimal
command
minimal is the smallest terminu app: one list and one action on it.
|
minimal is the smallest terminu app: one list and one action on it. |
|
showcase
command
Command showcase shows every component of terminu design and every way they combine, on fake data laid out like a real app.
|
Command showcase shows every component of terminu design and every way they combine, on fake data laid out like a real app. |
|
internal
|
|
|
testhook
Package testhook is how tdptest reaches into the lib: terminu fills these in when it loads.
|
Package testhook is how tdptest reaches into the lib: terminu fills these in when it loads. |
|
proto
|
|
|
c1
command
Package main is a throwaway prototype for C1 in the blind-spot record: does lipgloss v2's layer compositing keep frames straight when a Nerd Font icon advances the cursor two cells (tdp E5)? It is not the lib.
|
Package main is a throwaway prototype for C1 in the blind-spot record: does lipgloss v2's layer compositing keep frames straight when a Nerd Font icon advances the cursor two cells (tdp E5)? It is not the lib. |
|
Package tdptest drives a terminu App in a Go test the way a user does — keys, a paste, the terminal changing size, time going by — and checks, after every message, what tdp asks of every screen: each row exactly as wide as the terminal (tdp L4).
|
Package tdptest drives a terminu App in a Go test the way a user does — keys, a paste, the terminal changing size, time going by — and checks, after every message, what tdp asks of every screen: each row exactly as wide as the terminal (tdp L4). |