Try it without installing anything
A container with tmux, the binary, the config with everything turned on, five fake projects and a guided tour that walks through the bindings one at a time. Nothing is mounted from your machine and nothing is published off it, so the whole thing goes away with the container.
docker run --rm -it lonkarorg/tmux-companion:playgroundFrom a clone, scripts/playground.sh builds the image and runs it. The first
build compiles the crate inside the image and takes a few minutes; the rest
reuse the cargo layer.
scripts/playground.sh # build if needed, then runscripts/playground.sh shell # a shell in the image, no tourscripts/playground.sh a11y # the accessibility walkthrough, no tourscripts/playground.sh a11y on # the same, with the accessibility settings onscripts/playground.sh smoke # check the image is what the tour claimsscripts/playground.sh tourpass # drive the tour with keys, hardened and plainLocked down
Section titled “Locked down”The tour works the same with the container locked down: a read-only image, no
network, no capabilities, and a cap on processes and memory. The home
directory and /tmp become tmpfs, so nothing is written to disk at all.
docker run --rm -it \ --read-only --tmpfs /tmp --tmpfs /home/play:uid=1000,gid=1000 \ --network=none --cap-drop=ALL --security-opt=no-new-privileges \ --pids-limit=512 --memory=512m \ lonkarorg/tmux-companion:playgroundscripts/playground.sh runs with these flags; PLAIN=1 scripts/playground.sh
runs without them.
Checking the image
Section titled “Checking the image”Each published image is signed with cosign
by the workflow that built it, with no key: the signature names
.github/workflows/playground.yml and the tag it ran at. To check one:
cosign verify lonkarorg/tmux-companion:playground \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ --certificate-identity-regexp '^https://github.com/lonkar-org/tmux-companion/\.github/workflows/playground\.yml@'The image also carries an SBOM and a build provenance attestation:
docker buildx imagetools inspect lonkarorg/tmux-companion:playground --format '{{ json .SBOM }}'docker buildx imagetools inspect lonkarorg/tmux-companion:playground --format '{{ json .Provenance }}'Run it outside tmux
Section titled “Run it outside tmux”If you start the container from inside a tmux session, Ctrl-b goes to that
server and the playground never sees it, so every binding in the tour looks
broken. Use a terminal that is not already in tmux.
Nested anyway, press the prefix twice: Ctrl-b Ctrl-b ? reaches the inner
tmux. The entrypoint says so and waits before attaching when it sees $TMUX.
Option as Meta, on macOS
Section titled “Option as Meta, on macOS”Two of the bindings are Alt-s and Alt-a. Terminal.app and iTerm2 send an
accented character for Option until they are told otherwise:
| Terminal.app | Settings, Profiles, Keyboard, “Use Option as Meta key” |
| iTerm2 | Settings, Profiles, Keys, Left Option key: Esc+ |
| Ghostty | macos-option-as-alt = true |
| Alacritty, kitty, WezTerm | already send it |
The playground binds the same two to the prefix as well, so prefix P opens
the project picker and prefix A toggles, and nothing has to be configured
before the tour works. Those two are playground scaffolding; the shipped
config uses the Alt keys.
What you land in
Section titled “What you land in”Two tmux sessions. You start in playground, a shell in
~/projects/orchard-api, and the tour waits in instructions.
prefix then i the tour (prefix is Ctrl-b)Alt-s the project pickerStep one offers a detour: press t for nine screens of tmux itself — what a
server and a client are, what the prefix is for, how sessions, windows and
panes nest, and what detaching actually does, with a diagram for each and four
screens of keys to press. Nothing in the detour is checked. It ends with
learntmux.dev, which is 42 tasks against a real tmux
in the browser, and returns you to step two.
The tour is eighteen steps. Each one says what to press, sets the step on a
second status line so it is still in front of you after you have switched
sessions, and waits for Enter. Some steps check that the thing actually
happened and say so when it did not; s skips one and q leaves the tour for
a shell. tour starts it again.
This is the one thing the image cannot do for you. Glyphs are rendered by the terminal on your machine, so a Nerd Font has to be installed and selected there, not in the container. The first step of the tour prints four of them so you can see whether yours works.
- Nerd Fonts, any of them
- firacode-nfc-tweaked, the one this was built against
Everything works without the font. It reads worse.
What is not there
Section titled “What is not there”A container has no battery, so that segment stays empty. The network counters
sit below the threshold the bandwidth segment draws at unless something is
transferring, so that one is usually empty too. Both are there on a laptop, and
tmux-companion doctor inside the container says what it can and cannot see.
The window segment is off, the same as in the bar the author runs: drawing
windows through tmux-companion window costs one process spawn per window per
redraw, and tmux redraws on pane output as well as on the timer.
The five projects
Section titled “The five projects”Each one is in a different state, so the git segment has something different to say in each:
orchard-api |
clean |
orchard-web |
three modified, one untracked |
sparrow-cli |
staged and modified at once, on a branch long enough to be truncated |
lantern-docs |
detached HEAD, one untracked file |
anvil-infra |
two commits ahead of its upstream |
orchard-api/build.log holds a compiler error with a path, a line and a
column in it, for the copy-mode o binding to open.
The page on Docker Hub
Section titled “The page on Docker Hub”playground/DOCKERHUB.md is what Docker Hub shows on the image’s page. It is
pushed by the last step of .github/workflows/playground.yml, on a tag, so it
is reviewed like anything else rather than pasted into a web form and left to
drift. That step needs the Docker Hub token to carry delete scope as well as
read and write, and it is continue-on-error, because a description that did
not update is not worth failing a release whose image is already pushed.
Taking the config with you
Section titled “Taking the config with you”Everything the playground runs is a file in the image:
~/.config/tmux/companion.conf |
docs/tmux.conf.full.example, unchanged |
~/.config/tmux/playground.conf |
the tour’s scaffolding, not part of the tool |
~/.config/tmux-companion/config.toml |
the layout the projects open with |
/opt/playground/config.example.toml |
every option, annotated |
docker cp <container>:/home/play/.config/tmux/companion.conf . copies one
out, or read them in the container and copy what you want.