Documentation
¶
Overview ¶
Package config provides configuration constants, keybinding management, and user settings.
Index ¶
- Constants
- Variables
- func AddPluginDirInFile(path, dir string) (bool, error)
- func AmbiguityPartners(key string) []string
- func AmbiguitySurprises(key string) bool
- func AmbiguityVerdict(key string, hostDisambiguates bool) string
- func ApplyAppearanceConfig(cfg *UserConfig, s *Settings)
- func ApplyNotificationConfig(cfg *UserConfig, s *Settings)
- func ApplyOverrides(overrides Overrides, s *Settings)
- func AutoFPS(displayHz int) int
- func CanonicalKey(key string) string
- func CanonicalPaneGrants(names []string) (valid, unknown []string)
- func ClampMasterCount(n int) int
- func ConfigFileHeader(configPath string) string
- func ConfigWarnings(cfg *UserConfig) []string
- func CopyCommandLabel(command string) string
- func DefaultDockCenter() []string
- func DefaultDockLeft() []string
- func DefaultDockRight() []string
- func DockBuiltinComponents() []string
- func DockClockInterval(format string) time.Duration
- func DockEventTypes() []string
- func DockFixedSide(name string) string
- func DockModeIconUsable(value string) bool
- func DroppedWarnings(dropped []DroppedKey) []string
- func EffectiveDefault(opt Option) string
- func ExpandHome(p string) string
- func FirstRunConfig(path, include string) []byte
- func ForceMacOSHost(on bool) func()
- func GetConfigPath() (string, error)
- func GetOptionValue(cfg *UserConfig, path string) (string, bool)
- func HostsInFile(path string) (map[string]HostConfig, error)
- func IncludeLine(path string) string
- func InsideMultiplexer() bool
- func IsAgentPrefixKeybinding(k Keybinding) bool
- func IsAgentsSettingsPrefixKeybinding(k Keybinding) bool
- func IsDockBuiltin(name string) bool
- func IsDockEventType(name string) bool
- func IsHexColor(s string) bool
- func IsLeaderPress(pressed, leader string) bool
- func IsMasterPosition(pos string) bool
- func IsReviewPrefixKeybinding(k Keybinding) bool
- func KeyLabel(key string) string
- func MacOSOptionChord(r rune) (string, bool)
- func MacOptionAdvice(host HostTerminal, chord string) string
- func MarshalUserConfig(cfg *UserConfig) ([]byte, error)
- func NormalizeHerdrProtocol(v string) string
- func NormalizeHostProgramStatus(v string) string
- func NormalizePaneLabelKeys(keys string) string
- func OptionPaths() []string
- func ParseAgentRestFold(v string) (d time.Duration, ok bool)
- func ParseBoxSize(spec string) (value int, percent bool, err error)
- func ParseHostedGrace(s string) (time.Duration, error)
- func ParseKeyPath(key string) []string
- func ParseQuietHours(s string) (from, to int, err error)
- func PinPreV080Appearance(a *AppearanceConfig)
- func PrefixMenuActions(prefixType string, st MenuState) []string
- func PressesByAction(r *KeybindRegistry) map[string][]string
- func ReadConfigFile(path string) ([]byte, error)
- func RemoveHostFromFile(path, name string) (bool, error)
- func RemovePluginDirInFile(path, dir string) (bool, error)
- func RenderUserConfig(cfg *UserConfig) (func() (WriteNote, error), error)
- func ResetConfig(path string) error
- func ResolveBackground(own, all string) string
- func ResolveSecret(inline Secret, env, file string) (string, error)
- func ResolveShell(cfg *UserConfig) string
- func RetiredOption(path string) (msg string, ok bool)
- func RewindSave(cfg *UserConfig, err error)
- func SameKey(a, b string) bool
- func ScopedDescription(scope, action string) string
- func SectionNames() []string
- func SetOptionValue(cfg *UserConfig, path, value string) error
- func SetPluginEnabledInFile(path, id string, on bool) (bool, error)
- func ShellFor(preferred string) (shell string, missing bool)
- func SidebarCustomPlaced(sections string) bool
- func SidebarLayoutNames() []string
- func SidebarMetaTokenKey(name string) (string, bool)
- func SidebarSectionProblems(source string) []string
- func SidebarSectionsString(entries []SidebarSectionShare) string
- func SidebarSectionsWithout(source, section string) string
- func ValidMasterCount(n int) bool
- func ValidMasterPosition(pos string) string
- func WriteConfigFile(cfg *UserConfig, configPath string) error
- type AgentAlertPolicy
- func (p AgentAlertPolicy) Alerts(state string) bool
- func (p AgentAlertPolicy) AttentionCue(state string) bool
- func (p AgentAlertPolicy) CueFile(state string) string
- func (p AgentAlertPolicy) PlaysAudio() bool
- func (p AgentAlertPolicy) PlaysBell() bool
- func (p AgentAlertPolicy) Quiet(now time.Time) bool
- type AgentAlertSounds
- type AgentAlertStates
- type AgentAlertsConfig
- type AgentSoundMode
- type AgentsConfig
- type Ambiguity
- type AmbiguousBinding
- type AppearanceConfig
- type ApprovalsConfig
- type AutoEnterTerminalPolicy
- type Binding
- type CheckpointsConfig
- type Collision
- type CollisionLoser
- type CommandBinding
- func (c CommandBinding) Action() string
- func (c CommandBinding) BareKey() string
- func (c CommandBinding) HeightSpec() string
- func (c CommandBinding) Label() string
- func (c CommandBinding) ResolvedName() string
- func (c CommandBinding) ResolvedType() string
- func (c CommandBinding) Section() string
- func (c CommandBinding) WidthSpec() string
- type CommandProblem
- type ConfigLayer
- type ConfigReloadCallback
- type CopyModeProblem
- type CopyPipeBinding
- type DaemonConfig
- type DebugConfig
- type DockClockConfig
- type DockConfig
- type DockCustomConfig
- type DockRefresh
- type DockRefreshKind
- type DroppedKey
- type Evidence
- type FPSLimit
- type GlyphEnv
- type GuestClash
- type GuestProgram
- type HintsConfig
- type HooksConfig
- type HostConfig
- type HostTerminal
- type KeyFate
- type KeyNormalizer
- type KeyOrigin
- type KeyProblem
- type KeyReadAs
- type KeybindRegistry
- func (r *KeybindRegistry) Bindings() []Binding
- func (r *KeybindRegistry) Collisions() []Collision
- func (r *KeybindRegistry) Fate(key string, facts PaneFacts) KeyFate
- func (r *KeybindRegistry) GetAction(key string) string
- func (r *KeybindRegistry) GetConfig() *UserConfig
- func (r *KeybindRegistry) GetCopyModeAction(key string) string
- func (r *KeybindRegistry) GetCopyModeKeys(action string) []string
- func (r *KeybindRegistry) GetDebugPrefixAction(key string) string
- func (r *KeybindRegistry) GetGlobalAction(key string) string
- func (r *KeybindRegistry) GetInboxAction(key string) string
- func (r *KeybindRegistry) GetInboxKeys(action string) []string
- func (r *KeybindRegistry) GetInboxPeekAction(key string) string
- func (r *KeybindRegistry) GetKeys(action string) []string
- func (r *KeybindRegistry) GetLayoutPrefixAction(key string) string
- func (r *KeybindRegistry) GetMailAction(key string) string
- func (r *KeybindRegistry) GetMinimizePrefixAction(key string) string
- func (r *KeybindRegistry) GetPrefixAction(key string) string
- func (r *KeybindRegistry) GetScriptAction(key string) string
- func (r *KeybindRegistry) GetSidebarAction(key string) string
- func (r *KeybindRegistry) GetSidebarAgentsAction(key string) string
- func (r *KeybindRegistry) GetSidebarAgentsKeys(action string) []string
- func (r *KeybindRegistry) GetSidebarFilesAction(key string) string
- func (r *KeybindRegistry) GetSidebarFilesKeys(action string) []string
- func (r *KeybindRegistry) GetSidebarKeys(action string) []string
- func (r *KeybindRegistry) GetTapePrefixAction(key string) string
- func (r *KeybindRegistry) GetTerminalModeAction(key string) string
- func (r *KeybindRegistry) GetWindowPrefixAction(key string) string
- func (r *KeybindRegistry) GetWorkspacePrefixAction(key string) string
- func (r *KeybindRegistry) GuestClashes(running string) []GuestClash
- func (r *KeybindRegistry) HasAction(action string) bool
- func (r *KeybindRegistry) KeyProblems() []KeyProblem
- func (r *KeybindRegistry) OptionKeys() []KeyReadAs
- func (r *KeybindRegistry) Reload(cfg *UserConfig)
- func (r *KeybindRegistry) Report(facts PaneFacts) KeybindReport
- func (r *KeybindRegistry) StillHeldBy(key string) []string
- func (r *KeybindRegistry) TerminalModeSwallowed() []Swallow
- type KeybindReport
- type Keybinding
- type KeybindingGroup
- type KeybindingsConfig
- func (k *KeybindingsConfig) CommandFor(action string) (CommandBinding, bool)
- func (k *KeybindingsConfig) CommandProblems() []CommandProblem
- func (k *KeybindingsConfig) Commands() []CommandBinding
- func (k *KeybindingsConfig) CopyModeProblems() []CopyModeProblem
- func (k *KeybindingsConfig) CopyPipeFor(key string) (CopyPipeBinding, bool)
- func (k *KeybindingsConfig) CopyPipes() []CopyPipeBinding
- func (k *KeybindingsConfig) FreeKey(key string) []Removal
- func (k *KeybindingsConfig) SectionFor(name string) map[string][]string
- func (k *KeybindingsConfig) UnbindAction(section, action string) ([]Removal, bool)
- func (k *KeybindingsConfig) UnbindKey(section, action, key string) (Removal, bool)
- func (k *KeybindingsConfig) UnboundActions(section string) []string
- type LauncherConfig
- type LayerKind
- type LayeredConfig
- func (lc *LayeredConfig) Bytes() ([]byte, error)
- func (lc *LayeredConfig) DisplayPath(p string) string
- func (lc *LayeredConfig) Holders(key []string) []ConfigLayer
- func (lc *LayeredConfig) Merged() map[string]any
- func (lc *LayeredConfig) Origin(key []string) (string, bool)
- func (lc *LayeredConfig) Origins() []KeyOrigin
- func (lc *LayeredConfig) WriteTarget(key []string) (string, WriteNote, error)
- type LinkPolicy
- type MailAlertPolicy
- type MailAlertsConfig
- type MenuState
- type NotificationsConfig
- type NotifyConfig
- func (n *NotifyConfig) ContentLevel() string
- func (n *NotifyConfig) Cooldown() int
- func (n *NotifyConfig) Destinations() []string
- func (n *NotifyConfig) HasProvider() bool
- func (n *NotifyConfig) HourlyCap() int
- func (n *NotifyConfig) On() bool
- func (n *NotifyConfig) QuietActive() int
- func (n *NotifyConfig) Triggered(kind string) bool
- type NotifyTriggers
- type NtfyConfig
- type Observation
- type Option
- type Overrides
- type PaneFacts
- type PanesConfig
- type PasteBuffersConfig
- type PermissionsConfig
- type PiPConfig
- type PluginsConfig
- type PruneResult
- type PushoverConfig
- type QueueConfig
- type Reach
- type RecapConfig
- type Redirect
- type Removal
- type ResolvedPermissions
- type ResolvedRecap
- type RiskConfig
- type RiskRuleConfig
- type SaveError
- type Scope
- type ScratchConfig
- type ScreensaverConfig
- type ScreenshotConfig
- func (s ScreenshotConfig) CopyEnabled() bool
- func (s ScreenshotConfig) EffectiveFormat() string
- func (s ScreenshotConfig) PaddingPx() int
- func (s ScreenshotConfig) PreviewEnabled() bool
- func (s ScreenshotConfig) RadiusPx() int
- func (s ScreenshotConfig) ResolveDirectory() string
- func (s ScreenshotConfig) ScaleFactor() int
- func (s ScreenshotConfig) ShadowEnabled() bool
- type ScrollbarConfig
- type Secret
- type SelectionConfig
- type Settings
- func (s *Settings) AllBackgroundResolved() string
- func (s *Settings) AnimationsOn() bool
- func (s *Settings) BorderJoinsChromeRules() bool
- func (s *Settings) DesktopBackgroundResolved() string
- func (s *Settings) DockBackgroundResolved() string
- func (s *Settings) DockHeight() int
- func (s *Settings) FormatWindowTitle(title string, index int, cwd string) string
- func (s *Settings) FormatWorkspaceTab(name string, index int) string
- func (s *Settings) GetAnimationDuration() time.Duration
- func (s *Settings) GetBorderForStyle() lipgloss.Border
- func (s *Settings) GetClockFormat() string
- func (s *Settings) GetDockIconCloseSession() string
- func (s *Settings) GetDockIconLeaveRunning() string
- func (s *Settings) GetDockModeCapLeft() string
- func (s *Settings) GetDockModeCapRight() string
- func (s *Settings) GetDockModeIconTerminal() string
- func (s *Settings) GetDockModeIconTiling() string
- func (s *Settings) GetDockModeIconWindow() string
- func (s *Settings) GetDockPillLeftChar() string
- func (s *Settings) GetDockPillRightChar() string
- func (s *Settings) GetDockSeparator() string
- func (s *Settings) GetDockWorkspaceCapLeft() string
- func (s *Settings) GetDockWorkspaceCapRight() string
- func (s *Settings) GetDockWorkspaceMoreLeft() string
- func (s *Settings) GetDockWorkspaceMoreRight() string
- func (s *Settings) GetFastAnimationDuration() time.Duration
- func (s *Settings) GetNotificationCap(cap string) string
- func (s *Settings) GetNotificationRule(stroke string) string
- func (s *Settings) GetRailAddGlyph() string
- func (s *Settings) GetRailAttentionMark() string
- func (s *Settings) GetRailBullet() string
- func (s *Settings) GetRailCollapseGlyph() string
- func (s *Settings) GetRailExpandGlyph() string
- func (s *Settings) GetRailFileGlyph() string
- func (s *Settings) GetRailFocusMark() string
- func (s *Settings) GetRailFoldOpenGlyph() string
- func (s *Settings) GetRailFoldShutGlyph() string
- func (s *Settings) GetRailFolderGlyph() string
- func (s *Settings) GetRailParentGlyph() string
- func (s *Settings) GetRailRuleGlyph() string
- func (s *Settings) GetRailTreeBranch() string
- func (s *Settings) GetRailTreeLast() string
- func (s *Settings) GetScrollColumnMax() int
- func (s *Settings) GetScrollbarThumbChar() string
- func (s *Settings) GetScrollbarTrackChar() string
- func (s *Settings) GetSidebarPillLeftChar() string
- func (s *Settings) GetSidebarPillRightChar() string
- func (s *Settings) GetWindowBorderBottom() string
- func (s *Settings) GetWindowBorderBottomLeft() string
- func (s *Settings) GetWindowBorderBottomRight() string
- func (s *Settings) GetWindowBorderLeft() string
- func (s *Settings) GetWindowBorderTop() string
- func (s *Settings) GetWindowBorderTopLeft() string
- func (s *Settings) GetWindowBorderTopRight() string
- func (s *Settings) GetWindowButtonCloseMark() string
- func (s *Settings) GetWindowButtonDot() string
- func (s *Settings) GetWindowButtonMaximizeMark() string
- func (s *Settings) GetWindowButtonMinimizeMark() string
- func (s *Settings) GetWindowPillLeft() string
- func (s *Settings) GetWindowPillRight() string
- func (s *Settings) GetWindowSeparatorChar() string
- func (s *Settings) GetZoomSize() int
- func (s *Settings) GlyphsForSet(id string) map[string]string
- func (s *Settings) MasterRatioFraction() float64
- func (s *Settings) MotionAllows(level string) bool
- func (s *Settings) NerdFontsOff() bool
- func (s *Settings) PaneBackgroundResolved() string
- func (s *Settings) ResolvedGlyphs() map[string]string
- func (s *Settings) ScrollbarTintHex() (string, bool)
- func (s *Settings) ScrollbarTintResolved() string
- func (s *Settings) SetAnimationsOn(on bool)
- func (s *Settings) SidebarBackgroundResolved() string
- func (s *Settings) WindowChromeBackgroundResolved() string
- type SidebarAgentRowSpec
- type SidebarConfig
- type SidebarCustomConfig
- type SidebarSectionShare
- type SidebarTokenLook
- type SidebarTokenRule
- type SidebarTokenStyle
- type SpotlightConfig
- type StartupConfig
- type Swallow
- type TailscaleConfig
- type TapeConfig
- type UserConfig
- type ValidationError
- type ValidationResult
- type Watcher
- type WatcherOptions
- type WebhookConfig
- type WorkspacesConfig
- type WriteNote
- type YieldedDefault
Constants ¶
const ( HerdrProtocolAgents = "agents" HerdrProtocolAlways = "always" HerdrProtocolOff = "off" )
The values of [agents] herdr_protocol.
const ( HostProgramStatusAuto = "auto" HostProgramStatusOff = "off" )
The values of [agents] host_program_status.
const ( // RecapToast shows it in the dock when the person comes back to a pane, // as well as in the Inbox and agent-log. RecapToast = "toast" // RecapInbox shows it only in the Inbox's Finished detail and agent-log. RecapInbox = "inbox" // RecapOff shows it only in agent-log. RecapOff = "off" )
Recap modes: where the away recap is shown.
const ( DefaultQueueMax = 8 MaxQueueMax = 64 )
Queue bounds: how many messages one pane's delivery queue may hold.
const ( DefaultCheckpointKeep = 50 MaxCheckpointKeep = 1000 )
Checkpoint bounds: how many checkpoints one pane keeps.
const ( // DefaultAgentRestFold is how long an agent row rests before the rail // folds it into one line. DefaultAgentRestFold = time.Hour // AgentRestFoldOff turns folding off. AgentRestFoldOff = "off" )
Durations of appearance.sidebar.agent_rest_fold.
const ( CommandTypeScratch = "scratch" CommandTypePopup = "popup" CommandTypePane = "pane" CommandTypeShell = "shell" )
Command types.
const ( // DefaultWindowWidth is the default width for new terminal windows DefaultWindowWidth = 20 // DefaultWindowHeight is the default height for new terminal windows DefaultWindowHeight = 5 // MinWindowWidth is the minimum width a window can be resized to MinWindowWidth = 10 )
const ( // DefaultAnimationDuration is the standard animation duration for minimize/restore operations DefaultAnimationDuration = 300 * time.Millisecond // FastAnimationDuration is the duration for snapping and window swapping animations FastAnimationDuration = 200 * time.Millisecond )
const ( // CPUUpdateInterval is the interval between CPU usage updates CPUUpdateInterval = 500 * time.Millisecond // ProcessWaitDelay is the delay when waiting for process cleanup ProcessWaitDelay = 50 * time.Millisecond // WhichKeyDelay is the delay before showing which-key style overlay WhichKeyDelay = 500 * time.Millisecond )
const ( // DockFullHeight is the rows a full dock takes: the rule between the panes // and the dock, and the row of pills. DockFullHeight = 2 // DockCompactHeight is the rows a compact dock takes: the row of pills // alone. See Settings.DockHeight. DockCompactHeight = 1 // SidebarDefaultWidth is the preferred sidebar width on a wide screen. // Before v0.8.0 it was 28. SidebarDefaultWidth = 24 // SidebarNarrowWidth is the width of the narrow rail (glyph + short name) // used on mid-width screens. SidebarNarrowWidth = 16 // SidebarGlyphWidth is the width of the glyph-only rail used on small // screens: one glyph column plus a separator column. SidebarGlyphWidth = 3 // SidebarMinPaneFloor is the fewest columns the content area is allowed to // keep for panes. The sidebar drops to a narrower variant before it would // squeeze panes below this. SidebarMinPaneFloor = 30 // Sidebar breakpoints, measured against the render width. See // (*OS).GetSidebarWidth. SidebarBreakpointFull = 90 // >= this: full sidebar at SidebarWidth SidebarBreakpointNarrow = 60 // >= this: narrow rail SidebarBreakpointGlyph = 40 // >= this: glyph rail; below: auto-hidden // NotificationMaxWidth caps the dock's message block. Past about seventy // columns a message that keeps growing stops being a status line and starts // being a paragraph, so the rest is truncated instead. NotificationMaxWidth = 72 // NotificationDockReserve is what the message block leaves the rest of the // dock: enough for the mode pill and the workspace counts, which are never // given up for a message. NotificationDockReserve = 18 // NotificationMinWidth is the narrowest block worth reserving. Below it the // dock is too tight to split, and the message takes what the screen has // less a small margin instead. NotificationMinWidth = 14 )
const ( // DockPillLeftCharASCII is the ASCII fallback for pill left DockPillLeftCharASCII = "[" // DockPillRightCharASCII is the ASCII fallback for pill right DockPillRightCharASCII = "]" // DockModeIconWindowASCII is the ASCII fallback for window mode DockModeIconWindowASCII = " W " // DockModeIconTerminalASCII is the ASCII fallback for terminal mode DockModeIconTerminalASCII = " T " // DockModeIconTilingASCII is the ASCII fallback for tiling mode DockModeIconTilingASCII = " # " // DockIconTerminalCountASCII is the ASCII fallback for terminal count DockIconTerminalCountASCII = "win" // DockIconWorkspaceCountASCII is the ASCII fallback for workspace count DockIconWorkspaceCountASCII = "ws" // DockIconLeaveRunningASCII is the ASCII fallback for the leave-running // control. One cell, like the glyph it stands in for, so the strip's columns // do not move with the font. // // The keybind's own letter. "<" was an angle bracket that meant nothing on // its own, and the workspace strip's overflow arrow on the same row is also // "<"; with the words gone the fallback has to carry the control by itself, // and prefix-d is the thing it does. DockIconLeaveRunningASCII = "d" // DockIconCloseSessionASCII is the ASCII fallback for the close-session // control, which is also the letter prefix-X ends a session with. DockIconCloseSessionASCII = "X" // DockSeparatorASCII is the ASCII fallback separator DockSeparatorASCII = " | " // DockWorkspaceMoreLeftASCII and DockWorkspaceMoreRightASCII are the ASCII // fallbacks for the workspace strip's overflow arrows. DockWorkspaceMoreLeftASCII = "<" DockWorkspaceMoreRightASCII = ">" )
const ( // NotificationIconError is the error notification icon NotificationIconError = "[X]" // NotificationIconWarning is the warning notification icon NotificationIconWarning = "[!]" // NotificationIconSuccess is the success notification icon NotificationIconSuccess = "[OK]" // NotificationIconInfo is the info notification icon NotificationIconInfo = "[i]" )
const ( // NotificationCapLight is the info and success cap (U+258E, two eighths). NotificationCapLight = "▎" // NotificationCapMedium is the warning cap (U+258C, four eighths). NotificationCapMedium = "▌" // NotificationCapHeavy is the error cap (U+258A, six eighths). NotificationCapHeavy = "▊" // NotificationCapASCII is the cap with Nerd Fonts off. Weight cannot be // encoded in one ASCII cell, so severity falls back to the mark and the // colour alone. NotificationCapASCII = "|" )
The message block's opening edge. It is the severity rail in one cell: a freestanding partial block on the bare bar, inked two eighths for info and success, four for a warning and six for an error.
Two eighths apart rather than one because a single eighth is not a difference you can see without the two of them side by side, and they never are. The weight is what carries severity into a greyscale screenshot or a theme with no contrast to spare.
The ground behind the cap is the bar itself, never a fill. A sliver only reads as a weight against something that is not the same colour; against a solid severity field all it changes is where the field starts, with nothing to compare that against, and the severities become indistinguishable. That is why this design carries less colour than a filled pill would.
const ( // NotificationRuleLight is the burn stroke for info and success (U+2500). NotificationRuleLight = "─" // NotificationRuleHeavy is the burn stroke for warnings and errors (U+2501). NotificationRuleHeavy = "━" )
The dock hairline's stroke while a message is burning down over it. A warning or an error is drawn heavy, so an escalating message is a heavier line as well as a different colour.
const ( ZoomSizeMin = 50 ZoomSizeMax = 100 ZoomSizeDefault = 95 )
The zoom box's size as a percent of the content region, and its range.
100 is the whole region, which is what zoom was before v0.8.0. Below it the pane keeps the middle and the layout around it stays on screen at the edges, the way the scrolling layout leaves the next column peeking in, except in both directions at once: you can see what you are not looking at. The default leaves a thin band of that layout showing.
const ( SidebarFolderClickCd = "cd" SidebarFolderClickBoth = "both" )
What a click on a folder row in the files section does.
Navigate is the default because it is the only one of the three that touches nothing outside the rail: the listing moves and no key is typed into anybody's program. tuios does not know that a pane is at a shell prompt until it looks, and a cd that reached vim or a REPL would be a series of edits or a syntax error. A user who wants the pane to follow can say so once, here.
const ( SidebarFileDeleteTrash = "trash" SidebarFileDeletePermanent = "permanent" )
Where a delete from the files section sends the file.
Trash is the default. The rail is an incidental place for a keystroke to land in a way a file manager is not, and a delete that cannot be undone is the wrong default for an incidental place. Permanent is for somebody who has decided they mean it, and it is on a key of its own as well, because a file on another disk cannot go to the home trash at all.
const ( LayoutModeBSP = "bsp" LayoutModeMasterStack = "master-stack" LayoutModeScrolling = "scrolling" )
The tiling schemes, under the names they travel by: in [startup] layout, in session state, and in the command palette. They live here rather than in the package that implements them because the option registry has to publish the accepted set and cannot import that package.
const ( MasterRatioMin = 10 MasterRatioMax = 90 MasterRatioDefault = 50 )
The master ratio's range and its default. The master-stack tiler clamps to the same range (layout.MinSplitRatio and MaxSplitRatio are read from here), and it matches the resize_width_N actions, which go from 10 to 90 percent, so a percentage resize the tiler keeps is one the settings row can show.
const ( MasterPositionLeft = "left" MasterPositionRight = "right" MasterPositionTop = "top" MasterPositionBottom = "bottom" MasterPositionCenter = "center" )
Where the master-stack layout puts the master panes. Left is the layout as it was before the position could change. Center puts the masters in a middle column and deals the stack to the right and the left in turn, the way xmonad's ThreeColMid and Hyprland's center orientation do.
const ( MasterCountMin = 1 MasterCountMax = 9 MasterCountDefault = 1 )
The master count's range and its default. Nine is as many panes as a workspace can hold before most terminals run out of rows for them.
const ( ScrollColumnWidthMin = 20 ScrollColumnWidthMax = 90 ScrollColumnWidthCeiling = 100 ScrollColumnWidthDefault = 55 )
The column width's range and its default. The floor is the narrowest column a shell is usable in.
ScrollColumnWidthMax is the default ceiling, and it is where the strip's next column stops peeking in at the edge, which is the only thing that says there is one. appearance.scroll_column_max raises it, up to ScrollColumnWidthCeiling: a full-width column gives the pane the whole screen without zooming, so the strip keeps its columns and its fast switching, and the peek is what you spend for it.
const ( NiriScrollCellsMin = 1 NiriScrollCellsMax = 200 NiriScrollCellsDefault = 8 )
How far one wheel event walks the scrolling layout's strip, in cells.
It is a flat number of cells rather than a fraction of the visible width because a terminal reports trackpad scrolling as one wheel event per cell the fingers cross. A single flick and its momentum tail are tens of events, so a step of a fifth of the screen sends the strip to its clamp before the fingers leave the glass. A flat number is the same distance whatever the screen is, small enough that a flick lands where the user aimed, and large enough that a few notches of a wheel still get somewhere. Someone who only ever scrolls the strip with a wheel can raise it.
const ( // WindowBorderTopLeft is the top-left corner character for window borders (Nerd Font / Unicode). WindowBorderTopLeft = "╭" // U+256D // WindowBorderTopRight is the top-right corner character for window borders. WindowBorderTopRight = "╮" // U+256E // WindowBorderBottomLeft is the bottom-left corner character for window borders. WindowBorderBottomLeft = "╰" // U+2570 // WindowBorderBottomRight is the bottom-right corner character for window borders. WindowBorderBottomRight = "╯" // U+256F // WindowBorderHorizontal is the horizontal line character for window borders. WindowBorderHorizontal = "─" // U+2500 // WindowBorderVertical is the vertical line character for window borders. WindowBorderVertical = "│" // U+2502 // WindowButtonClose is the close/kill window button character. // // U+2715 MULTIPLICATION X, not the U+292B RISING DIAGONAL CROSSING FALLING // DIAGONAL it used to be. U+292B lives in Miscellaneous Mathematical // Symbols-B, which JetBrainsMono Nerd Font does not cover at all, so a // terminal running it falls back to whatever proportional system font // happens to have the codepoint. That substitute's advance is wider than // one cell, so the glyph draws past the column the layout budgeted for it // and the falling diagonal is clipped by whatever is painted next. // U+2715 is in the font, has an advance of exactly one cell, and keeps its // ink well inside it. It carries the same East Asian Width class "N" as // U+292B, so it still measures 1 cell and the button pill keeps its old // width. See the hit-test offsets below, which depend on that width. WindowButtonCloseMark = "✕" // WindowButtonClose is that mark padded into the three-cell button. WindowButtonClose = " " + WindowButtonCloseMark + " " // WindowButtonMaximizeMark is the maximize mark. WindowButtonMaximizeMark = "□" // U+25A1 // WindowButtonMinimizeMark is the minimize mark. WindowButtonMinimizeMark = "-" // WindowButtonDot is the disc the dots style draws each control as. // // U+25CF BLACK CIRCLE, which JetBrainsMono Nerd Font covers and draws at an // advance of exactly one cell. U+23FA BLACK CIRCLE FOR RECORD would have // been the closer shape and is not in the font at all, which is the defect // the close button's comment above records. WindowButtonDot = "●" // U+25CF // WindowSeparatorChar is the separator character for window elements. WindowSeparatorChar = "─" // U+2500 )
const ( // WindowButtonCloseASCII is the close/kill window button character (ASCII fallback). WindowButtonCloseMarkASCII = "X" // WindowButtonCloseASCII is that mark padded into the three-cell button. WindowButtonCloseASCII = " " + WindowButtonCloseMarkASCII + " " // WindowButtonMaximizeMarkASCII is the maximize mark (ASCII fallback). One // cell like the Unicode mark, so the padded button keeps its three cells and // the hit-test offsets below still hold. WindowButtonMaximizeMarkASCII = "O" // WindowButtonDotASCII is the dots style's disc in ASCII. One cell like the // disc it stands in for, so the traffic light keeps its layout and its // colours, and only loses the roundness. WindowButtonDotASCII = "o" // WindowPillLeftASCII is the left pill-style character for window decorations (ASCII fallback). WindowPillLeftASCII = "[" // WindowPillRightASCII is the right pill-style character for window decorations (ASCII fallback). WindowPillRightASCII = "]" // WindowSeparatorCharASCII is the separator character for window elements (ASCII fallback). WindowSeparatorCharASCII = "-" )
const ( // ZIndexSeparators is the z-index for shared border separator lines. It is // above every tiled window, whose Z counts up from zero, and below // the floating band. ZIndexSeparators = 500 // ZIndexAnimating is the z-index for windows currently animating. ZIndexAnimating = 501 // ZIndexPiP is the z-index of the picture-in-picture view. It is above // every tile, the separators and a zoomed pane, and below the floating // band, so a popup or the scratch terminal draws over it. ZIndexPiP = 502 // ZIndexFloating is where the floating band starts: a floating window is // drawn at ZIndexFloating plus its Z, capped at ZIndexFloatingTop. The band // used to start one above the separators at 998, which put a floating // window with Z >= 2 over the dock, the clock, the log viewer, the which-key // overlay and the scrollback browser: every overlay between 1000 and 1003 // was reachable with a handful of panes open. ZIndexFloating = 503 // ZIndexFloatingTop is the highest z-index a floating window can be drawn // at. Every overlay and the dock sit above it. ZIndexFloatingTop = 999 // ZIndexHelp is the z-index for help overlay ZIndexHelp = 1000 // ZIndexDock is the z-index for the dock ZIndexDock = 1000 // ZIndexTime is the z-index for the time display ZIndexTime = 1001 // ZIndexLogs is the z-index for log viewer overlay ZIndexLogs = 1001 // ZIndexWhichKey is the z-index for which-key overlay ZIndexWhichKey = 1002 // ZIndexScrollbackBrowser is the z-index for the scrollback browser overlay ZIndexScrollbackBrowser = 1003 // ZIndexCommandPalette is the z-index for command palette overlay ZIndexCommandPalette = 1004 // ZIndexSessionSwitcher is the z-index for session switcher overlay ZIndexSessionSwitcher = 1005 // ZIndexLayoutPicker is the z-index for layout picker overlay ZIndexLayoutPicker = 1006 // ZIndexOverlayBase is the base z-index for the draggable floating overlay // panels (settings, theme picker, palette, etc.). Each open panel is stacked // at this base plus its position in the click-to-raise order, so clicking a // panel brings it above the others. ZIndexOverlayBase = 1100 // ZIndexReview is the z-index for the review overlay. It covers the whole // screen and is opened from the Inbox and the rail, so it sits above every // floating panel; the context menu and notifications still draw over it. ZIndexReview = 1400 // ZIndexContextMenu is the z-index for the shift+right-click context menu. It // sits above every floating panel because it is opened on top of whatever is // already on screen and is dismissed by the next click either way, so nothing // is served by letting another panel cover it. ZIndexContextMenu = 1500 // ZIndexScreensaver is the z-index for the idle screen saver. It is above // everything, notifications included: the saver covers the screen, and a // message drawn over an animation of that same screen would only look like // part of the animation. ZIndexScreensaver = 3000 // ZIndexNotifications is the z-index for notifications ZIndexNotifications = 2000 )
const ( DefaultSelectionBg = "#45475A" DefaultSelectionFg = "" // Search is amber and the match under the cursor is a brighter one. They // are two steps of one colour rather than two colours, because they answer // two parts of the same question. DefaultSearchBg = "#8A6D2F" DefaultSearchFg = "#F5E7C8" DefaultMatchBg = "#E5A93D" DefaultMatchFg = "#1C1B19" // The copy mode cursor. Cyan, which is the one hue not used by the // selection or the search, so the three never read as each other. DefaultCopyCursorBg = "#39C5CF" DefaultCopyCursorFg = "#08222B" )
The colours a pane paints over its own output to mark text. See SelectionConfig for why they are settings rather than literals.
The selection is a neutral grey rather than the violet it used to be. A selection is not a status and should not introduce a hue the rest of the screen does not use: grey reads as "this is marked" against output of any colour, which is what every editor and browser settled on. The text keeps the colour the program wrote it in, so a selection over syntax-highlighted output stays readable as the same code.
const ( PrefixRepeatTimeDefault = 500 PrefixRepeatTimeMin = 0 PrefixRepeatTimeMax = 5000 )
The prefix repeat window, in milliseconds.
After a prefix command that is worth pressing twice, the prefix stays armed for this long, so ctrl+b then left left left walks three columns instead of one. It is tmux's repeat-time and the same default: long enough to press again without hurrying, short enough that a key struck afterwards for any other reason goes where it was meant to.
Zero turns it off, and every prefix command then takes its own prefix.
const ( CopyFlashMsDefault = 420 CopyFlashMsMin = 80 CopyFlashMsMax = 3000 // Empty, meaning the colour is derived from the pane's own background. // // It was a pale warm white, and one literal cannot serve both ends of the // theme range: that colour measures fourteen to one against a dark ground // and one point oh three against a light one. A value set here is still // honoured, which is what the setting is for. DefaultCopyFlashColor = "" // The shape the sweep takes. A diagonal falls across a paragraph, which is // what most copies are. DefaultCopyFlashStyle = "diagonal" )
The copy sweep: a band of light that crosses what was copied, once.
Copying is the one gesture in a terminal with no result to look at, so the feedback has to be put where the text was. See internal/app/copy_flash.go.
const ( CopyFlashDiagonal = "diagonal" CopyFlashDiagonalReverse = "diagonal-reverse" CopyFlashHorizontal = "horizontal" CopyFlashVertical = "vertical" )
CopyFlashStyles is every value appearance.selection.flash_style takes. It lives here rather than beside the shapes themselves so the option registry can name the set without importing the app.
const ( MultiCopyFormatPlain = "plain" MultiCopyFormatMarkdown = "markdown" MultiCopyFormatJSON = "json" )
The formats multi copy mode can yank in: appearance.selection.multi_format. Plain adds nothing, so it is the default: output that already carries its own identifier (a hostname on every line) needs no wrapping.
const ( CopyEntryCursor = "cursor" CopyEntryCenter = "center" )
Where copy mode puts its cursor on entry: appearance.selection.copy_entry. The terminal cursor is the default because tmux does the same, and the cursor is usually on the prompt line, which is where a search back through the output wants to start.
const ( OSC52WriteOff = "off" OSC52WriteAsk = "ask" OSC52WriteFocused = "focused" OSC52WriteOn = "on" )
What happens when a program in a pane sets the clipboard with OSC 52: appearance.selection.osc52_write.
Any program's output can carry OSC 52, including a file an agent prints, so the host clipboard is not handed to every pane. tmux goes further and ignores these writes by default, but that breaks the yank in an editor over ssh, which is what OSC 52 is mostly for, and that yank always comes from the pane the user is typing in. So the default lets the focused pane write, and says so on the dock when the text holds a line break or a control character. A write from any other pane waits for the user to allow it, which is what ask does for every pane.
Whatever the mode, a pane that runs without the daemon keeps its own copy, so the program that set it reads it back with an OSC 52 query. A pane under the daemon keeps none: the daemon's emulator has no clipboard callback, so every OSC 52 query there is answered with an empty string.
const ( ActionCopyModeSearchForward = "copy_mode_search_forward" ActionCopyModeSearchBackward = "copy_mode_search_backward" )
The actions that enter copy mode and open its search prompt in one key, the way tmux does it with "copy-mode \; send-keys ?". They have no default key. Bind them in any section, for example prefix_mode or global.
const ( ActionCopyModeLineStart = "copy_mode_line_start" ActionCopyModeLineEnd = "copy_mode_line_end" )
The copy-mode motions a config can bind, in [keybindings.copy_mode]. They are live only while a pane is in copy mode, in normal and visual selection. The vim keys 0 and $ do the same and are not bindings: copy mode reads them itself, with the other vim motions.
const ( DockComponentMode = "mode" DockComponentWorkspaces = "workspaces" DockComponentTrail = "trail" DockComponentTape = "tape" DockComponentWindows = "windows" DockComponentNotifications = "notifications" DockComponentCopyHelp = "copy-help" DockComponentCPU = "cpu" DockComponentRAM = "ram" DockComponentClock = "clock" DockComponentSessionControls = "session-controls" )
The dock's built-in component names. Every segment the bar has ever drawn is one of these, so a user reorders the bar by reordering strings rather than by waiting for an option per segment.
const ( // DockCustomTimeout is how long a one-shot command may run before it is // killed and its cell hidden. DockCustomTimeout = 3 * time.Second // DockCustomMaxOutput is how much of a command's stdout is read before the // rest is discarded. Only the first line is ever used, so this is a cap on // a command that writes forever without a newline. DockCustomMaxOutput = 64 << 10 // DockCustomDefaultMaxWidth is the cell width a component gets when its // table does not ask for one. DockCustomDefaultMaxWidth = 24 // DockCustomMaxWidthLimit is the widest a cell may ask to be. A cell wider // than this is not a cell, it is the bar. DockCustomMaxWidthLimit = 80 // DockCustomMinInterval is the floor under a polling component. Anything // faster is a push component that has not been written yet. DockCustomMinInterval = time.Second // DockCustomFailureLimit is how many consecutive failures a component gets // before it stops being re-run on its own schedule. It still runs on an // explicit refresh-dock, so a fixed script recovers without a restart. DockCustomFailureLimit = 5 )
Limits on what one custom component may cost. They exist because a dock cell is a subprocess someone else wrote: the bar has to stay a bar when it hangs, when it never exits, and when it writes a megabyte a second.
const ( HintsDefaultBuiltins = "all" HintsDefaultDim = 60 HintsMinDim = 10 HintsMaxDim = 90 )
Hints defaults and bounds, one source for DefaultConfig, the registry and the accessors.
const ( SectionWindowManagement = "window_management" SectionWorkspaces = "workspaces" SectionLayout = "layout" SectionModeControl = "mode_control" SectionSystem = "system" SectionRestoreMinimized = "restore_minimized" SectionPrefixMode = "prefix_mode" SectionWindowPrefix = "window_prefix" SectionMinimizePrefix = "minimize_prefix" SectionWorkspacePrefix = "workspace_prefix" SectionDebugPrefix = "debug_prefix" SectionTapePrefix = "tape_prefix" SectionLayoutPrefix = "layout_prefix" SectionTerminalMode = "terminal_mode" SectionSidebar = "sidebar" SectionSidebarFiles = "sidebar_files" SectionSidebarAgents = "sidebar_agents" SectionInbox = "inbox" SectionInboxPeek = "inbox_peek" SectionMail = "mail" SectionCopyMode = "copy_mode" SectionGlobal = "global" SectionScript = "script" )
Section names as they appear in config.toml, used to name where a binding came from without exposing the Go field.
const ( ScopeWindowMode = "window" ScopeTerminalMode = "terminal" ScopeSidebar = "sidebar" ScopeSidebarFiles = "sidebar.files" ScopeSidebarAgents = "sidebar.agents" ScopeInbox = "inbox" ScopeInboxPeek = "inbox.peek" ScopeMail = "mail" ScopeCopyMode = "copy" ScopePrefix = "prefix" ScopePrefixWindow = "prefix.window" ScopePrefixMinimize = "prefix.minimize" ScopePrefixWorkspce = "prefix.workspace" ScopePrefixDebug = "prefix.debug" ScopePrefixTape = "prefix.tape" ScopePrefixLayout = "prefix.layout" ScopeGlobal = "global" ScopeScript = "script" )
Scope identifiers. Stable strings rather than an iota because they are part of the JSON an agent reads.
const ( // LinkAllowList reads: listings, captures, screenshots, agent state, the // Inbox, prompt peeks, waits and the event stream. LinkAllowList = "list" // LinkAllowMail sends and reads agent mail and uses the stash. LinkAllowMail = "mail" // LinkAllowOpen starts processes here: sessions, windows, panes run for // the other machine, worktrees and fans. LinkAllowOpen = "open" // LinkAllowWrite changes what is already here: typing into panes, closing // and moving windows, options, layouts, names and agent reports. LinkAllowWrite = "write" // LinkAllowRespond answers what waits for the person: prompts, held // approvals, and dismissing Inbox items. LinkAllowRespond = "respond" )
Link capabilities, the values of allow.
const ( // MotionNone draws every change in one frame: no slides, no fades, no // shimmer, and confetti is a still sparkle. MotionNone = "none" // MotionBasic keeps the motion that carries information: windows slide // between positions and a zoom grows from its tile. MotionBasic = "basic" // MotionFull adds the decorative motion: an overlay fades in, a working // agent's row shimmers, and confetti flies. It is the default. MotionFull = "full" )
Motion levels. appearance.motion takes one of these, and it replaced the on/off appearance.animations_enabled.
Two levels of motion rather than one switch, because the motion tuios has is of two kinds. A window sliding to its tile says where the window went, and that is information. A panel fading in or a working agent's row shimmering says nothing a static frame does not, and some people find it distracting. basic keeps the first kind and drops the second.
const ( // OverlayFadeDuration is how long an overlay takes to come up. OverlayFadeDuration = 120 * time.Millisecond // OverlayFadeFrame is the interval between the fade's frames. OverlayFadeFrame = time.Second / 60 )
Overlay fade-in timing. The fade is short enough that it never makes anybody wait, and long enough to be seen as a fade rather than a flicker: at 60 frames a second it is seven or eight frames.
const ( // ModalDimDefault is how far the screen behind a modal is darkened when // nothing sets it. Enough that the panel is plainly the thing in front, // not so much that the context behind it cannot be read. ModalDimDefault = 30 // ModalDimMax caps it for the reason DimUnfocusedMax does: past this the // screen behind is gone rather than dimmed. ModalDimMax = 90 )
Modal dim. appearance.modal_dim is the percent the screen behind a modal overlay is darkened by; zero turns it off.
const ( NotifyContentSummary = "summary" NotifyContentTitle = "title" )
Notify content levels.
const ( OptionBool = "bool" OptionInt = "int" OptionString = "string" )
The three types an option can carry. A config value crosses the protocol as a string, so these say how to parse it back.
const ( DefaultDockbarPosition = "top" DefaultSidebarPosition = "right" DefaultWindowTitlePosition = "top" )
The shipped edges for the dock, the rail and the window title. Named because DefaultConfig, DefaultSettings, the registry and the typo fallback in ApplyAppearanceConfig all have to agree on them. v0.8.0 moved all three: the dock and the title were at the bottom and the rail on the left before it.
const ( // PaneGrantRead reads the pane's own session and the sessions of its fan // group: listings, captures, agent state, waits and the event stream. PaneGrantRead = "read" // PaneGrantWrite types into the panes of its own session and leaves mail // and stashed files there. PaneGrantWrite = "write" // PaneGrantFan does what write does in the sessions of its fan group and // the sessions it launched, and starts agents with fan and start-agent. PaneGrantFan = "fan" // PaneGrantRespond answers an on-screen prompt of a pane it may write to, // with respond, without the person's attach nonce. No mode gives it by // default, and admin does not imply it. PaneGrantRespond = "respond" // PaneGrantAdmin is everything else a pane could do before grants // existed: every session, the listings across sessions, windows, // layouts, options, attach and the rest. It implies read, write and fan. PaneGrantAdmin = "admin" )
Pane grants, the values of grants.
const ( // PaneModeOpen gives a pane started with no grants of its own admin. PaneModeOpen = "open" // PaneModeStrict gives a pane started with no grants of its own the // grants list. PaneModeStrict = "strict" )
Permission modes, the values of mode.
const ( // a tree. NavigatorLayoutTree = "tree" // workspace after its name. NavigatorLayoutFlat = "flat" // command, then the session, the workspace and the folder. NavigatorLayoutCards = "cards" )
The pane navigator's layouts.
const ( PiPCornerBottomRight = "bottom-right" PiPCornerBottomLeft = "bottom-left" PiPCornerTopRight = "top-right" PiPCornerTopLeft = "top-left" )
The four corners, in the spelling [pip] corner takes.
const ( PiPDefaultWidth = 40 PiPDefaultHeight = 12 PiPMinWidth = 12 PiPMaxWidth = 200 PiPMinHeight = 3 PiPMaxHeight = 100 )
PiP defaults and bounds. The minimum leaves a one-row, ten-column view inside the border, which is the least that still shows a line of output.
const ( ScratchDefaultWidth = "80%" ScratchDefaultHeight = "80%" )
Scratch defaults, one source for DefaultConfig, the registry and the accessors.
const ( ScreensaverDefaultIdleMinutes = 10 ScreensaverMinIdleMinutes = 1 ScreensaverMaxIdleMinutes = 240 // ScreensaverRandomEffect picks a different effect each time it starts. ScreensaverRandomEffect = "random" )
Screensaver defaults, one source for DefaultConfig and the accessors.
const ( ScreenshotDefaultFormat = "png" ScreenshotDefaultDirectory = "~/Pictures/tuios" ScreenshotDefaultFrame = "window" ScreenshotDefaultBackground = "auto" ScreenshotDefaultPadding = 48 ScreenshotDefaultRadius = 10 ScreenshotDefaultControls = "auto" ScreenshotDefaultTitleFormat = "{title}" ScreenshotDefaultFontFamily = "JetBrains Mono, monospace" ScreenshotDefaultScale = 2 ScreenshotMaxPadding = 128 ScreenshotMaxRadius = 32 ScreenshotMaxScale = 4 )
Screenshot defaults, one source for DefaultConfig and the accessors.
const ( KittyPlaceholdersAuto = "auto" KittyPlaceholdersOn = "on" KittyPlaceholdersOff = "off" )
DefaultSettings is tuios as it ships, before any config file, any flag and any settings page. It is the seed for Global and the value every unconfigured session starts from. The three answers appearance.kitty_placeholders takes.
const ( SpotlightFollowCursor = "cursor" SpotlightFollowMouse = "mouse" )
What the beam follows.
Mouse is the default because it is what a person means by a spotlight: they point at the thing they are talking about. Cursor was the first default and it was chosen on cost rather than on what anyone asked for, which is the wrong way round for a feature whose whole job is to put the light where the audience should look.
The cost is real and it is why cursor stays. A cursor-anchored beam moves only on frames that are being composed anyway, because getRealCursor already resolves the position for the hardware cursor. A mouse-anchored one asks for a frame per pointer move, which the motion throttle caps at the frame rate: about 1.8 KB per frame with a hard edge and 4.9 KB with a soft one, and only while the pointer is moving. On a local terminal that is nothing. Over SSH or in the browser client a continuous swipe is a steady tens of KB a second, so a remote client that wants the beam should set follow = "cursor".
Neither costs anything at all with the beam off, which is how it ships.
The two never mix. A rule that picked whichever moved last would put two sources on one beam and make the screen jump for a reason the user cannot see.
const ( SpotlightEdgeHard = "hard" SpotlightEdgeSoft = "soft" )
How the beam ends.
Hard cuts at the radius. Soft fades over the outer part of it, which reads more like a light and costs about three times the bytes each time the beam moves: the rim is a ring of sixteen colour steps, and every step is a style change the terminal has to be told about. Measured at radius 10 on a nine-pane 207x55 screen, one cell of movement is 1.8 KB hard and 4.9 KB soft. Hard is the default for that reason, and a local session can afford soft.
const ( SpotlightDefaultRadius = 10 SpotlightMinRadius = 2 SpotlightMaxRadius = 200 // SpotlightDefaultDim leaves an unlit cell at a quarter of its light. // // Dim N leaves the screen at (100-N) percent of its light. At 60 the // screen reads as merely a bit darker, and the text outside the beam still // competes with the text inside it. A quarter is near tuiffects' own unlit // character, which sits // at a fifth, and it leaves the layout visible while giving the beam the // whole of the reader's attention. SpotlightDefaultDim = 75 SpotlightMinDim = 10 SpotlightMaxDim = 95 // SpotlightFalloff is how much of the radius is soft rim, as a fraction. // It is the screen saver's own BeamFalloff, because the two draw the same // light and a beam that faded differently in the two places would read as // two features. SpotlightFalloff = 0.3 // SpotlightLevels is how many steps the rim is quantised to. The rim is a // continuous ramp, and every distinct colour on it is a style run of its // own in the frame, so the step count is what bounds the bytes a moving // beam puts on the wire. SpotlightLevels = 16 )
Spotlight defaults and bounds, one source for DefaultConfig, the option registry and the accessors.
const ( ResumeAgentsOff = "off" ResumeAgentsAsk = "ask" ResumeAgentsAuto = "auto" )
Resume modes. See DaemonConfig.ResumeAgents.
const ( SSHAgentOff = "off" SSHAgentFollow = "follow" )
SSH agent modes. See DaemonConfig.SSHAgent.
const ( WindowSizeSmallest = "smallest" WindowSizeLargest = "largest" WindowSizeLatest = "latest" )
Window size policies. See DaemonConfig.WindowSize.
const ( // ClickToTypeSingle enters terminal mode when a click on a pane's content // is released without a drag. ClickToTypeSingle = "single" // ClickToTypeDouble focuses on a single click and enters terminal mode only // on the second click of a double click. ClickToTypeDouble = "double" // ClickToTypeOff never changes mode from a click: the pane takes focus and // the keyboard stays with the window manager. ClickToTypeOff = "off" )
Click-to-type policies. See AppearanceConfig.ClickToType.
const ( // TilingSchemeSpiral alternates the split axis by the depth of the window // being split, bspwm-style (default). TilingSchemeSpiral = "spiral" // TilingSchemeLongestSide splits across a window's longer side. TilingSchemeLongestSide = "longest_side" // TilingSchemeAlternate alternates the split axis by the tree's total // split count. TilingSchemeAlternate = "alternate" // TilingSchemeSmartSplit picks the axis from the target window's aspect // ratio, falling back to depth parity when neither side dominates. TilingSchemeSmartSplit = "smart_split" )
BSP tiling insertion schemes. See AppearanceConfig.TilingScheme. The strings match layout.AutoScheme.String() and layout.ParseAutoScheme, which also parse a layout template's own tiling_scheme.
const ( // ZenModeDisabled keeps window borders always visible (default). ZenModeDisabled = "disabled" // ZenModeAlways hides window borders at all times. ZenModeAlways = "always" // ZenModeMouse hides window borders while the mouse is idle, revealing // them while the pointer is moving or any mouse button is held. ZenModeMouse = "mouse" )
Zen-mode policies. See AppearanceConfig.ZenMode.
const ( // LinksOff finds no links at all. LinksOff = "off" // LinksMarked finds only OSC 8 hyperlinks. LinksMarked = "marked" // LinksAll also finds bare URLs in plain text. LinksAll = "all" )
Link policies. See AppearanceConfig.Links.
The three values answer one question: what counts as a link the pointer may pick up. A program that emits OSC 8 has said outright that a run of cells is a link and where it points, so "marked" trusts only that. Almost no program does, though, and the links a person actually reads in a pane are plain text, so "all" also finds bare URLs (http, https, ftp, file, ssh, git) in plain text, with the detector hints mode uses. "off" is for anyone who wants the pointer to leave pane content alone.
const ( // LinkClickBoth opens a link on ctrl+click and on shift+click. LinkClickBoth = "both" // LinkClickCtrl opens a link on ctrl+click only. LinkClickCtrl = "ctrl" // LinkClickShift opens a link on shift+click only. LinkClickShift = "shift" // LinkClickOff never opens a link from a click. Hints still can. LinkClickOff = "off" )
Link clicks. See AppearanceConfig.LinkClick.
The click has to reach tuios to do anything, and the outer terminal decides that. Every common terminal keeps shift+click for itself while a program tracks the mouse (it is the xterm "bypass" modifier), so shift+click alone opened links only in terminals that pass it on. Ctrl+click reaches tuios in most terminals, which is why both is the default.
const ( // WindowButtonStylePill draws the controls as black glyphs on a filled pill // in the border's colour, capped with powerline half circles. WindowButtonStylePill = "pill" // WindowButtonStyleDots draws them as macOS traffic lights: three unlabelled // discs in red, yellow and green, sitting straight on the border, showing // their symbols while the pointer is on them. WindowButtonStyleDots = "dots" )
Window control styles. See AppearanceConfig.WindowButtonStyle.
const ( // WindowButtonPositionRight puts them against the border's trailing corner, // which is where Windows and most Linux desktops put them. WindowButtonPositionRight = "right" // WindowButtonPositionLeft puts them against the leading corner, the way // macOS does. WindowButtonPositionLeft = "left" )
Which end of the title bar the controls sit on. See AppearanceConfig.WindowButtonPosition.
const ( // ScrollbarStyleThin floats a hairline thumb over the pane's last content // column and draws nothing else. ScrollbarStyleThin = "thin" // ScrollbarStyleTrack draws a full-height track behind a block thumb // positioned to the half cell, after opentui's ScrollBar. ScrollbarStyleTrack = "track" )
Scrollbar styles. See ScrollbarConfig.Style.
const ( // ScrollbarTintQuiet draws the bar in the pane's own ink dimmed toward the // pane's own background: a mid-grey thumb on a dark theme, a mid-grey thumb // on a light one, and no hue of its own either way. ScrollbarTintQuiet = "quiet" // ScrollbarTintBorder draws the focused pane's bar in the colour its border // is drawn in, or in its accent when it has one. ScrollbarTintBorder = "border" // ScrollbarTintMuted draws every bar in the unfocused border grey. ScrollbarTintMuted = "muted" )
Scrollbar tints. See ScrollbarConfig.Tint.
const ( // BackgroundOff paints nothing: a cell left on the default background // shows the host terminal through it. The default. BackgroundOff = "off" // BackgroundTheme paints the active theme's background, and the theme's // foreground on text left in the default colour. With no theme set there // is no background to paint, so it behaves as off. BackgroundTheme = "theme" )
Backgrounds. See AppearanceConfig.Background and ResolveBackground.
const ( TapeAutorunOff = "off" TapeAutorunAsk = "ask" TapeAutorunAuto = "auto" )
Tape autorun modes. See TapeConfig.Autorun.
const ( ActionInboxDown = "inbox_down" ActionInboxUp = "inbox_up" ActionInboxPageDown = "inbox_page_down" ActionInboxPageUp = "inbox_page_up" ActionInboxFirst = "inbox_first" ActionInboxLast = "inbox_last" ActionInboxGo = "inbox_go" ActionInboxPeek = "inbox_peek" ActionInboxDismiss = "inbox_dismiss" ActionInboxReply = "inbox_reply" ActionInboxResume = "inbox_resume" ActionInboxPassOn = "inbox_pass_on" ActionInboxFilter = "inbox_filter" ActionInboxSelect = "inbox_select" ActionInboxMailbox = "inbox_mailbox" ActionInboxClose = "inbox_close" // The Inbox's review, triage and approval keys. ActionInboxReview = "inbox_review" ActionInboxSnooze = "inbox_snooze" ActionInboxUndo = "inbox_undo" ActionInboxShowSnoozed = "inbox_show_snoozed" ActionInboxDenyReason = "inbox_deny_reason" ActionInboxDetailDown = "inbox_detail_down" ActionInboxDetailUp = "inbox_detail_up" ActionAgentUnread = "agent_unread" ActionAgentSnooze = "agent_snooze" ActionAgentReply = "agent_reply" ActionAgentReview = "agent_review" ActionAgentCancelQueued = "agent_cancel_queued" // The prefix keys of the review and triage work (ctrl+b v, ctrl+b O). ActionPrefixReview = "prefix_review" ActionPrefixNextFinished = "prefix_next_finished" ActionPeekApprove = "peek_approve" ActionPeekApproveAlways = "peek_approve_always" ActionPeekDeny = "peek_deny" ActionPeekType = "peek_type" ActionPeekReadAgain = "peek_read_again" ActionPeekGo = "peek_go" ActionPeekBack = "peek_back" ActionMailDown = "mail_down" ActionMailUp = "mail_up" ActionMailPageDown = "mail_page_down" ActionMailPageUp = "mail_page_up" ActionMailOpen = "mail_open" ActionMailReply = "mail_reply" ActionMailFocusPane = "mail_focus_pane" ActionMailNew = "mail_new" ActionMailBack = "mail_back" )
The actions of the Inbox, the prompt open over it and the mailbox, named once so the input path, the key hints and the defaults cannot drift apart.
const AgentsOffMessage = "Agent features are off. Set agents.enabled = true in the config to use this command."
AgentsOffMessage is the one line a command, a verb or a key prints when it is an agent feature and the agent features are off.
const AgentsOffVerbMessage = "Agent features are off on this machine. Set agents.enabled = true in its config.toml to turn them on."
AgentsOffVerbMessage is what the daemon answers an agent verb with while the agent features are off. A verb can come from the CLI, an MCP client or a herdr client, so it names the machine and not a command.
const BorderStyleGlyphs = "glyphs"
BorderStyleGlyphs is the appearance.border_style value meaning "take the border from the active glyph set".
A set could have been let win over border_style whenever it defines a border, which is one fewer thing to say. It would also mean that selecting a set silently turned an option the user had already set into a no-op, with nothing on screen or in get-config to say why. This way both settings are always live and the one that is in charge is the one the user named.
const CommandActionPrefix = "command:"
CommandActionPrefix starts the action name of every command entry.
const DefaultCheckpointMaxUntrackedMB = 50
DefaultCheckpointMaxUntrackedMB is the default of max_untracked_mb.
const DefaultClockFormat = "15:04:05"
DefaultClockFormat is what the clock has always drawn.
const DefaultHostedGrace = 10 * time.Minute
DefaultHostedGrace is how long a pane run here for another machine outlives a dropped link when nothing says otherwise.
const DefaultLeaderKey = "ctrl+b"
DefaultLeaderKey is the prefix key tuios ships with. It is a constant rather than a read of Settings.LeaderKey because the places that fall back to it are asking "what does tuios bind when nobody said otherwise", which is one answer for the whole program and not one per session.
const DefaultRecapAway = 10 * time.Minute
DefaultRecapAway is how long the person must have been away from a pane for the dock to show a recap when they come back.
const DefaultScratchName = "scratch"
DefaultScratchName is the name of the built-in scratch terminal, the one toggle_scratch shows. A command entry cannot take it.
const DefaultScrollbackLines = 10000
DefaultScrollbackLines is how many lines a pane keeps behind it as it ships. Named because a caller with no session in reach (a window built in a test, or a harness) still has to say how deep the scrollback is, and the number is better said once here than repeated at every one of them.
const DimUnfocusedMax = 90
DimUnfocusedMax caps it. The cap is not a legibility floor (content is the user's own text and they may quiet it as far as they like). It only stops a pane from being erased outright, where there is nothing left to show the setting worked and no way to tell a dimmed pane from a crashed one.
const DockCustomPrefix = "custom/"
DockCustomPrefix marks a name in one of the dock lists as referring to a [dock.custom.NAME] table rather than to a built-in.
const DockModeIconDefault = "default"
DockModeIconDefault is the word that puts a mode icon back to the built-in for the glyph set. The empty string cannot do it, because an empty icon is a value: it hides the icon.
const DockModeIconMaxWidth = 8
DockModeIconMaxWidth is the widest icon, in cells, the mode pill takes from appearance.dock_mode_icon_*. The pill shares the dock's left block with the workspace strip, and an icon wider than this would take the strip's room.
const DropInDirName = "config.d"
DropInDirName is the directory beside config.toml whose *.toml files are merged in.
const FPSAuto = "auto"
FPSAuto is the max_fps value that follows the display's refresh rate.
const GhosttyAltArrowAdvice = "Ghostty rewrites alt+left/alt+right to word motions: " +
"add keybind = alt+left=unbind and keybind = alt+right=unbind to unbind them"
GhosttyAltArrowAdvice is the extra step Ghostty needs for the alt+arrow binds. Ghostty ships keybinds that rewrite alt+left/alt+right into the readline word motions ESC b and ESC f before any encoding happens, so those two chords never reach tuios even with macos-option-as-alt on and the Kitty protocol negotiated.
const ImageSymbolsAuto = "auto"
ImageSymbolsAuto is the default of appearance.image_symbols.
const IncludeKey = "include"
IncludeKey is the top-level key that lists the files a config file includes.
const LeaderAction = "leader_key"
LeaderAction is what Bindings names as the taker of a command entry's key when the key is the leader.
const LinkPolicyDefaultName = "*"
LinkPolicyDefaultName is the [hosts] key whose policy applies to every machine without a table of its own.
const MaxHostedGrace = 24 * time.Hour
MaxHostedGrace bounds hosted_grace, so a typo of hours cannot leave a process nobody can reach running for a week.
const (
// MaxLogMessages is the maximum number of log messages to keep in memory
MaxLogMessages = 100
)
const MaxPasteBufferKB = 256 << 10
MaxPasteBufferKB bounds max_kb: 256 MiB. The buffers are in the daemon's memory, and a value past this reads as it.
const PaneBackgroundOff = BackgroundOff
PaneBackgroundOff is the pane background's name from before the other surfaces had one. It is the same value as BackgroundOff.
const PaneGapMax = 8
PaneGapMax caps it. Past this the panes on a small terminal are further apart than they are wide, and spacing that swallows what it spaces has stopped being spacing.
const PanesDefaultLabelKeys = "1234567890"
PanesDefaultLabelKeys is the default label keys. Digits, as tmux's display-panes uses, so the first nine labels are the numbers select_window_1 to select_window_9 already give the same panes.
const PushoverAPI = "https://api.pushover.net/1/messages.json"
PushoverAPI is where a Pushover message goes when [notify.pushover] names no url.
const ScratchSessionUnused = "This key is no longer used. The scratch key shows one shell in a popup. Remove the key."
ScratchSessionUnused is what tuios says about the old [scratch] session key.
const ScrollbarTrackNone = "none"
ScrollbarTrackNone is the track value that draws no track at all, which is what the thin style looked like before it grew one.
const SectionCommand = "command"
SectionCommand is the section name a command entry's binding reports: the [[keybindings.command]] table.
const ShimmerFrame = time.Second / 15
ShimmerFrame is the interval between frames of the working-row shimmer: 15 frames a second. The band moves a column or less per frame at that rate, so more frames would draw the same picture again.
const SidebarAgentRowMaxRules = 8
SidebarAgentRowMaxRules is how many rules one token may carry. Eight is more than a row of seven tokens needs and few enough to read at once.
const SidebarContextWarnAt = 80
SidebarContextWarnAt is the percent of its context window an agent must be using before the context token draws. Below it the figure is noise on a narrow rail; at it and over, the agent is close to compacting or running out.
const SidebarCustomDefaultTitle = "Custom"
SidebarCustomDefaultTitle is the heading the section draws when the table names none.
const SidebarDefaultSections = "sessions:25,terminals,files:25,agents:34"
SidebarDefaultSections is the rail's layout as it ships.
The syntax is one section per comma, in the order they are stacked from the top, each optionally followed by ":" and the percent of the rail's content lines it may claim. A section with no percent is flexible: it takes whatever the others leave. A name left out of the list is a section the rail does not draw.
The percent is a ceiling, not a reservation. A section only ever claims the lines its own rows can fill, so the three quarters this default spends on sessions, files and agents are spent only when there are that many sessions, files and agents; the terminals list gets the rest, which on a normal rail is nearly all of it.
const SidebarSectionCustom = "custom"
SidebarSectionCustom is the rail section whose rows are the output of a command the user writes, configured in [appearance.sidebar.custom]. It is one section and not a family of named ones, because the rail's sections are a fixed enum that sizes its arrays, and one more value fits that as it is.
const SidebarSectionSpacer = "spacer"
SidebarSectionSpacer is the layout's empty block. It draws nothing and takes lines, which is how a person puts a gap between two sections or pushes what follows it to the bottom of the rail.
It is the one name the layout may carry more than once, because it names a place rather than a section. Two spacers in a layout are two gaps, and the parser keeps both; every other name is dropped the second time it appears, since a rail cannot draw one list in two places.
A spacer with a share takes that percent of the rail and keeps it. A spacer with no share takes the lines nothing else wants, which is what "push the rest to the bottom" means.
const (
// TapeRecordingIndicator is the recording indicator
TapeRecordingIndicator = "[REC]"
)
Variables ¶
var ( // MaxFPSCap is the highest max_fps tuios accepts, and the most a display // sold today refreshes at. // // Bubble Tea clamps its own frame ticker to 120 in NewProgram, which is // what this cap used to match: a larger value was accepted, handed to // tea.WithFPS and quietly ignored. OS.BindProgram now sets the ticker after // NewProgram, past that clamp, so every value up to this cap is one the // screen really gets. MaxFPSCap = 240 // DefaultFPS is the frame rate for max_fps = 0, and for "auto" when the // display's rate cannot be found. DefaultFPS = 60 // MinConfiguredFPS is the floor a configured max_fps is clamped to. Below it // the UI stops feeling like it is responding to the keyboard at all. MinConfiguredFPS = 10 // IdleFPS is the refresh rate when the terminal is idle (no output for ~500ms). // Reduces CPU usage from ~10% to near-zero on idle. IdleFPS = 10 )
var ( // DockPillLeftChar is the left character for pill-style indicators DockPillLeftChar string // DockPillRightChar is the right character for pill-style indicators DockPillRightChar string // DockModeIconWindow is the icon for window mode (Nerd Font: nf-fa-window_restore) DockModeIconWindow string // DockModeIconTerminal is the icon for terminal mode (Nerd Font: nf-fa-terminal) DockModeIconTerminal string // DockModeIconTiling is the icon for tiling mode (Nerd Font: nf-fa-th, a 3x3 grid) DockModeIconTiling string // DockIconTerminalCount is the icon for terminal count (Nerd Font: nf-fa-terminal) DockIconTerminalCount string // DockIconWorkspaceCount is the icon for workspace count (Nerd Font: nf-fa-th_large, a 2x2 grid) DockIconWorkspaceCount string // DockIconLeaveRunning is the icon for the control that quits this client and // leaves the session up (Nerd Font: nf-fa-sign_out). The desktop metaphor is // carried by the glyph so the label next to it can stay plain. DockIconLeaveRunning string // DockIconCloseSession is the icon for the control that ends the session and // everything in it (Nerd Font: nf-fa-power_off). DockIconCloseSession string // DockSeparator is the separator between dock sections DockSeparator = " " // Two spaces for breathing room // DockWorkspaceMoreLeft and DockWorkspaceMoreRight are the workspace strip's // overflow arrows. Single-angle quotes rather than triangles: they are one // cell in every font, so the strip's columns do not move with the glyph set, // and they read as "there is more this way" without the weight of a button. DockWorkspaceMoreLeft = "‹" DockWorkspaceMoreRight = "›" // WindowPillLeft is the left pill-style character for window decorations. WindowPillLeft string // WindowPillRight is the right pill-style character for window decorations. WindowPillRight string )
var ( // NotificationGlyphError is the error mark (nf-fa-times_circle). NotificationGlyphError string // NotificationGlyphWarning is the warning mark (nf-fa-exclamation_triangle). NotificationGlyphWarning string // NotificationGlyphSuccess is the success mark (nf-fa-check_circle). NotificationGlyphSuccess string // NotificationGlyphInfo is the info mark (nf-fa-info_circle). NotificationGlyphInfo string )
Nerd Font severity marks, from the same FontAwesome block the dock already draws its terminal and workspace counts from, so a terminal that renders the dock at all renders these. They come from go-nf rather than being written out as literals for the same reason the dock icons do: a private-use codepoint pasted into source is invisible to review and is silently lost by any tool that touches the file, which is exactly how the first version of this shipped four empty strings and drew a message with no mark at all.
var ( DockbarPositions = []string{"bottom", "top", "hidden"} SidebarPositions = []string{"left", "right", "hidden"} WhichKeyPositions = []string{"bottom-right", "bottom-left", "top-right", "top-left", "center"} WindowTitlePositions = []string{"bottom", "top", "hidden"} )
The enum sets shared by the registry, the validator and the settings page, so one spelling serves all three.
var ( ScreenshotFormats = []string{"png", "svg", "ansi", "html", "txt"} ScreenshotFrames = []string{"window", "plain", "none"} ScreenshotControlSet = []string{"auto", "macos", "glyphs", "none"} )
Enum values, shared by the registry and the verb.
var ( SpotlightFollowModes = []string{SpotlightFollowCursor, SpotlightFollowMouse} SpotlightEdges = []string{SpotlightEdgeHard, SpotlightEdgeSoft} )
SpotlightFollowModes and SpotlightEdges are what the two enum options accept, shared by the registry, the validator and the settings page so one spelling serves all three.
var ActionDescriptions = map[string]string{}/* 295 elements not displayed */
ActionDescriptions maps action names to their descriptions for help menu generation.
var AgentSoundModeNames = []string{ string(AgentSoundAudio), string(AgentSoundBell), string(AgentSoundBoth), }
AgentSoundModeNames lists the accepted sound_mode values, in the order they are documented.
var Ambiguities = []Ambiguity{ { Keys: []string{"ctrl+i", "tab"}, Byte: 0x09, Separable: true, Why: "Ctrl+I is byte 0x09, which is what Tab sends. Without disambiguation the two are one key.", }, { Keys: []string{"ctrl+m", "enter", "return"}, Byte: 0x0D, Separable: true, Why: "Ctrl+M is byte 0x0D, carriage return, which is what Enter sends.", }, { Keys: []string{"ctrl+[", "esc", "escape"}, Byte: 0x1B, Separable: true, Why: "Ctrl+[ is byte 0x1B, escape. Binding it also binds Esc, and Esc starts every escape sequence the terminal sends.", }, { Keys: []string{"ctrl+h", "backspace"}, Byte: 0x08, Separable: true, Why: "Ctrl+H is byte 0x08. Terminals disagree about whether Backspace sends 0x08 or 0x7F, so this pair collides on some hosts and not others.", }, { Keys: []string{"ctrl+j", "ctrl+enter"}, Byte: 0x0A, Separable: true, Why: "Ctrl+J is byte 0x0A, line feed. Some terminals send it for Ctrl+Enter and a few send it for Enter.", }, { Keys: []string{"ctrl+space", "ctrl+@"}, Byte: 0x00, Separable: true, Why: "Ctrl+Space is the null byte, which is also Ctrl+@. Some terminals send nothing at all for it.", }, }
Ambiguities is every pair worth warning about. Kept short on purpose: these are the ones a user reaches for and is then surprised by, not every control code in the table.
var AutoEnterTerminalModes = []string{ string(AutoEnterTerminalOff), string(AutoEnterTerminalTargeted), string(AutoEnterTerminalAll), }
AutoEnterTerminalModes lists the valid values for appearance.auto_enter_terminal_on_focus. off is first: it is the default, and the settings cycler draws the first accepted value for an unset enum.
var Backgrounds = []string{BackgroundOff, BackgroundTheme}
Backgrounds lists the keyword values every background option takes; a #RRGGBB literal is also accepted, and a surface's own option also takes empty, which follows appearance.background.
var BorderStyles = []string{ "rounded", "normal", "thick", "double", "block", "outer-half-block", "inner-half-block", "ascii", "hidden", BorderStyleGlyphs, }
BorderStyles is every border style the app offers, in the order the settings page cycles them. One list so a style added here is offered, validated and covered by the border tests at once.
var ClickToTypeModes = []string{ClickToTypeSingle, ClickToTypeDouble, ClickToTypeOff}
ClickToTypeModes lists the valid values for appearance.click_to_type.
var CopyEntries = []string{CopyEntryCursor, CopyEntryCenter}
CopyEntries is every value appearance.selection.copy_entry takes.
var CopyFlashStyles = []string{ CopyFlashDiagonal, CopyFlashDiagonalReverse, CopyFlashHorizontal, CopyFlashVertical, }
var DefaultLinkAllow = []string{LinkAllowList, LinkAllowMail, LinkAllowOpen, LinkAllowWrite}
DefaultLinkAllow is what a machine may do here when nothing says otherwise. It is what every link could do before the policy existed, less respond: answering a prompt for the person is opt-in.
var DefaultRecapTestPatterns = []string{
"go test", "npm test", "pnpm test", "yarn test", "bun test", "pytest",
"cargo test", "make test", "jest", "vitest", "mvn test", "gradle test",
}
DefaultRecapTestPatterns are the commands the recap reads as a test run.
var DefaultStrictGrants = []string{PaneGrantRead, PaneGrantWrite, PaneGrantFan}
DefaultStrictGrants is what a pane holds under strict when grants is not set: it reads its session and fan group, types into its own session, and starts and drives agents in its fan group.
var Global = DefaultSettings()
Global is the process seed: the config file and the CLI flags are applied to it once at startup, single-threaded, and every session copies it at construction. Nothing that serves a client writes to it after that, which is what stops one client's settings page reaching another client's frame.
Read it directly only where there is no session in reach: an entrypoint doing startup, or a harness with no OS.
var GuestPrograms = []GuestProgram{ { Name: "tmux", Comms: []string{"tmux", "tmux: client", "tmux: server"}, Keys: map[string]string{ "ctrl+b": "prefix (every tmux command starts here)", }, Note: "tmux's default prefix is the same key as tuios's. Nested, the outer one wins and the inner multiplexer is unreachable.", }, { Name: "GNU screen", Comms: []string{"screen", "SCREEN"}, Keys: map[string]string{ "ctrl+a": "prefix (every screen command starts here)", }, Note: "screen's prefix is ctrl+a, which is also readline's start-of-line.", }, { Name: "zellij", Comms: []string{"zellij"}, Keys: map[string]string{ "ctrl+p": "pane mode", "ctrl+t": "tab mode", "ctrl+n": "resize mode", "ctrl+s": "search / scroll mode", "ctrl+o": "session mode", "ctrl+g": "lock the whole keyboard", }, Note: "zellij claims a row of bare ctrl+letter chords rather than one prefix, so it collides with more of tuios than tmux does.", }, { Name: "wlterm", Comms: []string{"wlterm"}, Keys: map[string]string{ "ctrl+\\": "tapped twice, quits wlterm", "ctrl+b": "prefix, in wlterm -multi only", }, Note: "The default single-app mode has no prefix and sends every key to the app. A compositor in a pane also wants key releases.", }, { Name: "vim / neovim", Comms: []string{"vim", "nvim", "vi", "view"}, Keys: map[string]string{ "ctrl+w": "window commands", "ctrl+v": "visual block", "ctrl+o": "jump back", "ctrl+i": "jump forward (the same byte as Tab)", "ctrl+r": "redo", "ctrl+a": "increment number", "ctrl+d": "half page down", "ctrl+u": "half page up", "ctrl+p": "keyword completion", "ctrl+n": "keyword completion", }, Note: "vim binds most of the control range. ctrl+i is the one worth knowing: it is Tab's byte, so a terminal that does not disambiguate cannot tell them apart.", }, { Name: "emacs", Comms: []string{"emacs", "emacsclient"}, Keys: map[string]string{ "ctrl+x": "the C-x prefix (half of emacs lives here)", "ctrl+c": "the C-c prefix (mode-specific commands)", "ctrl+a": "start of line", "ctrl+e": "end of line", "ctrl+k": "kill line", "ctrl+s": "incremental search", "ctrl+g": "cancel", "ctrl+h": "help prefix", }, Note: "emacs treats ctrl+x and ctrl+c as prefixes, so taking either one away removes a large part of the program.", }, { Name: "readline (bash, zsh, and most REPLs)", Comms: []string{"bash", "zsh", "sh", "dash", "ksh", "python", "python3", "irb", "node", "psql", "sqlite3"}, Keys: map[string]string{ "ctrl+a": "start of line", "ctrl+e": "end of line", "ctrl+k": "kill to end of line", "ctrl+u": "kill to start of line", "ctrl+w": "kill previous word", "ctrl+r": "reverse history search", "ctrl+l": "clear screen", "ctrl+d": "end of input", "ctrl+y": "yank", "ctrl+t": "transpose characters", }, Note: "Every readline program shares this set, so a tuios binding on one of these keys is felt in the shell and in every REPL launched from it.", }, { Name: "fish", Comms: []string{"fish"}, Keys: map[string]string{ "ctrl+f": "accept the autosuggestion", "ctrl+r": "history search", "ctrl+p": "history back", "ctrl+n": "history forward", "alt+up": "history for the current token", }, Note: "fish's ctrl+f is the autosuggestion, which is the thing people notice missing first.", }, { Name: "less / man / git pager", Comms: []string{"less", "man", "more", "pager"}, Keys: map[string]string{ "ctrl+f": "page forward", "ctrl+b": "page back", "ctrl+d": "half page down", "ctrl+u": "half page up", }, Note: "less binds ctrl+b to page back, so a leader on ctrl+b is felt in every man page.", }, { Name: "fzf", Comms: []string{"fzf"}, Keys: map[string]string{ "ctrl+j": "move down", "ctrl+k": "move up", "ctrl+t": "file widget", "ctrl+r": "history widget", }, Note: "fzf is usually reached through a shell widget, so its keys are live for as long as the picker is up and not before.", }, { Name: "htop", Comms: []string{"htop", "btop", "top"}, Keys: map[string]string{}, Note: "Function keys and letters rather than control chords, so it collides with tuios rarely.", }, { Name: "yazi / ranger / mc", Comms: []string{"yazi", "ranger", "mc", "nnn", "lf"}, Keys: map[string]string{ "ctrl+a": "select all", "ctrl+r": "refresh", }, Note: "File managers lean on plain letters, which terminal mode forwards untouched.", }, { Name: "nano", Comms: []string{"nano", "pico"}, Keys: map[string]string{ "ctrl+o": "write out", "ctrl+x": "exit", "ctrl+w": "search", "ctrl+k": "cut line", "ctrl+g": "help", }, Note: "nano's whole command set is control chords, and it prints them along the bottom, so a stolen one is visibly broken.", }, }
GuestPrograms is the curated table.
It is a curated list of defaults, not detection. Nothing here is read from the program, its config, or its runtime state, so a user who moved tmux's prefix to ctrl+a has an entry that is wrong for them. It is worth carrying anyway: the collisions that actually bite are a short list, they are stable across years, and the alternative is an interface that shows a user their leader is ctrl+b without ever mentioning that so is tmux's.
var ImageSymbolModes = []string{ImageSymbolsAuto, "octant", "sextant", "quadrant", "half", "off"}
ImageSymbolModes is what appearance.image_symbols accepts. The names other than auto are mosaic.Kind names.
var KittyPlaceholderModes = []string{KittyPlaceholdersAuto, KittyPlaceholdersOn, KittyPlaceholdersOff}
KittyPlaceholderModes is what appearance.kitty_placeholders accepts.
var LayoutModes = []string{LayoutModeBSP, LayoutModeMasterStack, LayoutModeScrolling}
LayoutModes is the accepted set, for the registry and the validator.
var LinkCapabilities = []string{LinkAllowList, LinkAllowMail, LinkAllowOpen, LinkAllowWrite, LinkAllowRespond}
LinkCapabilities is every capability, in the order they are documented.
var LinkClickModes = []string{LinkClickBoth, LinkClickCtrl, LinkClickShift, LinkClickOff}
LinkClickModes lists the valid values for appearance.link_click.
var LinkModes = []string{LinksOff, LinksMarked, LinksAll}
LinkModes lists the valid values for appearance.links.
var MasterPositions = []string{ MasterPositionLeft, MasterPositionRight, MasterPositionTop, MasterPositionBottom, MasterPositionCenter, }
MasterPositions is the accepted set, in the order cycle_master_position steps through them.
var MotionLevels = []string{MotionNone, MotionBasic, MotionFull}
MotionLevels is what appearance.motion accepts, from least motion to most.
var MultiCopyFormats = []string{ MultiCopyFormatPlain, MultiCopyFormatMarkdown, MultiCopyFormatJSON, }
MultiCopyFormats is every value appearance.selection.multi_format takes, in the order the format key in multi copy mode cycles through them.
NavigatorLayouts is the accepted navigator_layout values, in the order the v key steps through them.
var NotifyContentNames = []string{NotifyContentSummary, NotifyContentTitle}
NotifyContentNames lists the accepted content values.
var OSC52WriteModes = []string{ OSC52WriteOff, OSC52WriteAsk, OSC52WriteFocused, OSC52WriteOn, }
OSC52WriteModes is every value appearance.selection.osc52_write takes.
var PaneGrantNames = []string{PaneGrantRead, PaneGrantWrite, PaneGrantFan, PaneGrantRespond, PaneGrantAdmin}
PaneGrantNames is every grant, in the order they are documented.
var PaneModes = []string{PaneModeOpen, PaneModeStrict}
PaneModes is every mode.
var PiPCorners = []string{PiPCornerBottomRight, PiPCornerBottomLeft, PiPCornerTopRight, PiPCornerTopLeft}
PiPCorners is what pip.corner accepts, shared by the registry, the validator and the settings page.
var RecapModes = []string{RecapToast, RecapInbox, RecapOff}
RecapModes lists the valid values for agents.recap.mode.
var ResumeAgentsModes = []string{ResumeAgentsAsk, ResumeAgentsAuto, ResumeAgentsOff}
ResumeAgentsModes lists the valid values for daemon.resume_agents.
var SSHAgentModes = []string{SSHAgentOff, SSHAgentFollow}
SSHAgentModes lists the valid values for daemon.ssh_agent.
var ScreensaverEffects = append([]string{ScreensaverRandomEffect}, tfx.Names()...)
ScreensaverEffects is what the effect option accepts: the random choice plus every effect the engine has registered. Deriving it from the engine is what stops the list here and the list there drifting apart.
var ScrollbarStyles = []string{ScrollbarStyleThin, ScrollbarStyleTrack}
ScrollbarStyles lists the valid values for appearance.scrollbar.style.
var ScrollbarTints = []string{ScrollbarTintQuiet, ScrollbarTintBorder, ScrollbarTintMuted}
ScrollbarTints lists the keyword values for appearance.scrollbar.tint; a #RRGGBB literal is also accepted.
var SidebarAgentRowDefaultTokens = []string{"session", "need", "harness", "name", "progress", "elapsed", "context", "subagents", "pr", "meta", "now", "message"}
SidebarAgentRowDefaultTokens is the row as it ships. state and host are left out because both have a value on every row and the glyph already says the state. need, context, subagents, meta and now draw on the second line only: need says what a row wants from you ("approval", "question", "errored", "finished"), context how full the agent's context is once that is worth a look, subagents how many subagents the agent still has at work, which on a row at rest is the one sign that work goes on, pr the pull request of the session's branch and its checks, meta whatever else the pane reported through set-agent-meta, which is nothing unless a hook or statusline feed writes it, and now what a working agent is doing ("Bash: go test ./..."). now comes last because the line cuts its last token first, and a long command is what can best lose its tail.
var SidebarAgentRowTokens = []string{"harness", "name", "state", "progress", "elapsed", "need", "now", "prompt", "context", "subagents", "pr", "meta", "message", "session", "host"}
SidebarAgentRowTokens is every token an agent row can carry, in the order a person is most likely to want them listed. Beside these, "$key" names one key of the pane's agent metadata (see SidebarMetaTokenKey).
now, prompt, context and subagents read the metadata tuios feeds itself, with a rule of their own on top of the raw value: now draws only while the agent works, prompt is the first line of the last prompt given to it, context draws "ctx 84%" only once the context is SidebarContextWarnAt percent full or more, in the warning ink unless its table says otherwise, and subagents says how many subagents the agent is running ("2 subagents") on any row, and nothing while there are none. pr is the pull request of the session's worktree branch ("PR #12 open pass"), which the daemon reads from gh, and nothing when there is none. $now, $prompt and $context draw the raw value on any row. progress draws "40%", the progress of the pane's OSC 7501 report, while the program works or waits, on the identity line.
var SidebarFeedMetaKeys = []string{"now", "prompt", "model", "context", "cost", "plan", "subagents"}
SidebarFeedMetaKeys are the metadata keys tuios feeds from hooks, the status line and protocol panes. The meta token leaves them out: each has a token of its own (now, prompt, context, subagents, or $model, $cost and $plan), so the model and the cost are not on every row unless a person places them.
var SidebarFileDeletes = []string{SidebarFileDeleteTrash, SidebarFileDeletePermanent}
SidebarFileDeletes lists the valid values for appearance.sidebar.file_delete.
var SidebarFolderClicks = []string{ SidebarFolderClickNavigate, SidebarFolderClickCd, SidebarFolderClickBoth, }
SidebarFolderClicks lists the valid values for appearance.sidebar.folder_click.
var SidebarSectionNames = []string{"sessions", "terminals", "files", "agents", "git", SidebarSectionCustom}
SidebarSectionNames are the sections appearance.sidebar.sections may name.
This is membership as well as order. A section left out of the layout is a section the rail does not draw, and that is the only way to turn one off: there is no second switch per section, because a switch cannot say where a thing goes and two spacers would have no switch to share.
var SidebarTokenColors = []string{"text", "dim", "muted", "accent", "warning", "error", "success", "info"}
SidebarTokenColors are the palette names a token's fg may take, beside a #rrggbb literal. They are the rail's own tiers and the four status inks.
var TapeAutorunModes = []string{TapeAutorunOff, TapeAutorunAsk, TapeAutorunAuto}
TapeAutorunModes lists the valid values for tape.autorun.
var TilingSchemes = []string{ TilingSchemeSpiral, TilingSchemeLongestSide, TilingSchemeAlternate, TilingSchemeSmartSplit, }
TilingSchemes lists the valid values for appearance.tiling_scheme, in the order cycle_tiling_scheme steps through them.
var WindowButtonPositions = []string{WindowButtonPositionRight, WindowButtonPositionLeft}
WindowButtonPositions lists the valid values for appearance.window_button_position.
var WindowButtonStyles = []string{WindowButtonStylePill, WindowButtonStyleDots}
WindowButtonStyles lists the valid values for appearance.window_button_style.
var WindowSizeModes = []string{WindowSizeSmallest, WindowSizeLargest, WindowSizeLatest}
WindowSizeModes lists the valid values for daemon.window_size.
var ZenModeModes = []string{ZenModeDisabled, ZenModeAlways, ZenModeMouse}
ZenModeModes lists the valid values for appearance.zen_mode.
Functions ¶
func AddPluginDirInFile ¶ added in v0.9.0
AddPluginDirInFile adds dir to [plugins] dirs. It reports whether the file changed.
func AmbiguityPartners ¶ added in v0.8.0
AmbiguityPartners returns the other names in key's pair, excluding key itself, or nil when it is in no pair.
func AmbiguitySurprises ¶ added in v0.8.0
AmbiguitySurprises reports whether key is the spelling of its pair that catches people out.
Both halves of a pair are equally ambiguous, but only one of them is worth warning about unprompted. Someone who binds Esc knows they bound Esc; being told it is also Ctrl+[ is noise, and with Esc, Tab and Enter bound in nine scopes it is fourteen rows of noise in the default config. Someone who binds Ctrl+I and finds Tab stops working has hit the actual bug.
The recorder still answers in both directions, because there the user pressed the key and is asking.
func AmbiguityVerdict ¶ added in v0.8.0
AmbiguityVerdict is what to tell a user about a key they just pressed, given whether the host terminal agreed to disambiguate.
The host's answer is the whole of it. tuios asks for disambiguation on every view; a terminal that granted it sends Ctrl+I as an escape sequence carrying the modifier, and the pair genuinely separates. A terminal that did not sends 0x09 and there is nothing to separate.
func ApplyAppearanceConfig ¶ added in v0.8.0
func ApplyAppearanceConfig(cfg *UserConfig, s *Settings)
ApplyAppearanceConfig applies a parsed config file to the package globals the render loop and the input handler read. It must be called on the Bubble Tea goroutine (from Update or at startup before the program runs), never from the file-watcher goroutine, because the globals are read concurrently on the render path.
This is the whole of the config-file-to-globals mapping, deliberately: an entrypoint that loads a config and calls this gets every setting the settings page can write, with nothing left needing a second call. That matters for callers that do not also call ApplyOverrides: `tuios tape`, the pkg/tuios embed, and every live config reload through ConfigReloadedMsg. A setting mapped only in ApplyOverrides would be dropped for them. ApplyOverrides still layers CLI flags on top, so flags keep winning where they are set.
func ApplyNotificationConfig ¶ added in v0.8.0
func ApplyNotificationConfig(cfg *UserConfig, s *Settings)
ApplyNotificationConfig applies the [notifications] section to the package globals the renderer reads. Absent or non-positive values leave the built-in default in place rather than collapsing a message to zero seconds, which is the failure mode the old 1500ms default was already close enough to.
func ApplyOverrides ¶ added in v0.7.0
ApplyOverrides layers explicit CLI flag values over the globals that ApplyAppearanceConfig set. Every entrypoint applies the config funnel first; a zero value here means the flag was not given and the config's value stands. Any new setting belongs in ApplyAppearanceConfig, and only needs a line here if a CLI flag can override it.
func AutoFPS ¶ added in v0.9.0
AutoFPS is the frame rate max_fps = "auto" draws at for a display that refreshes at displayHz: that rate inside the configured range, or DefaultFPS when the rate is not known (0).
func CanonicalKey ¶ added in v0.8.1
CanonicalKey is the one spelling of a key that tuios compares against a key event. Every key that comes from config.toml or from a command line goes through it before it is matched: the leader, every binding table, and the argument of `tuios keybinds explain`, `free` and `unbind`.
A single letter keeps its case (m and M are different keys). Anything else is lowercased, each modifier alias becomes the name Bubble Tea uses (opt+f12 and option+f12 become alt+f12, cmd+v becomes super+v, control+b becomes ctrl+b), a repeated modifier is dropped, and the modifiers are put in Bubble Tea's order. A chord with a modifier tuios does not know, or with an empty part, comes back lowercased and otherwise untouched, so the validator can still name what is wrong with it.
func CanonicalPaneGrants ¶ added in v0.8.0
CanonicalPaneGrants returns the valid names in names, lower-cased, without repeats and in documented order, and the names it dropped.
func ClampMasterCount ¶ added in v0.8.5
ClampMasterCount keeps a master count inside its range. Zero and below are unset and mean the default.
func ConfigFileHeader ¶ added in v0.8.0
ConfigFileHeader is the comment block written at the top of a generated config file. Exported so `tuios config reset` writes the same guidance a first-run config gets, including the notes on which keys cost you what.
func ConfigWarnings ¶ added in v0.8.0
func ConfigWarnings(cfg *UserConfig) []string
ConfigWarnings returns the non-fatal problems in cfg as human-readable lines, for surfacing inside the running TUI. Reported only to a log nobody reads, a typo in a keybinding looks like a broken feature rather than a broken config.
func CopyCommandLabel ¶ added in v0.8.3
CopyCommandLabel is a command line short enough for a dock message.
func DefaultDockCenter ¶ added in v0.8.0
func DefaultDockCenter() []string
func DefaultDockLeft ¶ added in v0.8.0
func DefaultDockLeft() []string
DefaultDockLeft, DefaultDockCenter and DefaultDockRight are the arrangement a config with no [dock] table gets. Copies, so a caller cannot edit the default.
func DefaultDockRight ¶ added in v0.8.0
func DefaultDockRight() []string
func DockBuiltinComponents ¶ added in v0.8.0
func DockBuiltinComponents() []string
DockBuiltinComponents returns the built-in component names, sorted. Used by the config warnings and by list-dock-components.
func DockClockInterval ¶ added in v0.8.0
DockClockInterval is how often a clock in this format has to be redrawn. A layout without seconds moves once a minute, and asking it to move sixty times a second was the whole of the old clock's cost.
func DockEventTypes ¶ added in v0.8.0
func DockEventTypes() []string
DockEventTypes returns the event names a refresh contract may watch, sorted.
func DockFixedSide ¶ added in v0.8.0
DockFixedSide is the side a component is always drawn on, or "" when it goes wherever it is listed.
func DockModeIconUsable ¶ added in v0.9.0
DockModeIconUsable reports whether value can stand as a mode pill icon: no control characters, which would move the cursor or start an escape sequence in the middle of the dock row, and at most DockModeIconMaxWidth cells. The width is the one the dock layout measures with, so a wide glyph is counted as the two cells it takes. The empty string is usable: it hides the icon.
func DroppedWarnings ¶ added in v0.9.0
func DroppedWarnings(dropped []DroppedKey) []string
DroppedWarnings is the Warning of each dropped key.
func EffectiveDefault ¶ added in v0.9.0
EffectiveDefault returns the value an option has when the user has not set it, for the config that applies on this machine.
For most options this is Option.Default. The two [startup] booleans differ: they ship on, but a config file without a [startup] table reads them as false, so an existing install keeps its floating, standalone session. Only a machine with no config file at all gets the shipped true.
func ExpandHome ¶ added in v0.9.0
ExpandHome replaces a leading ~/ with the home directory.
func FirstRunConfig ¶ added in v0.9.0
FirstRunConfig is the config.toml tuios writes when there is none: the comment header and nothing else, so every other file of the config applies. The one exception is [startup]. A config without it means the floating, standalone session tuios had before, so a first start writes tiled and daemon on, unless another file of the config already sets them. include is a line to keep, such as an include list, or "".
func ForceMacOSHost ¶ added in v0.8.0
func ForceMacOSHost(on bool) func()
ForceMacOSHost makes the defaults, the key normalizer and the validator build for the named platform, and returns the function that puts it back. It is for tests in other packages that assert the behaviour of the platform they are not running on.
It is not safe for parallel tests: one process has one platform.
func GetConfigPath ¶ added in v0.0.23
GetConfigPath returns the path to the config file
func GetOptionValue ¶ added in v0.8.0
func GetOptionValue(cfg *UserConfig, path string) (string, bool)
GetOptionValue reads the current value of a path as a string. A nil pointer field reads back as the option's default, since nil is the unset state and the default is what the app will act on. ok is false only for a path the registry does not carry.
func HostsInFile ¶ added in v0.8.0
func HostsInFile(path string) (map[string]HostConfig, error)
HostsInFile reads the [hosts] table at path. It is the set a command edits, read from the file rather than from a running daemon, so `tuios hosts add` works with no daemon running.
func IncludeLine ¶ added in v0.9.0
IncludeLine is the include key of the config file at path as one TOML line, or "" when the file has none or cannot be read.
func InsideMultiplexer ¶ added in v0.8.0
func InsideMultiplexer() bool
InsideMultiplexer reports whether another multiplexer sits between tuios and the terminal. It swallows keys of its own and has to be told to pass the Option chords through, so the advice has to mention it.
func IsAgentPrefixKeybinding ¶ added in v0.8.0
func IsAgentPrefixKeybinding(k Keybinding) bool
IsAgentPrefixKeybinding reports whether a prefix menu line is one that only means something to a person running agents: the Inbox, the oldest waiting item, the Inbox on its mail, reviewing a pane's changes, the newest finished turn and the Agents settings tab. The client leaves them out of the menu until an agent has been seen; the keys work either way.
func IsAgentsSettingsPrefixKeybinding ¶ added in v0.9.0
func IsAgentsSettingsPrefixKeybinding(k Keybinding) bool
IsAgentsSettingsPrefixKeybinding reports whether a prefix menu line is the one that opens the settings page's Agents tab. The client leaves it out where it has no such tab, such as over SSH.
func IsDockBuiltin ¶ added in v0.8.0
IsDockBuiltin reports whether name is one of the dock's built-in components.
func IsDockEventType ¶ added in v0.8.0
IsDockEventType reports whether name is an event a component may watch.
func IsHexColor ¶ added in v0.8.0
IsHexColor reports whether s is a colour literal the config can hold. One spelling, so a value written by the settings panel, typed at the CLI or put in the file by hand is the same string either way.
func IsLeaderPress ¶ added in v0.8.1
IsLeaderPress reports whether pressed, a key event's string, is the leader key spelled as leader in config.toml. pressed must be in the canonical form a key event has (see CanonicalKey); it is not normalized here, because this runs on every key press. The leader goes through the same normalizer as every binding table, so opt+f12 and option+f12 match the alt+f12 a terminal sends, and on macOS opt+1 also matches the ¡ that Option composes. An empty leader means the default.
func IsMasterPosition ¶ added in v0.8.5
IsMasterPosition reports whether pos is one of MasterPositions.
func IsReviewPrefixKeybinding ¶ added in v0.8.0
func IsReviewPrefixKeybinding(k Keybinding) bool
IsReviewPrefixKeybinding reports whether a prefix menu line is the review of the focused pane. The client leaves it out of the menu on a daemon that cannot review.
func KeyLabel ¶ added in v0.9.0
KeyLabel is how a which-key row shows one key from the config: named keys and modifiers capitalised (esc is Esc, shift+tab is Shift+Tab), the arrows as arrows, and a printable key as it is.
func MacOSOptionChord ¶ added in v0.8.0
MacOSOptionChord returns the alt+ chord a composed macOS Option glyph stands for, and whether r is such a glyph. Only meaningful on darwin: these glyphs are ordinary typed characters elsewhere.
func MacOptionAdvice ¶ added in v0.8.0
func MacOptionAdvice(host HostTerminal, chord string) string
MacOptionAdvice returns the one thing the user has to change so their terminal sends Alt for Option instead of composing a character, named for the terminal they are actually in. chord is the binding that just failed to fire, e.g. "alt+n".
Every one of these settings makes the terminal send the ESC-prefixed Meta encoding, which tuios already reads, so the advice is complete on its own: no tuios-side setting is involved.
func MarshalUserConfig ¶ added in v0.9.0
func MarshalUserConfig(cfg *UserConfig) ([]byte, error)
MarshalUserConfig is cfg as TOML, the way every config file tuios writes is encoded. It differs from toml.Marshal in one thing: a field may write its own TOML, which is how max_fps comes out as a bare 144 or a quoted "auto" from one field. toml.Marshal would quote both.
func NormalizeHerdrProtocol ¶ added in v0.8.0
NormalizeHerdrProtocol reads an [agents] herdr_protocol value. Empty and anything unrecognised mean the default, "always".
func NormalizeHostProgramStatus ¶ added in v0.9.0
NormalizeHostProgramStatus reads an [agents] host_program_status value. Empty and anything unrecognised mean the default, "auto".
func NormalizePaneLabelKeys ¶ added in v0.9.0
NormalizePaneLabelKeys makes a key list usable for pane labels: letters a to z (upper case counts as lower case) and digits, each once, in the order given. It returns the default when fewer than two keys are left, because one key cannot tell two panes apart.
func OptionPaths ¶ added in v0.8.0
func OptionPaths() []string
OptionPaths returns every path, sorted, for a did-you-mean hint on a typo.
func ParseAgentRestFold ¶ added in v0.8.0
ParseAgentRestFold reads appearance.sidebar.agent_rest_fold: a Go duration, or off (or 0) for never. ok is false for anything else, which reads as the default.
func ParseBoxSize ¶ added in v0.8.2
ParseBoxSize reads a size in cells or percent: a bare number is cells, a number with a trailing percent sign is a share of the region the box sits in. An empty spec is not a value and is reported as such, so a caller can tell "the user said nothing" from "the user said 0".
It is the one parser for tuios popup --width and --height and for the [scratch] sizes, so the two accept the same spellings.
func ParseHostedGrace ¶ added in v0.8.0
ParseHostedGrace reads hosted_grace: a Go duration, or "0" for none. A negative value is an error and a value past MaxHostedGrace is cut to it.
func ParseKeyPath ¶ added in v0.9.0
ParseKeyPath splits a dotted key, honouring quotes, so a host name with a dot in it can be asked about.
func ParseQuietHours ¶ added in v0.8.0
ParseQuietHours parses "HH:MM-HH:MM" into minutes since local midnight. An empty string is not an error and yields an empty window (0, 0), which Quiet reads as "never quiet".
func PinPreV080Appearance ¶ added in v0.8.0
func PinPreV080Appearance(a *AppearanceConfig)
PinPreV080Appearance writes into a the seven appearance values v0.8.0 changed, as they were before it:
sidebar.enabled false (now true) sidebar.position left (now right) sidebar.width 28 (now 24) dockbar_position bottom (now top) window_title_position bottom (now top) zoom_size 100 (now 95) click_to_type single (now double) scrollbar.style thin (now track)
The Learn tour runs with them, because its lessons describe that screen. Tests whose fixtures were measured against that screen use it too, so they keep testing what they were written to test.
func PrefixMenuActions ¶ added in v0.9.0
PrefixMenuActions lists every action a which-key menu has a row for, in order. The coverage test reads it to check that each action a prefix binds by default has a row with a description.
func PressesByAction ¶ added in v0.8.0
func PressesByAction(r *KeybindRegistry) map[string][]string
PressesByAction maps every action to the whole thing a user presses to reach it, chord included: "1" for a window-mode binding, "ctrl+b L 1" for one that lives under a prefix. An action bound in several scopes gets every press: launcher is both "alt+space" and "ctrl+b a".
GetKeys answers with the bare key of the first section that binds the action, which is the right answer for the keymap and the wrong one for anything that shows a binding to a human. launcher came back as "a", its key under the prefix, and not its global alt+space. An action reachable only under a chord would be listed as "1", and a help screen that says 1 snaps a window to a corner, while 1 selects a window, is the same class of lie this whole surface exists to catch.
Built in one pass and returned as a map because the help overlay is on the render path: asking per action would rescan every section for each of eighty of them, once a frame. The registry keeps the map until its next Reload, so callers share it and must not change it. Each slice is clipped, so an append to one copies it rather than writing into the next.
func ReadConfigFile ¶ added in v0.9.0
ReadConfigFile is the config at path as one TOML document, with every include and config.d file merged in. A main file that is not there is returned as the error os.ReadFile gave.
func RemoveHostFromFile ¶ added in v0.8.0
RemoveHostFromFile deletes the [hosts.NAME] table from every file of the config whose main file is at path. It reports whether a table was there to delete, so the caller can say "no host is named that" rather than reporting a success that removed nothing. A host that a read-only file sets is not removed from any file, and the error names that file.
func RemovePluginDirInFile ¶ added in v0.9.0
RemovePluginDirInFile removes dir from [plugins] dirs. It reports whether the file changed.
func RenderUserConfig ¶ added in v0.8.0
func RenderUserConfig(cfg *UserConfig) (func() (WriteNote, error), error)
RenderUserConfig reads cfg into the change a save makes and hands back the function that writes it. The split exists because the caller is the Update goroutine: reading the model is memory and can happen there, the file write cannot.
Reading cfg here rather than in the returned function is also what makes this safe without a deep copy. The config is the model's own and goes on being edited; a writer holding the pointer would be marshalling a struct changing underneath it.
The change is the difference between the config cfg was loaded from and cfg now, so a save writes the keys the person changed and nothing else (see include_write.go). The next save starts from here, so a change is written once.
The returned function is safe to call from anywhere and from several places at once. Writes are serialised and stamped, so when two saves are in flight the older one gives way rather than overwriting the newer. Its WriteNote says when a read-only file sent a change to another file.
func ResetConfig ¶ added in v0.9.0
ResetConfig writes config.toml at path as a first start writes it, with its include list kept.
func ResolveBackground ¶ added in v0.8.0
ResolveBackground is what one surface's background is behaving as, given its own setting and appearance.background: off, theme, or a #RRGGBB literal.
The surface's own setting wins whenever it holds a value, off included, so one surface can be left bare while the rest are painted. Empty follows the default for every surface. Anything unrecognised, in either place, resolves to off, the documented default, so a typo paints nothing rather than a guess.
func ResolveSecret ¶ added in v0.9.0
ResolveSecret reads a secret from the first source that is set: the value in the file, then the environment variable, then the file. A secret with no source is empty with no error. An error names the source, never the value.
func ResolveShell ¶ added in v0.8.0
func ResolveShell(cfg *UserConfig) string
ResolveShell returns the shell a new pane runs when nothing more specific names one, in the order ShellFor uses. A nil cfg skips appearance.preferred_shell. A preferred shell that does not exist is reported on stderr, which is where the standalone path that calls this has always reported it.
func RetiredOption ¶ added in v0.8.2
RetiredOption says why path can no longer be set, for a path the registry dropped but a user may still name. ok is false for any other path.
func RewindSave ¶ added in v0.9.0
func RewindSave(cfg *UserConfig, err error)
RewindSave undoes what RenderUserConfig did to cfg's baseline when the save err came from failed. Call it on the goroutine that owns cfg. It does nothing for another config or another error.
func ScopedDescription ¶ added in v0.9.0
ScopedDescription is the description of action as it acts in scope: the scope's own text when it has one, then ActionDescriptions, then the action name with its underscores opened.
func SectionNames ¶ added in v0.8.0
func SectionNames() []string
SectionNames returns every section name in the order Scopes visits them, so a caller can iterate the config's tables without repeating the switch above.
func SetOptionValue ¶ added in v0.8.0
func SetOptionValue(cfg *UserConfig, path, value string) error
SetOptionValue validates value against the option's type and accepted set, then writes it to cfg.
func SetPluginEnabledInFile ¶ added in v0.9.0
SetPluginEnabledInFile adds id to [plugins] enabled, or removes it, and rewrites only the enabled key of the file at path. Every comment and every other table stays where it is. It reports whether the file changed.
func ShellFor ¶ added in v0.8.0
ShellFor picks a shell: preferred when it names one that exists, then $SHELL, then the first platform default found. missing reports a preferred shell that was named and not found, so the caller can say so where its user will see it.
On Windows a missing .exe suffix is added to preferred and the name is looked up on PATH; elsewhere it must be a path that exists.
The standalone window path and the daemon both come here, so a pane runs the same shell whichever of them spawns it.
func SidebarCustomPlaced ¶ added in v0.9.0
SidebarCustomPlaced reports whether the layout names the custom section.
func SidebarLayoutNames ¶ added in v0.8.0
func SidebarLayoutNames() []string
SidebarLayoutNames are every name the layout may carry: the sections, and the spacer. Used where a person is told what they may type.
func SidebarMetaTokenKey ¶ added in v0.8.0
SidebarMetaTokenKey returns the metadata key a "$key" token names, and false for any other token. The key rules match the daemon's set-agent-meta: 1 to 24 lower-case letters, digits, '_' and '-', starting with a letter.
func SidebarSectionProblems ¶ added in v0.8.0
SidebarSectionProblems reports what a layout string asked for and did not get, one line per problem, for the config validator to print.
func SidebarSectionsString ¶ added in v0.8.0
func SidebarSectionsString(entries []SidebarSectionShare) string
SidebarSectionsString writes a whole layout back out.
func SidebarSectionsWithout ¶ added in v0.8.0
SidebarSectionsWithout returns the layout with one section taken out of it, keeping the order and the shares of the rest.
This is what the deprecated show_windows and show_agents booleans fold into. It is spelled here rather than at the call site because the layout's grammar lives here, and a second place that knows how to write one would be a second opinion about what it means.
func ValidMasterCount ¶ added in v0.8.5
ValidMasterCount reports whether n is inside the master count's range.
func ValidMasterPosition ¶ added in v0.8.5
ValidMasterPosition returns pos when it is one of MasterPositions and left otherwise, so a typo lays the panes out as they always were.
func WriteConfigFile ¶ added in v0.8.0
func WriteConfigFile(cfg *UserConfig, configPath string) error
WriteConfigFile marshals cfg to TOML (with the documented header) and writes it to configPath, creating the parent directory as needed.
Types ¶
type AgentAlertPolicy ¶ added in v0.8.0
type AgentAlertPolicy struct {
Enabled bool
Notify bool
Sound bool
SoundMode AgentSoundMode
SoundCooldown time.Duration
SoundDone string
SoundNeedsInput string
Dock bool
SuppressFocused bool
Settle time.Duration
// contains filtered or unexported fields
}
AgentAlertPolicy is AgentAlertsConfig with every default resolved and the quiet-hours string parsed, so the hot path is field reads and integer comparisons. Build it with ResolveAgentAlerts.
func ResolveAgentAlerts ¶ added in v0.8.0
func ResolveAgentAlerts(c *AgentAlertsConfig) AgentAlertPolicy
ResolveAgentAlerts turns the config table into a policy, applying every default. A nil receiver resolves to the defaults, so a caller with no config at all still gets the documented behavior.
func (AgentAlertPolicy) Alerts ¶ added in v0.8.0
func (p AgentAlertPolicy) Alerts(state string) bool
Alerts reports whether a transition into state is one the user asked to hear about. It is the only place the state toggles are read.
func (AgentAlertPolicy) AttentionCue ¶ added in v0.8.0
func (p AgentAlertPolicy) AttentionCue(state string) bool
AttentionCue reports whether a transition into state should use the cue that asks for a human rather than the one that reports the machine stopped. It is the state-to-cue map, kept here so the two callers cannot disagree.
func (AgentAlertPolicy) CueFile ¶ added in v0.8.0
func (p AgentAlertPolicy) CueFile(state string) string
CueFile is the user's replacement for the cue a transition into state uses, or empty for the built-in one.
func (AgentAlertPolicy) PlaysAudio ¶ added in v0.8.0
func (p AgentAlertPolicy) PlaysAudio() bool
PlaysAudio reports whether an alert should play a cue through an audio player.
func (AgentAlertPolicy) PlaysBell ¶ added in v0.8.0
func (p AgentAlertPolicy) PlaysBell() bool
PlaysBell reports whether an alert should write a BEL to the terminal.
type AgentAlertSounds ¶ added in v0.8.0
type AgentAlertSounds struct {
// Done is the cue for an agent that stopped. Default: built in.
Done string `toml:"done"`
// NeedsInput is the cue for an agent waiting on a human, or one that
// failed. Default: built in.
NeedsInput string `toml:"needs_input"`
}
AgentAlertSounds is the [notifications.agent.sounds] table: a path per cue.
There are two cues rather than five states, because a pair has to be told apart by ear in under half a second and a third would only be guessed at. needs_input and errored share the attention cue; done and idle share the other. A path that does not exist falls back to the built-in cue, so a typo costs the custom sound rather than all sound.
type AgentAlertStates ¶ added in v0.8.0
type AgentAlertStates struct {
// NeedsInput is the agent blocked on the user. Default: true.
NeedsInput *bool `toml:"needs_input"`
// Errored is the agent having stopped on an error. Default: true.
Errored *bool `toml:"errored"`
// Done is the agent having finished its task, which only an explicit report
// produces. Default: true.
Done *bool `toml:"done"`
// Idle is the agent having gone quiet. The stall timer guesses this one from
// silence, so it is the flappy state and the one that would make tuios the
// thing people mute. Default: false.
Idle *bool `toml:"idle"`
// Working is the agent starting work, which is not news. Default: false.
Working *bool `toml:"working"`
}
AgentAlertStates is the [notifications.agent.states] table: one toggle per agent state, naming the states worth interrupting someone for.
type AgentAlertsConfig ¶ added in v0.8.0
type AgentAlertsConfig struct {
// Enabled is the master switch. False silences every sink below, including
// the command. Default: true.
Enabled *bool `toml:"enabled"`
// States selects which transitions alert at all.
States AgentAlertStates `toml:"states"`
// Notify writes an in-band desktop notification to the terminal the client
// is attached to. Default: true.
Notify *bool `toml:"notify"`
// Sound makes the alert audible. What that means is SoundMode's job.
// Default: false.
Sound *bool `toml:"sound"`
// SoundMode chooses how Sound makes a noise: "audio" plays one of tuios's
// two cues through whatever audio player the machine has, "bell" writes a
// BEL and lets the terminal decide what that means, and "both" does each.
// An unrecognised value is reported as a config warning and read as the
// default. Default: "audio".
SoundMode string `toml:"sound_mode"`
// SoundCooldownSeconds is the shortest gap between two audible cues,
// counted across every pane. It exists because a workspace where six agents
// finish together should make one sound rather than six. It does not apply
// to the bell, which the terminal rate-limits or does not, as it prefers.
// Default: 3.
SoundCooldownSeconds *int `toml:"sound_cooldown_seconds"`
// Sounds replaces the built-in cues with files of the user's own.
Sounds AgentAlertSounds `toml:"sounds"`
// Dock shows the message in tuios's own dock, where it is clickable and
// jumps to the pane that raised it. Default: true.
Dock *bool `toml:"dock"`
// Command is a shell command run on an alert, shorthand for registering one
// under the after-agent-state hook. Default: empty (nothing runs).
Command string `toml:"command"`
// SettleSeconds holds an alert for this long and drops it if the pane leaves
// the state before it expires, so a flapping agent produces one alert rather
// than a stream. Zero alerts immediately. Default: 2.
SettleSeconds *int `toml:"settle_seconds"`
// SuppressFocused drops alerts for the pane the user is already looking at,
// which is what tuios did before any of this was configurable. A pane is
// looked at while it is focused and the host terminal has not reported
// losing focus (DECSET 1004 focus events). Set it false
// to be told anyway, on the grounds that a pane being on screen is not
// evidence anyone read it. Default: true.
SuppressFocused *bool `toml:"suppress_focused"`
// QuietHours silences every sink inside a local-time window written
// "HH:MM-HH:MM". A window that wraps midnight is understood. Default: empty
// (never quiet).
QuietHours string `toml:"quiet_hours"`
}
AgentAlertsConfig is the [notifications.agent] table: what tuios does when a pane's agent state changes.
Every toggle is a pointer so nil can mean "unset, use the default" and an explicit false survives a reload, matching [appearance.sidebar]. The defaults are deliberately quiet: an agent that flips between working and idle all day is the reason people mute their tools, so only the two states that mean the machine has stopped and is waiting on a human raise anything.
type AgentSoundMode ¶ added in v0.8.0
type AgentSoundMode string
AgentSoundMode is how an audible alert is made audible.
const ( // AgentSoundAudio plays a cue through a system audio player. AgentSoundAudio AgentSoundMode = "audio" // AgentSoundBell writes a BEL and lets the terminal decide. AgentSoundBell AgentSoundMode = "bell" // AgentSoundBoth does each, for a machine where either might be missed. AgentSoundBoth AgentSoundMode = "both" )
func ParseAgentSoundMode ¶ added in v0.8.0
func ParseAgentSoundMode(s string) (AgentSoundMode, bool)
ParseAgentSoundMode resolves a config value, reporting whether it was one of the accepted names. An empty value is accepted as the default.
type AgentsConfig ¶ added in v0.8.0
type AgentsConfig struct {
// Enabled turns every agent feature on or off: agent detection, the
// agent rows of the rail, the Inbox, agent mail, approvals, attention,
// the agent keys and start-agent. Nil means on, the default. False keeps
// only the multiplexer. See On.
Enabled *bool `toml:"enabled,omitempty"`
// Approvals is the [agents.approvals] table. See ApprovalsConfig.
Approvals ApprovalsConfig `toml:"approvals,omitempty"`
// Permissions is the [agents.permissions] table: what a process in a
// pane may do through tuios. See pane_grants.go.
Permissions PermissionsConfig `toml:"permissions,omitempty"`
// Recap is the [agents.recap] table: the summary of what an agent did
// while the person was away. See agents_work.go.
Recap RecapConfig `toml:"recap,omitempty"`
// Queue is the [agents.queue] table: messages waiting to be typed to an
// agent when it comes to rest. See agents_work.go.
Queue QueueConfig `toml:"queue,omitempty"`
// Checkpoints is the [agents.checkpoints] table: the state of a pane's
// git work tree saved at the end of each agent turn. See agents_work.go.
Checkpoints CheckpointsConfig `toml:"checkpoints,omitempty"`
// HerdrProtocol says which panes are told about the socket tuios accepts
// herdr's pane state protocol on, which Crush and other harnesses report
// to by themselves: "always" (the default) for every pane, the way herdr
// tells every pane, so a harness started from a shell reports too;
// "agents" for a pane that starts such a harness directly; and "off" for
// none. A pane told about it reads as a herdr pane to anything that checks
// HERDR_ENV, herdr itself included, which refuses to start inside one
// unless its own config allows nesting. See docs/AGENT_STATE.md.
HerdrProtocol string `toml:"herdr_protocol,omitempty"`
// HostProgramStatus says whether tuios reports its panes' agent states to
// the terminal it runs in, with OSC 7501 (the Program Status Protocol):
// "auto" (the default) asks the terminal at start and reports only when
// it answers, and "off" never asks. See docs/PROGRAM_STATUS.md.
HostProgramStatus string `toml:"host_program_status,omitempty"`
}
AgentsConfig is the [agents] table.
func (AgentsConfig) On ¶ added in v0.9.0
func (a AgentsConfig) On() bool
On reports whether the agent features are on. They are unless the file says enabled = false.
type Ambiguity ¶ added in v0.8.0
type Ambiguity struct {
// Keys are the names that collapse onto one another.
Keys []string `json:"keys"`
// Byte is the control code they all arrive as in the legacy encoding.
Byte byte `json:"byte"`
// Why is the one sentence explaining the pair.
Why string `json:"why"`
// Separable is whether the Kitty keyboard protocol's disambiguation can
// tell them apart when the host grants it. All the control-code pairs can
// be; the pair kept here that cannot is noted in its Why.
Separable bool `json:"separable"`
}
Ambiguity is a pair of key names that a terminal sends as the same byte, so binding one of them binds both.
This is not a tuios quirk to be worked around. It is what a VT100 keyboard was: Ctrl+letter is the letter's code with the top three bits cleared, and Tab, Return and Escape happen to sit exactly where Ctrl+I, Ctrl+M and Ctrl+[ land. Nothing downstream of the terminal can undo that, which is why the only thing that changes the answer is the terminal agreeing to send something else.
func AmbiguityFor ¶ added in v0.8.0
AmbiguityFor returns the pair a key belongs to, and whether it is in one.
type AmbiguousBinding ¶ added in v0.8.0
type AmbiguousBinding struct {
Scope string `json:"scope"`
Action string `json:"action"`
Key string `json:"key"`
Partners []string `json:"partners"`
Verdict string `json:"verdict"`
Evidence Evidence `json:"evidence"`
}
AmbiguousBinding is a binding whose key is half of a pair the terminal cannot always tell apart.
type AppearanceConfig ¶ added in v0.2.2
type AppearanceConfig struct {
BorderStyle string `toml:"border_style"` // Border style: rounded, normal, thick, double, hidden, block, ascii, outer-half-block, inner-half-block, glyphs
ZenMode string `toml:"zen_mode"` // Zen mode: disabled, always, mouse (default: disabled)
Links string `toml:"links"` // Links tuios acts on: off, marked, all (default: all)
LinkClick string `toml:"link_click"` // The click that opens a link: both, ctrl, shift, off (default: both)
LinkOpener string `toml:"link_opener"` // Command that opens a web link; empty uses $BROWSER, then the system opener
HideWindowButtons bool `toml:"hide_window_buttons"` // Hide window control buttons (minimize, maximize, close)
WindowButtonStyle string `toml:"window_button_style"` // Window control style: pill, dots (default: dots)
WindowButtonPosition string `toml:"window_button_position"` // Which end of the title bar the window controls sit on: right, left (default: left)
HideScrollbar bool `toml:"hide_scrollbar"` // Hide the window scrollbar thumb on the border
ScrollbackLines int `toml:"scrollback_lines"` // Number of lines to keep in scrollback buffer (default: 10000, min: 100, max: 1000000)
ScrollLines int `toml:"scroll_lines"` // Lines scrolled per mouse wheel notch (default: 3, min: 1, max: 50)
CopyOnSelect *bool `toml:"copy_on_select"` // Copy a mouse selection to the clipboard on release (default: true)
FocusFollowsMouse *bool `toml:"focus_follows_mouse"` // Focus the pane under the cursor as the mouse moves (default: false)
AltDrag *bool `toml:"alt_drag"` // Alt + left-drag moves a pane (default: true)
RightClickOpensMenu *bool `toml:"right_click_opens_menu"` // A plain right-click on a pane in terminal mode opens the pane menu (default: false)
KittyPlaceholders string `toml:"kitty_placeholders"` // Draw kitty Unicode placeholder images: auto, on, off (default: auto)
ImageSymbols string `toml:"image_symbols"` // Draw pane images as block glyphs on a terminal without graphics: auto, octant, sextant, quadrant, half, off (default: auto)
NewWindowInheritCwd *bool `toml:"new_window_inherit_cwd"` // A new window starts in the focused pane's working directory (default: true)
NewWindowFollowSSH *bool `toml:"new_window_follow_ssh"` // A split or new window of a pane that runs ssh runs the same ssh (default: false)
AutoEnterTerminalOnFocus AutoEnterTerminalPolicy `toml:"auto_enter_terminal_on_focus"` // When a keyboard focus command should start typing in that pane: off, targeted, all (default: off)
ClickToType string `toml:"click_to_type"` // What a click on a pane's content does in window-management mode: single, double, off (default: double)
WordCharacters *string `toml:"word_characters"` // Punctuation that counts as part of a word for double-click selection (default: "@-./_~?&=%+#")
DockbarPosition string `toml:"dockbar_position"` // Dockbar position: bottom, top, hidden (default: top)
PreferredShell string `toml:"preferred_shell"` // Preferred shell: if empty, auto-detect based on platform.
AnimationsEnabled *bool `toml:"animations_enabled,omitempty"` // Deprecated: folded into motion on load (false is none)
Motion string `toml:"motion"` // How much moves: none, basic (window slides, copy sweep), full (also fades and the working shimmer) (default: full)
ModalDim *int `toml:"modal_dim"` // Percent the screen behind a modal overlay is darkened; 0 is off (default: 30)
ConfirmQuit *bool `toml:"confirm_quit"` // Always show quit confirmation dialog (default: false). When false, only shown if foreground processes are running.
WhichKeyEnabled *bool `toml:"whichkey_enabled"` // Show which-key popup after pressing leader key (default: true)
WhichKeyPosition string `toml:"whichkey_position"` // Which-key popup position: bottom-right, bottom-left, top-right, top-left, center (default: bottom-right)
WrapLists *bool `toml:"wrap_lists"` // Up on a list's first row goes to its last, and down on the last to the first (default: true)
WindowTitlePosition string `toml:"window_title_position"` // Window title position: bottom, top, hidden (default: top). Shows CustomName if set, else terminal title.
HideClock bool `toml:"hide_clock"` // Hide the clock overlay (deprecated, use show_clock)
ShowClock bool `toml:"show_clock"` // Show the clock overlay (default: false)
ShowCPU bool `toml:"show_cpu"` // Show CPU graph in dock (default: false)
ShowRAM bool `toml:"show_ram"` // Show RAM usage in dock (default: false)
Theme string `toml:"theme"` // Color theme name (e.g., dracula, nord, my-custom-theme)
// Customization
BorderFocusedColor string `toml:"border_focused_color"` // Hex color for focused pane border (e.g., "#89b4fa")
BorderUnfocusedColor string `toml:"border_unfocused_color"` // Hex color for unfocused pane border (e.g., "#585b70")
WindowTitleFormat string `toml:"window_title_format"` // Format string for window titles: {title}, {index}, {cwd}
ZoomMaxWidth int `toml:"zoom_max_width"` // Max width in cells for zoom mode (0 = fullscreen, e.g. 120 centers at 120 cols)
NiriReverseScroll bool `toml:"niri_reverse_scroll"` // Reverse mouse scroll direction in niri scrolling mode (default: false)
NiriScrollCells int `toml:"niri_scroll_cells"` // Cells the niri viewport moves per mouse wheel event (default: 8, min: 1, max: 200)
// PrefixRepeatTime is how long the prefix stays armed after a repeatable
// prefix command, in milliseconds, so ctrl+b then left left left walks
// three columns. Zero turns it off. This is tmux's repeat-time.
PrefixRepeatTime *int `toml:"prefix_repeat_time"`
MaxFPS FPSLimit `toml:"max_fps"` // Maximum render FPS: 0 uses 60, "auto" follows the display, otherwise 10 to 240
DockWorkspaceTabs *bool `toml:"dock_workspace_tabs"` // Clickable workspace strip in the dock (default: true)
DockWorkspaceTabFormat string `toml:"dock_workspace_tab_format"` // Format string for workspace tabs: {index}, {name} (default: "{name}")
DockWorkspaceTooltip *bool `toml:"dock_workspace_tooltip"` // Pop a truncated workspace name in full on hover (default: true)
DockWorkspaceLabelMax *int `toml:"dock_workspace_label_max"` // Cell cap on a workspace pill's label; 0 draws the whole name (default: 12)
DockPillCaps *bool `toml:"dock_pill_caps"` // Rounded caps on every dock pill (default: true; false draws flat pills)
DockModeIconWindow *string `toml:"dock_mode_icon_window"` // Mode pill icon in window mode; "" draws none (default: the glyph set's)
DockModeIconTerminal *string `toml:"dock_mode_icon_terminal"` // Mode pill icon in terminal mode; "" draws none (default: the glyph set's)
DockModeIconTiling *string `toml:"dock_mode_icon_tiling"` // Mode pill icon while tiling is on; "" draws none (default: the glyph set's)
DockCompact bool `toml:"dock_compact"` // One-row dock with no rule (default: false)
SessionColors *bool `toml:"session_colors"` // Give each session its own colour on the rail and the switcher (default: true)
SessionBorder *bool `toml:"session_border"` // Carry that colour on every pane border too (default: false)
GlobalSession *bool `toml:"global_session"` // Offer a session that holds panes from several machines (default: true)
NiriClickReveals *bool `toml:"niri_click_reveals"` // Bring a clicked column fully on screen in the scrolling layout (default: true)
NiriHoverReveals *bool `toml:"niri_hover_reveals"` // With focus-follows-mouse on, bring the hovered column fully on screen (default: true)
ZoomAnimation *bool `toml:"zoom_animation"` // Slide a pane between its tile and the zoom box (default: true)
ZoomBorderless bool `toml:"zoom_borderless"` // A zoomed pane fills the whole pane region with no border (default: false)
ZoomFollowsFocus *bool `toml:"zoom_follows_focus"` // Hand the zoom to the pane the focus lands on (default: true)
WindowButtonZoom *bool `toml:"window_button_zoom"` // Carry the zoom control on a tiled pane's title bar (default: true)
SidebarGitDirty *bool `toml:"git_dirty"` // Count changed and untracked paths in the rail's git section (default: true)
Glyphs string `toml:"glyphs"` // Chrome glyph set: default, unicode, heavy, ascii, or one from ~/.config/tuios/glyphs
Gap int `toml:"gap"` // Cells of empty space kept between neighbouring tiled panes (default: 0)
// TilingScheme is the BSP insertion scheme a workspace starts with the
// first time it is tiled: spiral, longest_side, alternate or smart_split.
// See TilingSchemes. A workspace that already has a tree keeps its own
// scheme, set here, by a layout template, or by cycle_tiling_scheme;
// changing this later does not move it. See GetOrCreateBSPTree.
TilingScheme string `toml:"tiling_scheme"` // Default BSP insertion scheme for a new workspace (default: spiral)
// MasterRatio and ScrollColumnWidth are percentages rather than fractions
// because that is what a settings stepper and a CLI argument can carry: the
// option registry holds ints, and "50" is a value a person types. The model
// keeps the master ratio as the fraction the tilers want.
MasterRatio int `toml:"master_ratio"` // Master pane width in the master-stack layout, percent of the screen (default: 50)
ScrollColumnWidth int `toml:"scroll_column_width"` // New column width in the scrolling layout, percent of the screen (default: 55)
ScrollColumnMax int `toml:"scroll_column_max"` // Highest that width may be set to, percent of the screen (default: 90, up to 100)
ZoomSize int `toml:"zoom_size"` // How much of the screen a zoomed pane takes, percent (default: 95)
PanelPadding int `toml:"panel_padding"` // Columns of surface padding inside every overlay panel (default: 2)
ClockFormat string `toml:"clock_format"` // Go time layout the clock overlay is drawn with (default: 15:04:05)
DimUnfocused int `toml:"dim_unfocused"` // Percent an unfocused pane's content is carried toward its own ground (default: 0)
DimMultifocus bool `toml:"dim_multifocus"` // Dim the panes in the multifocus set too (default: false)
// MasterPosition, MasterCount and MasterGrid shape the master-stack layout
// for a workspace nobody has changed at run time. The actions that change
// them (cycle_master_position, add_master, remove_master and the rest) act
// on the current workspace only, and the session keeps what they set.
MasterPosition string `toml:"master_position"` // Side the master panes take: left, right, top, bottom or center (default: left)
MasterCount int `toml:"master_count"` // How many panes are masters (default: 1)
MasterGrid *bool `toml:"master_grid"` // With one master on the left, show four or more panes as a grid (default: true)
// The backgrounds tuios paints on cells that have none of their own. Each
// takes off, theme or #RRGGBB. background is the default for every
// surface; a surface's own key overrides it, and empty follows it. See
// ResolveBackground.
Background string `toml:"background"` // Ground for every surface not set on its own (default: off)
PaneBackground string `toml:"pane_background"` // Ground behind pane content (default: empty, follows background)
DesktopBackground string `toml:"desktop_background"` // Ground behind and between panes (default: empty, follows background)
WindowChromeBackground string `toml:"window_chrome_background"` // Ground under pane borders and title bars (default: empty, follows background)
DockBackground string `toml:"dock_background"` // Ground under the dock (default: empty, follows background)
// Legacy flat sidebar keys, superseded by the [appearance.sidebar] table.
// migrateLegacySidebar folds them into it and clears them, so they are read
// from an old file but never written back to a new one.
SidebarEnabled *bool `toml:"sidebar_enabled,omitempty"`
SidebarPosition string `toml:"sidebar_position,omitempty"`
SidebarWidth int `toml:"sidebar_width,omitempty"`
SidebarShowWindows *bool `toml:"sidebar_show_windows,omitempty"`
SidebarShowGlyphs *bool `toml:"sidebar_show_glyphs,omitempty"`
SidebarShowCounts *bool `toml:"sidebar_show_counts,omitempty"`
// The tables are last so the TOML encoder emits them after every scalar key
// of [appearance]; a table written mid-section would swallow the keys that
// follow it.
Scrollbar ScrollbarConfig `toml:"scrollbar"`
// Selection is the [appearance.selection] table: the colours a pane uses to
// mark text. See SelectionConfig.
Selection SelectionConfig `toml:"selection"`
Sidebar SidebarConfig `toml:"sidebar"`
}
AppearanceConfig holds appearance-related settings
type ApprovalsConfig ¶ added in v0.8.0
type ApprovalsConfig struct {
// Enabled lists the harnesses whose approvals the Inbox may answer, by
// harness id or alias (claude, claude-code, opencode, kilo, qwen). Empty, the
// default, turns the feature off.
Enabled []string `toml:"enabled,omitempty"`
// HoldSeconds is how long a hook waits for an answer before it gives the
// prompt back to the harness. Zero means the default, 120. The daemon
// keeps it between 10 and 300, and the Claude Code hook tuios installs
// allows 310 seconds, so a hold never outlives the hook.
HoldSeconds int `toml:"hold_seconds,omitempty"`
// HoldPlans also hands a plan an agent in plan mode asks to have
// approved to the Inbox, for the harnesses Enabled names. Unset means
// true: a plan follows enabled. See PlansHeld.
HoldPlans *bool `toml:"hold_plans,omitempty"`
// Risk is the [agents.approvals.risk] table: the rules that mark an
// approval risky. See RiskConfig.
Risk RiskConfig `toml:"risk,omitempty"`
}
ApprovalsConfig is the [agents.approvals] table: which harnesses hand their permission prompts to the Inbox, so the person can answer one from wherever they are instead of going to the pane.
It is off by default. A harness named here has its approval hook wait, for up to HoldSeconds, for an answer from the Inbox. While it waits the harness shows no prompt of its own, which is why nothing waits unless asked to. When the wait ends with no answer the harness shows its own prompt as before.
func (ApprovalsConfig) PlansHeld ¶ added in v0.8.0
func (c ApprovalsConfig) PlansHeld() bool
PlansHeld reports whether plans are held for the Inbox, for the harnesses Enabled names.
type AutoEnterTerminalPolicy ¶ added in v0.8.0
type AutoEnterTerminalPolicy string
AutoEnterTerminalPolicy is appearance.auto_enter_terminal_on_focus. A leftover true/false from the unreleased bool shape unmarshals here rather than failing the whole config file: true becomes all, false off.
const ( // AutoEnterTerminalOff never changes mode from a keyboard focus command. AutoEnterTerminalOff AutoEnterTerminalPolicy = "off" // AutoEnterTerminalTargeted enters terminal mode when a command picks a // pane (numbered select, directional arrows, scrolling left/right), not // when Tab or prefix n/p cycle through them. AutoEnterTerminalTargeted AutoEnterTerminalPolicy = "targeted" // AutoEnterTerminalAll enters terminal mode on every covered focus // command that actually moves focus, including next/prev window. AutoEnterTerminalAll AutoEnterTerminalPolicy = "all" )
func (*AutoEnterTerminalPolicy) UnmarshalText ¶ added in v0.8.0
func (p *AutoEnterTerminalPolicy) UnmarshalText(text []byte) error
UnmarshalText accepts the three policies and the two bool leftovers.
type Binding ¶ added in v0.8.0
type Binding struct {
Scope string `json:"scope"`
Section string `json:"section"`
Action string `json:"action"`
Desc string `json:"description"`
// Key is the key as the lookup sees it, after the normalizer's platform
// expansion has been undone: what the user wrote in config.toml.
Key string `json:"key"`
// Press is the whole thing to press, chord included.
Press string `json:"press"`
// Shadowed is set when an earlier claimant in the same scope already took
// the key, so pressing it runs that other action instead of this one.
Shadowed bool `json:"shadowed"`
// ShadowedBy names the action that actually runs, when Shadowed.
ShadowedBy string `json:"shadowed_by,omitempty"`
// Unbound is set on the one row an action with no keys still gets. Key and
// Press are empty on such a row.
//
// It is listed rather than left out because the alternative is a one-way
// door: an action taken off its key would vanish from every surface that
// reads this, and the overlay binds a key by selecting the action's row.
// Unbinding something and then being unable to find it again is not an
// unbind, it is a loss.
Unbound bool `json:"unbound,omitempty"`
}
Binding is one key bound to one action inside one scope.
type CheckpointsConfig ¶ added in v0.9.0
type CheckpointsConfig struct {
// Enabled saves a checkpoint of a pane's git work tree each time its
// agent finishes a turn. Unset means true.
Enabled *bool `toml:"enabled,omitempty"`
// Keep is how many checkpoints one pane keeps. Zero means the default,
// 50; values past 1000 read as 1000.
Keep int `toml:"keep,omitempty"`
// MaxUntrackedMB is the size past which an untracked file is left out
// of a checkpoint, in megabytes. Zero means the default, 50. A negative
// value means no limit.
MaxUntrackedMB int `toml:"max_untracked_mb,omitempty"`
}
CheckpointsConfig is the [agents.checkpoints] table.
func (CheckpointsConfig) KeepCount ¶ added in v0.9.0
func (c CheckpointsConfig) KeepCount() int
KeepCount is Keep with its default and bound applied.
func (CheckpointsConfig) MaxUntrackedBytes ¶ added in v0.9.0
func (c CheckpointsConfig) MaxUntrackedBytes() int64
MaxUntrackedBytes is MaxUntrackedMB in bytes with its default applied, and zero for no limit.
func (CheckpointsConfig) On ¶ added in v0.9.0
func (c CheckpointsConfig) On() bool
On reports whether checkpoints are taken.
type Collision ¶ added in v0.8.0
type Collision struct {
Scope string `json:"scope"`
ScopeName string `json:"scope_name"`
Key string `json:"key"`
Press string `json:"press"`
// Winner is the action the key actually runs.
Winner string `json:"winner"`
WinnerDesc string `json:"winner_description"`
// Losers are the actions bound to the same key that never run.
Losers []CollisionLoser `json:"losers"`
// CrossSection is true when the competing actions came from different
// tables in config.toml. Those are the ones worth flagging loudest: the two
// bindings look unrelated in the file, and nothing in the TOML hints that
// one of them is dead.
CrossSection bool `json:"cross_section"`
Evidence Evidence `json:"evidence"`
}
Collision is two tuios actions competing for one key inside one scope. It is the certain tier: it is decided entirely by tuios's own lookup order, so it is not a guess about anything.
type CollisionLoser ¶ added in v0.8.0
type CollisionLoser struct {
Action string `json:"action"`
Desc string `json:"description"`
Section string `json:"section"`
}
CollisionLoser is one action that lost a key.
type CommandBinding ¶ added in v0.8.2
type CommandBinding struct {
// Key is the key that runs the command. "prefix+" puts it after the
// leader. Any other key acts in window mode and terminal mode.
Key string `toml:"key"`
// Type is scratch, popup, pane or shell. Empty means popup.
Type string `toml:"type,omitempty"`
// Command is run by sh -c, so it can hold pipes and quotes. A scratch
// entry with no command runs the user's shell.
Command string `toml:"command,omitempty"`
// Description names the entry in the command palette and in
// tuios keybinds list. Optional.
Description string `toml:"description,omitempty"`
// Name is the entry's stable name. Optional: see ResolvedName.
Name string `toml:"name,omitempty"`
// Width and Height size a scratch or popup entry, in cells (60) or
// percent (80%) of the pane region. Empty means 80%.
Width string `toml:"width,omitempty"`
Height string `toml:"height,omitempty"`
}
CommandBinding is one [[keybindings.command]] entry.
func (CommandBinding) Action ¶ added in v0.8.2
func (c CommandBinding) Action() string
Action is the entry's action name, for the registry and the dispatcher.
func (CommandBinding) BareKey ¶ added in v0.8.2
func (c CommandBinding) BareKey() string
BareKey is the key without "prefix+".
func (CommandBinding) HeightSpec ¶ added in v0.8.2
func (c CommandBinding) HeightSpec() string
func (CommandBinding) Label ¶ added in v0.8.2
func (c CommandBinding) Label() string
Label is what the palette and keybinds list call the entry.
func (CommandBinding) ResolvedName ¶ added in v0.8.2
func (c CommandBinding) ResolvedName() string
ResolvedName is the entry's name: its own name field, else a slug of its description, else a slug of its command.
A slug keeps ASCII letters and digits only, so a description in another script can give an empty one. The key comes next, which is ASCII. The last resort is a hash of the entry's text, which is the same on every run.
func (CommandBinding) ResolvedType ¶ added in v0.8.2
func (c CommandBinding) ResolvedType() string
ResolvedType is the entry's type with the default filled in.
func (CommandBinding) Section ¶ added in v0.8.2
func (c CommandBinding) Section() string
Section and BareKey split the key into the section it acts in and the key as that section writes it: "prefix+alt+g" is alt+g in prefix_mode, and "alt+g" is alt+g in global.
func (CommandBinding) WidthSpec ¶ added in v0.8.2
func (c CommandBinding) WidthSpec() string
WidthSpec and HeightSpec are the effective sizes. A size that does not parse falls back to 80%, as a popup does.
type CommandProblem ¶ added in v0.9.0
type CommandProblem struct {
// Entry is the entry's place in config.toml, from 1.
Entry int `json:"entry"`
Key string `json:"key"`
// Name is the name tuios gives the entry, when it can make one.
Name string `json:"name,omitempty"`
// Ignored is true when tuios leaves the entry out.
Ignored bool `json:"ignored"`
Problem string `json:"problem"`
}
CommandProblem is a [[keybindings.command]] entry that needs attention: one tuios ignores, or one whose key every pane loses.
type ConfigLayer ¶ added in v0.9.0
type ConfigLayer struct {
// Path is the file as named, made absolute. A symlink is not resolved, so
// the listing shows the path the person wrote.
Path string
// Real is Path with its symlinks resolved. The watcher follows both.
Real string
Kind LayerKind
// From is the file whose include list named this one, empty for the main
// file and the config.d files.
From string
// Data is the file as read. It is nil for a main file that is not there
// yet.
Data []byte
// Values is the file parsed, without its include key, and with the
// relative file paths of an included file made absolute.
Values map[string]any
}
ConfigLayer is one file of the config.
func (ConfigLayer) Writable ¶ added in v0.9.0
func (l ConfigLayer) Writable() bool
Writable reports whether tuios can write this file. A file is read-only when it has no owner write bit, or when no file can be made beside it, which is the case for a link into the Nix store and for a file in a read-only mount.
It is asked only when a write is about to happen: the check makes and removes a temporary file, which is not something a plain load should do.
type ConfigReloadCallback ¶ added in v0.8.0
type ConfigReloadCallback func(newConfig *UserConfig, err error)
ConfigReloadCallback is called when config changes are detected. Exactly one of newConfig and err is set. An err means the file on disk cannot be used and the running config stands.
type CopyModeProblem ¶ added in v0.9.0
type CopyModeProblem struct {
Action string `json:"action"`
Key string `json:"key"`
Problem string `json:"problem"`
}
CopyModeProblem is a [keybindings.copy_mode] key that another copy-mode key also uses.
type CopyPipeBinding ¶ added in v0.8.3
type CopyPipeBinding struct {
// Key is the copy-mode key, written as elsewhere in the config.
Key string `toml:"key"`
// Command is run by sh -c with the selection on stdin. What it writes to
// stdout goes to the clipboard.
Command string `toml:"command"`
// Cancel leaves copy mode after the yank (copy-pipe-and-cancel). False
// stays in copy mode at the same place (copy-pipe).
Cancel bool `toml:"cancel,omitempty"`
// Description names the entry in the dock messages. Optional.
Description string `toml:"description,omitempty"`
}
CopyPipeBinding is one [[keybindings.copy_pipe]] entry.
func (CopyPipeBinding) Label ¶ added in v0.8.3
func (c CopyPipeBinding) Label() string
Label is what the dock calls the entry: its description, else its command.
type DaemonConfig ¶ added in v0.5.0
type DaemonConfig struct {
LogLevel string `toml:"log_level"` // Debug log level: off, errors, basic, messages, verbose, trace (default: off)
// AgentAutoDetect toggles automatic detection of a pane's foreground AI-agent
// CLI (claude, codex, aider, ...), which sets the pane's agent-state glyph
// without set-agent-state. Nil means enabled (the default); set to false to
// turn it off.
AgentAutoDetect *bool `toml:"agent_autodetect"`
// AgentDetectSeconds overrides how often the auto-detector polls each pane, in
// seconds. Zero uses the default (2s); a negative value disables detection.
AgentDetectSeconds int `toml:"agent_detect_seconds"`
// AgentBinaries lists extra binary names to treat as agents, merged with the
// built-in defaults (not replacing them).
AgentBinaries []string `toml:"agent_binaries"`
// RespondFromShell lets `tuios respond`, run from a shell outside every
// pane, answer an agent's prompt without an attached client. Off by default:
// respond is then for the person at the Inbox of an attached client. A
// caller inside a pane is refused either way.
RespondFromShell bool `toml:"respond_from_shell"`
// ResumeAgents is what a daemon restart does with the agent conversations
// the restored panes were running: "ask" (the default) puts one Inbox item
// per pane that the person answers, "auto" types each harness's resume
// command into its restored shell, and "off" does neither. The processes
// themselves never survive a restart; this brings back the conversation.
ResumeAgents string `toml:"resume_agents"`
// PersistScrollback saves each pane's history with its session, and a
// restore after a daemon restart or a reboot shows it again above the new
// shell. Nil means on, the default. The files hold whatever the panes
// printed, secrets included, so false is for the person who does not want
// that on disk; turning it off deletes what was saved when the daemon
// next starts.
PersistScrollback *bool `toml:"persist_scrollback"`
// PersistScrollbackLines is the most history lines one pane saves, the
// screen not counted. Zero means 1000.
PersistScrollbackLines int `toml:"persist_scrollback_lines"`
// PersistScrollbackKB is the most one pane's saved history takes on
// disk, compressed, in KiB. Zero means 2048. A pane over it saves fewer
// lines.
PersistScrollbackKB int `toml:"persist_scrollback_kb"`
// WindowSize decides the size of a session with more than one client
// attached, as tmux's window-size option does: "smallest" (the default)
// takes the smallest client, "largest" the largest, and "latest" the
// client that last had input. A client smaller than the session shows
// the part of it around the focused pane's cursor.
WindowSize string `toml:"window_size"`
// SingleClient keeps one client per session, like tmux's attach -d on
// every attach: a client that attaches takes the other clients off the
// session, and each of them exits with a message. Off by default.
SingleClient bool `toml:"single_client"`
// SSHAgent is "follow" to keep, for each session, a link to the ssh
// agent socket of the client that attached or used it last, and give
// new panes SSH_AUTH_SOCK naming the link. "off", the default, or empty
// leaves SSH_AUTH_SOCK as the daemon has it.
SSHAgent string `toml:"ssh_agent"`
}
DaemonConfig holds daemon-related settings
type DebugConfig ¶ added in v0.8.0
type DebugConfig struct {
// ShowKeyEvents enables the on-screen showkeys overlay, a bottom-right
// keycast that shows the last several keypresses as styled pills in both
// window management and terminal mode. The same overlay is toggled by the
// --show-keys flag, the settings entry, the command palette, and the
// leader-D-k keybinding. Default false.
ShowKeyEvents bool `toml:"show_key_events"`
}
DebugConfig holds diagnostic settings. These are off by default so a normal session is unaffected; they exist to diagnose input and rendering problems.
type DockClockConfig ¶ added in v0.8.0
type DockClockConfig struct {
// Format is a Go reference-time layout, e.g. "15:04" or "Mon 15:04:05".
// The refresh cadence is derived from it: a layout showing seconds is
// scheduled to the next second, one without to the next minute.
Format string `toml:"format,omitempty"`
}
DockClockConfig is [dock.clock].
type DockConfig ¶ added in v0.8.0
type DockConfig struct {
Left *[]string `toml:"left,omitempty"`
Center *[]string `toml:"center,omitempty"`
Right *[]string `toml:"right,omitempty"`
// Clock is [dock.clock]: the format the clock component and the status
// badge both render. Empty means the built-in default.
Clock DockClockConfig `toml:"clock"`
// Custom is the set of [dock.custom.NAME] tables. A list entry of
// "custom/NAME" draws the cell this table describes.
Custom map[string]DockCustomConfig `toml:"custom,omitempty"`
}
DockConfig is the [dock] table: the bar as three ordered lists of named components, plus the tables that configure them.
The lists are pointers because "absent" and "empty" have to stay different answers. A missing list takes the default arrangement; an explicitly empty one draws nothing on that side. The settings page rewrites the whole file through toml.Marshal, so both states have to survive the round trip, and a plain []string cannot tell them apart once it has been through it.
func (DockConfig) DockClockFormat ¶ added in v0.8.0
func (c DockConfig) DockClockFormat(s *Settings) string
DockClockFormat is the layout the clock renders in, falling back to the format the status badge has always used.
func (DockConfig) DockList ¶ added in v0.8.0
func (c DockConfig) DockList(side string) []string
DockList returns the components on one side, resolving an absent list to the default arrangement for that side.
type DockCustomConfig ¶ added in v0.8.0
type DockCustomConfig struct {
// Command is run through sh -c. Its first line of stdout is the cell.
Command string `toml:"command"`
// Refresh is when to run it: "once" (the default), a duration such as
// "30s", "push" (the command stays running and each line it writes is an
// update), or "event:TYPE[,TYPE]" (re-run when the daemon reports one).
Refresh string `toml:"refresh,omitempty"`
// OnClick is run through sh -c when the cell is clicked, like a hook.
OnClick string `toml:"on-click,omitempty"`
// MaxWidth caps the cell in cells; 0 takes DockCustomDefaultMaxWidth.
MaxWidth int `toml:"max-width,omitempty"`
}
DockCustomConfig is one [dock.custom.NAME] table: the whole of what a person has to write to put their own cell on the bar.
The contract is deliberately small enough to have no version: environment variables in, one line of text out. There is nothing here that a future tuios can break, because there is no API behind it.
type DockRefresh ¶ added in v0.8.0
type DockRefresh struct {
Kind DockRefreshKind
Interval time.Duration
Events []string
}
DockRefresh is a parsed refresh contract.
func ParseDockRefresh ¶ added in v0.8.0
func ParseDockRefresh(s string) (DockRefresh, error)
ParseDockRefresh reads the refresh field of a [dock.custom] table.
An interval below the floor is raised to it rather than rejected: the value the user wanted is obvious, and a dock that refuses to start over "0.1s" is worse than one that polls a little slower than asked.
func ParseSidebarCustomRefresh ¶ added in v0.9.0
func ParseSidebarCustomRefresh(s string) (DockRefresh, error)
ParseSidebarCustomRefresh reads the section's refresh field. It is the dock's grammar with push taken out.
type DockRefreshKind ¶ added in v0.8.0
type DockRefreshKind int
DockRefreshKind is how a custom component is re-run.
const ( // DockRefreshOnce runs the command at startup and then only on demand. DockRefreshOnce DockRefreshKind = iota // DockRefreshInterval polls on a deadline. DockRefreshInterval // DockRefreshPush keeps the command running and reads its lines. DockRefreshPush // DockRefreshEvent re-runs the command when a named session event lands. DockRefreshEvent )
func (DockRefreshKind) String ¶ added in v0.8.0
func (k DockRefreshKind) String() string
String names the kind as it is written in config and reported by list-dock-components.
type DroppedKey ¶ added in v0.9.0
type DroppedKey struct {
// File is the config file that sets the key, as DisplayPath writes it,
// or "config.toml" when the files are not known.
File string `json:"file"`
// Section is the config table, or "keybindings" for the leader.
Section string `json:"section"`
// Action is the action the key was bound to, or "leader_key".
Action string `json:"action"`
Key string `json:"key"`
// Problem is what is wrong, in the validator's words.
Problem string `json:"problem"`
// Fallback is the key the action uses now: the default key when the
// action had no other key, or the default leader. It is empty when the
// action kept another key of its own, or when every default key was
// already another action's.
Fallback []string `json:"fallback,omitempty"`
// TakenBy is the action that holds the default key, when the action got
// no key back because of it.
TakenBy string `json:"taken_by,omitempty"`
// KeptOthers is true when the action still has another key of its own.
KeptOthers bool `json:"kept_others,omitempty"`
}
DroppedKey is one key DropUnreadableKeys took out of a config.
func DropUnreadableKeys ¶ added in v0.9.0
func DropUnreadableKeys(cfg *UserConfig, lc *LayeredConfig) []DroppedKey
DropUnreadableKeys takes out of cfg every key that ValidateConfig calls an error, and returns what it took out. lc names the file each key came from; it may be nil.
Without it one such key cost the whole file: the load failed, tuios ran on the defaults, and the error went to a stderr the first frame wiped (issue #556). An action left with no key gets its default back, because an empty list in the file means "unbound" and nobody wrote that. A default key that another action already holds is left out, the same yield fillMissingKeybinds makes, so the fallback never takes a key from a binding the user wrote. A leader that cannot be read goes back to the default leader.
The baseline is taken again afterwards, so a later save does not write the dropped keys out of the file. The file stays as the user wrote it. The result is kept on cfg as DroppedKeys, for keybinds doctor.
func (DroppedKey) IsLeader ¶ added in v0.9.0
func (d DroppedKey) IsLeader() bool
IsLeader reports whether the dropped key was the leader.
func (DroppedKey) Outcome ¶ added in v0.9.0
func (d DroppedKey) Outcome() string
Outcome says what tuios does instead of the key, in one sentence.
func (DroppedKey) Warning ¶ added in v0.9.0
func (d DroppedKey) Warning() string
Warning is the line the TUI logs for the dropped key.
type Evidence ¶ added in v0.8.0
type Evidence string
Evidence says how much weight a finding carries. tuios sits between the keyboard and someone else's program, and the three tiers are the three genuinely different things it can say about that program: what tuios itself does (it decided it), what this pane has asserted (it was told), and what a program of that name usually binds (nobody checked).
The tier travels with every finding rather than being implied by the section it is printed under, because the whole point of the guest half of this analysis is that its weakest tier must never be read as its strongest.
const ( // EvidenceCertain is a fact about tuios's own routing, derived from the // registry and the dispatch order. If it is wrong, tuios has a bug. EvidenceCertain Evidence = "certain" // EvidenceObserved is a fact the pane asserted at the moment it was read: // the alternate screen is on, the kitty keyboard protocol was pushed with // these flags, this is the foreground process group's command name. True // when read, and possibly stale a second later. EvidenceObserved Evidence = "observed" // EvidenceReference is a curated list of what a program of that name binds // by default. It is not detection: the program is not asked, its config is // not read, and a user who rebound it is not accounted for. It is here // because a curated list of the six prefixes that actually collide is worth // more than silence, and it is labelled so it is never mistaken for the // tier above. EvidenceReference Evidence = "reference" )
type FPSLimit ¶ added in v0.9.0
type FPSLimit string
FPSLimit is appearance.max_fps: a whole number of frames a second, or "auto". The file may spell a number either bare (max_fps = 144) or quoted; go-toml hands both to UnmarshalText.
func (FPSLimit) MarshalTOML ¶ added in v0.9.0
MarshalTOML writes a number bare and auto quoted, so a file tuios saves reads the way a person would have written it. A value that is neither stays as it was written, quoted, so saving does not quietly change it. It takes effect through MarshalUserConfig.
func (FPSLimit) Number ¶ added in v0.9.0
Number is the value as a whole number. The empty value is 0, the default.
func (*FPSLimit) UnmarshalText ¶ added in v0.9.0
UnmarshalText reads a bare number into one spelling for each value: the number in decimal with 0 as empty, and auto in lower case. go-toml calls it for a bare number only; ParseUserConfig settles a quoted value the same way. A save and a reload then give back the value that was loaded. Anything else is kept as written, so validation can name it; ApplyAppearanceConfig reads it as 0.
type GlyphEnv ¶ added in v0.8.0
type GlyphEnv uint8
GlyphEnv is what the terminal tuios draws on can show, as far as its environment says. It picks the glyphs when nobody chose them: a wrong glyph is worse than a plain one, and a terminal that cannot draw box drawing or a Nerd Font icon shows a box or a question mark in its place.
const ( // GlyphEnvFull is a terminal that says nothing against drawing // everything: the default glyph set, Nerd Font icons included. GlyphEnvFull GlyphEnv = iota // GlyphEnvUnicode is the Linux console (TERM=linux). Its font has box // drawing and a few geometric shapes and no Nerd Font icons, so the chrome // takes the unicode glyph set and the dock and notification icons their // ASCII forms. GlyphEnvUnicode // GlyphEnvASCII is a locale that is not UTF-8. The terminal decodes bytes // in some other encoding, so anything past 7-bit ASCII comes out as // garbage: tuios runs as if --ascii-only were given. GlyphEnvASCII )
func DetectGlyphEnv ¶ added in v0.8.0
DetectGlyphEnv reads the locale and TERM through getenv.
The locale is the first of LC_ALL, LC_CTYPE and LANG that is set, which is the order the C library resolves the character type in. One that names UTF-8 in either spelling is fine, and any other value is not: C, POSIX and en_US.ISO-8859-1 all mean an 8-bit or 7-bit terminal. None of the three set at all is read as nothing known, not as the C locale. That is how a macOS terminal with "set locale environment variables" off and a fresh container both start, and both draw UTF-8 perfectly well; treating them as C would put the ASCII chrome on a great many screens that can draw the real one.
The locale is checked first because it is the stronger statement: on a console with a non-UTF-8 locale, even box drawing is wrong.
type GuestClash ¶ added in v0.8.0
type GuestClash struct {
Key string `json:"key"`
// TuiosAction is what tuios does with the key instead.
TuiosAction string `json:"tuios_action"`
TuiosDesc string `json:"tuios_description"`
Program string `json:"program"`
// ProgramUse is what the program would have done with it.
ProgramUse string `json:"program_use"`
Note string `json:"note"`
// Evidence is EvidenceReference for every entry here, and it is carried
// explicitly so a consumer never has to infer it from the field's name.
Evidence Evidence `json:"evidence"`
// Running is true when the pane that was inspected is actually running this
// program, which lifts the finding from "some day" to "right now". The
// clash itself stays reference-tier either way: knowing nvim is running is
// observation, knowing nvim wants ctrl+w is not.
Running bool `json:"running"`
}
GuestClash is one key tuios withholds that a curated program is known to want.
type GuestProgram ¶ added in v0.8.0
type GuestProgram struct {
// Name is what to call it on screen.
Name string
// Comms are the process names it appears under in the foreground process
// group, used to raise an entry from reference to "this is what is running".
Comms []string
// Keys maps a key to what the program does with it. Deliberately short: the
// entries earn their place by colliding with something tuios binds or by
// being the program's prefix, not by being complete. A complete keymap for
// vim would be a lie told at length.
Keys map[string]string
// Note is the one sentence a user needs about this program's claim.
Note string
}
GuestProgram is one entry in the curated table: a program that runs inside a pane and the keys it claims by default.
func GuestProgramByComm ¶ added in v0.8.0
func GuestProgramByComm(comm string) (GuestProgram, bool)
GuestProgramByComm returns the curated entry whose process names include comm, and whether one was found. The comparison is on the base name lowercased, so /usr/bin/nvim and NVIM both land on the vim entry.
type HintsConfig ¶ added in v0.8.1
type HintsConfig struct {
// Builtins names the built-in patterns in use: "all", "none", or a comma
// separated list such as "url,path,sha" (default: all).
Builtins string `toml:"builtins"`
// Patterns are more regular expressions to look for, in Go syntax. A
// group named match narrows what is copied: "branch: (?P<match>\S+)".
Patterns []string `toml:"patterns"`
// Alphabet is the letters labels are made of, nearest match first
// (default: asdfghjkl). Lowercase letters only.
Alphabet string `toml:"alphabet"`
// Open lets Ctrl and a label open a URL or a path (default: true).
Open *bool `toml:"open"`
// Dim is the percent of its light the text around the matches loses
// (default: 60).
Dim int `toml:"dim"`
// AllPanes makes the hints action label every pane the workspace shows,
// as hints_all_panes does, instead of the focused pane only
// (default: false).
AllPanes bool `toml:"all_panes"`
}
HintsConfig is the hints section: what hints mode looks for on a pane and how it labels what it finds. Hints mode puts a short label on every URL, path, hash and address on the focused pane, and typing a label copies it.
Nothing here is session state. It is read when hints mode opens, so an edit to the file is in force the next time it is opened.
func (HintsConfig) DimPercent ¶ added in v0.8.1
func (h HintsConfig) DimPercent() int
DimPercent is the effective dim, held to its range.
func (HintsConfig) LabelAlphabet ¶ added in v0.8.1
func (h HintsConfig) LabelAlphabet() string
LabelAlphabet is the effective alphabet.
func (HintsConfig) OpenEnabled ¶ added in v0.8.1
func (h HintsConfig) OpenEnabled() bool
OpenEnabled reports whether Ctrl and a label may open what it names.
type HooksConfig ¶ added in v0.8.0
HooksConfig holds shell command hooks for events.
type HostConfig ¶ added in v0.8.0
type HostConfig struct {
// Addr is anything ssh understands, ssh_config aliases included. A host
// with no addr is ignored, and the daemon logs why.
Addr string `toml:"addr"`
// ConnectTimeout is how many seconds one dial may take before the host is
// called unreachable. Zero uses the built-in default. It is also handed to
// ssh, so a machine that is powered off is reported rather than waited on.
ConnectTimeout int `toml:"connect_timeout,omitempty"`
// Command is the tuios binary on the far side. Empty means the link finds
// one itself: on the PATH, at the known install paths, or through the
// login shell. Set it to run a given binary instead; nothing is then
// looked for.
Command string `toml:"command,omitempty"`
// SSHOptions are extra arguments passed to ssh before the address, for a
// host that needs a flag ssh_config cannot carry.
SSHOptions []string `toml:"ssh_options,omitempty"`
// ReposRoot is the directory on the host where its checkouts live. When
// a command on this machine names a repository on the host by its origin
// URL (fan --host, worktree new --host, start-agent -s HOST:SESSION), the
// host looks for the checkout under it, and clones into it with --clone.
// Empty lets the host look under its usual source directories. It is a
// path on the host, written the way the host reads it: absolute, or
// starting with ~/ for the host's home.
ReposRoot string `toml:"repos_root,omitempty"`
// TailscaleLogin is the origin of a Headscale server that sends this
// host's Tailscale SSH check, such as "https://headscale.example". tuios
// shows and opens a sign-in link only on Tailscale's own login origins
// and on this one, because the banner that carries the link can be
// printed by anything on the host.
TailscaleLogin string `toml:"tailscale_login,omitempty"`
// Allow is the capabilities the machine gets, from LinkCapabilities. Nil
// inherits [hosts."*"] and then DefaultLinkAllow; an empty list allows
// nothing.
Allow []string `toml:"allow,omitempty"`
// HoldMail, when true, holds mail from the machine in the Inbox until the
// person passes it on. Nil inherits.
HoldMail *bool `toml:"hold_mail,omitempty"`
// HostedGrace is how long a pane this machine runs for the other one
// outlives a dropped link, waiting to be reattached, as a Go duration
// such as "10m". "0" ends it with the link. Empty inherits.
HostedGrace string `toml:"hosted_grace,omitempty"`
}
HostConfig is one [hosts.NAME] table.
func (HostConfig) HasLinkPolicy ¶ added in v0.8.0
func (h HostConfig) HasLinkPolicy() bool
HasLinkPolicy reports whether the entry says anything about what the machine of its name may do here.
type HostTerminal ¶ added in v0.8.0
type HostTerminal string
HostTerminal names the terminal emulator tuios is running inside, as far as the environment gives it away.
const ( HostUnknown HostTerminal = "" HostAppleTerminal HostTerminal = "Terminal.app" HostITerm2 HostTerminal = "iTerm2" HostGhostty HostTerminal = "Ghostty" HostKitty HostTerminal = "kitty" HostWezTerm HostTerminal = "WezTerm" HostAlacritty HostTerminal = "Alacritty" HostVSCode HostTerminal = "VS Code" HostRio HostTerminal = "Rio" HostWarp HostTerminal = "Warp" )
The hosts tuios can recognise. Unknown is not a failure: it only means the advice has to stay generic.
func DetectHostTerminal ¶ added in v0.8.0
func DetectHostTerminal() HostTerminal
DetectHostTerminal identifies the host terminal from the environment.
TERM_PROGRAM is checked before TERM because a multiplexer rewrites TERM to screen/tmux while leaving TERM_PROGRAM alone, and the Option-key setting that matters lives in the outer terminal either way.
type KeyFate ¶ added in v0.8.0
type KeyFate struct {
Key string `json:"key"`
// ReadAs is the spelling tuios matches the key in, when it differs from
// Key by more than case: opt+f12 is read as alt+f12.
ReadAs string `json:"read_as,omitempty"`
// Acts is every scope the key does something in.
Acts []Binding `json:"acts"`
// SwallowedInTerminal is set when the key does not reach the pane's program
// while typing, with the reason.
SwallowedInTerminal bool `json:"swallowed_in_terminal"`
SwallowReason string `json:"swallow_reason,omitempty"`
// Ambiguity is the terminal-level pair the key belongs to, if any.
Ambiguity string `json:"ambiguity,omitempty"`
// GuestWants is every curated program that binds this key.
GuestWants []GuestClash `json:"guest_wants,omitempty"`
// Free is true when nothing in tuios claims the key in any scope.
Free bool `json:"free"`
}
KeyFate is what tuios does with one key, everywhere it could do something. It is what the recorder answers with, and it is deliberately the whole picture rather than the first match: a key can be a window-mode action and a prefix action and be swallowed in terminal mode all at once, and knowing only one of those is how a user ends up rebinding the wrong one.
type KeyNormalizer ¶ added in v0.0.23
type KeyNormalizer struct {
// contains filtered or unexported fields
}
KeyNormalizer handles platform-specific key normalization Converts user-friendly key strings (like "opt+1" on macOS) to their actual representations
func NewKeyNormalizer ¶ added in v0.0.23
func NewKeyNormalizer() *KeyNormalizer
NewKeyNormalizer creates a new key normalizer with platform detection
func (*KeyNormalizer) ExpandKeys ¶ added in v0.0.23
func (kn *KeyNormalizer) ExpandKeys(keys []string) []string
ExpandKeys takes a slice of user-provided keys and expands them to all platform-specific variants
func (*KeyNormalizer) IsMacOS ¶ added in v0.0.23
func (kn *KeyNormalizer) IsMacOS() bool
IsMacOS returns whether the current platform is macOS
func (*KeyNormalizer) NormalizeKey ¶ added in v0.0.23
func (kn *KeyNormalizer) NormalizeKey(key string) []string
NormalizeKey converts a key string to its canonical form for the current platform For example, on macOS: "opt+1" → "¡" or "alt+1" depending on context
func (*KeyNormalizer) ValidateKey ¶ added in v0.0.23
func (kn *KeyNormalizer) ValidateKey(key string) (bool, string)
ValidateKey checks if a key string is valid for the current platform
type KeyOrigin ¶ added in v0.9.0
type KeyOrigin struct {
// Key is the dotted path. An entry of an array of tables is written
// with its name, or its key, in brackets, such as
// keybindings.command[ctrl+g].
Key string
// File is the file whose value is in force.
File string
// Hidden are the earlier files that also set it, whose values lose.
Hidden []string
}
KeyOrigin is one set key and the files that set it.
type KeyProblem ¶ added in v0.8.1
type KeyProblem struct {
// Section is the config table, or "keybindings" for the leader.
Section string `json:"section"`
// Action is the action the key is bound to, or "leader_key".
Action string `json:"action"`
Key string `json:"key"`
// Problem is what is wrong, in the validator's words.
Problem string `json:"problem"`
// File is the config file that sets the key.
File string `json:"file"`
// Outcome says what tuios does instead: the action uses its default
// key, the leader is the default leader, or no key press matches.
Outcome string `json:"outcome"`
Evidence Evidence `json:"evidence"`
}
KeyProblem is one key in config.toml that tuios cannot read, so it never matches a key press.
type KeyReadAs ¶ added in v0.9.0
type KeyReadAs struct {
// Section is the config table, or "keybindings" for the leader.
Section string `json:"section"`
// Action is the action the key is bound to, or "leader_key".
Action string `json:"action"`
Key string `json:"key"`
ReadAs string `json:"read_as"`
}
KeyReadAs is one key that tuios reads in another spelling.
type KeybindRegistry ¶ added in v0.0.23
type KeybindRegistry struct {
// contains filtered or unexported fields
}
KeybindRegistry manages the mapping between keys and actions
func NewKeybindRegistry ¶ added in v0.0.23
func NewKeybindRegistry(cfg *UserConfig) *KeybindRegistry
NewKeybindRegistry creates a new keybind registry from config
func (*KeybindRegistry) Bindings ¶ added in v0.8.0
func (r *KeybindRegistry) Bindings() []Binding
Bindings returns every binding in every scope, in scope order, section order, and then action-name order.
Which of two bindings on one key is the live one is not the same question inside a section as across them, and getting that backwards makes the whole report name the wrong action. Inside a section, sectionKeyMap hands the key to the first claimant in action-name order and later ones are skipped. Across sections, addSection does a maps.Copy into the shared map, so a later section overwrites what an earlier one put there. The two rules pull in opposite directions, which is why the winner is resolved in its own pass below rather than by whoever got there first.
func (*KeybindRegistry) Collisions ¶ added in v0.8.0
func (r *KeybindRegistry) Collisions() []Collision
Collisions returns every key claimed more than once inside a single scope.
func (*KeybindRegistry) Fate ¶ added in v0.8.0
func (r *KeybindRegistry) Fate(key string, facts PaneFacts) KeyFate
Fate returns everything tuios knows about one key.
func (*KeybindRegistry) GetAction ¶ added in v0.0.23
func (r *KeybindRegistry) GetAction(key string) string
GetAction returns the action name for a given key in normal mode
func (*KeybindRegistry) GetConfig ¶ added in v0.0.23
func (r *KeybindRegistry) GetConfig() *UserConfig
GetConfig returns the underlying config
func (*KeybindRegistry) GetCopyModeAction ¶ added in v0.9.0
func (r *KeybindRegistry) GetCopyModeAction(key string) string
GetCopyModeAction returns the action a key runs in copy mode, or "" for a key the section does not bind. Copy mode reads its vim motions itself.
func (*KeybindRegistry) GetCopyModeKeys ¶ added in v0.9.0
func (r *KeybindRegistry) GetCopyModeKeys(action string) []string
GetCopyModeKeys is GetKeys for the copy_mode section, for the help overlay.
func (*KeybindRegistry) GetDebugPrefixAction ¶ added in v0.4.0
func (r *KeybindRegistry) GetDebugPrefixAction(key string) string
GetDebugPrefixAction returns the action name for a given key in debug prefix mode (Ctrl+B, D)
func (*KeybindRegistry) GetGlobalAction ¶ added in v0.8.0
func (r *KeybindRegistry) GetGlobalAction(key string) string
GetGlobalAction returns the action name for a key in the global scope, the binds that act in window mode and terminal mode alike. Kept out of buildMappings so a global bind cannot be overwritten by a same-key bind in one of the seven flattened window-mode sections.
func (*KeybindRegistry) GetInboxAction ¶ added in v0.8.0
func (r *KeybindRegistry) GetInboxAction(key string) string
GetInboxAction returns the action a key runs in the Inbox's list.
func (*KeybindRegistry) GetInboxKeys ¶ added in v0.8.0
func (r *KeybindRegistry) GetInboxKeys(action string) []string
GetInboxKeys is GetKeys for the Inbox, its peek and the mailbox, whose action names are their own: the key hints of those overlays read what the config binds rather than a letter written into the renderer.
func (*KeybindRegistry) GetInboxPeekAction ¶ added in v0.8.0
func (r *KeybindRegistry) GetInboxPeekAction(key string) string
GetInboxPeekAction returns the action a key runs in the prompt open over the Inbox.
func (*KeybindRegistry) GetKeys ¶ added in v0.0.23
func (r *KeybindRegistry) GetKeys(action string) []string
GetKeys returns the keys bound to an action in the first section below that binds it, as bare keys with no chord. An action bound in two sections, such as launcher (global alt+space and prefix a), answers with one of them only. Use PressesByAction to show a binding to a person.
func (*KeybindRegistry) GetLayoutPrefixAction ¶ added in v0.8.0
func (r *KeybindRegistry) GetLayoutPrefixAction(key string) string
GetLayoutPrefixAction returns the action name for a given key in layout prefix mode (Ctrl+B, L).
func (*KeybindRegistry) GetMailAction ¶ added in v0.8.0
func (r *KeybindRegistry) GetMailAction(key string) string
GetMailAction returns the action a key runs in the mailbox.
func (*KeybindRegistry) GetMinimizePrefixAction ¶ added in v0.0.23
func (r *KeybindRegistry) GetMinimizePrefixAction(key string) string
GetMinimizePrefixAction returns the action name for a given key in minimize prefix mode (Ctrl+B, m)
func (*KeybindRegistry) GetPrefixAction ¶ added in v0.0.23
func (r *KeybindRegistry) GetPrefixAction(key string) string
GetPrefixAction returns the action name for a given key in the main prefix mode (Ctrl+B)
func (*KeybindRegistry) GetScriptAction ¶ added in v0.8.0
func (r *KeybindRegistry) GetScriptAction(key string) string
GetScriptAction returns the action name for a key while a tape script is playing back.
func (*KeybindRegistry) GetSidebarAction ¶ added in v0.8.0
func (r *KeybindRegistry) GetSidebarAction(key string) string
GetSidebarAction returns the action name for a given key in the rail's keyboard scope. Looked up in its own section rather than through the global keymap so rail keys (j/k/h/l/enter) never fire on a pane; only consulted while SidebarFocused.
func (*KeybindRegistry) GetSidebarAgentsAction ¶ added in v0.8.0
func (r *KeybindRegistry) GetSidebarAgentsAction(key string) string
GetSidebarAgentsAction returns the action name for a key among the agent rows' own binds. Consulted before GetSidebarAction, and only while the rail's cursor is on an agent row.
func (*KeybindRegistry) GetSidebarAgentsKeys ¶ added in v0.8.0
func (r *KeybindRegistry) GetSidebarAgentsKeys(action string) []string
GetSidebarAgentsKeys is GetKeys for the agent rows' binds, for the help overlay.
func (*KeybindRegistry) GetSidebarFilesAction ¶ added in v0.8.0
func (r *KeybindRegistry) GetSidebarFilesAction(key string) string
GetSidebarFilesAction returns the action name for a key among the files section's own binds. Consulted before GetSidebarAction, and only while the rail's cursor is on a row of the listing, so the three keys the two sections share each mean the thing the row under the cursor is.
func (*KeybindRegistry) GetSidebarFilesKeys ¶ added in v0.8.0
func (r *KeybindRegistry) GetSidebarFilesKeys(action string) []string
GetSidebarFilesKeys is GetKeys for the files section's binds, for the help overlay.
func (*KeybindRegistry) GetSidebarKeys ¶ added in v0.8.0
func (r *KeybindRegistry) GetSidebarKeys(action string) []string
GetSidebarKeys is GetKeys for the rail's scope. GetKeys deliberately does not search the sidebar section (its action names collide with the global ones), so the help overlay needs its own way to read what the rail is bound to.
func (*KeybindRegistry) GetTapePrefixAction ¶ added in v0.4.0
func (r *KeybindRegistry) GetTapePrefixAction(key string) string
GetTapePrefixAction returns the action name for a given key in tape prefix mode (Ctrl+B, T)
func (*KeybindRegistry) GetTerminalModeAction ¶ added in v0.8.0
func (r *KeybindRegistry) GetTerminalModeAction(key string) string
GetTerminalModeAction returns the action name for a given key among the direct terminal-mode binds (no prefix required).
func (*KeybindRegistry) GetWindowPrefixAction ¶ added in v0.0.23
func (r *KeybindRegistry) GetWindowPrefixAction(key string) string
GetWindowPrefixAction returns the action name for a given key in window prefix mode (Ctrl+B, t)
func (*KeybindRegistry) GetWorkspacePrefixAction ¶ added in v0.0.23
func (r *KeybindRegistry) GetWorkspacePrefixAction(key string) string
GetWorkspacePrefixAction returns the action name for a given key in workspace prefix mode (Ctrl+B, w)
func (*KeybindRegistry) GuestClashes ¶ added in v0.8.0
func (r *KeybindRegistry) GuestClashes(running string) []GuestClash
GuestClashes crosses the terminal-mode swallow set with the curated table.
Only the swallow set is crossed, because a key tuios forwards costs the guest nothing no matter who else binds it. That is what keeps the output to the handful of rows that are actually about a program being broken.
running is the foreground process name of the pane being inspected, or "" when it is not known; it only marks rows, it does not filter them.
func (*KeybindRegistry) HasAction ¶ added in v0.0.23
func (r *KeybindRegistry) HasAction(action string) bool
HasAction checks if an action exists in the registry
func (*KeybindRegistry) KeyProblems ¶ added in v0.8.1
func (r *KeybindRegistry) KeyProblems() []KeyProblem
KeyProblems returns every key in the leader and the binding tables that the validator rejects. Such a key is loaded but no key press ever matches it, so without this the only sign of it is a binding that does nothing.
A config that went through DropUnreadableKeys has no such key left, and its DroppedKeys are reported instead, with the file and what tuios does now.
func (*KeybindRegistry) OptionKeys ¶ added in v0.9.0
func (r *KeybindRegistry) OptionKeys() []KeyReadAs
OptionKeys returns every opt+ or option+ key in the leader and the binding tables, with the alt+ spelling tuios reads it as. It is empty on macOS, where opt+ is the native name of the key and needs no note.
func (*KeybindRegistry) Reload ¶ added in v0.0.23
func (r *KeybindRegistry) Reload(cfg *UserConfig)
Reload reloads the keybind mappings from the config
func (*KeybindRegistry) Report ¶ added in v0.8.0
func (r *KeybindRegistry) Report(facts PaneFacts) KeybindReport
Report builds the whole analysis for the given pane.
func (*KeybindRegistry) StillHeldBy ¶ added in v0.8.0
func (r *KeybindRegistry) StillHeldBy(key string) []string
StillHeldBy names every reason the key does not reach the pane's program after the config has stopped claiming it, or nil when nothing holds it.
Two things survive FreeKey. The leader is keybindings.leader_key rather than an entry in a section, so it is moved rather than unbound. The built-in terminal-mode keys are literals in the input path with no config entry at all. Saying so is the difference between "freed" and "the config no longer claims it, and it still will not arrive".
func (*KeybindRegistry) TerminalModeSwallowed ¶ added in v0.8.0
func (r *KeybindRegistry) TerminalModeSwallowed() []Swallow
TerminalModeSwallowed returns every key that does not reach the program running in the focused pane while the user is typing into it.
This is the honest half of the guest question. tuios cannot know what the guest wants, but it knows exactly what it withholds, and that set is small enough to read: the leader, the terminal_mode table, the handful of navigation actions that survive into terminal mode on a reserved chord, and the literals above. Everything absent from this list is forwarded.
type KeybindReport ¶ added in v0.8.0
type KeybindReport struct {
Leader string `json:"leader"`
// LeaderReadAs is the spelling tuios matches the leader in, when it
// differs from Leader by more than case.
LeaderReadAs string `json:"leader_read_as,omitempty"`
// KeyProblems are the keys in config.toml that tuios cannot read.
KeyProblems []KeyProblem `json:"key_problems"`
// OptionKeys are the opt+ and option+ keys tuios reads as alt+ off
// macOS. They are information, not problems: a config.toml shared with a
// Mac works as it is.
OptionKeys []KeyReadAs `json:"option_keys_read_as_alt,omitempty"`
// CommandProblems are the [[keybindings.command]] entries tuios ignores
// or warns about, in the validator's words.
CommandProblems []CommandProblem `json:"command_problems"`
// CopyModeProblems are the [keybindings.copy_mode] keys that a copy pipe
// entry or one of copy mode's own keys also uses.
CopyModeProblems []CopyModeProblem `json:"copy_mode_problems"`
// EvidenceNote is the report explaining its own tiers. It ships inside the
// payload because a consumer that only ever sees the JSON has nowhere else
// to learn that one third of it is a curated list.
EvidenceNote map[Evidence]string `json:"evidence_note"`
Pane PaneFacts `json:"pane"`
Observations []Observation `json:"observations"`
Bindings []Binding `json:"bindings"`
Collisions []Collision `json:"collisions"`
Swallowed []Swallow `json:"terminal_mode_swallowed"`
GuestClashes []GuestClash `json:"guest_clashes"`
Ambiguous []AmbiguousBinding `json:"ambiguous_bindings"`
// Yielded are new default bindings tuios left off because the key was
// already bound to another action in the same table.
Yielded []YieldedDefault `json:"yielded_defaults,omitempty"`
}
KeybindReport is the whole analysis as data. The overlay and `tuios keybinds doctor --json` render the same value, so what an agent reads and what a human sees cannot drift apart.
func (KeybindReport) Summary ¶ added in v0.8.0
func (rep KeybindReport) Summary() string
Summary is the one line a report leads with.
type Keybinding ¶ added in v0.0.12
type Keybinding struct {
Key string
Description string
// something itself. The panel draws it with a leading + so nested menus
// can be told from actions at a glance.
Submenu bool
// Action names the row: the first action the menu built it from. It
// stays the same when the row's keys are rebound, so code that finds a
// row finds it by this and never by the keys a config may have moved.
Action string
}
Keybinding is one line of a which-key panel: a key and what it does.
type KeybindingGroup ¶ added in v0.8.0
type KeybindingGroup struct {
Title string
Bindings []Keybinding
}
KeybindingGroup is a titled section of a which-key panel. A panel with one untitled group is a plain list.
func PrefixMenuGroups ¶ added in v0.9.0
func PrefixMenuGroups(r *KeybindRegistry, prefixType string, st MenuState) []KeybindingGroup
PrefixMenuGroups returns a which-key menu's lines, in the sections the panel draws them under, with the keys the registry has bound. prefixType is "" for the leader's menu, or the name of a sub-prefix: workspace, minimize, window, debug, tape or layout.
A row whose action has no live key is left out: an unbound key, or one another action shadows, does nothing, and a menu that offers it is wrong. A key bound in the prefix to an action the menu has no row for, such as a command entry, gets a row of its own at the end.
A nil registry reads the shipped keymap.
type KeybindingsConfig ¶ added in v0.0.23
type KeybindingsConfig struct {
LeaderKey string `toml:"leader_key"` // Leader key for prefix commands (default: ctrl+b)
WindowManagement map[string][]string `toml:"window_management"`
Workspaces map[string][]string `toml:"workspaces"`
Layout map[string][]string `toml:"layout"`
ModeControl map[string][]string `toml:"mode_control"`
System map[string][]string `toml:"system"`
RestoreMinimized map[string][]string `toml:"restore_minimized"`
PrefixMode map[string][]string `toml:"prefix_mode"`
WindowPrefix map[string][]string `toml:"window_prefix"`
MinimizePrefix map[string][]string `toml:"minimize_prefix"`
WorkspacePrefix map[string][]string `toml:"workspace_prefix"`
DebugPrefix map[string][]string `toml:"debug_prefix"`
TapePrefix map[string][]string `toml:"tape_prefix"`
LayoutPrefix map[string][]string `toml:"layout_prefix"`
TerminalMode map[string][]string `toml:"terminal_mode"` // Direct keybinds in terminal mode (no prefix required)
// Global binds are consulted in window mode and in terminal mode alike, so
// the palette and the launcher answer to one key wherever the user is. They
// are a section of their own rather than entries in terminal_mode because
// they are not terminal-mode-only, and rather than literals in the input
// path because a key nobody can rebind is a key nobody can inspect.
Global map[string][]string `toml:"global"`
// Command is the [[keybindings.command]] entries: a key that runs a
// command the user writes. See command_keys.go.
Command []CommandBinding `toml:"command,omitempty"`
// CopyPipe is the [[keybindings.copy_pipe]] entries: a copy-mode key
// that pipes the selection through a command. See copy_pipe.go.
CopyPipe []CopyPipeBinding `toml:"copy_pipe,omitempty"`
// Script binds are live only while a .tape is playing back. Its own section
// because it is its own keyboard context: sharing ctrl+p with the palette by
// default is not a conflict, since only one of the two contexts is ever
// active.
Script map[string][]string `toml:"script"`
// Sidebar binds are looked up only while the rail owns the keyboard
// (SidebarFocused), through GetSidebarAction. They are deliberately kept out
// of buildMappings: that flattens sections into the global keymap, which would
// leak rail keys (j/k/h/l/enter) onto panes.
Sidebar map[string][]string `toml:"sidebar"`
// SidebarFiles binds are looked up before Sidebar, and only while the rail's
// cursor is on a row of the files section. See
// getDefaultSidebarFilesKeybinds for why they are not in Sidebar.
SidebarFiles map[string][]string `toml:"sidebar_files"`
// SidebarAgents binds are looked up before Sidebar, and only while the
// rail's cursor is on an agent row. See getDefaultSidebarAgentsKeybinds.
SidebarAgents map[string][]string `toml:"sidebar_agents"`
// Inbox binds are live while the Inbox is open and its selector line is
// not, through GetInboxAction. The digits 1 to 9 are not in it: they
// answer a held approval or a question by its number, which is the number
// the prompt itself shows. See getDefaultInboxKeybinds.
Inbox map[string][]string `toml:"inbox"`
// InboxPeek binds are live while a prompt is open over the Inbox and its
// text line is not. A scope of its own because d dismisses in the list and
// denies in the peek.
InboxPeek map[string][]string `toml:"inbox_peek"`
// Mail binds are live while the mailbox is open and no reply is being
// written.
Mail map[string][]string `toml:"mail"`
// CopyMode binds are live while a pane is in copy mode, in normal and
// visual selection. Copy mode's vim motions are fixed keys and are not
// here. See getDefaultCopyModeKeybinds.
CopyMode map[string][]string `toml:"copy_mode"`
}
KeybindingsConfig holds all keybinding configurations
func (*KeybindingsConfig) CommandFor ¶ added in v0.8.2
func (k *KeybindingsConfig) CommandFor(action string) (CommandBinding, bool)
CommandFor returns the entry behind an action name, if the action is one.
func (*KeybindingsConfig) CommandProblems ¶ added in v0.9.0
func (k *KeybindingsConfig) CommandProblems() []CommandProblem
CommandProblems lists what is wrong with the command entries, in file order. validateCommands warns with it at load, and the doctor prints it.
func (*KeybindingsConfig) Commands ¶ added in v0.8.2
func (k *KeybindingsConfig) Commands() []CommandBinding
Commands returns the entries tuios uses: every valid entry, with a second entry of the same name left out. validateCommands warns about the others.
func (*KeybindingsConfig) CopyModeProblems ¶ added in v0.9.0
func (k *KeybindingsConfig) CopyModeProblems() []CopyModeProblem
CopyModeProblems lists the [keybindings.copy_mode] keys that a copy pipe entry or one of copy mode's own keys also uses, by action and then key. validateCopyModeKeys warns with it at load, and the doctor prints it.
func (*KeybindingsConfig) CopyPipeFor ¶ added in v0.8.3
func (k *KeybindingsConfig) CopyPipeFor(key string) (CopyPipeBinding, bool)
CopyPipeFor returns the entry on a copy-mode key, if there is one.
func (*KeybindingsConfig) CopyPipes ¶ added in v0.8.3
func (k *KeybindingsConfig) CopyPipes() []CopyPipeBinding
CopyPipes returns the entries tuios uses: every valid entry, with a second entry on the same key left out. validateCopyPipes warns about the others.
func (*KeybindingsConfig) FreeKey ¶ added in v0.8.0
func (k *KeybindingsConfig) FreeKey(key string) []Removal
FreeKey takes one key off every action in every section, so nothing in the config claims it any more. It reports what it removed, in section order.
Every scope at once is the point. A key bound in window mode and in the prefix table is still a key the user has to press twice to be rid of, and a key left on one of the two scopes that reach the pane (global and terminal_mode) still never arrives there. Freeing one action at a time is what UnbindKey is for.
func (*KeybindingsConfig) SectionFor ¶ added in v0.8.0
func (k *KeybindingsConfig) SectionFor(name string) map[string][]string
SectionFor returns the config table with the given name so a caller can add a binding to it, or nil for a name that is not a section. The map is the live one, which is the point: a recorder writing into it and then reloading the registry is how a newly bound key takes effect without a restart.
func (*KeybindingsConfig) UnbindAction ¶ added in v0.8.0
func (k *KeybindingsConfig) UnbindAction(section, action string) ([]Removal, bool)
UnbindAction takes every key off one action, so the action has no key at all and the default does not come back. It reports the keys it removed.
func (*KeybindingsConfig) UnbindKey ¶ added in v0.8.0
func (k *KeybindingsConfig) UnbindKey(section, action, key string) (Removal, bool)
UnbindKey takes one key off one action, leaving the action present with an empty list when it was the last one. It reports whether anything changed.
The action is never deleted from the map. Deleting it would put it back to "not mentioned", which fillMissingKeybinds reads as a request for the default, and the binding would return on the next load.
func (*KeybindingsConfig) UnboundActions ¶ added in v0.8.0
func (k *KeybindingsConfig) UnboundActions(section string) []string
UnboundActions returns every action a section leaves with no keys, sorted. These are the deliberate removals: fillMissingKeybinds never creates one.
type LauncherConfig ¶ added in v0.9.0
type LauncherConfig struct {
// GUICommand is a command that starts a graphical desktop entry instead of
// a new pane. The entry's argv is appended to it. With it empty, every
// entry runs in a pane, as before.
//
// It exists for a Wayland compositor that shows its windows as panes
// (tuios-wayland launch --), and works as well for one that does not
// (niri msg action spawn --).
//
// tuios runs the argv directly, but the command it names may not. A
// spawn command that joins its arguments into one shell line (swaymsg
// exec --, hyprctl dispatch exec) turns the text of a desktop entry,
// which any installed package can write, into shell code. Only commands
// that keep the argv as an argv are safe here.
GUICommand string `toml:"gui_command"`
}
LauncherConfig is the [launcher] section.
func (LauncherConfig) GUIPrefix ¶ added in v0.9.0
func (l LauncherConfig) GUIPrefix() []string
GUIPrefix is GUICommand split into an argv prefix. Double and single quotes group words, so a path with a space can be given. It is nil when the option is unset.
type LayeredConfig ¶ added in v0.9.0
type LayeredConfig struct {
// Main is the path of config.toml.
Main string
// Layers are the files in merge order, lowest precedence first. The main
// file is last.
Layers []ConfigLayer
// Missing are the included files that were not there, as resolved paths,
// optional ones included. The watcher follows them.
Missing []string
// Warnings say what was skipped and why.
Warnings []string
// Layered is true when config.toml has an include key or a config.d
// directory exists.
Layered bool
// DropInDir is the config.d directory, whether or not it exists.
DropInDir string
// MainMissing is true when config.toml is not there yet. Only a load for a
// write accepts that.
MainMissing bool
// contains filtered or unexported fields
}
LayeredConfig is the config as every file that makes it up.
func LoadLayered ¶ added in v0.9.0
func LoadLayered(mainPath string) (*LayeredConfig, error)
LoadLayered reads config.toml at mainPath and every file it brings in. A main file that cannot be read is returned as the error os.ReadFile gave, so a caller can test it with errors.Is(err, fs.ErrNotExist).
func (*LayeredConfig) Bytes ¶ added in v0.9.0
func (lc *LayeredConfig) Bytes() ([]byte, error)
Bytes is the merged config as one TOML document. When the config is config.toml alone, with no tombstone in it, it is the file exactly as read, so a single-file config takes the same path it always did.
func (*LayeredConfig) DisplayPath ¶ added in v0.9.0
func (lc *LayeredConfig) DisplayPath(p string) string
DisplayPath writes p for a person: relative to the directory of config.toml when it is inside it, with ~ for the home directory otherwise.
func (*LayeredConfig) Holders ¶ added in v0.9.0
func (lc *LayeredConfig) Holders(key []string) []ConfigLayer
Holders are the files that set key, in merge order.
func (*LayeredConfig) Merged ¶ added in v0.9.0
func (lc *LayeredConfig) Merged() map[string]any
Merged is every layer merged into one table, in merge order, with the tombstones applied.
func (*LayeredConfig) Origin ¶ added in v0.9.0
func (lc *LayeredConfig) Origin(key []string) (string, bool)
Origin is the file the value at key comes from: the last file in merge order that sets it. key is a dotted path such as appearance.theme. ok is false when no file sets it, which means the value is the built-in default.
func (*LayeredConfig) Origins ¶ added in v0.9.0
func (lc *LayeredConfig) Origins() []KeyOrigin
Origins lists every key some file sets, in key order, with the file it comes from.
func (*LayeredConfig) WriteTarget ¶ added in v0.9.0
func (lc *LayeredConfig) WriteTarget(key []string) (string, WriteNote, error)
WriteTarget is the file a change to key is written to, and the note that says so when the file that holds it is read-only.
type LinkPolicy ¶ added in v0.8.0
type LinkPolicy struct {
// Peer is the name the machine arrived under, empty when it gave none.
Peer string
// Allow is the capabilities it has, a subset of LinkCapabilities.
Allow []string
// HoldMail holds its mail in the Inbox until the person passes it on.
HoldMail bool
// HostedGrace is how long a pane run for it outlives a dropped link.
HostedGrace time.Duration
// Source names the table the policy came from, for an error that tells
// the caller which key to change: hosts.laptop, hosts."*", or empty for
// the built-in default.
Source string
}
LinkPolicy is what one machine may do here, resolved.
func DefaultLinkPolicy ¶ added in v0.8.0
func DefaultLinkPolicy() LinkPolicy
DefaultLinkPolicy is the policy with nothing configured.
func LinkPolicyFor ¶ added in v0.8.0
func LinkPolicyFor(hosts map[string]HostConfig, peer string) LinkPolicy
LinkPolicyFor resolves the policy for a machine that linked in as peer: the built-in default, then [hosts."*"], then [hosts.PEER]. A field an entry leaves unset is inherited from the one before it. Unknown capabilities and an unreadable hosted_grace are ignored here; ValidateConfig reports them.
func (LinkPolicy) Allows ¶ added in v0.8.0
func (p LinkPolicy) Allows(caps ...string) bool
Allows reports whether the policy grants every capability in caps.
type MailAlertPolicy ¶ added in v0.8.1
type MailAlertPolicy struct {
AgentAlertPolicy
// BetweenAgents is true when a message between two agents alerts too.
BetweenAgents bool
}
MailAlertPolicy is the policy a mail alert runs under: the agent policy with the [notifications.mail] keys laid over it. The embedded policy keeps its sound mode, cooldown, cue files and quiet hours.
func ResolveMailAlerts ¶ added in v0.8.1
func ResolveMailAlerts(c *MailAlertsConfig, agent AgentAlertPolicy) MailAlertPolicy
ResolveMailAlerts lays the mail table over an already resolved agent policy. A nil table, or a key it leaves out, keeps the agent value.
type MailAlertsConfig ¶ added in v0.8.1
type MailAlertsConfig struct {
// Enabled is the switch for mail alerts. Unset follows
// notifications.agent.enabled.
Enabled *bool `toml:"enabled"`
// Notify writes a desktop notification to the attached terminal. Unset
// follows notifications.agent.notify.
Notify *bool `toml:"notify"`
// Sound makes a mail alert audible, the way notifications.agent.sound_mode
// says. Unset follows notifications.agent.sound.
Sound *bool `toml:"sound"`
// Dock shows the alert in the dock, where a click opens the thread. Unset
// follows notifications.agent.dock.
Dock *bool `toml:"dock"`
// BetweenAgents alerts on a message from one agent to another as well.
// Such a message only counts on the recipient's rail row otherwise, since
// it is the two agents' business. Default: false.
BetweenAgents *bool `toml:"between_agents"`
}
MailAlertsConfig is the [notifications.mail] table: what tuios does when agent mail arrives for the person, or a notice goes to the whole session.
Every key is a pointer, and a key left out follows the same key in [notifications.agent]. Mail alerts used that table before this one existed, so a config that does not name [notifications.mail] behaves as it did. Sound mode, the cooldown, the cue files and quiet hours always come from [notifications.agent]: one clock and one set of sounds for every alert.
type MenuState ¶ added in v0.9.0
type MenuState struct {
// Daemon swaps the leader menu's detach and quit rows: in a daemon
// session d detaches and q opens the quit menu.
Daemon bool
// MultiCopy is the number of panes multi copy mode would take, zero when
// it is off. The copy-mode row says so when it is on.
MultiCopy int
// Spotlight is set while the spotlight is on, and the sidebar row then
// says the key turns it off.
Spotlight bool
// Minimized is the number of minimized windows the restore row counts,
// or -1 to leave the count out.
Minimized int
}
MenuState is what a which-key menu's rows depend on besides the keymap.
type NotificationsConfig ¶ added in v0.8.0
type NotificationsConfig struct {
// Duration is how long an info or success message stays up, in seconds.
Duration int `toml:"duration"`
// WarningDuration is how long a warning stays up, in seconds.
WarningDuration int `toml:"warning_duration"`
// ErrorDuration is how long an error stays up, in seconds, when
// error_sticky is false.
ErrorDuration int `toml:"error_duration"`
// ErrorSticky makes errors wait for esc instead of expiring (default true).
ErrorSticky *bool `toml:"error_sticky"`
// Agent is the [notifications.agent] table: what happens when a pane's
// agent state changes. See agent_alerts.go.
Agent AgentAlertsConfig `toml:"agent"`
// Mail is the [notifications.mail] table: what happens when agent mail
// arrives for the person. A key it leaves out follows the same key in
// Agent. See mail_alerts.go.
Mail MailAlertsConfig `toml:"mail"`
}
NotificationsConfig holds how long a dock message stays up.
Durations are in seconds and are a floor, not a cap: a caller that asks for longer than the severity's default still gets what it asked for. Zero or absent means "use the built-in default", which is the value documented on the corresponding package var in constants.go.
type NotifyConfig ¶ added in v0.9.0
type NotifyConfig struct {
// Enabled is the master switch. Nothing is sent without a provider, so
// the default is on. Default: true.
Enabled *bool `toml:"enabled,omitempty"`
// WebURL is the public address of tuios-web. When it is set, every
// notification links to the Inbox item there. Default: empty (no link).
WebURL string `toml:"web_url,omitempty"`
// Content is how much a notification says: "summary" (the title and the
// one line the Inbox shows) or "title" (only what kind of item it is and
// the session). Default: "summary".
Content string `toml:"content,omitempty"`
// QuietActiveSeconds holds a notification while a person typed at an
// attached client in the last this many seconds, so the person at the
// desk is not told twice. When they stay away that long and the item is
// still open, it is sent. Zero sends at once. Default: 120.
QuietActiveSeconds *int `toml:"quiet_active_seconds,omitempty"`
// CooldownSeconds is the shortest gap between two notifications for the
// same pane and kind. Default: 60.
CooldownSeconds *int `toml:"cooldown_seconds,omitempty"`
// MaxPerHour bounds every notification together. Default: 30.
MaxPerHour *int `toml:"max_per_hour,omitempty"`
// AllowHTTPRedirects lets a provider's https address redirect to a plain
// http one. Default: false.
AllowHTTPRedirects bool `toml:"allow_http_redirects,omitempty"`
// Triggers says which Inbox kinds send a notification.
Triggers NotifyTriggers `toml:"triggers,omitempty"`
// The providers. Each one set gets every notification.
Ntfy *NtfyConfig `toml:"ntfy,omitempty"`
Pushover *PushoverConfig `toml:"pushover,omitempty"`
Webhook *WebhookConfig `toml:"webhook,omitempty"`
}
NotifyConfig is the [notify] table: push notifications the daemon sends to a phone when the Inbox gets something that waits for the person.
The daemon sends them, because the daemon runs when no client is attached, and that is when a phone is the only way to reach the person. It sits outside the option registry for the reason [hosts] does: where the Inbox's text goes, and with which credentials, is not for a pane to change over the control protocol.
func (*NotifyConfig) ContentLevel ¶ added in v0.9.0
func (n *NotifyConfig) ContentLevel() string
ContentLevel is Content, or the default.
func (*NotifyConfig) Cooldown ¶ added in v0.9.0
func (n *NotifyConfig) Cooldown() int
Cooldown is CooldownSeconds, or the default.
func (*NotifyConfig) Destinations ¶ added in v0.9.0
func (n *NotifyConfig) Destinations() []string
Destinations names everything that decides where a notification goes and with which credentials: the addresses, and where each secret is read from. A config reload that changes it gives the Inbox's text to someone new, so the daemon applies such a change only from tuios config apply or a restart. The secrets themselves are not in it, only where they come from.
func (*NotifyConfig) HasProvider ¶ added in v0.9.0
func (n *NotifyConfig) HasProvider() bool
HasProvider reports whether any provider is set.
func (*NotifyConfig) HourlyCap ¶ added in v0.9.0
func (n *NotifyConfig) HourlyCap() int
HourlyCap is MaxPerHour, or the default. Zero means no cap.
func (*NotifyConfig) On ¶ added in v0.9.0
func (n *NotifyConfig) On() bool
On reports whether notifications are on.
func (*NotifyConfig) QuietActive ¶ added in v0.9.0
func (n *NotifyConfig) QuietActive() int
QuietActive is QuietActiveSeconds, or the default.
func (*NotifyConfig) Triggered ¶ added in v0.9.0
func (n *NotifyConfig) Triggered(kind string) bool
Triggered reports whether an Inbox item of this kind sends a notification. The kinds are the session package's attention kinds.
type NotifyTriggers ¶ added in v0.9.0
type NotifyTriggers struct {
Approval *bool `toml:"approval,omitempty"` // a held or shown permission prompt. Default: true.
Plan *bool `toml:"plan,omitempty"` // a plan to approve. Default: true.
Question *bool `toml:"question,omitempty"` // an agent asking in its pane. Default: true.
Ask *bool `toml:"ask,omitempty"` // tuios ask-human. Default: true.
Mail *bool `toml:"mail,omitempty"` // agent mail to you. Default: false.
Errored *bool `toml:"errored,omitempty"` // an agent that stopped on an error. Default: false.
Finished *bool `toml:"finished,omitempty"` // a finished turn. Default: false.
}
NotifyTriggers is the [notify.triggers] table. A kind that waits on the person is on by default. A kind that only reports is off.
type NtfyConfig ¶ added in v0.9.0
type NtfyConfig struct {
// URL is the topic's address, such as https://ntfy.sh/my-topic. On a
// public server the topic name is the secret, so it is never logged.
URL string `toml:"url"`
// Priority is the ntfy priority, 1 to 5. Zero leaves it to the kind:
// 4 for an item that waits on the person, 3 for the rest.
Priority int `toml:"priority,omitempty"`
Token Secret `toml:"token,omitempty"`
TokenEnv string `toml:"token_env,omitempty"`
TokenFile string `toml:"token_file,omitempty"`
}
NtfyConfig is [notify.ntfy]: a topic on an ntfy server.
type Observation ¶ added in v0.8.0
type Observation struct {
What string `json:"what"`
Detail string `json:"detail"`
Evidence Evidence `json:"evidence"`
}
Observation is one thing the report can state about the pane as fact.
type Option ¶ added in v0.8.0
type Option struct {
Path string `json:"path"` // dotted toml path, e.g. "appearance.sidebar.position"
Type string `json:"type"` // bool, int or string
Section string `json:"section"` // grouping for display
Description string `json:"description"` // one line
Accepted []string `json:"accepted,omitempty"` // closed value set, when there is one
Default string `json:"default"` // what DefaultConfig holds, rendered as a string
Min int `json:"min,omitempty"` // int options only
Max int `json:"max,omitempty"` // int options only, and only when a range is enforced
Deprecated string `json:"deprecated,omitempty"` // why it is deprecated and what replaced it
// Color marks a string option whose value is a colour literal. The type
// stays string because that is what the field holds and what crosses the
// protocol; this says what the string means, which is what lets the settings
// panel offer a colour picker instead of a text field and what makes an
// unparseable colour an error at the CLI rather than a broken border later.
//
// A colour option with Accepted set takes either one of those keywords or a
// literal, which is the scrollbar tint's shape.
Color bool `json:"color,omitempty"`
// Theme marks the string option whose value is a registered theme id. Like
// Color it says what the string means rather than what it is, and for the
// same reason: the set is open (a user's own theme file joins it) and far
// too long to publish as Accepted, so neither a closed set nor no check at
// all is right. Without it a misspelled theme was recorded, reported as
// applied, and drew the palette it already had.
Theme bool `json:"theme,omitempty"`
// GlyphSet marks the string option whose value is a glyph set id. Like
// Theme it names an open set kept in a directory of its own, so neither an
// Accepted list nor no check at all is right, and for the same reason:
// without it a misspelled set is recorded, reported as applied, and draws
// the glyphs it already had.
GlyphSet bool `json:"glyph_set,omitempty"`
// Percent marks an int option whose value is a share of something, with
// Min and Max as the real ends of its travel rather than as a guard against
// a silly number. Like Color and Theme it says what the value means rather
// than what it is, and it is what earns the option a gauge on the settings
// panel and a % after its number.
//
// The line it draws is between a proportion and a count. Both are ints with
// a Max, but a gauge on a count says nothing: notifications.duration allows
// up to an hour, so the usual four seconds would draw an empty bar, and
// appearance.scrollback_lines allows a million, so ten thousand would too.
// A proportion is the case
// where the far end is a place you would actually put the value, which is
// the only case where seeing how far along it sits tells you anything.
Percent bool `json:"percent,omitempty"`
// Follows names the option whose value this one takes while it is unset.
// Such an option takes the empty string as a value, which clears it, so
// it can go back to following once it has been set.
Follows string `json:"follows,omitempty"`
// DefaultClears marks a string option whose Default is a word rather than
// a value. Writing that word clears the field back to unset, and an unset
// field reads back as it. It is for an option where the empty string is a
// value of its own: an empty mode icon hides the icon, so the empty string
// cannot also be the way back to the built-in.
DefaultClears bool `json:"default_clears,omitempty"`
// Icon marks a string option whose value is drawn in the dock as an icon.
// A value with a control character, or wider than DockModeIconMaxWidth
// cells, is refused, because it would break the dock row's layout.
Icon bool `json:"icon,omitempty"`
// BoxSize marks a string option whose value is a size in cells (60) or
// percent (80%), read by ParseBoxSize. An empty value means the default.
BoxSize bool `json:"box_size,omitempty"`
// Auto marks an int option that also takes the word "auto". Its config
// field is a string type, such as FPSLimit, that can hold either.
Auto bool `json:"auto,omitempty"`
}
Option describes one settable configuration path.
The registry below is what lets a caller outside the process discover and change a setting. Before it, a runtime set-config knew six hardcoded paths, so the sidebar, the dock and everything else in the file were reachable only by editing the file and reloading.
func LookupOption ¶ added in v0.8.0
LookupOption returns the option a dotted path names.
type Overrides ¶ added in v0.7.0
type Overrides struct {
// ASCIIOnly uses ASCII characters instead of Nerd Font icons
ASCIIOnly bool
// BorderStyle overrides the window border style
BorderStyle string
// DockbarPosition overrides the dockbar position
DockbarPosition string
// HideWindowButtons overrides hiding window control buttons
HideWindowButtons bool
// HideScrollbar overrides hiding the scrollbar thumb
HideScrollbar bool
// WindowButtonStyle overrides how the window controls are drawn
WindowButtonStyle string
// WindowButtonPosition overrides which end of the title bar they sit on
WindowButtonPosition string
// WindowTitlePosition overrides the window title position
WindowTitlePosition string
// HideClock overrides hiding the clock (deprecated, use ShowClock)
HideClock bool
// ShowClock enables the clock overlay
ShowClock bool
// ShowCPU enables the CPU graph in the dock
ShowCPU bool
// ShowRAM enables the RAM usage in the dock
ShowRAM bool
SharedBorders bool
// ScrollbackLines overrides the scrollback buffer size (0 means use default)
ScrollbackLines int
// NoAnimations disables UI animations
NoAnimations bool
// ConfirmQuit always shows quit confirmation dialog
ConfirmQuit bool
// ThemeName is the theme to load
ThemeName string
// ZoomMaxWidth caps the zoom mode width (0 = fullscreen)
ZoomMaxWidth int
}
Overrides contains CLI flag values that can override user config. Zero values indicate the flag was not set and should use the user config default.
type PaneFacts ¶ added in v0.8.0
type PaneFacts struct {
// Command is the foreground process group's command name, or "" when it
// could not be read (no pane, not Linux, the process went away).
Command string `json:"command,omitempty"`
// AltScreen is whether the pane's program is on the alternate screen, which
// is the closest thing to "a full-screen program is running" that a
// terminal emulator can observe.
AltScreen bool `json:"alt_screen"`
// GuestKittyFlags are the kitty keyboard protocol flags the pane's program
// pushed. Non-zero means the program explicitly asked to be sent keys in a
// disambiguated form, which is the strongest statement a guest ever makes
// about what it wants from the keyboard.
GuestKittyFlags int `json:"guest_kitty_flags"`
// HostDisambiguates is whether the host terminal granted tuios key
// disambiguation. It decides whether the ambiguous pairs are separable
// here.
HostDisambiguates bool `json:"host_disambiguates"`
// HasForeground is whether anything beyond the pane's shell is running.
HasForeground bool `json:"has_foreground_process"`
}
PaneFacts is what the caller observed about the pane the report is about. Every field is optional; a zero PaneFacts produces a report with no observed-tier findings rather than a report with wrong ones.
func (PaneFacts) Observations ¶ added in v0.8.0
func (f PaneFacts) Observations() []Observation
Observations turns the pane facts into sentences, each carrying the tier it was arrived at. Only facts that were actually available produce a line: an absent signal is left out rather than reported as a negative, because "no program detected" and "detection is not available on this platform" are different things and only one of them is true here.
type PanesConfig ¶ added in v0.9.0
type PanesConfig struct {
// LabelKeys is the keys the labels are made of, first pane first
// (default: 1234567890). Letters a to z and digits only. With more panes
// than keys, the labels take two keys.
LabelKeys string `toml:"label_keys"`
// panes when it opens: tree, flat or cards (default: tree). The v key
// changes it while the navigator is open.
NavigatorLayout string `toml:"navigator_layout"`
}
PanesConfig is the [panes] section: how display_panes labels the panes on the screen. display_panes puts a large label on every pane the workspace shows, and typing a label focuses that pane.
It is read each time the labels open, so an edit to the file is in force the next time.
func (PanesConfig) LabelKeysInUse ¶ added in v0.9.0
func (p PanesConfig) LabelKeysInUse() string
LabelKeysInUse is the effective label keys.
func (PanesConfig) NavigatorLayoutInUse ¶ added in v0.9.0
func (p PanesConfig) NavigatorLayoutInUse() string
NavigatorLayoutInUse is the effective navigator layout. An unknown value is the tree.
type PasteBuffersConfig ¶ added in v0.9.0
type PasteBuffersConfig struct {
// Limit is how many automatic buffers to keep. 0 keeps none, and a yank
// then goes only to the clipboard. A pointer so an explicit 0 is told
// apart from a file that never mentions it (default: 20).
Limit *int `toml:"limit"`
// MaxKB is how many KiB all buffers hold together. When a new buffer
// passes it, the oldest go. 0 uses 16384 (16 MiB), and the most it may
// be is MaxPasteBufferKB.
MaxKB int `toml:"max_kb"`
}
PasteBuffersConfig is the [paste_buffers] table: how many yanks tuios keeps to paste again, after tmux's buffer-limit. The daemon reads it when it starts and when the file changes. A client with no daemon reads it the same way.
func (PasteBuffersConfig) Resolved ¶ added in v0.9.0
func (c PasteBuffersConfig) Resolved() (limit, maxBytes int)
Resolved returns the count limit and the byte cap the store runs with.
type PermissionsConfig ¶ added in v0.8.0
type PermissionsConfig struct {
// Mode is open or strict. Empty is open. Any other value is read as
// strict, so a typo never turns the protection off.
Mode string `toml:"mode,omitempty"`
// Grants is what a pane holds under strict when it was started with no
// grants of its own. Nil is DefaultStrictGrants; an empty list is no
// grants at all. Names outside PaneGrantNames are dropped.
Grants []string `toml:"grants,omitempty"`
}
PermissionsConfig is the [agents.permissions] table.
func (PermissionsConfig) Resolve ¶ added in v0.8.0
func (c PermissionsConfig) Resolve() ResolvedPermissions
Resolve reads the table: the mode, with anything but open or empty read as strict, and the grants with unknown names dropped.
type PiPConfig ¶ added in v0.8.3
type PiPConfig struct {
// Width and Height are the size of the whole box, border included, in
// cells (default: 40x12). The box shrinks to fit a smaller screen.
Width int `toml:"width"`
Height int `toml:"height"`
// Corner is where the box goes first (default: bottom-right). When the
// focused pane's cursor enters the box, the box moves to another corner.
Corner string `toml:"corner"`
}
PiPConfig is the [pip] section: the picture-in-picture view, a small live copy of one pane drawn in a corner of the screen while another pane has the focus.
Nothing here is session state. The view is what this client's screen shows, like the spotlight, so a second client attached to the same session keeps its own view (or none).
func (PiPConfig) CornerName ¶ added in v0.8.3
CornerName is the corner the box goes to first, defaulting to bottom-right for an empty or unknown value.
type PluginsConfig ¶ added in v0.9.0
type PluginsConfig struct {
// Enabled are the ids of the plugins tuios runs.
Enabled []string `toml:"enabled,omitempty"`
// Dirs are more plugin folders, or manifests, to list. tuios plugins
// link adds to it.
Dirs []string `toml:"dirs,omitempty"`
}
PluginsConfig is the [plugins] table: which herdr plugins tuios runs, and where it finds plugins besides the places it looks by default. See internal/herdrplugin.
A plugin is found and listed without being enabled. Nothing it names runs until its id is in Enabled. herdr's own enabled flag is not read: a plugin herdr runs is off in tuios until the person enables it here.
func PluginsInFile ¶ added in v0.9.0
func PluginsInFile(path string) (PluginsConfig, error)
PluginsInFile reads the [plugins] table of the file at path. A missing file is an empty table.
type PruneResult ¶ added in v0.9.0
type PruneResult struct {
// Keys are the dotted keys removed.
Keys []string
// Uncovered are the removed keys another file sets, with that file. Its
// value applies once the key is gone from config.toml.
Uncovered []KeyOrigin
}
PruneResult is what PruneConfig removed, or would remove.
func PruneConfig ¶ added in v0.9.0
func PruneConfig(path string, dryRun bool) (PruneResult, error)
PruneConfig removes from config.toml every key whose value is the default, unless its absence means something else, as it does for [startup]. A config.toml written by an older tuios sets every key, which hides every included file; this is the way back to a config.toml that holds only what the person chose. With dryRun it changes nothing and reports what it would remove.
type PushoverConfig ¶ added in v0.9.0
type PushoverConfig struct {
User Secret `toml:"user,omitempty"`
UserEnv string `toml:"user_env,omitempty"`
UserFile string `toml:"user_file,omitempty"`
Token Secret `toml:"token,omitempty"`
TokenEnv string `toml:"token_env,omitempty"`
TokenFile string `toml:"token_file,omitempty"`
// URL replaces the Pushover API address, for a relay. Default: the
// Pushover messages endpoint.
URL string `toml:"url,omitempty"`
}
PushoverConfig is [notify.pushover]: the Pushover API.
type QueueConfig ¶ added in v0.8.0
type QueueConfig struct {
// Max is how many messages one pane's queue holds. Zero means the
// default, 8; values past 64 read as 64.
Max int `toml:"max,omitempty"`
}
QueueConfig is the [agents.queue] table.
func (QueueConfig) MaxEntries ¶ added in v0.8.0
func (c QueueConfig) MaxEntries() int
MaxEntries is Max with its default and bound applied.
type Reach ¶ added in v0.8.0
type Reach int
Reach says what a scope's bindings do to the program running in the pane.
const ( // ReachModal means tuios owns the whole keyboard while the scope is active, // so no binding here can be said to steal anything: the guest is not being // typed at in the first place. ReachModal Reach = iota // ReachSteals means the scope is active while the user is typing into the // guest, so every key bound here is one the guest will never see. ReachSteals // ReachChorded means the scope is only reached after a chord, so it costs // the guest nothing beyond the chord's own first key. ReachChorded )
type RecapConfig ¶ added in v0.8.0
type RecapConfig struct {
// Mode is one of RecapModes. Empty means toast.
Mode string `toml:"mode,omitempty"`
// Away is a Go duration ("10m"). Empty means DefaultRecapAway.
Away string `toml:"away,omitempty"`
// TestPatterns replaces DefaultRecapTestPatterns when set.
TestPatterns []string `toml:"test_patterns,omitempty"`
}
RecapConfig is the [agents.recap] table.
func (RecapConfig) Resolved ¶ added in v0.8.0
func (c RecapConfig) Resolved() ResolvedRecap
Resolved applies the defaults. A value validation warns about reads as its default.
type Redirect ¶ added in v0.9.0
type Redirect struct {
From, To string
}
Redirect is one read-only file and the file its change went to.
type Removal ¶ added in v0.8.0
type Removal struct {
Section string `json:"section"`
Action string `json:"action"`
Key string `json:"key"`
// LeftUnbound is true when this was the action's last key, so the action is
// now written as an empty list.
LeftUnbound bool `json:"left_unbound"`
}
Removal is one key taken off one action.
type ResolvedPermissions ¶ added in v0.8.0
type ResolvedPermissions struct {
// Strict is true under strict mode.
Strict bool
// Grants is the default for a pane started with no grants of its own
// under strict, valid names only, in documented order.
Grants []string
}
ResolvedPermissions is the table as the daemon uses it.
type ResolvedRecap ¶ added in v0.8.0
ResolvedRecap is RecapConfig with its defaults applied and bad values replaced by them.
type RiskConfig ¶ added in v0.8.0
type RiskConfig struct {
// Builtin keeps the rules tuios ships. Unset means true.
Builtin *bool `toml:"builtin,omitempty"`
// PanesMayAllow lets a pane holding the respond grant allow an approval
// that matched a rule. Off by default: such a pane may deny it and not
// allow it, and only the person allows it.
PanesMayAllow bool `toml:"panes_may_allow,omitempty"`
// Rules are rules of the person's own, added to the shipped ones.
Rules []RiskRuleConfig `toml:"rule,omitempty"`
}
RiskConfig is the [agents.approvals.risk] table.
func (RiskConfig) BuiltinRules ¶ added in v0.8.0
func (r RiskConfig) BuiltinRules() bool
BuiltinRules reports whether the shipped risk rules apply.
type RiskRuleConfig ¶ added in v0.8.0
type RiskRuleConfig struct {
// Name is what the Inbox and the risk list call the rule.
Name string `toml:"name"`
// Tools are the tool names the rule applies to. Empty applies it to
// every tool.
Tools []string `toml:"tools,omitempty"`
// Pattern is an RE2 regular expression matched against each command
// segment of the call.
Pattern string `toml:"pattern"`
}
RiskRuleConfig is one [[agents.approvals.risk.rule]].
type SaveError ¶ added in v0.9.0
type SaveError struct {
Err error
// contains filtered or unexported fields
}
SaveError is a save that failed. The change it carried is not in any file, so RewindSave puts the config's baseline back and the next save writes the change again.
type Scope ¶ added in v0.8.0
type Scope struct {
ID string
// Name is what the scope is called on screen.
Name string
// Chord is what has to be pressed to get into this scope, empty when the
// scope is entered by being in a mode rather than by a chord. It prefixes
// every key in the scope when the binding is shown as something to press.
Chord string
// Sections are the config tables the scope's keys are drawn from, in the
// order they are consulted.
Sections []string
// Reaches is the guest-facing consequence of the scope: whether keys bound
// here are taken out of the stream that would otherwise reach the program
// running in the pane.
Reaches Reach
}
A Scope is one keyboard context: a set of keys that are looked up together and therefore compete with each other. Two actions on one key only collide when they share a scope, so the scope is the unit every conflict is stated against.
The scopes are not a re-description of the config's sections. Seven sections are flattened into one lookup map by buildMappings, so those seven share a scope and a key bound twice across them is a real collision even though the TOML shows it in two different tables. The prefix sections each stay their own scope because they are only ever consulted after their chord.
func Scopes ¶ added in v0.8.0
Scopes returns every keyboard context, in the order a reader should meet them: the two modes the user spends their time in, then the rail, then the chords.
The chords are spelled with the configured leader rather than a literal ctrl+b, since rebinding the leader moves every one of them.
type ScratchConfig ¶ added in v0.8.2
type ScratchConfig struct {
// Width and Height are the popup's size, in cells (60) or percent (80%)
// of the pane region, as tuios popup takes them (default: 80%).
Width string `toml:"width"`
Height string `toml:"height"`
// Session named the session the first design showed in the popup, a
// nested tuios. The popup is a plain shell now, so the key is read only
// to tell the user it is no longer used (see validateScratch). A config
// that still has it loads.
Session string `toml:"session,omitempty"`
}
ScratchConfig is the [scratch] section: the size of the scratch terminal, the one shell toggle_scratch shows in a popup over the current layout.
func (ScratchConfig) HeightSpec ¶ added in v0.8.2
func (s ScratchConfig) HeightSpec() string
func (ScratchConfig) WidthSpec ¶ added in v0.8.2
func (s ScratchConfig) WidthSpec() string
WidthSpec and HeightSpec are the effective sizes. A value that does not parse falls back to the default, as a popup does, so a typo still shows the session.
type ScreensaverConfig ¶ added in v0.8.0
type ScreensaverConfig struct {
Enabled *bool `toml:"enabled"` // run a screen saver at all (default: false)
IdleMinutes int `toml:"idle_minutes"` // quiet time before it starts (default: 10)
Effect string `toml:"effect"` // random, or one effect by name (default: random)
WhileBusy *bool `toml:"while_busy"` // start even when a pane is working (default: false)
}
ScreensaverConfig is the [screensaver] section: whether the screen animates itself after a spell of quiet, how long that spell is, and which effect runs.
Enabled is a pointer so that turning it off in the settings page survives a reload rather than reading as "unset" and snapping back on.
func (ScreensaverConfig) EffectName ¶ added in v0.8.0
func (s ScreensaverConfig) EffectName() string
EffectName is the effect to run, or the random marker. A retired name maps to its replacement and any other unknown name falls back to random, so a config written against a different version still starts a saver.
func (ScreensaverConfig) IdleDelayMinutes ¶ added in v0.8.0
func (s ScreensaverConfig) IdleDelayMinutes() int
IdleDelayMinutes is the effective quiet time before the saver starts.
func (ScreensaverConfig) IsEnabled ¶ added in v0.8.0
func (s ScreensaverConfig) IsEnabled() bool
IsEnabled reports whether a screen saver should ever start.
func (ScreensaverConfig) RunsWhileBusy ¶ added in v0.8.0
func (s ScreensaverConfig) RunsWhileBusy() bool
RunsWhileBusy reports whether the saver may cover a pane that is working. The default is no: a saver that hides a running build is a bug.
type ScreenshotConfig ¶ added in v0.8.0
type ScreenshotConfig struct {
Format string `toml:"format"` // png | svg | ansi | html | txt (default: png)
Copy *bool `toml:"copy"` // attempt a clipboard copy after capture (default: true)
Preview *bool `toml:"preview"` // open the preview panel after capture (default: true)
Directory string `toml:"directory"` // where files land (default: ~/Pictures/tuios)
Frame string `toml:"frame"` // window | plain | none (default: window)
Background string `toml:"background"` // auto | none | hex | hex..hex (default: auto)
Padding *int `toml:"padding"` // px around the card, 0..128 (default: 48)
Radius *int `toml:"radius"` // card corner radius px, 0..32 (default: 10)
Shadow *bool `toml:"shadow"` // drop shadow under the card (default: true)
Controls string `toml:"controls"` // auto | macos | glyphs | none (default: auto, the macOS lights)
TitleFormat string `toml:"title_format"` // window_title_format tokens (default: {title})
FontFamily string `toml:"font_family"` // SVG/HTML font stack (default: JetBrains Mono, monospace)
FontFile string `toml:"font_file"` // a .ttf to embed in SVG and rasterize PNG with
Scale *int `toml:"scale"` // PNG raster scale, 1..4 (default: 2)
Cursor bool `toml:"cursor"` // draw the cursor cell (default: false)
}
ScreenshotConfig is the [screenshot] section: how a capture renders and where it lands. Pointer fields distinguish "unset" from an explicit zero, so `padding = 0` and `copy = false` survive a reload instead of snapping back to the defaults.
func (ScreenshotConfig) CopyEnabled ¶ added in v0.8.0
func (s ScreenshotConfig) CopyEnabled() bool
CopyEnabled reports whether a capture should attempt a clipboard copy.
func (ScreenshotConfig) EffectiveFormat ¶ added in v0.8.0
func (s ScreenshotConfig) EffectiveFormat() string
EffectiveFormat is the format with the default applied.
func (ScreenshotConfig) PaddingPx ¶ added in v0.8.0
func (s ScreenshotConfig) PaddingPx() int
PaddingPx is the effective card padding.
func (ScreenshotConfig) PreviewEnabled ¶ added in v0.8.0
func (s ScreenshotConfig) PreviewEnabled() bool
PreviewEnabled reports whether the preview panel opens after a capture.
func (ScreenshotConfig) RadiusPx ¶ added in v0.8.0
func (s ScreenshotConfig) RadiusPx() int
RadiusPx is the effective corner radius.
func (ScreenshotConfig) ResolveDirectory ¶ added in v0.8.0
func (s ScreenshotConfig) ResolveDirectory() string
ResolveDirectory expands the configured directory to an absolute path, with ~ resolved against the process's home.
func (ScreenshotConfig) ScaleFactor ¶ added in v0.8.0
func (s ScreenshotConfig) ScaleFactor() int
ScaleFactor is the effective PNG raster scale.
func (ScreenshotConfig) ShadowEnabled ¶ added in v0.8.0
func (s ScreenshotConfig) ShadowEnabled() bool
ShadowEnabled reports whether the card gets a drop shadow.
type ScrollbarConfig ¶ added in v0.8.0
type ScrollbarConfig struct {
Style string `toml:"style"` // thin, track (default: track)
Thumb string `toml:"thumb"` // one-cell glyph (default: thin ▐, track █, ASCII |)
Track string `toml:"track"` // one-cell glyph or none (default: thin ▕, track the surface fill, ASCII none)
Tint string `toml:"tint"` // quiet, border, muted, #RRGGBB (default: quiet)
}
ScrollbarConfig is the pane scrollbar's own table. hide_scrollbar predates it and stays where it is, so existing files keep working. Every key here is optional and an absent one takes the style's own default, so a file written before the table grew renders exactly what the release documents.
type Secret ¶ added in v0.9.0
type Secret string
Secret is a credential read from config.toml. It prints as [redacted] everywhere fmt or encoding/json reaches it, so a config that is logged or dumped does not carry it. The TOML encoder writes the value itself, which is what keeps it in the file when tuios saves the config. Reveal is the one way to read it.
func (Secret) Format ¶ added in v0.9.0
Format hides the value from every fmt verb, %x and %q included.
func (Secret) MarshalJSON ¶ added in v0.9.0
MarshalJSON hides the value from a JSON dump.
type SelectionConfig ¶ added in v0.8.0
type SelectionConfig struct {
// Bg and Fg are the selection in copy mode's visual state.
Bg string `toml:"bg"`
Fg string `toml:"fg"`
// Bold draws selected text bold as well. Off by default: the background
// already says what is selected, and reweighting the text moves it.
Bold *bool `toml:"bold"`
// SearchBg is every match of a search, and MatchBg is the one the cursor
// is on. Two colours because "where are the matches" and "which one am I
// on" are two questions, and one colour answers only the first.
SearchBg string `toml:"search_bg"`
SearchFg string `toml:"search_fg"`
MatchBg string `toml:"match_bg"`
MatchFg string `toml:"match_fg"`
// CursorBg is the block copy mode draws where its cursor is.
CursorBg string `toml:"cursor_bg"`
CursorFg string `toml:"cursor_fg"`
// Flash sweeps a band of light over text that was just copied. Copying is
// the one gesture in a terminal with no result to look at: the text does
// not change and the selection usually disappears.
Flash *bool `toml:"flash"`
// FlashMs is how long one sweep takes, and FlashColor is the light.
FlashMs int `toml:"flash_ms,omitempty"`
FlashColor string `toml:"flash_color,omitempty"`
// FlashStyle is the shape the sweep takes: diagonal, diagonal-reverse,
// horizontal or vertical. Which one reads best depends on what is usually
// copied, so it is a choice rather than a constant.
FlashStyle string `toml:"flash_style,omitempty"`
// MultiFormat is the format multi copy mode yanks in until the format
// key changes it: plain, markdown or json.
MultiFormat string `toml:"multi_format,omitempty"`
// CopyEntry is where copy mode puts its cursor when it starts: "cursor"
// (the terminal cursor, as tmux does) or "center" (the middle row).
CopyEntry string `toml:"copy_entry,omitempty"`
// OSC52Write says what happens when a program in a pane sets the
// clipboard with OSC 52: off, ask, focused or on. See OSC52WriteModes.
OSC52Write string `toml:"osc52_write,omitempty"`
// CopyCommand is a command every copy-mode yank pipes the selection
// through, as tmux's copy-command. Empty copies the selection as it is.
CopyCommand string `toml:"copy_command,omitempty"`
}
SelectionConfig holds the [appearance.selection] table: the colours a pane paints over its own output to mark text.
All four were fixed hex literals in the render loop. They are the one part of a pane's colours tuios chooses rather than the program running in it, so they are the one part a person cannot fix by changing their theme, and the selection colour in particular sat over every pane in a violet nothing else on screen used.
A background is a colour literal. A foreground may also be empty, which leaves the text the colour the program wrote it in and tints only the background behind it, the way a browser or an editor marks a selection.
type Settings ¶ added in v0.8.0
type Settings struct {
// NotificationDuration is how long an info or success message stays up. It
// is also the floor for any duration a caller asks for; a caller wanting
// longer still gets longer.
NotificationDuration time.Duration
// NotificationWarningDuration is how long a warning stays up.
NotificationWarningDuration time.Duration
// NotificationErrorDuration is how long an error stays up when
// NotificationErrorSticky is off.
NotificationErrorDuration time.Duration
// NotificationErrorSticky makes errors wait for a dismissal instead of
// expiring. The dock's rule stops burning down when this is what is on
// screen, which is the affordance that it is waiting for you.
NotificationErrorSticky bool
// NormalFPS is the normal refresh rate during regular operation.
// Set via appearance.max_fps config (default 60, up to MaxFPSCap).
NormalFPS int
// MaxFPSAuto is set when appearance.max_fps is "auto": NormalFPS then
// follows DisplayFPS.
MaxFPSAuto bool
// DisplayFPS is the refresh rate the client found for this machine's
// displays, or 0 before it has looked or when it cannot tell. It is not
// read from the config, so a reload keeps it.
DisplayFPS int
// UseASCIIOnly controls whether to use ASCII fallback characters instead
// of Nerd Fonts. It is the effective answer: set by --ascii-only
// (ASCIIRequested), or by a terminal whose locale is not UTF-8 when no
// glyph set was chosen (see GlyphEnv).
UseASCIIOnly bool
// ASCIIRequested records --ascii-only, so re-applying the config at
// runtime can recompute UseASCIIOnly without losing the flag.
ASCIIRequested bool
// GlyphEnv is what the terminal tuios draws on can show, read from its
// locale and TERM when the client starts. See DetectGlyphEnv.
GlyphEnv GlyphEnv
// NoNerdFont is set when GlyphEnv is GlyphEnvUnicode and no glyph set was
// chosen: the icons that are not glyph set roles (the dock's, the
// notification marks) take their ASCII forms. Read it through
// NerdFontsOff.
NoNerdFont bool
// Motion is how much the UI animates: MotionNone, MotionBasic or
// MotionFull. Set via appearance.motion, or --no-animations for none.
// Read it through MotionAllows, which also honours AnimationsSuppressed.
Motion string
// NoAnimationsFlag records --no-animations, so re-applying the config at
// runtime keeps the level at none until something sets the level itself
// (OS.SetMotion).
NoAnimationsFlag bool
// AnimationsSuppressed is set to true temporarily to disable animations
// (e.g., during remote command processing). This takes precedence over
// Motion.
AnimationsSuppressed bool
// ModalDim is the percent the screen behind a modal overlay is darkened
// by. Zero turns it off. Set via appearance.modal_dim.
ModalDim int
// AlwaysConfirmQuit controls whether the quit confirmation dialog is shown
// every time, regardless of whether there are active foreground processes.
// Set via confirm_quit config option.
AlwaysConfirmQuit bool
// WhichKeyEnabled controls whether the which-key popup is shown after pressing leader key
// Set via appearance.whichkey_enabled config
WhichKeyEnabled bool
// WhichKeyPosition controls where the which-key popup appears
// Options: bottom-right, bottom-left, top-right, top-left, center
// Set via appearance.whichkey_position config
WhichKeyPosition string
// WrapLists makes a single step off either end of a list land on the other
// end: up on the first row goes to the last. Set via appearance.wrap_lists.
// See internal/listnav.
WrapLists bool
// instead of having two separate borders side by side.
// Set via --shared-borders flag or appearance.shared_borders config
// Default: false (disabled, opt-in)
SharedBorders bool
// BorderStyle controls which border style to use for windows
// Set via --border-style flag or appearance.border_style config
BorderStyle string
// TilingScheme is the BSP insertion scheme a workspace starts with the
// first time it is tiled: one of the TilingScheme* constants (spiral,
// longest_side, alternate, smart_split). Set via appearance.tiling_scheme.
// GetOrCreateBSPTree reads this only when a workspace has no tree yet; a
// workspace that is already tiled keeps its own scheme regardless of this
// value.
TilingScheme string
// ZenMode controls when window borders are hidden. Valid values are the
// ZenMode* constants: disabled (always visible), always (always hidden) or
// mouse (hidden while the pointer is idle). Set via appearance.zen_mode.
ZenMode string
// Links controls what tuios treats as a link in pane content. Valid values are
// the Links* constants: off, marked (OSC 8 only) or all (bare URLs too). Set
// via appearance.links.
Links string
// LinkClick is the click that opens a link: one of the LinkClick*
// constants. Set via appearance.link_click.
LinkClick string
// LinkOpener is the command that opens a web link. Empty uses $BROWSER,
// then the system opener. Set via appearance.link_opener.
LinkOpener string
// DockbarPosition controls the position of the dockbar
// Set via --dockbar-position flag or appearance.dockbar_position config
DockbarPosition string
// SidebarEnabled turns the sidebar on. Default on since v0.8.0.
SidebarEnabled bool
// SidebarPosition is which edge the sidebar reserves: "left", "right", or
// "hidden" (reserves nothing even when enabled).
SidebarPosition string
// SidebarWidth is the preferred sidebar width in columns for a wide screen.
// GetSidebarWidth folds this together with the narrow-screen breakpoints.
SidebarWidth int
// SidebarShowGlyphs draws the agent-state glyph on each row.
SidebarShowGlyphs bool
// SidebarShowCounts draws the window count on each session row.
SidebarShowCounts bool
// SidebarShowNumbers draws the switch number ahead of each session name.
// Off by default: the quiet rail is the default, and the people who want
// the numbers set show_numbers in [appearance.sidebar].
SidebarShowNumbers bool
// SidebarMarquee scrolls a hovered row's title when it overflows its columns.
SidebarMarquee bool
// SidebarSections is the rail's layout: which sections it stacks, in what
// order, and the share of the rail each one may claim. See
// SidebarDefaultSections for the syntax.
SidebarSections string
// SidebarFileIcons draws a nerd font icon per file type in the files
// section. Off, and on a terminal running in ASCII, the section falls back
// to the glyph set's folder, parent and file marks.
SidebarFileIcons bool
// SidebarFileIconColors draws each of those icons in its own file type's
// colour, the way yeetui does. It needs the icons under it, so it draws
// nothing when they are off or the terminal is running in ASCII.
SidebarFileIconColors bool
// SidebarFolderClick is what a click on a folder row does: walk the listing
// into it, tell the pane to cd there, or both.
SidebarFolderClick string
// SidebarEditor is the terminal editor command; empty uses the environment.
SidebarEditor string
// SidebarFileActions lets the files section create, rename, delete, copy,
// cut and paste. On leaves the listing exactly as it was until a key is
// pressed or a menu row is picked; off makes those keys do nothing at all.
//
// It is a setting because the rail is beside a terminal rather than in front
// of one. A file manager is a place somebody went; a rail is a place they
// are, and not everybody wants the folder they are looking at to be one they
// can delete from by mistake.
SidebarFileActions bool
// SidebarAgentRestFold is how long an agent row rests (idle, unknown, or
// done and seen) before the rail folds it into one line with the others.
// Zero never folds. From appearance.sidebar.agent_rest_fold.
SidebarAgentRestFold time.Duration
// SidebarFileDelete is where a deleted file goes: the trash, or nowhere.
SidebarFileDelete string
// SidebarAgentRow is what an agent row draws and how each token is inked,
// from [appearance.sidebar.agent_row]. See sidebar_agent_row.go.
SidebarAgentRow SidebarAgentRowSpec
// Tooltips pops a one-row label naming whatever icon-only control the
// pointer is over: a row of the collapsed rail, or one of the dock's session
// controls. A glyph is enough to steer by and not enough to read.
Tooltips bool
// SessionColors gives every session a colour of its own and marks it on the
// surfaces that show more than one session at once: the rail's sessions and
// agents sections, and the session switcher. Off leaves each of those exactly
// as it was before the colours existed.
// SessionBorder carries the session's colour on every pane border, not only
// on the rail. It is off by default because it changes the look of every
// window, and it is separate from SessionColors so the rail's marks and the
// borders can be turned on independently.
//
// It is for telling one machine from another at a glance. Once panes can be
// attached on several machines, the session is the thing every pane in the
// view has in common, and its colour is the cheapest way to say which one
// you are looking at without reading the rail.
// SidebarGitDirty adds the count of staged, changed and untracked paths to
// the rail's git section.
//
// Separate from the section itself because it is the only part of it that
// costs a walk of the working tree. A branch and a divergence are recorded
// facts and come from a few file reads; dirtiness is recorded nowhere, so
// the only way to know is to compare the tree against the index. On a large
// repository that is the part worth being able to turn off.
// NiriClickReveals brings a clicked column fully on screen in the scrolling
// layout.
//
// A click is different from the other ways focus moves. A workspace switch
// or a focus the daemon moved is not a statement about the viewport, and
// revealing on those threw away wherever the user had scrolled the strip,
// which is the bug that put every focus change on the least-scroll rule.
// Clicking a column that is half off the edge is a statement: you picked
// that pane to work in, so the strip brings all of it to you.
NiriClickReveals bool
// NiriHoverReveals brings the column under the pointer fully on screen in
// the scrolling layout, while focus-follows-mouse is on.
//
// Hovering a column with that setting on is the same statement clicking one
// is: it is how you pick the pane to work in, and there is no other gesture
// to make. Without it the focus moved to a column that stayed half off the
// edge, so the pane you had just focused was the one you could not see.
//
// It does nothing unless appearance.focus_follows_mouse is on, since
// nothing focuses on hover otherwise.
NiriHoverReveals bool
SidebarGitDirty bool
SessionBorder bool
// GlobalSession offers a session that holds panes from more than one
// machine, listed in the rail once a second machine is reachable.
//
// It is a session of its own rather than a thing any session can become.
// An ordinary session is the machine it is on, and a new pane in it is a
// pane there, with nothing to ask about. The global session is the one
// place the question is worth putting, so it is the one place it is asked.
GlobalSession bool
SessionColors bool
// DockWorkspaceTabs draws the dock's clickable workspace strip. Off leaves the
// dock exactly as it was before the strip existed.
DockWorkspaceTabs bool
// DockWorkspaceTabFormat is the format string for each workspace tab in the
// dock strip. Placeholders: {index} (the workspace number) and {name} (the
// workspace name, or its number when it has no name). Empty means "{name}",
// the historic rendering.
DockWorkspaceTabFormat string
// DockWorkspaceTooltip pops the whole name of a workspace whose pill had to cut
// it short. Off, a long name stays truncated with no way to read the rest.
DockWorkspaceTooltip bool
// DockWorkspaceLabelMax caps a workspace pill's label in cells. 0 draws the
// whole name and lets the strip's scroll arithmetic handle the width.
DockWorkspaceLabelMax int
// DockPillCaps puts powerline half-circle caps on the dock's mode chip,
// workspace tabs and minimized-window pills. On by default. Off, each is a
// flat filled cell, for anyone who reads a row of caps as a row of beads.
DockPillCaps bool
// DockModeIconWindow, DockModeIconTerminal and DockModeIconTiling are the
// mode pill's icons from appearance.dock_mode_icon_*. Nil is unset, which
// draws the built-in for the glyph set. An empty string draws no icon.
// Read them through GetDockModeIconWindow and its siblings.
DockModeIconWindow *string
DockModeIconTerminal *string
DockModeIconTiling *string
// DockCompact draws the dock as one row: the pills without the rule above
// or below them. The panes get the row back. Off by default.
DockCompact bool
// HideWindowButtons controls whether to hide window control buttons
// Set via --hide-window-buttons flag or appearance.hide_window_buttons config
HideWindowButtons bool
// WindowButtonStyle selects how the window controls are drawn. See
// appearance.window_button_style.
WindowButtonStyle string
// WindowButtonPosition selects which end of the title bar the window controls
// sit on. See appearance.window_button_position.
WindowButtonPosition string
// ScrollbarStyle selects how a scrolled-back pane draws its position. See
// appearance.scrollbar.style.
ScrollbarStyle string
ScrollbarThumb string
ScrollbarTrack string
ScrollbarTint string
// The colours a pane paints over its own output to mark text. See
// SelectionConfig. An empty foreground leaves the text the colour the
// program wrote it in and tints only the background.
SelectionBg string
SelectionFg string
SelectionBold bool
SearchBg string
SearchFg string
MatchBg string
MatchFg string
CopyCursorBg string
CopyCursorFg string
// CopyFlash sweeps a band of light over text that was just copied.
// CopyFlashMs is how long one sweep takes and CopyFlashColor is the light.
CopyFlash bool
CopyFlashMs int
CopyFlashColor string
// CopyFlashStyle is the shape the sweep takes. One of CopyFlashStyles.
CopyFlashStyle string
// MultiCopyFormat is the format multi copy mode starts in: one of
// MultiCopyFormats.
MultiCopyFormat string
// CopyEntry is where copy mode puts its cursor on entry: one of
// CopyEntries.
CopyEntry string
// OSC52Write says what happens when a program in a pane sets the
// clipboard with OSC 52. One of OSC52WriteModes.
OSC52Write string
// CopyCommand is the command a copy-mode yank pipes the selection
// through: appearance.selection.copy_command. Empty copies it as it is.
CopyCommand string
// HideScrollbar controls whether the window scrollbar is hidden.
// Automatically treated as true when BorderStyle == "hidden" since there is
// no border to draw the thumb on in that mode.
// Set via --hide-scrollbar flag or appearance.hide_scrollbar config
HideScrollbar bool
// WindowTitlePosition controls where window titles are displayed
// Options: bottom, top, hidden
// Set via --window-title-position flag or appearance.window_title_position config
WindowTitlePosition string
// WindowTitleFormat is the template used to build a window's displayed title.
// Empty (the default) means the title is shown as-is. See FormatWindowTitle for
// the supported placeholders.
// Set via appearance.window_title_format config
WindowTitleFormat string
// HideClock controls whether the clock overlay is hidden
// Set via --hide-clock flag or appearance.hide_clock config
// Deprecated: Use ShowClock instead. HideClock takes precedence when true.
HideClock bool
// ShowClock controls whether the clock overlay is shown (default: hidden).
// Set via --show-clock flag or appearance.show_clock config
ShowClock bool
// ShowCPU controls whether the CPU graph is shown in the dock (default: hidden).
// Set via --show-cpu flag or appearance.show_cpu config
ShowCPU bool
// ShowRAM controls whether RAM usage is shown in the dock (default: hidden).
// Set via --show-ram flag or appearance.show_ram config
ShowRAM bool
// ScrollbackLines controls the number of lines to keep in scrollback buffer
// Set via --scrollback-lines flag or appearance.scrollback_lines config
ScrollbackLines int
// ScrollLines is how many lines one mouse wheel notch scrolls in scrollback,
// copy mode and the scrollback browser.
// Set via appearance.scroll_lines config
ScrollLines int
// CopyOnSelect puts the text on the clipboard as soon as a mouse selection is
// released, the way X11's primary selection and kitty's copy_on_select do.
// Turn it off to keep the clipboard until an explicit yank.
// Set via appearance.copy_on_select config.
CopyOnSelect bool
// negotiate terminal focus keys through OSC 7777. It is off by default.
// Set via appearance.nvim_navigation config.
NvimNavigation bool
// FocusFollowsMouse focuses the pane under the cursor as the mouse moves over
// it, without a click and without entering terminal mode. It is a divisive
// window-manager habit, so it defaults off and users opt in.
// Set via appearance.focus_follows_mouse config.
FocusFollowsMouse bool
// AltDrag makes alt + left-drag move a pane, the gesture nearly every desktop
// window manager binds. It is on by default because the hands that know it
// already outnumber the ones that do not. Turning it off hands alt-drag back to
// the pane: selection while typing, and whatever a mouse-tracking app makes of
// it. Alt + right-drag resizes either way, since that is the ordinary
// right-press resize with alt only keeping the menu out of the way.
// Set via appearance.alt_drag config.
AltDrag bool
// AutoEnterTerminalOnFocus enters terminal mode when a window-management
// keyboard command actually moves focus to another pane. Hover-focus and
// click-to-type keep their own policies; this is only those explicit focus
// commands. A no-op that leaves the already-focused pane focused does not
// change mode.
//
// off (the default): Tab keeps cycling in window-management mode.
// targeted: numbered select and directional arrows enter terminal mode; Tab
// does not.
// all: every covered focus command that actually moves focus also enters
// terminal mode, including next/prev window.
// Set via appearance.auto_enter_terminal_on_focus config.
AutoEnterTerminalOnFocus AutoEnterTerminalPolicy
// ClickToType decides what a left click on a pane's content does while the
// keyboard is driving the window manager. "single" enters terminal mode on the
// release, which is what a newcomer expects a click to do (the default before
// v0.8.0). "double" focuses on one click and enters on two, so arranging panes
// with the mouse does not let a stray click take the window manager's keys
// away; it is the default. "off" never changes mode from a click: the way in
// stays the enter_terminal_mode binding.
//
// The mode decides who owns the mouse, here as everywhere else: a pane whose
// app asked for mouse tracking is only forwarded to in terminal mode, so under
// "off" the mouse alone cannot reach that app. "double" is the setting for
// someone who lives in mouse-mode apps and still wants the mouse to be a
// pointer first.
// Set via appearance.click_to_type config.
ClickToType string
// RightClickOpensMenu makes a plain right-click on a pane's content open the
// pane menu while the keyboard is typing in it, instead of reserving the
// unmodified right button.
//
// Off by default: a pointer reaches the menu with ctrl or shift held and a
// plain right-click is consumed, so the button stays with the pane. A touch
// client has no modifier and opens the menu with a long press regardless.
// Turning this on is how someone makes the menu's Paste row one plain click
// away, without selecting anything first.
// Set via appearance.right_click_opens_menu config.
RightClickOpensMenu bool
// KittyPlaceholders decides whether images an application positions with
// kitty Unicode placeholders are drawn.
//
// "auto" draws them when the host terminal is one known to implement them,
// which is read off the name and version it reports rather than from TERM;
// there is no way to ask a terminal whether it has the feature. "on" and
// "off" say so outright, for a terminal the table does not know or gets
// wrong.
//
// Off means the placeholder cells are dropped, which is what tuios always
// did and which leaves the blank space the application made room for.
// Keeping them on a host that cannot draw them fills that space with
// missing-glyph boxes instead.
// Set via appearance.kitty_placeholders config.
KittyPlaceholders string
// ImageSymbols decides how a pane's sixel image is shown on a host
// terminal that draws no graphics, such as kmscon or the Linux console.
// A glyph set name draws the picture as block glyphs of that set:
// octant (Unicode 16), sextant (Unicode 13), quadrant, half. "auto"
// picks by TERM: octant on kmscon, half on the Linux console, quadrant
// elsewhere (see imageSymbolKind in internal/app). "off" draws a box and
// tells the pane there is no sixel, so programs use their own text.
// Set via appearance.image_symbols config.
ImageSymbols string
// NewWindowInheritCwd starts a new window in the working directory of the
// pane that was focused when it was asked for, rather than in the
// directory the daemon itself was started in.
//
// On by default. A window opened from a pane deep in a project is almost
// always wanted in that project, and the old behaviour dropped the shell
// back in $HOME to be cd'd again by hand. The directory is read from the
// focused pane's live shell, so it follows the pane rather than where the
// pane started, and anything that cannot be read falls back to the old
// behaviour rather than failing to open a window.
// Set via appearance.new_window_inherit_cwd config.
NewWindowInheritCwd bool
// NewWindowFollowSSH makes the ordinary split and new-window actions
// behave like their ssh versions: when the focused pane runs ssh, the new
// pane runs the same ssh. Off by default, so a split is a local shell
// unless the person asks for the ssh version by its own key.
// Set via appearance.new_window_follow_ssh config.
NewWindowFollowSSH bool
// WordCharacters lists the punctuation that counts as part of a word when a
// double-click selects one, on top of letters and digits, which always do.
//
// The default is kitty's select_by_word_characters, and it is chosen for what
// terminal content actually looks like: it takes a path, a URL, a version
// number, or a flag such as --no-vm as a single word instead of stopping at
// every punctuation mark. A colon is deliberately absent, so host:port and
// file:line select as their parts.
// Set via appearance.word_characters config.
WordCharacters string
// NiriReverseScroll reverses mouse scroll direction in niri scrolling mode.
// When true, scroll-up moves viewport right and scroll-down moves left.
// Set via appearance.niri_reverse_scroll config
NiriReverseScroll bool
// NiriScrollCells is how many cells one wheel event walks the strip in the
// scrolling layout. See NiriScrollCellsDefault for why it is a flat count
// and not a share of the screen.
// Set via appearance.niri_scroll_cells config
NiriScrollCells int
// PrefixRepeatTime is how long the prefix stays armed after a repeatable
// prefix command, in milliseconds. Zero turns it off. See
// PrefixRepeatTimeDefault.
PrefixRepeatTime int
// LeaderKey is the prefix key for commands (default: ctrl+b)
// Set via appearance.leader_key config
LeaderKey string
// PaneGap is the cells of empty space the tiler keeps between two neighbouring
// panes: i3's inner gap, and about the only spacing a terminal window manager
// can honestly offer.
//
// Inner only. An outer gap would have to inset the content region, which the
// sidebar's width, the dock's height, every overlay's placement and every mouse
// hit test are measured against, so a margin the sidebar already draws one of
// would cost a move of the whole frame.
PaneGap int
// MasterRatioPercent is how much of the screen the master pane takes in the
// master-stack layout, as a percent. It is the value a new session starts at;
// once a session is running the ratio is the session's, moved by the resize
// keys and settled across every attached client, because it decides how many
// columns a pane gets and a PTY has exactly one size.
MasterRatioPercent int
// MasterPosition, MasterCount and MasterNoGrid are the master-stack shape
// a workspace starts with: the side the masters take (one of
// MasterPositions), how many panes are masters, and whether one master on
// the left stops turning four or more panes into a grid. A workspace
// changed at run time keeps its own values in the session. Set via
// appearance.master_position, master_count and master_grid. The zero value
// of each is the layout as it was before they existed.
MasterPosition string
MasterCount int
MasterNoGrid bool
// ScrollColumnWidth is how wide a column is in the scrolling layout, as a
// percent of the screen, before anything resizes it. Session state for the same
// reason the master ratio is.
//
// The default is deliberately over half. The strip is meant to be wider than
// the viewport (that is what makes it a strip rather than a grid), so a
// default that let two columns sit side by side exactly would show the layout
// as a two-pane split and never as something you scroll.
ScrollColumnWidth int
// ScrollColumnMax is the highest ScrollColumnWidth may be set to, as a
// percent of the screen.
//
// The default, 90, is where the next column stops peeking in at the edge,
// which is the only thing that says the strip has one. Raising it to 100
// gives a column the whole screen: it is the ask from somebody who wanted a
// pane at full width without zooming, because zooming costs them the fast
// window switching the strip is for. The peek is what that trades away,
// which is why it is a setting and not the new default.
//
// Read it through GetScrollColumnMax, never directly: a Settings built by
// hand carries a zero here, and a clamp against zero pins every column to
// the floor.
ScrollColumnMax int
// ZoomSize is how much of the content region a zoomed pane takes, as a
// percent. 100, the default, is the whole of it.
//
// Below 100 the layout around the pane stays on screen at the edges, which
// is the scrolling layout's peek in both directions at once: a zoom that
// still shows you what you are not looking at. The box is pulled toward the
// pane's own corner rather than centred, so the neighbours that show are the
// ones it actually has.
//
// Read it through GetZoomSize, never directly.
ZoomSize int
// WindowButtonZoom draws the third title bar control on a tiled pane, where
// it toggles the zoom.
//
// On a tiled pane a maximize means zoom, since the tiler owns the
// rectangle, and a tiled pane is exactly where a zoom is worth reaching
// for. The green disc is the control everybody already knows.
WindowButtonZoom bool
// ZoomFollowsFocus hands the zoom to the pane the focus lands on.
//
// A zoomed workspace shows one pane. If focus moved underneath it, the
// next-pane key would focus the pane after it while the zoomed pane kept
// the box, and keys would go to a pane nobody can see. The zoom is the
// statement that you want one pane and the whole region for it; a focus
// move is the statement of which pane.
ZoomFollowsFocus bool
// ZoomAnimation slides a pane between its tile and the zoom box instead of
// swapping the two in one frame.
//
// Without it, zoom is a cut: the pane is at its tile in one frame and
// filling the region in the next, with nothing to say which pane has grown.
// That is worst exactly when it matters, which is a zoom that moves from one pane to
// another, where two panes change at once and neither says so.
ZoomAnimation bool
// ZoomBorderless makes a zoom the whole pane region with no chrome: the
// zoomed pane drops its border and title bar, and its guest is told the
// full size of the region. zoom_size and zoom_max_width do not apply while
// it is on, since a pane with no border has nothing to show around it.
ZoomBorderless bool
// DimUnfocused is how far an unfocused pane's content is carried toward the
// pane's own ground, as a percentage. Zero, the default, draws every pane's
// content the same.
//
// One number rather than wezterm's hue, saturation and brightness triple. A
// blend toward the ground already moves saturation and brightness together,
// because a pane's ground is both darker and flatter than the text on it, and
// rotating the hue of somebody else's program output is a novelty rather than a
// thing a rice wants. One number is also the only form that says the same thing
// on a light theme as on a dark one.
DimUnfocused int
// DimMultifocus dims the panes in the multifocus set like every other
// unfocused pane. False, the default, leaves them undimmed: they take the
// keys the user types, and full-strength content is what says so.
DimMultifocus bool
// Background is the ground painted on every surface that does not set
// its own: "off", the default, leaves the default background transparent
// so the host terminal shows through; "theme" paints the active theme's
// background; a #RRGGBB literal paints that colour.
//
// PaneBackground, DesktopBackground, WindowChromeBackground,
// DockBackground and SidebarBackground are each surface's own setting.
// Each takes the same values, and empty follows Background. Only cells
// left on the default background are painted, so a background a program
// or a piece of chrome chose wins. See ResolveBackground and the
// *BackgroundResolved methods.
Background string
PaneBackground string
DesktopBackground string
WindowChromeBackground string
DockBackground string
SidebarBackground string
// ClockFormat is the Go time layout the clock overlay draws with. Empty takes
// DefaultClockFormat.
//
// A layout rather than a set of toggles, for the reason window_title_format is
// one: "seconds on or off" is two of the questions people actually have about a
// clock, and the standard library already has a spelling for all of them.
ClockFormat string
// ZoomMaxWidth is the maximum width in cells for zoom/zen mode.
// 0 means fullscreen (no max width cap). When set (e.g., 120), the zoomed
// window is centered horizontally and capped at this width.
ZoomMaxWidth int
// GlyphSet names the chrome glyph set, or "default" for the shipped one. It is
// the shape half of a rice, beside Theme's colour half.
GlyphSet string
}
Settings is every appearance and behaviour value a running session reads.
It is a struct rather than a wall of package variables because one tuios process is not one user. `tuios ssh` and tuios-web each run a goroutine per connection, so a package variable that the settings page writes on every keypress is a setting the person on the other connection did not choose. Each session holds its own copy; the settings page writes into that copy, and the panes beside it on somebody else's screen keep the border, the zen mode and the rail their own reader picked.
A value, copied once per connection, so a read costs a field offset and no session can ever see another halfway through a write. Nothing here is a pointer or a map for the same reason.
The theme is deliberately not in here yet. It is a package of its own with style caches keyed off it, and it is still process-wide under a server; see the note the settings page carries on that row.
func AppearanceFrom ¶ added in v0.8.0
func AppearanceFrom(cfg *UserConfig, ov Overrides) Settings
AppearanceFrom builds the appearance settings a newly served session starts from: the built-in defaults, the config file as it is now, then the caller's flag overrides.
It is the same order the process globals get once at server startup, run per connection instead of once, so a session that connects after an edit follows the file rather than the copy the server loaded when it started. A nil cfg is an empty one, so the overrides still apply.
func DefaultSettings ¶ added in v0.8.0
func DefaultSettings() Settings
func (*Settings) AllBackgroundResolved ¶ added in v0.8.0
AllBackgroundResolved is appearance.background on its own.
func (*Settings) AnimationsOn ¶ added in v0.8.0
AnimationsOn reports whether any motion is configured. It is what the animation toggle and the tape executor's status read.
func (*Settings) BorderJoinsChromeRules ¶ added in v0.8.0
BorderJoinsChromeRules reports whether a divider drawn in the active style can meet the rule that closes the content region. Only a style drawn with strokes can: its junction glyph carries the rule's own stroke through the cell it takes over. A style drawn with fills would cover the rule instead, having inked its last cell up to the boundary already, and the hidden style would rub a cell of the rule out.
func (*Settings) DesktopBackgroundResolved ¶ added in v0.8.0
DesktopBackgroundResolved is the background behind and between panes.
func (*Settings) DockBackgroundResolved ¶ added in v0.8.0
DockBackgroundResolved is the background under the dock.
func (*Settings) DockHeight ¶ added in v0.9.0
DockHeight is the rows the dock takes when it is shown: one with appearance.dock_compact, two without. It does not look at DockbarPosition, so a caller that has to treat a hidden dock as no rows checks that itself.
func (*Settings) FormatWindowTitle ¶ added in v0.8.0
FormatWindowTitle expands WindowTitleFormat for one window. The placeholders are {title} (the custom or terminal-reported title), {index} (the window's 1-based position in its workspace, the same number the leader-digit shortcuts use) and {cwd} (the shell's working directory, empty where it cannot be read).
An empty format returns the title unchanged, which is what keeps the default rendering free of any formatting work.
func (*Settings) FormatWorkspaceTab ¶ added in v0.8.0
FormatWorkspaceTab renders a dock workspace tab label from the configured DockWorkspaceTabFormat. Placeholders are {index} (the workspace number) and {name} (the workspace's name, or its number when unnamed). An empty format returns the name unchanged, which is the historic rendering.
func (*Settings) GetAnimationDuration ¶ added in v0.8.0
GetAnimationDuration returns the animation duration for standard operations. Returns 0 when the motion level is none or animations are suppressed, so the transition is instant.
func (*Settings) GetBorderForStyle ¶ added in v0.8.0
GetBorderForStyle returns the lipgloss Border for the current style
func (*Settings) GetClockFormat ¶ added in v0.8.0
GetClockFormat returns the layout in effect.
func (*Settings) GetDockIconCloseSession ¶ added in v0.8.0
GetDockIconCloseSession returns the close-session icon for the current glyph set.
func (*Settings) GetDockIconLeaveRunning ¶ added in v0.8.0
GetDockIconLeaveRunning returns the leave-running icon for the current glyph set.
func (*Settings) GetDockModeCapLeft ¶ added in v0.8.0
GetDockModeCapLeft returns the mode chip's left cap, empty when the dock's pills are flat.
The mode chip, the workspace tabs and the minimized run all follow DockPillCaps. The chip and the tabs once capped regardless of it, so dock_pill_caps = false left the caps on the two pills a user sees most (#451) while the settings page reported them off.
func (*Settings) GetDockModeCapRight ¶ added in v0.8.0
GetDockModeCapRight returns the mode chip's right cap, empty when the dock's pills are flat.
func (*Settings) GetDockModeIconTerminal ¶ added in v0.8.0
GetDockModeIconTerminal returns the terminal mode icon: appearance.dock_mode_icon_terminal when set, and otherwise the built-in for the glyph set.
func (*Settings) GetDockModeIconTiling ¶ added in v0.8.0
GetDockModeIconTiling returns the tiling mode icon: appearance.dock_mode_icon_tiling when set, and otherwise the built-in for the glyph set.
func (*Settings) GetDockModeIconWindow ¶ added in v0.8.0
GetDockModeIconWindow returns the window mode icon: appearance.dock_mode_icon_window when set, and otherwise the built-in for the glyph set.
func (*Settings) GetDockPillLeftChar ¶ added in v0.8.0
GetDockPillLeftChar returns the pill's left cap, empty when pills are flat.
func (*Settings) GetDockPillRightChar ¶ added in v0.8.0
GetDockPillRightChar returns the pill's right cap, empty when pills are flat.
func (*Settings) GetDockSeparator ¶ added in v0.8.0
GetDockSeparator returns the appropriate separator based on UseASCIIOnly
func (*Settings) GetDockWorkspaceCapLeft ¶ added in v0.8.0
GetDockWorkspaceCapLeft returns the workspace pill's left cap, empty when the dock's pills are flat.
Empty under ASCII too. A half circle has no 7-bit stand-in: "[" is a bracket drawn beside the pill rather than the pill's own edge, and it reads as punctuation in a row that has none.
func (*Settings) GetDockWorkspaceCapRight ¶ added in v0.8.0
GetDockWorkspaceCapRight returns the workspace pill's right cap, empty when the dock's pills are flat.
func (*Settings) GetDockWorkspaceMoreLeft ¶ added in v0.8.0
GetDockWorkspaceMoreLeft returns the strip's left overflow arrow.
func (*Settings) GetDockWorkspaceMoreRight ¶ added in v0.8.0
GetDockWorkspaceMoreRight returns the strip's right overflow arrow.
func (*Settings) GetFastAnimationDuration ¶ added in v0.8.0
GetFastAnimationDuration returns the animation duration for fast operations. Returns 0 when the motion level is none or animations are suppressed, so the transition is instant.
func (*Settings) GetNotificationCap ¶ added in v0.8.0
GetNotificationCap returns the weighted cap for a severity, or the ASCII fallback when Nerd Fonts are off.
func (*Settings) GetNotificationRule ¶ added in v0.8.0
GetNotificationRule returns the burn stroke for the dock's hairline, matching the separator character the rest of the row is drawn with when Nerd Fonts are off so the lit run and the unlit run stay the same shape.
func (*Settings) GetRailAddGlyph ¶ added in v0.8.0
GetRailAddGlyph is the new-session and new-window control.
func (*Settings) GetRailAttentionMark ¶ added in v0.8.0
GetRailAttentionMark is the gutter mark saying "this one wants a human".
func (*Settings) GetRailBullet ¶ added in v0.8.0
GetRailBullet is the quiet mark a resting row carries.
func (*Settings) GetRailCollapseGlyph ¶ added in v0.8.0
GetRailCollapseGlyph is the arrow that folds the rail down to its strip.
Two cells in ASCII, where "«" has no one-cell stand-in: a lone "<" in the footer of a column of one-cell marks reads as one more mark rather than as a control. The rail measures its own footer, so unlike a window button this role is not held to a width.
func (*Settings) GetRailExpandGlyph ¶ added in v0.8.0
GetRailExpandGlyph is the arrow that opens it again.
func (*Settings) GetRailFileGlyph ¶ added in v0.8.0
GetRailFileGlyph is the mark on a plain file row.
func (*Settings) GetRailFocusMark ¶ added in v0.8.0
GetRailFocusMark is the one-cell gutter mark saying "you are here".
func (*Settings) GetRailFoldOpenGlyph ¶ added in v0.8.0
GetRailFoldOpenGlyph is the mark on a group header whose rows are on screen under it, and GetRailFoldShutGlyph the mark on one that is folded shut. The rail draws them on a machine's row in the sessions section. One cell each, so the header's name lands on the same spine every other row's does.
A pointing triangle in both modes rather than a machine icon: the one thing the mark has to say is that the row folds, and which way it is folded now. The ASCII pair is "v" and ">", the shape the same arrows take in every seven-bit tree.
func (*Settings) GetRailFoldShutGlyph ¶ added in v0.8.0
GetRailFoldShutGlyph is the mark on a group header that is folded shut.
func (*Settings) GetRailFolderGlyph ¶ added in v0.8.0
GetRailFolderGlyph is the mark on a directory row.
func (*Settings) GetRailParentGlyph ¶ added in v0.8.0
GetRailParentGlyph is the mark on the ".." row. Distinct from the folder mark because ".." is the one row that moves the listing out rather than in, and a listing where every row wore the same mark gave the user nothing to aim at.
func (*Settings) GetRailRuleGlyph ¶ added in v0.8.0
GetRailRuleGlyph is the rule that runs out of a group heading to the rail's right spine. One cell, repeated.
The rule, not weight or the brightest ink, tells the heading from the rows under it. Emphasis there would put the loudest treatment on the least actionable row, above the session names you actually act on. The rule is structure rather than emphasis, so it holds with colour switched off. It shares the "rule" role with the window separator rather than taking a role of its own: both are a hairline made of one repeated cell, and a set that restyles one has said what it wants the other to be.
func (*Settings) GetRailTreeBranch ¶ added in v0.8.0
GetRailTreeBranch is the mark in front of a grouped row that has a sibling below it, and GetRailTreeLast is the mark on the row that closes the group. The rail draws them in front of the name of every worktree session under its repository, which is what says the rows belong to the row above them.
Three cells each, the trailing space included, so a grouped name starts on the same column whichever mark it wears.
func (*Settings) GetRailTreeLast ¶ added in v0.8.0
GetRailTreeLast is the mark on the last row of a group.
func (*Settings) GetScrollColumnMax ¶ added in v0.8.0
GetScrollColumnMax is the highest a scrolling column's width may be set to, as a percent of the screen.
A value outside the allowed range, including the zero a Settings built by hand carries, reads as the default ceiling. Nothing that clamps a width may read the constant directly, or the setting would be ignored on whichever path forgot.
func (*Settings) GetScrollbarThumbChar ¶ added in v0.8.0
GetScrollbarThumbChar returns the glyph the thumb is drawn with: the configured one when it is usable, else the active style's default.
func (*Settings) GetScrollbarTrackChar ¶ added in v0.8.0
GetScrollbarTrackChar returns the glyph drawn on the track's uncovered cells. An empty string is a blank cell, which in the track style is its surface fill and in the thin style is no track at all. That is also what ASCII gets since it has no hairline to draw one with.
func (*Settings) GetSidebarPillLeftChar ¶ added in v0.8.0
GetSidebarPillLeftChar returns the rail's left pill cap. The rail keeps its own accessor so the dock's flat/capped setting cannot reshape its rows.
func (*Settings) GetSidebarPillRightChar ¶ added in v0.8.0
GetSidebarPillRightChar returns the rail's right pill cap.
func (*Settings) GetWindowBorderBottom ¶ added in v0.8.0
GetWindowBorderBottom returns the appropriate bottom border character
func (*Settings) GetWindowBorderBottomLeft ¶ added in v0.8.0
GetWindowBorderBottomLeft returns the appropriate bottom-left border character
func (*Settings) GetWindowBorderBottomRight ¶ added in v0.8.0
GetWindowBorderBottomRight returns the appropriate bottom-right border character
func (*Settings) GetWindowBorderLeft ¶ added in v0.8.0
GetWindowBorderLeft returns the appropriate left border character
func (*Settings) GetWindowBorderTop ¶ added in v0.8.0
GetWindowBorderTop returns the appropriate top border character
func (*Settings) GetWindowBorderTopLeft ¶ added in v0.8.0
GetWindowBorderTopLeft returns the appropriate top-left border character
func (*Settings) GetWindowBorderTopRight ¶ added in v0.8.0
GetWindowBorderTopRight returns the appropriate top-right border character
func (*Settings) GetWindowButtonCloseMark ¶ added in v0.8.0
GetWindowButtonCloseMark returns the one-cell close mark.
func (*Settings) GetWindowButtonDot ¶ added in v0.8.0
GetWindowButtonDot returns the appropriate dots-style disc character
func (*Settings) GetWindowButtonMaximizeMark ¶ added in v0.8.0
GetWindowButtonMaximizeMark returns the one-cell maximize mark.
func (*Settings) GetWindowButtonMinimizeMark ¶ added in v0.8.0
GetWindowButtonMinimizeMark returns the one-cell minimize mark. It has no separate ASCII form because the mark is already 7-bit, so --ascii-only needs nothing different here.
func (*Settings) GetWindowPillLeft ¶ added in v0.8.0
GetWindowPillLeft returns the appropriate pill left character
func (*Settings) GetWindowPillRight ¶ added in v0.8.0
GetWindowPillRight returns the appropriate pill right character
func (*Settings) GetWindowSeparatorChar ¶ added in v0.8.0
GetWindowSeparatorChar returns the appropriate separator character
func (*Settings) GetZoomSize ¶ added in v0.8.0
GetZoomSize is the zoom box's size as a percent of the content region.
A value outside the range, including the zero a Settings built by hand carries, reads as the default. Nothing that computes the box may read the field directly, or a hand-built model would zoom to half a screen.
func (*Settings) GlyphsForSet ¶ added in v0.8.0
GlyphsForSet is what a set would draw if it were selected, without selecting it.
Answered by borrowing the selection, reading through the same accessors the renderer calls, and putting it back. That is the honest answer and the only one that cannot drift from what a frame would actually show: a preview built by reading the set's own fields would report the roles it names and say nothing about the built-ins underneath, which is most of what a person sees.
The borrow is process-local state that no frame is composed from while it is held, so a caller on the render goroutine is safe. It is still not free, so callers building a list of previews should do it once rather than per frame.
func (*Settings) MasterRatioFraction ¶ added in v0.8.0
MasterRatioFraction is the configured master ratio as the fraction the tilers take. One conversion in one place, so a percentage in the file and a fraction in the layout cannot drift apart.
func (*Settings) MotionAllows ¶ added in v0.8.0
MotionAllows reports whether motion of the given level may run now: the configured level reaches it and nothing has suppressed animations for the moment (a remote command in flight, a tape being played).
func (*Settings) NerdFontsOff ¶ added in v0.8.0
NerdFontsOff reports whether Nerd Font icons must not be drawn: under ASCII mode, and on a terminal whose font has none (GlyphEnvUnicode).
func (*Settings) PaneBackgroundResolved ¶ added in v0.8.0
PaneBackgroundResolved is the background behind pane content.
func (*Settings) ResolvedGlyphs ¶ added in v0.8.0
ResolvedGlyphs reports what is actually drawn for every role: the active set's glyph where it names one, and the built-in beneath it where it does not.
It exists because a set says only what it changes, which is the right shape for a file a person writes and the wrong answer to "what will this look like". The describe verb reports this rather than the set's own fields, so a caller ricing over the protocol sees the frame it is going to get.
func (*Settings) ScrollbarTintHex ¶ added in v0.8.0
ScrollbarTintHex returns the configured tint when it is a colour literal rather than a keyword. A malformed one is not a colour, so it is refused here as well as warned about at load: a bar drawn in nothing is invisible.
func (*Settings) ScrollbarTintResolved ¶ added in v0.8.0
ScrollbarTintResolved is the keyword the tint is behaving as, with unset resolved to the documented default.
Unset used to reach the renderer as the empty string and match none of its cases, so it fell through to the border rule: clearing the tint gave the one tint that is not the default. The registry, the validator and the config header all say empty means quiet, and now so does the bar.
func (*Settings) SetAnimationsOn ¶ added in v0.8.0
SetAnimationsOn is the on/off switch over the levels: off is none, and on is full, the level tuios ships with. A caller that wants basic sets Motion.
func (*Settings) SidebarBackgroundResolved ¶ added in v0.8.0
SidebarBackgroundResolved is the background under the rail.
func (*Settings) WindowChromeBackgroundResolved ¶ added in v0.8.0
WindowChromeBackgroundResolved is the background under pane borders and title bars.
type SidebarAgentRowSpec ¶ added in v0.8.0
type SidebarAgentRowSpec struct {
Tokens []string
Styles map[string]SidebarTokenStyle
// Problems is one line per value the reader dropped, for the validator.
Problems []string
// Fingerprint changes whenever the drawn result could, for a render cache
// to key on.
Fingerprint string
}
SidebarAgentRowSpec is the parsed table: the tokens in order and a style per token, plus what the reader could not use.
func DefaultSidebarAgentRow ¶ added in v0.8.0
func DefaultSidebarAgentRow() SidebarAgentRowSpec
DefaultSidebarAgentRow is the row as it ships.
func ParseSidebarAgentRow ¶ added in v0.8.0
func ParseSidebarAgentRow(table map[string]any) SidebarAgentRowSpec
ParseSidebarAgentRow reads the generic table. A nil or empty table is the shipped row.
func (*SidebarAgentRowSpec) Custom ¶ added in v0.8.0
func (s *SidebarAgentRowSpec) Custom() bool
Custom reports whether the table changed anything from the shipped row.
func (*SidebarAgentRowSpec) Has ¶ added in v0.8.0
func (s *SidebarAgentRowSpec) Has(token string) bool
Has reports whether the row carries a token at all.
func (*SidebarAgentRowSpec) RuleCount ¶ added in v0.8.0
func (s *SidebarAgentRowSpec) RuleCount() int
RuleCount is how many rules the table carries over every token.
func (*SidebarAgentRowSpec) Style ¶ added in v0.8.0
func (s *SidebarAgentRowSpec) Style(token string) SidebarTokenStyle
Style is the token's style, empty for a token the table does not mention.
type SidebarConfig ¶ added in v0.8.0
type SidebarConfig struct {
Enabled *bool `toml:"enabled"` // Show the rail (default: true)
Position string `toml:"position"` // Edge: left, right, hidden (default: right)
Width int `toml:"width"` // Preferred width in columns for a wide screen (default: 24)
ShowWindows *bool `toml:"show_windows"` // The terminals section (default: true)
ShowGlyphs *bool `toml:"show_glyphs"` // Agent-state glyph on each row (default: true)
ShowCounts *bool `toml:"show_counts"` // Window count on each session row (default: true)
ShowNumbers *bool `toml:"show_numbers"` // Switch number ahead of each session name (default: false)
ShowAgents *bool `toml:"show_agents"` // Agents section at the rail's bottom (default: true)
// Workspaces named the workspace chip band, which the rail no longer draws:
// panes say which workspace they are on with a tag of their own, and
// switching stays on the dock and alt+1..9. Still parsed so an existing
// config file loads unchanged; validation warns once and nothing reads it.
Workspaces string `toml:"workspaces"`
Marquee *bool `toml:"marquee"` // Scroll a hovered row's overflowing title (default: true)
Tooltips *bool `toml:"tooltips"` // Label the collapsed strip on hover (default: true)
// Sections is the rail's layout: which sections it stacks, in what order,
// and the share of it each may claim. See SidebarDefaultSections.
Sections string `toml:"sections"`
// FileIcons draws a nerd font icon per file type in the files section
// (default: true).
FileIcons *bool `toml:"file_icons"`
// FileIconColors draws each of those icons in its file type's own colour
// (default: true).
FileIconColors *bool `toml:"file_icon_colors"`
// FolderClick is what a click on a folder row does: navigate, cd or both
// (default: navigate).
FolderClick string `toml:"folder_click"`
// Editor is the terminal editor command for files (default: $EDITOR,
// $VISUAL or vi).
Editor string `toml:"editor"`
// FileActions lets the files section create, rename, delete, copy, cut and
// paste (default: true).
FileActions *bool `toml:"file_actions"`
// FileDelete is where a delete sends the file: trash or permanent
// (default: trash).
FileDelete string `toml:"file_delete"`
// Background is the ground painted under the rail: off, theme or
// #RRGGBB, and empty follows appearance.background (default: empty).
Background string `toml:"background"`
// AgentRow is the [appearance.sidebar.agent_row] table: the tokens an
// agent row draws and the value rules that colour them. Decoded as generic
// TOML and read by ParseSidebarAgentRow, so a wrong value in it is a
// warning rather than a config file that will not load.
AgentRow map[string]any `toml:"agent_row"`
// AgentRestFold is how long an agent row rests before the rail folds it
// into one line: a duration, or off (default: 1h).
AgentRestFold string `toml:"agent_rest_fold"`
// Custom is the [appearance.sidebar.custom] table: the command whose
// output the custom section draws, its heading, and when it runs. Read
// from the file only; see SidebarCustomConfig for why.
Custom SidebarCustomConfig `toml:"custom"`
}
SidebarConfig holds the [appearance.sidebar] table: everything about the vertical session rail. Each toggle is a pointer so nil can mean "unset, use the default" and an explicit false survives a reload.
type SidebarCustomConfig ¶ added in v0.9.0
type SidebarCustomConfig struct {
// Title is the section's heading. Empty means SidebarCustomDefaultTitle.
Title string `toml:"title,omitempty"`
// Command is run through sh -c. Each line of its stdout is a row.
Command string `toml:"command,omitempty"`
// Refresh is when to run it: "once" (the default), a duration such as
// "30s", or "event:TYPE[,TYPE]". "push" is refused.
Refresh string `toml:"refresh,omitempty"`
}
SidebarCustomConfig is [appearance.sidebar.custom].
It stays out of the option registry on purpose, so set-option and set-config cannot set the command. The command runs outside every pane on every refresh, as dock commands and hooks do, and in the default open mode any pane can call set-option. The section's place in the layout stays settable; only what it runs is not. daemon.respond_from_shell is kept out of the registry for the same reason.
func (SidebarCustomConfig) HasCommand ¶ added in v0.9.0
func (c SidebarCustomConfig) HasCommand() bool
HasCommand reports whether the table names a command to run.
func (SidebarCustomConfig) ResolvedTitle ¶ added in v0.9.0
func (c SidebarCustomConfig) ResolvedTitle() string
ResolvedTitle is the heading the section draws.
type SidebarSectionShare ¶ added in v0.8.0
type SidebarSectionShare struct {
// zero for a flexible section that takes what the others leave.
Share int
}
SidebarSectionShare is one entry of the layout: a section, and the share of the rail it may claim.
func ParseSidebarSections ¶ added in v0.8.0
func ParseSidebarSections(source string) []SidebarSectionShare
ParseSidebarSections reads "name:percent,name,..." into a layout.
It is forgiving on purpose: an unknown name, a percent that is not a number and a repeated section name are all dropped rather than refused, because the rail draws from this on every frame and a rail that refuses to lay itself out is worse than one that lays itself out slightly differently from what was typed. SidebarSectionProblems is where a person is told what was wrong. A string with no section in it falls back to the shipped layout, since a rail of nothing but empty blocks is not a state anybody meant to ask for.
The spacer is the exception to the repeat rule. It names a place rather than a section, so a layout may carry as many as it likes and each one is its own entry in the result.
func (SidebarSectionShare) IsSpacer ¶ added in v0.8.0
func (s SidebarSectionShare) IsSpacer() bool
IsSpacer reports whether this entry is the layout's empty block rather than one of the rail's sections.
func (SidebarSectionShare) String ¶ added in v0.8.0
func (s SidebarSectionShare) String() string
String writes one entry back in the grammar it was read from.
type SidebarTokenLook ¶ added in v0.8.0
SidebarTokenLook is what a token or a rule says about ink: a colour name or hex, and bold and dim as three-state so an absent key leaves the rail's own choice alone and an explicit false turns the rail's bold off.
func (SidebarTokenLook) Overlay ¶ added in v0.8.0
func (l SidebarTokenLook) Overlay(over SidebarTokenLook) SidebarTokenLook
Overlay is this look with another's set fields written over it.
func (SidebarTokenLook) Set ¶ added in v0.8.0
func (l SidebarTokenLook) Set() bool
Set reports whether the look says anything at all.
type SidebarTokenRule ¶ added in v0.8.0
type SidebarTokenRule struct {
Test string
Text string
Number float64
IgnoreCase bool
Look SidebarTokenLook
}
SidebarTokenRule is one value rule: a test, its operand, and the look a match earns.
func (SidebarTokenRule) Matches ¶ added in v0.8.0
func (r SidebarTokenRule) Matches(text string, number float64, hasNumber bool) bool
Matches applies the rule to a token's drawn text and, for the numeric tests, its number. hasNumber is false for a token that is not a number, and such a token matches no numeric rule.
type SidebarTokenStyle ¶ added in v0.8.0
type SidebarTokenStyle struct {
Base SidebarTokenLook
Rules []SidebarTokenRule
}
SidebarTokenStyle is one token's base look and its ordered rules.
func (SidebarTokenStyle) Resolve ¶ added in v0.8.0
func (s SidebarTokenStyle) Resolve(text string, number float64, hasNumber bool) SidebarTokenLook
Resolve is the look a token with this text and number gets: the base, with the first matching rule's look written over it.
type SpotlightConfig ¶ added in v0.8.0
type SpotlightConfig struct {
Enabled *bool `toml:"enabled"` // draw the beam from startup (default: false)
Follow string `toml:"follow"` // what the beam is anchored to (default: mouse)
Radius int `toml:"radius"` // half the beam's height, in rows (default: 10)
Dim int `toml:"dim"` // percent of its light an unlit cell loses (default: 75)
Edge string `toml:"edge"` // hard cut or soft rim (default: hard)
Shake bool `toml:"shake"` // a shake of the pointer toggles the beam (default: false)
}
SpotlightConfig is the [spotlight] section: a beam that lights one part of the screen and turns the light down on everything outside it.
It is a presentation aid, not a mode. Nothing about it is session state: a second client attached to the same session sees its own screen unchanged, the same way it does for the showkeys overlay and the theme. What lives here is the shape of the beam and where it follows, so a person who wants it can keep it across restarts.
Enabled is a pointer so that turning the beam off in the settings page survives a reload rather than reading as "unset" and snapping back on.
func (SpotlightConfig) DimPercent ¶ added in v0.8.0
func (s SpotlightConfig) DimPercent() int
DimPercent is the percent of its light an unlit cell loses.
func (SpotlightConfig) EdgeStyle ¶ added in v0.8.0
func (s SpotlightConfig) EdgeStyle() string
EdgeStyle is the rim style, defaulting to hard.
func (SpotlightConfig) FollowMode ¶ added in v0.8.0
func (s SpotlightConfig) FollowMode() string
FollowMode is what the beam is anchored to, defaulting to the mouse.
func (SpotlightConfig) IsEnabled ¶ added in v0.8.0
func (s SpotlightConfig) IsEnabled() bool
IsEnabled reports whether the beam is drawn from startup.
func (SpotlightConfig) RadiusRows ¶ added in v0.8.0
func (s SpotlightConfig) RadiusRows() int
RadiusRows is the effective radius in rows.
func (SpotlightConfig) ShakeToggles ¶ added in v0.8.0
func (s SpotlightConfig) ShakeToggles() bool
ShakeToggles reports whether a shake of the pointer toggles the beam.
Off by default. The gesture is one a person can make by accident, and a screen that goes dark for a reason nobody typed is worse than a gesture nobody has. A person who wants it turns it on and knows what it does.
type StartupConfig ¶ added in v0.8.0
type StartupConfig struct {
OpenDefaultWindow bool `toml:"open_default_window"` // Open one terminal window automatically when a session starts with none (default: false)
Tiled bool `toml:"tiled"` // Start a new session with tiling enabled instead of floating (default: true)
StartInTerminalMode bool `toml:"start_in_terminal_mode"` // Start focused in terminal mode so typing goes straight to the shell, when a window is present (default: false)
// Layout is the tiling scheme a new session arranges its panes with: bsp,
// master-stack or scrolling. It only ever decides where a session starts.
// Once one is running the scheme is the session's own and travels in its
// state, so attaching to a session laid out one way never re-arranges it to
// match the config of whoever attached.
Layout string `toml:"layout"`
// Daemon makes a bare "tuios" attach to a daemon-backed session instead of
// running a standalone one, so a session survives the terminal window it was
// started in without anybody typing "tuios attach" (default: true).
//
// It changes bare "tuios" and nothing else: every subcommand already says
// which it wants, and a session already running is a separate process this
// cannot reach. TUIOS_NO_DAEMON=1 and --standalone both override it, and a
// bare "tuios" whose daemon will not start runs standalone for that one run
// and says so, so this never leaves the user without a terminal.
Daemon bool `toml:"daemon"`
}
StartupConfig holds settings that only take effect when a session starts.
Tiled and Daemon ship on: a fresh install comes up tiled, in a daemon-backed session, on an empty screen the user opens the first window on. The two are booleans with no fill-missing pass, so a config file that does not name them reads them as false and an existing install keeps the floating, standalone session it already had.
type Swallow ¶ added in v0.8.0
type Swallow struct {
Key string `json:"key"`
Action string `json:"action"`
Desc string `json:"description"`
// Origin says where the claim comes from: a config section, or "built-in"
// for the keys the input path spells literally.
Origin string `json:"origin"`
}
Swallow is one key terminal mode takes before the pane's program can see it.
type TailscaleConfig ¶ added in v0.8.0
type TailscaleConfig struct {
// Enabled offers tailnet machines as addresses. Default true: the list is
// read from the tailscaled already running on this machine, costs one
// local call, and is empty on a machine that is not on a tailnet.
Enabled *bool `toml:"enabled,omitempty"`
// Addr is which form of address to offer: "dns" for the MagicDNS name,
// "name" for the short name, "ip" for the 100.x address. Default "dns",
// which is the form that works without depending on a search domain.
Addr string `toml:"addr,omitempty"`
// User is an ssh login put in front of every address, so a candidate reads
// ubuntu@box.example.ts.net. Empty offers the address alone.
User string `toml:"user,omitempty"`
// Users are per-machine logins keyed by the machine's short name, for a
// tailnet where the login differs from box to box. A machine named here
// wins over User.
//
// [tailscale.users]
// build = "ubuntu"
Users map[string]string `toml:"users,omitempty"`
// OS are the operating systems to offer. Default is the ones that can run
// a tuios daemon, which is what keeps a phone out of the list. An empty
// list offers every machine.
OS []string `toml:"os,omitempty"`
// Offline offers machines the control plane says are not connected.
// Default false.
Offline bool `toml:"offline,omitempty"`
// Self offers this machine. Default false: `local` already means the
// daemon you are talking to, and the host table refuses an entry for it.
Self bool `toml:"self,omitempty"`
// false.
Shared bool `toml:"shared,omitempty"`
// Include and Exclude are glob patterns matched against both the short
// name and the MagicDNS name. Exclude wins over Include, and an empty
// Include means everything.
Include []string `toml:"include,omitempty"`
Exclude []string `toml:"exclude,omitempty"`
// Max bounds the offered list. Zero uses the built-in default.
Max int `toml:"max,omitempty"`
// Socket overrides the path to the tailscaled local API socket, for a
// machine where it is not in the usual place. Empty finds it the way the
// tailscale command does.
Socket string `toml:"socket,omitempty"`
}
TailscaleConfig is the [tailscale] table.
func TailscaleInFile ¶ added in v0.8.0
func TailscaleInFile(path string) (TailscaleConfig, error)
TailscaleInFile is the [tailscale] table in the file at path, read without creating anything.
It exists alongside HostsInFile rather than going through LoadUserConfig for the reason that one does: LoadUserConfig writes a default config file when there is none, and a reader asking what the table says must not create a file as a side effect of asking. A caller on a background goroutine makes that a race as well as a surprise.
func (TailscaleConfig) TailnetOptions ¶ added in v0.8.0
func (t TailscaleConfig) TailnetOptions() federation.TailnetOptions
TailnetOptions turns the table into what internal/federation asks for.
A field the user did not set keeps the built-in default rather than reading as "off", which is why this starts from DefaultTailnetOptions instead of building an empty struct.
func (TailscaleConfig) TailscaleEnabled ¶ added in v0.8.0
func (t TailscaleConfig) TailscaleEnabled() bool
TailscaleEnabled reports whether tailnet machines are offered. Absent means yes: the call is local and cheap, and it answers nothing on a machine with no tailscale.
type TapeConfig ¶ added in v0.8.0
type TapeConfig struct {
Autorun string `toml:"autorun"` // off | ask | auto (default: ask)
AutoReview bool `toml:"auto_review"` // auto-open the review dialog on detection (default: false)
}
TapeConfig holds settings for per-directory project tapes (.tuios.tape).
Autorun is the master switch for detecting a project tape when the focused window's shell enters a directory that carries one:
- "off": no detection, no indicator, the feature is invisible.
- "ask": detection on; an encountered tape surfaces a passive indicator (a dock badge and a non-focus-stealing notification) showing its trust status. Nothing runs without the user's explicit action.
- "auto": a trusted, unedited tape runs automatically on entry; an untrusted or changed tape falls back to the "ask" behavior and never auto-runs.
In "ask" the passive indicator plus the review dialog (leader T t, or the command palette) are the only path to running a tape; nothing executes without the user opening the dialog and choosing Run. "auto" is the only mode that runs anything without a keypress, and only content the user already read and trusted. The default is "ask", which is safe by construction. A tape edited since it was trusted reverts to untrusted (hash mismatch) and re-prompts.
AutoReview (default false) is an opt-in convenience: when true, entering a directory with a reviewable tape opens the review/trust dialog automatically instead of only surfacing the passive banner and badge, saving the keypress that opens it. It never weakens the trust boundary: the user still chooses Run once / Trust and run / Never / Not now, and it never auto-opens for a denied tape, an already-handled directory this session, or (in auto mode) a trusted-unedited tape that runs on its own.
type UserConfig ¶ added in v0.0.23
type UserConfig struct {
Appearance AppearanceConfig `toml:"appearance"`
Notifications NotificationsConfig `toml:"notifications"`
Keybindings KeybindingsConfig `toml:"keybindings"`
Daemon DaemonConfig `toml:"daemon"`
Startup StartupConfig `toml:"startup"`
Tape TapeConfig `toml:"tape"`
Hooks HooksConfig `toml:"hooks"`
Debug DebugConfig `toml:"debug"`
// Screenshot is the [screenshot] table: how a capture renders and where
// the file lands. See screenshot.go.
Screenshot ScreenshotConfig `toml:"screenshot"`
// Screensaver is the [screensaver] table: whether the screen animates
// itself after a spell of quiet, and with what. See screensaver.go.
Screensaver ScreensaverConfig `toml:"screensaver"`
// Spotlight is the [spotlight] table: the beam that lights one part of the
// screen and dims the rest. Client-local appearance, like the theme. See
// spotlight.go.
Spotlight SpotlightConfig `toml:"spotlight"`
// Hints is the [hints] table: what hints mode labels on a pane. See
// hints.go.
Hints HintsConfig `toml:"hints"`
// Panes is the [panes] table: the keys display_panes labels the panes
// with. See panes.go.
Panes PanesConfig `toml:"panes"`
// Scratch is the [scratch] table: the size of the scratch terminal that
// toggle_scratch shows in a popup. See scratch.go.
Scratch ScratchConfig `toml:"scratch"`
// PiP is the [pip] table: the size and corner of the picture-in-picture
// view that toggle_pip pins. Client-local, like the spotlight. See pip.go.
PiP PiPConfig `toml:"pip"`
// Launcher is the [launcher] table: how the app launcher starts a
// graphical program. See launcher.go.
Launcher LauncherConfig `toml:"launcher"`
// Workspaces is the [workspaces] table: what happens when the workspace
// on screen loses its last pane. See workspaces.go.
Workspaces WorkspacesConfig `toml:"workspaces"`
// PasteBuffers is the [paste_buffers] table: how many yanks tuios keeps
// to paste again. See paste_buffers.go.
PasteBuffers PasteBuffersConfig `toml:"paste_buffers"`
// YieldedDefaults are the new default bindings left off because the key
// was already the user's for another action in the same table. It is
// worked out on load and never written. See yieldingDefaults.
YieldedDefaults []YieldedDefault `toml:"-"`
// LoadWarnings say what the load of a config split over several files
// skipped: an included file that is not there, or an include cycle. It is
// worked out on load and never written. See include.go.
LoadWarnings []string `toml:"-"`
// DroppedKeys are the keys the load took out because tuios cannot read
// them. Worked out on load and never written. See DropUnreadableKeys.
DroppedKeys []DroppedKey `toml:"-"`
// Dock is the [dock] table: the bar as ordered lists of named components.
// It sits outside the option registry for the same reason [hooks] and
// [keybindings] do, being file-plane config rather than a settable option.
Dock DockConfig `toml:"dock"`
// Hosts is the [hosts.NAME] set: the other machines this daemon may ask for
// listings. Outside the option registry for the same reason as the tables
// above. See hosts.go.
Hosts map[string]HostConfig `toml:"hosts,omitempty"`
// Tailscale is the [tailscale] table: which machines on your tailnet are
// offered as addresses when adding a host. It changes suggestions only;
// nothing is added on its own. See tailscale.go.
Tailscale TailscaleConfig `toml:"tailscale,omitempty"`
// Agents is the [agents] table: how tuios treats the coding agents in its
// panes. Outside the option registry for the same reason as the tables
// above. See agents.go.
Agents AgentsConfig `toml:"agents,omitempty"`
// Notify is the [notify] table: push notifications for the Inbox, sent
// by the daemon. Outside the option registry for the same reason as
// [hosts]. See notify.go.
Notify NotifyConfig `toml:"notify,omitempty"`
// Plugins is the [plugins] table: the herdr plugins tuios runs. Outside
// the option registry for the same reason as [hosts]. See plugins.go.
Plugins PluginsConfig `toml:"plugins,omitempty"`
// contains filtered or unexported fields
}
UserConfig represents the user's custom configuration
func DefaultConfig ¶ added in v0.0.23
func DefaultConfig() *UserConfig
DefaultConfig returns the default configuration
func LoadUserConfig ¶ added in v0.0.23
func LoadUserConfig() (*UserConfig, error)
LoadUserConfig loads the user configuration from XDG config directory
func ParseUserConfig ¶ added in v0.8.0
func ParseUserConfig(data []byte) (*UserConfig, error)
ParseUserConfig turns the bytes of a config file into a config with every missing section filled from the defaults. It does not validate.
It is one function rather than a list of calls at each call site because the list is the part that goes wrong. A caller that fills only some sections gets back, for example, an empty [spotlight], [tape], [screenshot] and [screensaver], and a beam whose radius reads as zero.
func ReloadConfig ¶ added in v0.8.0
func ReloadConfig(path string) (*UserConfig, error)
ReloadConfig loads and validates a config from the given path, with every file it includes.
type ValidationError ¶ added in v0.0.23
ValidationError represents a validation error or warning
type ValidationResult ¶ added in v0.0.23
type ValidationResult struct {
Errors []ValidationError
Warnings []ValidationError
}
ValidationResult contains all validation errors and warnings
func ValidateConfig ¶ added in v0.0.23
func ValidateConfig(cfg *UserConfig) *ValidationResult
ValidateConfig validates the user configuration
func (*ValidationResult) HasErrors ¶ added in v0.0.23
func (vr *ValidationResult) HasErrors() bool
HasErrors returns true if there are any errors
type Watcher ¶ added in v0.8.0
type Watcher struct {
// contains filtered or unexported fields
}
Watcher watches the config file for changes and triggers reloads. A config split over several files is watched as a whole: every included file, every file in config.d, and config.d itself, so a drop-in file added or removed is a change too.
func NewWatcher ¶ added in v0.8.0
func NewWatcher(configPath string, callback ConfigReloadCallback) (*Watcher, error)
NewWatcher creates a file watcher for the config file. The callback is called with the new config (or error) when changes are detected.
func NewWatcherWithOptions ¶ added in v0.8.0
func NewWatcherWithOptions(configPath string, callback ConfigReloadCallback, opts WatcherOptions) (*Watcher, error)
NewWatcherWithOptions is NewWatcher with the options set.
type WatcherOptions ¶ added in v0.8.0
type WatcherOptions struct {
// DeliverSelfWrites delivers a change tuios itself wrote, which is normally
// dropped (see the note above on why some saves are dropped).
//
// The daemon sets it. The settings page writes the config file from the
// client, and in a server that holds a daemon in the same process the two
// share the ring of hashes, so the daemon's watcher would call its own
// client's save a self write and never see the [hosts] table it changed.
// The daemon writes no config of its own, so it has nothing to suppress.
DeliverSelfWrites bool
// DeliverUnchanged delivers a change even when the file says what was
// last delivered. The daemon sets it: it can apply part of the file by
// another path (tuios config apply), so what it last saw here is not
// what is in force, and an edit and its undo inside one debounce must
// still reach it.
DeliverUnchanged bool
}
WatcherOptions tune one watcher.
type WebhookConfig ¶ added in v0.9.0
type WebhookConfig struct {
URL string `toml:"url"`
// The token, when set, goes in an Authorization: Bearer header.
Token Secret `toml:"token,omitempty"`
TokenEnv string `toml:"token_env,omitempty"`
TokenFile string `toml:"token_file,omitempty"`
}
WebhookConfig is [notify.webhook]: a JSON POST to an address of your own.
type WorkspacesConfig ¶ added in v0.9.0
type WorkspacesConfig struct {
// ReturnWhenEmpty switches the session back to the workspace the person
// came from when the workspace on screen loses its last pane, instead of
// leaving the splash screen up. A pointer so an explicit false in the
// file is told apart from a file that never mentions it (default: true).
ReturnWhenEmpty *bool `toml:"return_when_empty"`
// NewWindowWhenEmpty opens a window when the person switches to a
// workspace that has no panes, as the new-window key would. The window
// starts in the directory of the pane focused on the workspace they
// came from (default: false).
NewWindowWhenEmpty bool `toml:"new_window_when_empty"`
}
WorkspacesConfig is the [workspaces] section. The daemon reads return_when_empty: it owns the window set, so it is the side that sees a workspace lose its last pane. The client reads new_window_when_empty: it is the side that knows a switch came from the person and not from a command that brings its own panes.
func (WorkspacesConfig) ReturnsWhenEmpty ¶ added in v0.9.0
func (w WorkspacesConfig) ReturnsWhenEmpty() bool
ReturnsWhenEmpty reports whether return_when_empty is on. Unset means on.
type WriteNote ¶ added in v0.9.0
type WriteNote struct {
// Main is config.toml.
Main string
// Redirected are the changes that went to another file because the file
// that holds the key is read-only.
Redirected []Redirect
// Kept are read-only files that hold a key the save removed. The key is
// still there.
Kept []string
// Moved are the changes that went to config.toml because tuios could not
// change the lines of the file that holds the key without rewriting it.
Moved []Redirect
}
WriteNote says where a save put a change when that is not the file that holds the key. The zero value has nothing to say.
func SaveUserConfig ¶ added in v0.8.0
func SaveUserConfig(cfg *UserConfig) (WriteNote, error)
SaveUserConfig persists cfg to the user's config file at the standard XDG location, the same way the settings page does.
func SetHostInFile ¶ added in v0.8.0
func SetHostInFile(path, name string, h HostConfig) (WriteNote, error)
SetHostInFile writes the [hosts.NAME] table of the config whose main file is at path. A config split over several files is written where the host is: the file that sets [hosts.NAME], or for a new host the file that holds the other hosts, or config.toml. A read-only file is not written: the table goes to config.toml, and the WriteNote says so. It creates the file and its directory when neither exists.
Source Files
¶
- agent_alerts.go
- agents.go
- agents_work.go
- command_keys.go
- constants.go
- copy_mode_actions.go
- copy_pipe.go
- dock.go
- glyph_env.go
- glyphs.go
- hints.go
- hosts.go
- hosts_edit.go
- hostterm.go
- include.go
- include_write.go
- keybind_ambiguity.go
- keybind_descriptions.go
- keybind_guest.go
- keybind_report.go
- keybind_scopes.go
- keybind_unbind.go
- keybindings.go
- keynormalizer.go
- launcher.go
- link_policy.go
- mail_alerts.go
- motion.go
- notify.go
- options.go
- overrides.go
- pane_grants.go
- panes.go
- paste_buffers.go
- pip.go
- platform.go
- plugins.go
- prev080.go
- registry.go
- save.go
- scratch.go
- screensaver.go
- screenshot.go
- settings.go
- shell.go
- sidebar_agent_row.go
- sidebar_custom.go
- sidebar_sections.go
- spotlight.go
- startup.go
- tailscale.go
- toml_edit.go
- userconfig.go
- validation.go
- watcher.go
- whichkey_menu.go
- workspaces.go