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 ColorText(c Color) 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 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 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 Repeat(s string, n int) string
- func SetIconWidth(icon, powerline int)
- func SliderTrack(value, bottom, top float64, width int, color Color) string
- func StripStyles(s string) string
- func Truncate(s string, w int) string
- func TruncateLeft(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) Confirm(ask Ask, accept func() tea.Cmd) tea.Cmd
- func (a *App) Error(title, message string) tea.Cmd
- func (a *App) Find(f *Finder) tea.Cmd
- func (a *App) Form(f *Form) tea.Cmd
- func (a *App) Frame() []string
- func (a *App) Init() tea.Cmd
- func (a *App) Menu(title string, sections ...MenuSection) 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) Run() error
- func (a *App) Screen() *Screen
- func (a *App) Select(s Select) 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) 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 Finder
- type FinderItem
- type Form
- type FormField
- 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) Empty() bool
- func (l *List) Filtering() bool
- func (l *List) Focus()
- func (l *List) HasItem() bool
- func (l *List) Key(key string, msg tea.KeyMsg) (bool, tea.Cmd)
- func (l *List) Marked() []string
- 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)
- 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 ProbeResult
- type RGB
- type Rect
- type Row
- type Scope
- type Screen
- type Select
- type Selection
- type Slider
- type SortKey
- type Splash
- type Style
- type Terminal
- func (t *Terminal) Draw(w, h int, focused bool) []string
- 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) MoveKeys() []KeyRow
- func (t *Terminal) Running() bool
- func (t *Terminal) Scroll() string
- func (t *Terminal) Start() tea.Cmd
- func (t *Terminal) Stop()
- type TerminalKey
- type TextInput
- type Textarea
- type ToastKind
- type Values
- 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).
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.
Functions ¶
func ColorText ¶
ColorText is a colour on a form or a panel: a small swatch and its hex (components/input/color-picker).
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 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 MarkLabel ¶
MarkLabel writes a hotkey into its label the way Rules M5 says: in place when it is the label's first letter ("[r]ename") or a letter inside it ("UR[L]"), in front otherwise ("[n] New"); a modifier key in place of the letter it ends with ("[Alt-t]erm"), several letters in place ("[go]to"), a digit, a core key or a symbol always in front ("[3] Favorites", "[Enter] Edit", "[/] Search"). The case counts: "[A]dd" is Shift-A. 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 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 SliderTrack ¶
SliderTrack draws a value on a track of width cells in color, then the number (components/input/slider): a heavy line with a dot where the value is.
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 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".
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
// 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
// Stay keeps the menu it runs from open (a step of its own over it).
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
// 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
// Global are the global operations besides switching screens and
// quitting (Principle P3); their hotkeys work on panels too (Rules M4).
Global []Action
// Status draws the statusbar in w cells (layout/screen); nil for none.
Status func(w int) string
// 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; 4 when unset (components/input/textarea).
InputTabWidth int
// 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
// 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
// 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) 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) 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), a mistake in the program.
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) 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) Run ¶
Run asks the terminal how wide an icon is and what its colours are, then runs the app in the alternate screen.
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)
}
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
// Done gets the new set. It is not called when nothing changed.
Done func([]bool) 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 Color
// Done gets the new colour. It is not called when it did not change.
Done func(Color) 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 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 lets the column give up room first when the panel is narrow.
Flex bool
// Path cuts the column's values from the front ("…/.ssh/id_ed25519").
Path 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
}
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").
Value func() string
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
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
}
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
}
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 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
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
// Icon, when set, goes before the text in IconColor (a file's type).
Icon string
IconColor Color
}
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 submit button's text: what the form does ("Save").
Button string
// 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)
}
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 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
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
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 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
// 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
// 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) 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) 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) SetRows ¶
SetRows replaces the list's rows, keeping the cursor on the same row when it is still there.
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 an optional title (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 field's name in the range error ("Port").
Name string
Old string
Min, Max float64
Negative bool // "-" may be typed
Decimal bool // "." may be typed
Check func(string) error
Done func(string) 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).
func (*Pager) HasItem ¶
HasItem is false: a text has no items (Rules K3: Enter works on the whole panel).
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
// 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
// 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); otherwise one • per character from the left.
Unlock bool
MaxLen int
Check func(string) error
// Done gets the new password; "" with clear true when it was removed.
Done func(value string, clear bool) tea.Cmd
}
PasswordInput is a masked input (components/input/password).
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 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 Row ¶
type Row struct {
ID string // what marks are kept by; the row's place when empty
Cells []string // one per column; may carry the app's own colours
// Sort, when set, are the values sorted by instead of the cells (an age
// shown as "3d" sorted by seconds).
Sort []string
// 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
// Done gets the chosen option. It is not called when the value did not
// change.
Done func(int) 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 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 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
// History lets PgUp and PgDn scroll back through what went off the top.
History bool
// 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
// 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) 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.
type TerminalKey ¶
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
// Old is the value now: offered in grey from the cursor on, Tab takes it
// (components/input/README, the grey suggestion).
Old 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
// Done gets the new value. It is not called when the value did not change.
Done func(string) tea.Cmd
}
TextInput is a one-line text input popup (components/input/text): a prompt, the value, an error row.
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
Old string
// Done gets the new text. It is not called when it did not change.
Done func(string) 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 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
// 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) 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, when set, gives it a selection mode (Rules K11).
Select *Selection
// 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.
Source Files
¶
- action.go
- app.go
- color.go
- colorpicker.go
- confirm.go
- corekeys.go
- datetime.go
- editor.go
- filepicker.go
- finder.go
- form.go
- frame.go
- input.go
- keys.go
- list.go
- match.go
- menu.go
- note.go
- output.go
- pager.go
- panel.go
- popup.go
- preview.go
- probe.go
- probe_unix.go
- slider.go
- splash.go
- terminal.go
- terminal_unix.go
- textarea.go
- toast.go
- values.go
- viewer.go
- vt.go
- width.go
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
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. |
|
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. |