Documentation
¶
Overview ¶
Package gui owns everything terminal-facing: the gocui bootstrap, the layout, the keybindings and the rendering loop.
Index ¶
- func ActionIDs() []string
- func ColorNameHints() []string
- func Effective(cfg config.Config) config.Config
- func ParseKey(spec string) (any, gocui.Modifier, error)
- func ValidateConfig(cfg config.Config) []error
- type Binding
- type Gui
- func (gui *Gui) GroupKill(group string) (int, error)
- func (gui *Gui) GroupOrder() []string
- func (gui *Gui) GroupSend(group, text string) (int, error)
- func (gui *Gui) Kill(idOrName string) error
- func (gui *Gui) List(group string) []control.SessionInfo
- func (gui *Gui) LockedSessions() map[string]bool
- func (gui *Gui) New(spec control.NewSpec) (string, error)
- func (gui *Gui) PendingRestore() (*config.StateFile, string)
- func (gui *Gui) Read(idOrName string, tail int) (string, error)
- func (gui *Gui) Rename(idOrName, name string) error
- func (gui *Gui) Run() (err error)
- func (gui *Gui) Send(idOrName, text string) error
- func (gui *Gui) SetDebug(logger *debug.Logger)
- func (gui *Gui) SetGroup(idOrName, group string) error
- func (gui *Gui) SetGroupOrder(groups []string)
- func (gui *Gui) SetLockedSessions(locked map[string]bool)
- func (gui *Gui) SetPendingRestore(state *config.StateFile, shell string)
- func (gui *Gui) SetStartupError(msg string)
- func (gui *Gui) StartupError() string
- func (gui *Gui) Wait(idOrName, group, state string, timeout time.Duration) (control.SessionInfo, error)
- type Theme
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ActionIDs ¶ added in v1.16.0
func ActionIDs() []string
ActionIDs lists every remappable action id, sorted — the same source knownActions checks against, exported for cmd/gen-config-schema so a keybindings: row in the generated form can offer them as a closed choice instead of free text, without that tool re-deriving the list by hand from bindings() itself.
func ColorNameHints ¶ added in v1.16.0
func ColorNameHints() []string
ColorNameHints lists the ANSI color names resolveColor accepts as an alias (see ansiColorAliases), sorted. A theme/marker color also accepts any W3C name or "#rrggbb" — this is a hint list for cmd/gen-config-schema's generated form, not the closed set validateTheme actually enforces.
func Effective ¶
Effective fills in the parts of a configuration whose real defaults live in this package rather than in pkg/config: an empty theme colour and a missing keybinding both mean "whatever the application decided", and pkg/config has no way to know what that is.
It exists for `lazyshell config show`, whose entire promise is to report what is actually applied. Reporting `active_border_color: ""` for a border that is visibly green, or listing only the two keys someone remapped, would make the command answer a different question than the one it is asked.
The resolution rules are the running code's own — resolveBinding for keys, resolveColor for colours — so what is printed cannot drift from what is drawn. A value the user wrote that those functions reject is replaced by the default they fall back to, which is the honest report: that is what the UI is using.
func ParseKey ¶
ParseKey exposes gocui's key-spec parser to packages that must not import gocui themselves — pkg/app checking $LAZYSHELL_PREFIX before reporting it as effective. Same signature as gocui.Parse, on purpose.
func ValidateConfig ¶
ValidateConfig reports everything wrong with the parts of the configuration that only this package can check: key specs and colors both need gocui to parse, and pkg/config deliberately has no gocui dependency (see its Theme, kept as plain strings for exactly that reason).
It reports, it does not repair: every consumer here already falls back to its built-in default on an unparseable value — resolveBinding keeps the default key, resolveColor keeps the default color, prefixFrom keeps Ctrl-O. That graceful degradation is precisely the problem this function exists for: it is silent, so the user sees a keybinding that simply does not take and has no way to learn why.
Called from pkg/app before gocui takes the terminal, so the messages land on a terminal that can still show them.
Types ¶
type Binding ¶
type Binding struct {
// ViewName is the view the binding applies to, empty for a global binding.
ViewName string
// Action is the stable id a config file's keybindings map remaps by
// (pkg/config's Keybindings). Empty means "not user-remappable" — used
// for the fixed alternate bindings (arrow keys, Ctrl-C, the second key of
// a pair) that exist alongside a remappable primary one.
Action string
Key any
Modifier gocui.Modifier
Handler func(*gocui.Gui, *gocui.View) error
Description string
// Enabled reports whether Handler can meaningfully act right now, given
// the current session/filter state. nil means always enabled. Only
// consulted by the help popup (pkg/gui/help.go), which uses it to
// separate actionable bindings from ones that would currently no-op —
// setKeybindings itself registers every binding unconditionally, since a
// key that momentarily does nothing is normal behaviour, not an error.
Enabled func(*Gui) bool
}
Binding describes a single keybinding. The list is kept flat on purpose (lazydocker model); lazygit's per-domain controllers are deliberately not used here.
type Gui ¶
type Gui struct {
// PauseBackgroundThreads stops the periodic tasks started by goEvery, for
// when the terminal is handed over to another process.
PauseBackgroundThreads bool
// contains filtered or unexported fields
}
Gui holds the gocui instance and the state of the interface.
func New ¶
New allocates the Gui around an already-running session Manager and a loaded configuration. It does not touch the terminal: that only happens in Run.
func (*Gui) GroupKill ¶
GroupKill terminates every session of a group, leaving them listed as exited — VerbKill's fan-out, with the same "kill, never delete" limit.
Same split as Kill, for the same reason and more so: the killing runs inline (killSessions), and only the repaint crosses over.
killSessions kills concurrently, which here is a correctness requirement and not a speed-up: run in sequence, a group of two already exceeds pkg/control's 3 s callTimeout, and the caller would get a transport timeout for kills that in fact succeeded — the one answer this API must never give.
func (*Gui) GroupOrder ¶
GroupOrder reports what SetGroupOrder recorded — pkg/app's bootstrap tests assert on it, the same way they do on StartupError.
func (*Gui) GroupSend ¶
GroupSend writes text into every session of a group and reports how many it reached — VerbSend's fan-out, and the point of the whole feature for an orchestrating agent: one call to give the same instruction to four workers.
Inline, like Send: every write goes to a pty that carries its own mutex, and nothing here belongs to gocui.
Exited sessions are skipped rather than failing the call, unlike Send's single target. A group in which one worker has finished is the normal state, and refusing to reach the other three because of it would make the verb useless exactly when it is wanted. The count says how many actually got it.
func (*Gui) Kill ¶
Kill terminates a session's process and leaves it listed as exited — the semantics of the interface's own kill binding, not of its delete. Removing a session outright is not exposed: it is the one destructive act with no recovery, and an agent has no business taking it.
Manager.Kill runs here, not inside onGUI: it waits for the process group to actually be reaped, escalating to SIGKILL after KillTimeout and waiting again — up to 4 s by default. The interface's own binding already refuses to run it on gocui's goroutine for that reason (killSession wraps it in runBusy, which is a background goroutine), and putting it there would blow onGUI's 2 s guard on a kill that is merely slow, not stuck. Only the repaint crosses over.
func (*Gui) List ¶
func (gui *Gui) List(group string) []control.SessionInfo
List reports every session, in creation order, exited ones included — the same list the panel shows, so an agent and a human are looking at the same thing. A non-empty group narrows it to that group's sessions.
Creation order, deliberately not the panel's group-clustered display order: this is an inventory, and a caller that wants them grouped has the group on every entry to do it with.
func (*Gui) LockedSessions ¶ added in v1.13.0
LockedSessions reports what SetLockedSessions recorded, for pkg/app's bootstrap tests — same purpose as GroupOrder above.
func (*Gui) New ¶
New creates a session and leaves the selection alone. Deliberately unlike the `n` binding, which also selects the new session and hands it the keyboard (selectNewlyCreatedSession, focusSelectedShell): that is right when the user pressed a key and wrong when a background agent did, since it would yank the cursor out of whatever the user was typing into.
func (*Gui) PendingRestore ¶ added in v1.14.0
PendingRestore reports what SetPendingRestore recorded, for pkg/app's bootstrap tests — same purpose as GroupOrder/LockedSessions/StartupError.
func (*Gui) Read ¶
Read returns a session's output as plain text — no SGR, no cursor positioning. tail limits it to the last N lines; zero means the whole scrollback, which is exactly what exportSession dumps to a file.
This is the verb that hands over whatever a session has printed, secrets included and unmasked: env_tab.go's looksLikeSecret has no equivalent here, because a credential echoed into a shell is indistinguishable from any other text once it is on screen. That is a property of the feature, documented in the ADR, not an oversight to patch here.
func (*Gui) Rename ¶
Rename changes a session's display name. Cosmetic, like the interface's own rename: SetName does not touch the running shell.
func (*Gui) Run ¶
Run initialises gocui and blocks in the main loop until the user quits. The terminal is always restored before returning, including on panic.
func (*Gui) Send ¶
Send writes text into a session's pty, exactly as if it had been typed. The caller supplies its own "\r" to press Enter: pkg/control's Request.Text is verbatim, on the same reasoning as tmux's send-keys.
func (*Gui) SetDebug ¶
SetDebug turns the debug mode on with the recorder pkg/app opened for --debug, and shows its panel straight away — a flag whose effect you have to go and find is a flag that gets passed twice. Must be called before Run, like SetStartupError; passing nil (the flag was not given) leaves everything off. Hiding the panel afterwards does not stop the recording.
func (*Gui) SetGroup ¶
SetGroup moves a session into a group, or out of every group when group is empty — the socket's half of the "g" key.
Through onGUI, unlike Rename which only writes a name: a regrouping changes the panel's display order, which the selection is an index into, so the reselection and the repaint have to happen together on gocui's goroutine or the cursor can end up on a different session than it was on.
func (*Gui) SetGroupOrder ¶
SetGroupOrder fixes the order the sessions panel draws group headers in, from the project file's `groups:` block. Must be called before Run: the render goroutine reads groupOrder with no mutex, which is only sound because nothing writes it once the interface is up.
func (*Gui) SetLockedSessions ¶ added in v1.13.0
SetLockedSessions records the lock state the project file declared for each session it started, keyed by session id (pkg/app's autostart builds it). Unlike SetGroupOrder this map keeps being written after Run — every explicit lock/unlock gesture adds an entry — but only ever from gocui's own event dispatch goroutine, the same rule that lets passThroughActive go without a mutex. A nil map is the ordinary case (no project file) and stays usable: reads on a nil map are legal, and rememberLockState allocates on first write.
func (*Gui) SetPendingRestore ¶ added in v1.14.0
SetPendingRestore records a saved layout (config.LoadState) for Run to offer once the terminal is up, when Config.RestoreLayout is "ask". Must be called before Run, like SetStartupError — pendingRestore is read with no lock, which is only sound because nothing writes it once the interface is up.
func (*Gui) SetStartupError ¶
SetStartupError records a problem that happened during bootstrap — a project file that could not be read, a session that failed to start — so it is shown in the status bar as soon as the interface comes up. Must be called before Run: renderStatus already gives lastError priority over everything else.
func (*Gui) StartupError ¶
StartupError reports what SetStartupError recorded, so pkg/app's bootstrap tests can assert on what the user will be told without standing up a terminal.
func (*Gui) Wait ¶ added in v1.17.0
func (gui *Gui) Wait(idOrName, group, state string, timeout time.Duration) (control.SessionInfo, error)
Wait blocks until idOrName — or, with idOrName empty and group set, the first session of group — reaches state, or timeout elapses first.
Inline, never onGUI: it polls only Session.AgentState/Status, both self-mutexed getters safe from any goroutine, and never touches anything gocui owns. A wait bounded by minutes would blow onGUI's 2 s guard many times over even if it didn't need to touch gocui at all — see this file's top comment.
type Theme ¶
type Theme struct {
// ActiveBorderColor is the current view's frame color (lazydocker's
// model: g.Highlight draws SelFrameColor on whichever view is current).
ActiveBorderColor gocui.Attribute
// InactiveBorderColor is every other view's frame color.
InactiveBorderColor gocui.Attribute
// SelectedBgColor is the sessions panel's highlighted-line background.
SelectedBgColor gocui.Attribute
// LockedBorderColor replaces ActiveBorderColor on the output view while
// it is "locked" — pass-through off — the roadmap's second mode
// indicator, alongside the status bar text. See borderColorFor
// (pkg/gui/input.go) and docs/adr/0011-passthrough-par-defaut.md.
LockedBorderColor gocui.Attribute
// TabActiveColor is the output panel's selected tab (pkg/gui/tabs.go).
// gocui draws it from the view's SelFgColor, whose zero value is
// ColorDefault — i.e. identical to the inactive tabs, which would leave
// the strip with no way to tell which tab is showing.
TabActiveColor gocui.Attribute
}
Theme holds every color lazyshell draws chrome with, resolved to gocui Attributes once at startup (pkg/config's Theme is still plain strings, so it stays free of a gocui dependency).
Source Files
¶
- agents_panel.go
- broadcast.go
- busy.go
- clipboard.go
- confirm.go
- control.go
- copymode.go
- debug_panel.go
- debug_trace.go
- effective.go
- env_tab.go
- exit_watch.go
- export.go
- filter.go
- focus.go
- footer.go
- group.go
- group_picker.go
- gui.go
- help.go
- input.go
- keybindings.go
- layout.go
- mouse.go
- notify.go
- output.go
- perf_chart.go
- perf_history.go
- perf_sampler.go
- perf_tab.go
- prompt.go
- prompt_nav.go
- quit.go
- restore.go
- search.go
- sessions_panel.go
- stats.go
- tabs.go
- theme.go
- title.go
- validate.go
- welcome.go