Install the keybindings
Put the picker, the watch dashboard, and the jumps on your prefix key. What each key does is in Keybindings; this page is how the bindings get onto your tmux server and how to change them once they are.
Install
tma install-keys
This writes the default bindings to a managed file (~/.config/tma/tmux.conf) and
adds one line to your tmux config. The line names the file through tmux’s own
variable expansion, so a tmux config kept in a dotfiles repo works on every
machine; -q makes the XDG_CONFIG_HOME path a quiet miss when that variable is
unset, and the $HOME one loads instead:
source-file -q "$XDG_CONFIG_HOME/tma/tmux.conf" "$HOME/.config/tma/tmux.conf" # tma keys
With --config-dir (or TMA_CONFIG_DIR) the line carries that literal path
instead, double-quoted so a dir with a space still parses.
It shows the diff and asks before writing, naming the file it resolved; pass
--yes to skip the prompt. Reload tmux afterward, pointing at whichever config
the diff named:
tmux source-file ~/.config/tmux/tmux.conf
Which config gets the line
tma does not assume ~/.tmux.conf. It marks the first of tmux’s own config files
that exists, in tmux’s load order:
~/.tmux.conf$XDG_CONFIG_HOME/tmux/tmux.conf~/.config/tmux/tmux.conf
(tmux 3.6 sources every one of those that exists, in that order, so a later file’s
set wins; older tmux loads only the first.) If none exists, tma creates
$XDG_CONFIG_HOME/tmux/tmux.conf when XDG_CONFIG_HOME is set; with it unset it
creates ~/.config/tmux/tmux.conf if ~/.config is there, and ~/.tmux.conf
otherwise. Creating only ever happens when you have no tmux config at all, so the
file tma creates can never shadow one you already have. --conf <path> overrides
all of this.
Verify and undo
tma install-keys --check
tma install-keys --uninstall
--check confirms the managed file is current and that your tmux config sources
it exactly once; both resolve the config the same way install did. --uninstall
removes the managed file and the marked source-file line, and nothing else:
your own bindings live in your tmux config, tma’s live only in the managed file,
so there is nothing of yours to corrupt.
Rebind a key
install-keys claims only keys that are unbound in stock tmux (that is why the
temporary watch session is on G: g is already jump --blocked). If one
clashes with a
personal binding of yours, copy the line you want out of
~/.config/tma/tmux.conf into your own tmux config with a new key and drop the
managed file. Editing the managed file in place also works, but the edit survives
only until the next install-keys run, which rewrites the whole file from tma’s
defaults.
Clickable status segments
Each count tma status prints is wrapped in a tmux range marker, so a click can
be resolved to the class you clicked. The bindings that act on that are opt-in:
tma install-keys --mouse
They also need tmux’s mouse mode, which tma never turns on for you, because it
changes selection and copy/paste in every pane (drag-select stops reaching your
terminal; hold Shift to get the terminal’s own selection back). Turn it on
yourself if you want it:
set -g mouse on
With both in place, the mouse table applies: the blocked count jumps to the longest-blocked agent, any other count opens the picker popup, and a right-click on either opens the agent menu.
One thing a click cannot do is close the popup it opened. tmux delivers mouse
events to an open display-popup and drops everything outside it, so the second
click on the status line never reaches a binding. Esc closes it.
The range markers ship always. Without --mouse, or without set -g mouse on,
they are inert: tmux draws the counts exactly as before, and nothing is
clickable. tma doctor flags the half-wired case (bindings installed, mouse
off).
The cost of opting in: those four bindings claim tmux’s status-line mouse keys
for the whole status line, not just tma’s segments. A left-click elsewhere still
switches to the window you clicked (the binding ends with tmux’s own
switch-client -t=), but a right-click on a window name no longer opens tmux’s
window menu (Alt-right-click still does, since tmux binds that separately). If
you would rather keep the plain right-click, delete the two MouseDown3 lines
from ~/.config/tma/tmux.conf.
tma install-keys --check --mouse verifies the group is installed; a plain
--check accepts a file with or without it, so not opting in is never reported
as drift.
The daemon launcher
Every install writes one line that is not a binding:
run-shell -b 'tma --socket-path "#{socket_path}" daemon --ensure >/dev/null 2>&1'
It starts the event-hub daemon for whichever server loads the file, so a new tmux
server is at tier 3 before you open a surface. It is safe on a re-source
(--ensure takes a single-instance lock) and needs no matching stop line,
because the daemon exits when its tmux server does.
To skip it:
tma install-keys --no-daemon
That is a standing choice rather than a one-off: a plain --check calls the
missing line drift, so use --check --no-daemon in whatever verifies your setup.
Details and the other ways to start a daemon in
Run the daemon.
Bind them by hand instead
If you would rather not let tma write config, add the bindings to your tmux
config yourself. These are the same shapes install-keys writes.
The picker opens best in a popup. display-popup does not format-expand its
command, so pass no --client: the picker resolves the client that opened the
popup itself (a --client "#{client_name}" here would arrive literal and target
a client that does not exist).
bind-key a display-popup -E -w 80% -h 60% 'tma'
The managed full-width dashboard uses a dedicated temporary session. run-shell
format-expands the invoking client; --temporary-session switches that client to
the one-use session, and a jump or quit closes it. --table opens straight into
the table; p inside tma watch toggles it against the preview:
bind-key G run-shell 'tma watch --temporary-session --table --client "#{client_name}"'
If you would rather keep a persistent watcher beside your work, bind a plain
tma watch split instead. A narrow pane falls back to the single-column list:
bind-key W split-window -h -l 40 'tma watch'
Mind that a plain watcher is persistent and follows nothing: jump to an agent in another window and the pane stays behind in the window you left.
Jump straight to whoever needs you, no picker. run-shell does format-expand, so
pass the client: tma then switches the client that pressed the key and keys the
--back origin by it:
bind-key j run-shell 'tma jump --attention --client "#{client_name}"'
bind-key g run-shell 'tma jump --blocked --client "#{client_name}"'
bind-key b run-shell 'tma jump --back --client "#{client_name}"'
bind-key h run-shell 'tma jump --home --client "#{client_name}"'
The action menu for the pane you are standing in, likewise expanded by
run-shell:
bind-key A run-shell 'tma act --menu --pane "#{pane_id}"'
Should an old binding still pass an unexpanded #{client_name}, tma reads it
as no client at all and falls back to resolving the acting client itself.
tma watch runs in a normal pane, so q, Esc, or ctrl-c inside it quits and
takes the pane (or window) with it.
What a binding can reach
A binding is a shell command running as you, so it can do anything tma can do,
which is anything you can do to your own tmux server. That is the whole boundary;
see The security model for what follows from
it, particularly before you bind an action that writes.