Help us shape the future of Go! Take the 2026 Go Developer Survey

tmuxcc

package
v0.68.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 30, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package tmuxcc is a tmux control-mode (`tmux -C`) client: it attaches to one existing tmux session, models that session's windows, streams each window's decoded output, and drives tmux with ordinary commands. It owns no transport and no UI — an adapter subscribes to a client's event stream and renders it.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnavailable is returned on the server build, on unsupported platforms,
	// and when tmux is missing or older than 3.2.
	ErrUnavailable = errors.New("tmuxcc: control mode unavailable")
	// ErrInvalidSize is returned for out-of-bounds cols/rows.
	ErrInvalidSize = errors.New("tmuxcc: invalid terminal size")
	// ErrNotAttached is returned for a slug with no live client.
	ErrNotAttached = errors.New("tmuxcc: no client attached")
	// ErrUnknownWindow is returned for a window id absent from the window set.
	ErrUnknownWindow = errors.New("tmuxcc: unknown window")
	// ErrUnknownPane is returned for a pane id no tracked window owns.
	ErrUnknownPane = errors.New("tmuxcc: unknown pane")
	// ErrInvalidDirection is returned for a split or pane-selection direction
	// outside the vocabulary.
	ErrInvalidDirection = errors.New("tmuxcc: invalid direction")
	// ErrInvalidName is returned for a window name tmux could not carry.
	ErrInvalidName = errors.New("tmuxcc: invalid window name")
	// ErrInvalidPosition is returned for a move to a position outside the
	// session's window order.
	ErrInvalidPosition = errors.New("tmuxcc: invalid window position")
)
View Source
var ErrLaunchPending = errors.New("tmux session launch is in progress or was interrupted")

ErrLaunchPending identifies an allocated session that has not committed its launch.

View Source
var ErrSessionExists = errors.New("tmuxcc: session already exists")

ErrSessionExists reports a NewSession call for a name that already addresses a live tmux session. Unlike Attach, which is meant to reuse whatever is already there, a caller of NewSession is minting a session it expects to be new.

Functions

func ObserveFrameLatency

func ObserveFrameLatency(ctx context.Context, d time.Duration)

ObserveFrameLatency is exported because only the transport knows when a frame reached the wire.

func RunnerArgs

func RunnerArgs(args []string) []string

RunnerArgs keeps one-shot commands on an inherited custom tmux socket after RunnerEnviron removes the parent client's tmux variables.

func RunnerEnviron

func RunnerEnviron(environ func(context.Context) []string) func(context.Context) []string

RunnerEnviron adapts Desktop's resolved environment for one-shot tmux commands without exposing the parent client's tmux variables to child panes.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is one control-mode connection to one Hive session.

func Attach

func Attach(ctx, lifetime context.Context, opts Options) (*Client, error)

Attach spawns `tmux -C attach -t <slug>` over the process seam and runs the attach sequence: handshake, client size, window enumeration, then a capture-pane first paint per pane. Live output produced during that sequence is buffered and replayed behind each pane's snapshot.

ctx bounds the handshake and the attach commands only; lifetime bounds the client's own goroutines, which outlive the request that opened them.

func (*Client) Close

func (c *Client) Close(ctx context.Context) error

Close detaches and waits for the process to exit. Idempotent.

func (*Client) CloseWindow

func (c *Client) CloseWindow(ctx context.Context, windowID string) error

func (*Client) KillPane

func (c *Client) KillPane(ctx context.Context, pane string) error

KillPane kills one pane. tmux closes the window with its last pane, and announces that as %window-close like any other close.

func (*Client) ListPanes

func (c *Client) ListPanes(ctx context.Context, windowID string) ([]Pane, error)

ListPanes reports the panes of one window. It is a live query rather than controller state: only a window's active pane id is modelled there, and what a pane is running changes without tmux announcing anything.

func (*Client) MoveWindow

func (c *Client) MoveWindow(ctx context.Context, windowID string, position int) ([]Window, error)

MoveWindow moves windowID to position in the session's window order and answers with the order tmux settled on. position indexes the resulting order, which is what a drop on a tab strip means; the reply is authoritative because the order is tmux session state and every other client attached sees the move.

Two tmux behaviours are load-bearing. A move is an unlink and a relink, so tmux announces the window being moved as closed even though it is still there — suppressed here, or the tab would be torn down and rebuilt blank. And tmux selects whatever it moves unless told not to, while -d on the window that is already selected deselects it: the flag has to follow the moved window, or the active window changes under a reorder that was never about selection.

func (*Client) NewWindow

func (c *Client) NewWindow(ctx context.Context) (string, error)

NewWindow creates a window and returns its id. The tab set itself is driven by the %window-add notification that follows.

It opens where the active pane is rather than where the session was started, which is what a new tab means in a terminal emulator: the window the user is looking at is the one they are asking for another of.

func (*Client) PaneWindow

func (c *Client) PaneWindow(paneID string) (Window, error)

PaneWindow resolves a pane to the window that owns it.

func (*Client) Paste

func (c *Client) Paste(ctx context.Context, pane string, p []byte) error

Paste inserts text into a pane as a paste rather than as keystrokes. tmux applies the brackets because tmux is the only side that knows whether the pane's program asked for them: a first paint reconstructs mouse input state, but not bracketed-paste mode, and tmux never re-sends that mode to a control client (ADR pastes-are-tmux-paste-buffer-operations-not-keystrokes).

The text rides tmux's stdin rather than an argument so it stays out of the process table, and the buffer is named so it stays out of the numbered stack holding the user's own copies.

func (*Client) RenameWindow

func (c *Client) RenameWindow(ctx context.Context, windowID, name string) error

func (*Client) Renegotiate

func (c *Client) Renegotiate(ctx context.Context, cols, rows int) (err error)

Renegotiate re-votes the client size and refreshes the window set from tmux's post-vote answer — the same vote-then-list order negotiate runs on a fresh attach, for the same reason: a snapshot painted at a stale size tears the moment the surface's own vote lands. The %layout-change notification is asynchronous, so only an explicit list after the vote reads the size tmux actually settled on.

func (*Client) Repaint

func (c *Client) Repaint(ctx context.Context) (err error)

Repaint re-runs the first paint for every window, so a caller re-attaching to a live client is handed the same paintable stream a fresh attach would be. A transport-only drop — a stalled write, a webview reload — leaves this client attached while taking the emulator that rendered it, and what the dropped stream already delivered is not in the backlog to replay: without a fresh snapshot the new panes open blank against a session that never stopped.

The broker is reset first, which is what makes the snapshot the caller's: see broker.reset. The captures are bounded like an attach's own, because the manager runs this under the lock every other attach queues behind.

func (*Client) Resize

func (c *Client) Resize(ctx context.Context, cols, rows int) error

Resize renegotiates the client size. Every client attached to a window renders the same grid and tmux's window-size option picks whose size that is — by default the most recently used client's — so this is a vote, and %layout-change is the answer.

func (*Client) ResizePane

func (c *Client) ResizePane(ctx context.Context, pane string, width, height int) error

ResizePane sets width and/or height in cells. Zero leaves that axis unchanged; nonzero values must be in 1..1000. tmux adjusts the divider after the pane, or before it when the pane is last.

func (*Client) SelectPane

func (c *Client) SelectPane(ctx context.Context, pane string, direction PaneDirection) error

SelectPane makes a pane its window's active pane — the pane itself, or the neighbour direction names, which tmux picks the way its own select-pane bindings do. %window-pane-changed carries the answer.

func (*Client) SelectWindow

func (c *Client) SelectWindow(ctx context.Context, windowID string) error

func (*Client) SplitPane

func (c *Client) SplitPane(ctx context.Context, pane string, direction SplitDirection) (string, error)

SplitPane splits a pane and returns the new pane's id. The layout itself arrives on %layout-change, and the new pane's first paint follows from the reconcile that triggers. It opens where the split pane is, the same way a new window does (ADR a-new-tab-and-a-launcher-open-where-the-terminal-s-active-pane-is).

func (*Client) Subscribe

func (c *Client) Subscribe() (<-chan Event, func())

Subscribe returns this client's event channel plus its unsubscribe func. There is one active subscriber: a second call closes the first channel.

func (*Client) Windows

func (c *Client) Windows() []Window

Windows returns a snapshot of the current window set.

func (*Client) Write

func (c *Client) Write(ctx context.Context, pane string, p []byte) error

Write sends bytes to a pane. Every byte goes as hex (send-keys -H), which sidesteps tmux's key-name and literal parsing entirely. The pane is named rather than resolved from its window's active pane: a click that moves focus has its select-pane in flight while the first keystrokes follow it, and they must land where the user is typing.

func (*Client) ZoomPane

func (c *Client) ZoomPane(ctx context.Context, pane string) error

ZoomPane toggles a pane between filling its window and its place in the layout. tmux makes the pane active on the way in.

type CommandError

type CommandError struct {
	Command string
	Message string
}

CommandError is a tmux %error reply. The app service classifies it into an error Kind; nothing matches on its text inside this package.

func (*CommandError) Error

func (e *CommandError) Error() string

type ContinueNotification

type ContinueNotification struct{ Pane string }

type Event

type Event interface {
	// contains filtered or unexported methods
}

Event is one item on a client's outbound stream.

type ExitNotification

type ExitNotification struct{ Reason string }

type Gateway

type Gateway struct {
	// contains filtered or unexported fields
}

Gateway is the protocol engine: it serializes command writes to the control-mode client's stdin, pairs each %begin/%end block with the command that produced it, and routes interleaved notifications. It owns no transport beyond the io.Writer it was handed.

func NewGateway

func NewGateway(log zerolog.Logger, stdin io.Writer, notify func(Notification)) *Gateway

NewGateway wires a gateway over the control client's stdin. notify runs on the reader goroutine in stream order and MUST NOT block: a pending command's %end reply shares that goroutine.

func (*Gateway) Feed

func (g *Gateway) Feed(line []byte) error

Feed advances the state machine by one control-mode line (CR already stripped). line must not be retained. It returns a non-nil error only for a fatal desync, which also fails every pending command.

Inside an open block only the guard that closes it is a guard: capture-pane replies carry screen contents verbatim, and a line of pane output can look like any of them. Anything else — a mismatched %end, a well-formed %begin — is reply content (iTerm2 reads the protocol the same way). A block that never closes therefore surfaces as the caller's Send timing out rather than as a desync, which is bounded and does not kill a session over a screenful of text.

func (*Gateway) Send

func (g *Gateway) Send(ctx context.Context, cmd string) ([]string, error)

Send writes cmd and blocks until its %end (reply lines) or %error (*CommandError). A ctx cancellation leaves a tombstone in the FIFO so the reply tmux still sends is drained rather than handed to the next caller.

func (*Gateway) ServerError

func (g *Gateway) ServerError() string

ServerError reports the content of the last server-originated %error block, if any — the text tmux prints when it rejects the attach outright.

type IndexedWindow

type IndexedWindow struct {
	ID    string
	Index string
	Name  string
}

IndexedWindow identifies a tmux window by both its stable id and mutable index.

type Layout

type Layout struct {
	Pane   string
	Split  SplitKind
	X, Y   int
	Width  int
	Height int
	Cells  []Layout
}

Layout is a window's pane tree as tmux lays it out, in cells. A leaf names a pane; a node divides its box among Cells, each a Layout of its own. Every cell carries its own box, so a renderer places a pane without walking the tree, and the one-cell gap between two siblings is tmux's border. tmux never nests a node inside one of the same kind, so the divider between two siblings always belongs to their parent.

func ParseLayout

func ParseLayout(s string) (Layout, error)

ParseLayout reads tmux's layout string: `<checksum>,<cell>`, where a cell is `WxH,X,Y` followed by `,<pane>` for a leaf, `{<cells>}` for a left-right split or `[<cells>]` for a top-bottom one. Pane ids in it are bare numbers; they come back carrying the `%` every other tmux surface spells them with.

func (Layout) Equal

func (l Layout) Equal(o Layout) bool

Equal reports whether two layouts describe the same tree over the same boxes.

func (Layout) Leaves

func (l Layout) Leaves() []Layout

Leaves lists every pane cell, left to right and top to bottom.

func (Layout) Panes

func (l Layout) Panes() []string

Panes lists the pane ids of every leaf, in Leaves order.

func (Layout) String

func (l Layout) String() string

String renders the tree back in tmux's own notation, minus the checksum — the form a test fixture and a log line both read best in.

type LayoutChanged

type LayoutChanged struct {
	Window string
	Layout Layout
	Zoomed bool
}

LayoutChanged carries the window's new pane tree and whether its active pane is zoomed over it. Layout is the zero value when the string could not be read; the reconcile the same notification triggers carries the tree authoritatively.

type LifecycleChanged

type LifecycleChanged struct {
	Kind     LifecycleKind
	WindowID string
	Message  string
}

LifecycleChanged reports attach/pause/resume/exit/error. WindowID is set for per-window pause/resume; Message carries an exit reason or error text.

type LifecycleKind

type LifecycleKind string

LifecycleKind is the connection-state vocabulary, wire strings likewise.

const (
	LifecycleAttached LifecycleKind = "attached"
	LifecyclePaused   LifecycleKind = "paused"
	LifecycleResumed  LifecycleKind = "resumed"
	LifecycleExited   LifecycleKind = "exited"
	LifecycleError    LifecycleKind = "error"
	// LifecycleDegraded says output was lost and a repaint is following it onto
	// the same stream. It is an edge, not a mode: nothing clears it, because
	// there is no state to clear — the snapshot behind it is the recovery.
	LifecycleDegraded LifecycleKind = "degraded"
)

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager owns one control-mode client per session slug.

func NewManager

func NewManager(ctx context.Context, opts ManagerOptions) *Manager

NewManager builds the client set. ctx is the app's lifetime context: every tmux client's goroutines descend from it.

func (*Manager) Attach

func (m *Manager) Attach(ctx context.Context, slug string, cols, rows int) ([]Window, error)

Attach opens, or returns the windows of, the client for slug, and either way leaves a first paint on its stream: a caller attaches to render, and the one re-attaching over a transport that dropped has nothing else to render from. A second attach for a live slug therefore reuses the client and repaints it, keeping the size it already voted — the vote belongs to a fresh attach. After a client exits its slug is free again and a re-attach starts fresh. cols/rows of 0x0 attach unsized — see Options.unsized.

func (*Manager) Available

func (m *Manager) Available(ctx context.Context) error

Available reports nil when a usable tmux (>= 3.2) is present on a supported build and platform, else ErrUnavailable. A successful probe is cached along with the binary it ran; a failing one is retried, so installing tmux does not require a restart.

func (*Manager) CapturePane

func (m *Manager) CapturePane(ctx context.Context, name string) (string, error)

CapturePane returns the current screen of name's active pane. -p prints to stdout and -J joins wrapped lines — the exact capture-pane invocation hive's own status detection runs (internal/platform/tmux/status.TmuxCapture.CapturePane), so terminal.Detector sees the input it was tuned against.

func (*Manager) CapturePaneID added in v0.65.0

func (m *Manager) CapturePaneID(ctx context.Context, pane string) (string, error)

CapturePaneID is CapturePane for one pane by its id, for a caller that acts on that pane and must judge the same screen whichever pane is active.

func (*Manager) CheckLaunch added in v0.63.0

func (m *Manager) CheckLaunch(ctx context.Context, slug string) error

CheckLaunch rejects an uncommitted Hive session before a user attaches to its placeholders.

func (*Manager) Client

func (m *Manager) Client(slug string) (*Client, bool)

func (*Manager) CurrentPath

func (m *Manager) CurrentPath(ctx context.Context, slug string) (string, error)

CurrentPath answers where a session's active pane is: the directory a prompt in it would print, which follows a cd where the session's own start directory does not. It is what "here" means for anything opened from a terminal on screen — a new window, or a launcher with no directory of its own.

It is a one-shot whether or not this app holds a control client, because the answer is tmux's session state and asking over the control stream would cost a round trip to reach the same pane.

func (*Manager) Detach

func (m *Manager) Detach(ctx context.Context, slug string) error

Detach closes slug's client. Unknown slugs are a no-op.

func (*Manager) FirstPane added in v0.65.0

func (m *Manager) FirstPane(ctx context.Context, session string) (string, error)

FirstPane returns the pane id of the first pane of session's first window.

func (*Manager) HasSession

func (m *Manager) HasSession(ctx context.Context, slug string) (bool, error)

HasSession reports whether tmux is running a session named slug. Attach and start both ask before doing anything, so "there is no session" is a probe's answer rather than a reading of an attach failure's message. A live client is proof enough, which keeps a warm re-attach free of the round trip.

func (*Manager) KillSession

func (m *Manager) KillSession(ctx context.Context, slug string) (bool, error)

KillSession kills the tmux session named slug and reports whether there was one to kill; a slug tmux is not running is success with nothing done, the same tolerance RenameSession has. The control client goes with it, synchronously: the child would exit on its own moments later, and a caller that re-attaches in between must not be handed the dying client's window set.

func (*Manager) ListAllWindows

func (m *Manager) ListAllWindows(ctx context.Context, slugs []string) (map[string][]Window, error)

ListAllWindows answers the window sets of every slug in one tmux call.

Asking per slug cost two spawns for each unattached session — a has-session probe and a list-windows — so a sidebar sweep spawned twice as many processes as it had sessions, all at once. `list-windows -a` is one spawn for the whole server, and a slug it has no session for is simply absent from the output, which is the answer has-session was being paid for.

Attached slugs still answer from their live client, as ListWindows has them: it is authoritative, already in memory, and carries the sizes tmux settled on.

func (*Manager) ListIndexedWindows

func (m *Manager) ListIndexedWindows(ctx context.Context, slugs []string) (map[string][]IndexedWindow, error)

ListIndexedWindows answers window identities for every requested slug in one tmux call. Status integrations report window indices, while terminal clients address stable window ids, so this is the seam that joins those views.

func (*Manager) NewCommandWindow

func (m *Manager) NewCommandWindow(ctx context.Context, slug, dir, name, command string, env []string) (string, error)

NewCommandWindow runs a command in a peer window using the same environment and login-shell contract as NewSession. env entries are KEY=VALUE pairs set for this window only. It never creates a missing session.

func (*Manager) NewSession

func (m *Manager) NewSession(ctx context.Context, name, dir, command string, env []string) error

NewSession creates a detached tmux session named name, in dir, running command through a login shell. command is a shell command line rather than an argv — the same contract ptyterm.Spec.Command uses (ADR subprocess-environment): tmux execs the login shell directly with -c command as its own argv (more than one trailing argument after new-session's flags is executed as-is, never re-parsed by a shell), so the shell's aliases and functions resolve. Empty command opens an interactive login shell instead.

A login shell with -c is not an interactive one, so zsh reads .zprofile but not .zshrc — the file a PATH is as often set in (ADR tmux-runs-in-the-resolved-environment). The environment tmux itself is spawned with is therefore load-bearing rather than incidental: a pane inherits the client that created it, so ManagerOptions.Environ is the floor under whatever the startup files that do run add to it.

env entries ("KEY=VALUE") are set in the session's own environment via new-session -e (tmux ≥ 3.2, which Available already requires), so — unlike prefixing the command line — they also seed any window the process opens in the session later.

func (*Manager) NewWindow

func (m *Manager) NewWindow(ctx context.Context, slug string) (string, error)

NewWindow creates a window in a session this app holds no control client for, and returns its id. An attached client has its own NewWindow; this is for the row a user pressed + on before anything attached to it.

The directory is spelled out because tmux resolves an unset start-directory against the *client* running the command — and a one-shot command client is this process, so the window would open in the app's working directory. It is the active pane's rather than the session's for the reason CurrentPath explains.

func (*Manager) RenameSession

func (m *Manager) RenameSession(ctx context.Context, from, to string) error

RenameSession renames a live tmux session when one exists.

func (*Manager) RenameSessionIfPresent

func (m *Manager) RenameSessionIfPresent(ctx context.Context, from, to string) (bool, error)

RenameSessionIfPresent renames the live tmux session named from to to and reports whether it changed tmux. It drops the control client registered under the old slug so nothing keeps addressing a name tmux no longer answers to.

A session hive knows about does not have to have a tmux session behind it -- it may never have been spawned, or its tmux server may have been restarted -- so an absent one is success, not an error. Existence is probed with has-session rather than inferred from rename-session's stderr, because the alternative is matching on tmux's message text.

func (*Manager) SendText added in v0.65.0

func (m *Manager) SendText(ctx context.Context, pane string, text []byte, submitDelay time.Duration) error

SendText pastes text into a pane as one bracketed paste and presses Enter after submitDelay. It needs no attached client. The program in the pane decides whether the paste stays one message: it must have turned on bracketed paste, or each newline submits.

func (*Manager) SessionNames

func (m *Manager) SessionNames(ctx context.Context, prefix string) ([]string, error)

SessionNames lists every live tmux session name carrying prefix. A server with no sessions at all — or none matching — reports zero names rather than an error, the same tolerance ListAllWindows extends to an empty tmux server.

func (*Manager) Stop

func (m *Manager) Stop(ctx context.Context) error

Stop closes every client, joins their readers, and cancels the app-lifetime context. Idempotent.

Clients close concurrently and the join is bounded by ctx, because closing one is not: teardown waits on the reader, the command worker and the tmux child with no deadline of its own, and the detach it sends first writes to a pipe that nothing guarantees is being read. Serially and unbounded, a single client that will not come down holds App.Close — and therefore the whole quit — open forever. Every client has already been sent its kill by the time the deadline can expire, so what is abandoned here is the join, not the teardown.

func (*Manager) Subscribe

func (m *Manager) Subscribe(slug string) (<-chan Event, func(), error)

Subscribe returns slug's event channel and unsubscribe func. There is one active subscriber per slug; a new call closes the previous channel. Events buffered before the call — first paint included — replay on the new one.

type ManagerOptions

type ManagerOptions struct {
	Logger      zerolog.Logger
	BufferBytes int

	// Binary answers which tmux to exec, and is consulted on every failed
	// availability probe rather than once at startup, so installing tmux does not
	// need a relaunch. nil means $PATH.
	Binary func() (string, error)

	// Environ answers the environment tmux is spawned with — execenv's resolved
	// PATH in the app, whatever a test hands it otherwise. nil means this
	// process's own. It is the same hook ptyterm.ManagerOptions carries, held
	// separately because the two backends share no interface (ADR ephemeral-popup-terminals).
	Environ func(context.Context) []string
	// contains filtered or unexported fields
}

ManagerOptions configures the client set.

type Notification

type Notification interface {
	// contains filtered or unexported methods
}

Notification is a parsed %-line the gateway dispatches to the controller.

type Options

type Options struct {
	Slug string // tmux session name == Hive session slug
	// Cols and Rows are the opening size vote, and 0x0 means the caller has
	// nothing measured to vote with — see unsized.
	Cols        int
	Rows        int
	Binary      string // tmux executable; empty resolves "tmux" through $PATH
	BufferBytes int    // broker bound; 0 == defaultBufferBytes
	Logger      zerolog.Logger
	OnExit      func(slug, reason string)
	// Environ is what tmux is spawned with, minus the client variables
	// withoutTmuxClient drops — execenv's resolved environment in the app, nil
	// meaning this process's own.
	Environ []string
	// contains filtered or unexported fields
}

Options configures one attach.

type Output

type Output struct {
	At       time.Time
	WindowID string
	PaneID   string
	Data     []byte
}

Output is one pane's decoded bytes. Every pane in a window's layout streams; only a pane no tracked window owns is dropped. At is the decode timestamp the WebSocket adapter measures send latency against.

type OutputNotification

type OutputNotification struct {
	Pane string
	Data []byte
}

OutputNotification carries already-decoded pane bytes.

type Pane

type Pane struct {
	ID      string
	PID     int
	Active  bool
	Dead    bool
	Command string
}

Pane is one pane of a window. Command is its foreground process — the name tmux's own status line shows — while PID is the process tmux started the pane with, so the two name the same process only while nothing that process started is running. PID is 0 when tmux reported one this cannot read.

type PaneDirection

type PaneDirection string

PaneDirection names a neighbour of a pane; the empty value names the pane itself.

const (
	PaneSelf  PaneDirection = ""
	PaneLeft  PaneDirection = "left"
	PaneRight PaneDirection = "right"
	PaneUp    PaneDirection = "up"
	PaneDown  PaneDirection = "down"
)

type PauseNotification

type PauseNotification struct{ Pane string }

type SessionChanged

type SessionChanged struct{ Session, Name string }

type SessionWindowChanged

type SessionWindowChanged struct{ Session, Window string }

type SplitDirection

type SplitDirection string

SplitDirection is which way a split lays the new pane, in tmux's words: a horizontal split puts it to the right, a vertical one below.

const (
	SplitHorizontal SplitDirection = "horizontal"
	SplitVertical   SplitDirection = "vertical"
)

type SplitKind

type SplitKind string

SplitKind says how a layout node divides its box among its cells.

const (
	// SplitNone marks a leaf: one pane filling the box.
	SplitNone SplitKind = ""
	// SplitLeftRight lays cells side by side — what `split-window -h` makes.
	SplitLeftRight SplitKind = "leftright"
	// SplitTopBottom stacks cells — what `split-window -v` makes.
	SplitTopBottom SplitKind = "topbottom"
)

type Window

type Window struct {
	ID         string // tmux window id, e.g. "@275"
	Name       string
	Active     bool
	ActivePane string // tmux pane id, e.g. "%512"
	// Width and Height are tmux's own size for this window — whichever attached
	// client tmux's window-size option picked, not necessarily ours. A renderer
	// that draws at any other size mangles the pane's cursor-addressed output.
	// 0 means not known yet.
	Width  int
	Height int
	// Layout is the pane tree, at the window's unzoomed geometry; the zero
	// value means tmux has not reported one yet. Zoomed says the active pane is
	// drawn over the whole window while Layout still records where it goes
	// back to.
	Layout Layout
	Zoomed bool
}

Window is the app-side model of one tmux window.

func (Window) Panes

func (w Window) Panes() []string

Panes lists the window's pane ids in layout order. A window whose layout has not been read yet offers only its active pane.

type WindowAddNotification

type WindowAddNotification struct{ Window string }

type WindowChanged

type WindowChanged struct {
	Kind   WindowEventKind
	Window Window
}

WindowChanged reports a change to the tab set.

type WindowCloseNotification

type WindowCloseNotification struct{ Window string }

type WindowEventKind

type WindowEventKind string

WindowEventKind is the tab-set change vocabulary. The values are the wire strings the WebSocket adapter emits verbatim.

const (
	WindowAdded         WindowEventKind = "added"
	WindowClosed        WindowEventKind = "closed"
	WindowRenamed       WindowEventKind = "renamed"
	WindowActiveChanged WindowEventKind = "active-changed"
	// WindowLayoutChanged covers a resize as well as a split, a closed pane or
	// a zoom: the window's size is its layout's root box.
	WindowLayoutChanged WindowEventKind = "layout-changed"
)

type WindowPaneChanged

type WindowPaneChanged struct{ Window, Pane string }

type WindowRenamedNotification

type WindowRenamedNotification struct{ Window, Name string }

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL