Documentation
¶
Overview ¶
Package tui renders workflow's terminal interface: a rail of panes down the left, a detail pane beside it, the loop's stages across the top and the keys along the bottom.
Index ¶
- func CheckKeys(overrides map[string]string) error
- func KeyActions(reviewNoun, messagingService string, overrides map[string]string) []seams.KeyAction
- func PaneSections() []seams.PageSection
- func WebBoundActions() []string
- type Deps
- type EditorDeps
- type FormDeps
- type ListedKeyContext
- type Model
- func (m Model) Arrived(next Next) Model
- func (m Model) Destination() Next
- func (m Model) Init() tea.Cmd
- func (m Model) OverlayKeyContext() (ListedKeyContext, bool)
- func (m Model) StayedAfter(next Next, err error) Model
- func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m Model) View() tea.View
- func (m Model) WithAccessibleForms() Model
- func (m Model) WithContext(ctx context.Context) Model
- func (m Model) WithDryRun() Model
- func (m Model) WithLifetime(ctx context.Context) Model
- func (m Model) WithoutColor() Model
- type Next
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckKeys ¶ added in v0.1.0
CheckKeys reports whether a ui.keys override map is usable. It refuses an entry naming no action (config.ErrUnknownKeyAction); a move of jump-to-pane, which answers a digit per pane that no one key stands in for (config.ErrKeyNotRebindable); interrupt on a key that types or edits text (config.ErrInterruptEdits); two actions live at the same time bound to one key, on a pane, in a section of the web page that shows several panes, or in an overlay (config.ErrKeyConflict); an action a text field's overlay answers on a key the field edits with (config.ErrTextFieldKey); and an action whose press opens a last look on a key apply has, which would confirm it (config.ErrKeyConfirmsItself). It builds the keymap the overrides produce and inspects it, so it checks exactly what the interface would run — the default set, with no overrides, passes. The glyphs only name the arrow keys in the help, which key collisions do not depend on, so a default set stands in for them.
func KeyActions ¶ added in v0.7.0
KeyActions is every action the help lists, in its order, with the ui.keys overrides applied: what another surface offers of the interface's keys, read from the same bindings the interface runs, so a rebinding reaches both. The review noun names open-pull-request for the forge, and the messaging service names its group, as the help does; a binding the help draws on another's line, with no words of its own, is left out, as the help leaves it. Each names the key it has with no override, too.
func PaneSections ¶ added in v0.9.0
func PaneSections() []seams.PageSection
PaneSections is the --web page's section each pane is shown in, in the panes' order, which is the order of the pane numbers: what the page opens on a pane number, and where CheckKeys finds two panes' keys live at once.
func WebBoundActions ¶ added in v0.9.0
func WebBoundActions() []string
WebBoundActions is the actions the --web page has a control for, by the names ui.keys gives them, which are the only ones live in a section of the page. web/src/features/keyboard/boundActions.ts is the page's own copy, and a test holds the two to one list.
Types ¶
type Deps ¶
type Deps struct {
Jira seams.Jira
Git seams.Git
Forge seams.Forge
Messaging seams.Messaging
Hooks seams.Hooks
Editor EditorDeps
// Forms asks a form's questions as plain prompts, when the interface is
// told to; see FormDeps.
Forms FormDeps
Store seams.Store
// Tasks is nil-fielded when no task program is found or the integration is
// disabled; see seams.Tasks.
Tasks seams.Tasks
Repositories seams.Repositories
// Settings reads and saves the configuration files, and lists and removes
// the local data.
Settings seams.Settings
// Clock tells the time, for how long ago a comment was written. Nil means
// time.Now.
Clock func() time.Time
// CIInterval is how often CI is asked about while it runs, or while a post
// waits for it to pass. Zero means every twenty seconds.
CIInterval time.Duration
// After is the timer every wait goes through — the selection resting before
// an issue is read, the gap between CI checks: a command that delivers fire's
// message once the wait has passed. Nil means tea.Tick.
After func(wait time.Duration, fire func(time.Time) tea.Msg) tea.Cmd
// Notify rings the terminal and sends a desktop notification, for when CI
// finishes while the developer is looking elsewhere. Nil where the interface
// cannot reach the terminal to ring it.
Notify func()
// OpenURL opens a page in the user's browser, for a check whose detail lives
// on the forge. Nil where there is no opener to reach.
OpenURL func(ctx context.Context, url string) error
// Copy puts text on the system clipboard. In production it is tea.SetClipboard,
// which writes it through the terminal's own OSC 52 sequence — no program, and
// it works over SSH. Nil where the interface cannot reach the terminal.
Copy func(text string) tea.Cmd
// contains filtered or unexported fields
}
Deps is everything the interface asks of the world outside the terminal, grouped by what it asks. Each is a function rather than a client, so the model never holds a credential, and a test can hand it canned answers without a network, a repository or a subprocess. A function that does I/O is asked under the session's context, which Model.WithContext sets; New has each write ignore the session's end, and Model.WithLifetime ends it with the program's lifetime instead.
A load the interface starts by itself is skipped when its function is nil, so a test need only supply what it exercises. An action is only offered once the model has what it acts on.
The groups every surface shares are declared in package seams. Editor, Forms, After and Copy speak Bubble Tea, so the bundle is declared here (TRADE-11).
type EditorDeps ¶
type EditorDeps struct {
Edit func(text, help string, done func(string, error) tea.Msg) tea.Cmd
Open func(file string, line int, done func(error) tea.Msg) tea.Cmd
// Resolve turns the places a tool printed into the files that open them,
// keyed by the place as printed and leaving out any that names none. A place
// relative to a package, not the root, is the common miss. It can walk the
// whole checkout, so it runs in a command, never in Update.
Resolve func(places []string) map[string]string
}
EditorDeps hands text and files to the user's editor, which takes the terminal while it is open.
Trade-off TRADE-11: it stays in this package, not in package seams, because its functions take and return Bubble Tea's messages and commands.
type FormDeps ¶ added in v0.11.0
type FormDeps struct {
// Ask runs form's prompts and delivers done's message, with the error that
// stopped it if any, once it has its answers. Nil hands the program's
// terminal to Huh's accessible prompts through tea.Exec.
Ask func(form *huh.Form, done func(error) tea.Msg) tea.Cmd
}
FormDeps hands a form the terminal to ask its questions as plain prompts, one at a time, which a screen reader reads as it would any command's. It takes the terminal while it asks, as the editor does.
type ListedKeyContext ¶ added in v0.9.0
ListedKeyContext is one keyboard surface — a pane, or an overlay while it is open — by name, and every action live on it at once. CheckKeys refuses a ui.keys map that binds two of its actions to one key.
func OverlayKeyContexts ¶ added in v0.9.0
func OverlayKeyContexts() []ListedKeyContext
OverlayKeyContexts is the key context of every overlay, as CheckKeys reads them.
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
Model is the interface's state.
func New ¶
New builds the interface for a configuration, the error if any from loading it, and what it may ask of the world outside.
func (Model) Arrived ¶ added in v0.6.0
Arrived is the interface opened after a switch: the session's state carried in, the Repositories pane in focus, and where it is now said.
func (Model) Destination ¶ added in v0.6.0
Destination is where the interface was asked to go when it ended, or a zero Next when it was not.
func (Model) Init ¶
Init implements tea.Model: it starts every load the panes need. Each runs inside a command, which Bubble Tea executes off the update loop, so a slow service never freezes the screen — and each pane fills in, or fails, on its own.
func (Model) OverlayKeyContext ¶ added in v0.9.0
func (m Model) OverlayKeyContext() (ListedKeyContext, bool)
OverlayKeyContext is the open overlay's key context, as CheckKeys reads it, and false when no overlay is open.
func (Model) StayedAfter ¶ added in v0.6.0
StayedAfter is the interface reopened where it was after a switch to next.Dir, or a reopen with a save, could not be made, saying why.
func (Model) Update ¶
Update implements tea.Model. Every load and result is an applier, which knows what it changes, so this only routes. A key or a result may close an overlay, so both settle, opening whatever follow-up waited on it.
func (Model) View ¶
View implements tea.Model. v2 takes the screen and its terminal features declaratively: the alternate screen keeps the session from scrolling the terminal and hands the scrollback back untouched on exit, and the mouse mode follows the model's own toggle.
func (Model) WithAccessibleForms ¶ added in v0.11.0
WithAccessibleForms is the interface asking each multi-field form's questions as plain prompts that take the whole terminal, one at a time, for a screen reader, rather than drawing the form over the screen.
func (Model) WithContext ¶ added in v0.9.0
WithContext is the interface asking every system outside it under ctx, its session's, which New leaves unending; Run gives it one that ends when the program does. Its end stops a read in flight, never a write.
func (Model) WithDryRun ¶
WithDryRun is the interface holding back every write — to Jira, the forge, the messaging service, Taskwarrior, git and files — and saying instead what it would have done. Reads stay live, so what it says is about the real state of things. Of the store it keeps only the kept reads — whom a post would tag, and the favorites — which --dry-run binds to kept.db, read read-only, and it reads nothing from the cache.
func (Model) WithLifetime ¶ added in v0.9.0
WithLifetime is the interface ending every write it sends once ctx ends, and not before, and counting it in flight, by name, in the lifetime.InFlight ctx carries until it lands. A write outlasts its session, so a quit or a switch never stops git midway with its index locked. ctx is the program's lifetime, the context Run is given: the command line's ends on SIGINT or SIGTERM, as a signal stops every command. New leaves its writes unending and uncounted.
func (Model) WithoutColor ¶
WithoutColor draws no hue while keeping the bold, faint and reverse-video cursor that carry meaning without it: its styles hold no hue, and Run forces the ANSI profile, which still draws those attributes.
type Next ¶ added in v0.6.0
type Next struct {
Dir string
// contains filtered or unexported fields
}
Next is where the interface was asked to go when it ended, and what of the session goes with it; a zero Dir is an interface that ended by quitting. A save in Settings asks for the directory it works in, so the interface opened next is wired with what was saved. The command line opens the next interface there, wired to that directory, and hands this back to Arrived, or to StayedAfter when it could not.
Trade-off TRADE-34: switching ends the program and starts another, so every pane is read again for the new directory, and only what belongs to the session rather than the repository is carried.
func Run ¶
Run starts the interface, reading keys from in — or from the terminal the process runs on, when in is a file that is not one — and drawing on out, and blocks until the user quits, or switches directory, which Next says. The context cancels the program, so a caller can shut the interface down, and the program's session ends when it does, stopping the reads it left in flight. A write it sent outlasts the program, but not the context: canceling it stops every write still under way too, even once Run has returned, so a caller cancels it only to end the program's lifetime, never to tidy up after a quit. The program takes no signal itself, so Bubble Tea's handler cannot block handing it a quit the context already gave: a caller ends it on SIGINT or SIGTERM through the context, and ctrl+c reaches it as a key. The alternate screen and mouse mode are set declaratively in View, as v2 asks.
Source Files
¶
- branch.go
- branchcreator.go
- branchlink.go
- branchresult.go
- calendar.go
- checks.go
- ci.go
- comment.go
- commentcomposer.go
- commits.go
- composer.go
- deps.go
- detail.go
- dialog.go
- diff.go
- dirpicker.go
- dirrows.go
- dryrun.go
- errorwords.go
- failure.go
- fields.go
- finish.go
- fixup.go
- footer.go
- glyphs.go
- help.go
- hookgen.go
- hookpicker.go
- huhform.go
- issuekeys.go
- issuelink.go
- issueplaces.go
- issues.go
- issuesearch.go
- issuewrite.go
- keycheck.go
- keys.go
- links.go
- localdata.go
- merge.go
- messaging.go
- messagingheld.go
- messagingpreview.go
- motion.go
- mouse.go
- options.go
- overlay.go
- ownerlink.go
- panekeys.go
- panes.go
- people.go
- peoplegroups.go
- picker.go
- prbaseredraft.go
- prcomposer.go
- prcreate.go
- preditor.go
- prforms.go
- prstarts.go
- render.go
- repositories.go
- reposrender.go
- reposwitch.go
- review.go
- reviewfacets.go
- reviewqueue.go
- run.go
- scopesuggest.go
- settings.go
- settingsedit.go
- settingsfields.go
- settingsrefusals.go
- settingsremove.go
- settingssection.go
- settingsvalues.go
- setupform.go
- setupsteps.go
- spine.go
- summary.go
- summarypost.go
- switchtask.go
- tagging.go
- taskactions.go
- taskline.go
- tasklist.go
- taskoffers.go
- tasks.go
- tasksrender.go
- tasktrack.go
- tui.go
- views.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package frame draws a titled, bordered box of an exact size.
|
Package frame draws a titled, bordered box of an exact size. |
|
Package layout decides where each region of the terminal interface goes for a given terminal size.
|
Package layout decides where each region of the terminal interface goes for a given terminal size. |
|
Package quietinput is a Huh field typing one line of text, as huh.Input does, over an input whose cursor never blinks: what every form of the terminal's takes typed text through.
|
Package quietinput is a Huh field typing one line of text, as huh.Input does, over an input whose cursor never blinks: what every form of the terminal's takes typed text through. |