(???) !DOCTYPE html>
(???) html>
(???) <head>
(???) <meta charset="utf-8" />
(???) <meta name="viewport" content="width=device-width, initial-scale=1.0" />
(???) <title>tmux - Terminal Multiplexer</title>
(???) <link href="/slides.css" rel="stylesheet" />
(???) <script src="/slides.js" type="module"></script>
(???) <script src="/timer.js" defer></script>
(???) <link href="tmux.css" rel="stylesheet" />
(???) <!-- alpine linux using container2wasm -->
(???) <script src="/container2wasm/xterm-pty-0.9.4.min.js"></script>
(???) <script src="/container2wasm/xterm-addon-fit-0.8.0.min.js"></script>
(???) <script src="/container2wasm/xterm-5.3.0.min.js"></script>
(???) <link href="/container2wasm/xterm-5.3.0.min.css" rel="stylesheet" />
(???) <script src="./stack.js"></script>
(???) <script src="./ws-delegate.js"></script>
(???) <style>
(???) #terminal {
(???) text-align: left;
(???) }
(???) </style>
(???) </head>
(???) <body>
(???) <main class="slides" tabindex="0" autofocus>
(???) <section class="paragraph" id="navigate-hint">
(???) <p>
(???) <kbd>←</kbd> prev<br />
(???) <kbd>→</kbd> next
(???) </p>
(???) </section>
(???) <section>
(???) <img src="tmux.svg" width="27%" class="logo" />
(???) </section>
(???) <section class="paragraph small" id="print-hint">
(???) Interactive version:<br /><br />
(???) <a href="https://joriszwart.nl/tmux">joriszwart.nl/tmux</a>
(???) </section>
(???) <section class="paragraph blockquote">
(???) <p><u>T</u>erminal <u>mu</u>ltiple<u>x</u>er</p>
(???) <!-- but there is more! (session management) -->
(???) </section>
(???) <section class="paragraph shell-hell">
(???) <pre class="shell" title="(s)hell 1">
(???) <span class="cursor"> </span>
(???) </pre>
(???) <pre class="shell" title="(s)hell 2">
(???) <span class="cursor"> </span>
(???) </pre>
(???) <pre class="shell" title="(s)hell 3">
(???) <span class="cursor"> </span>
(???) </pre>
(???) <pre class="shell" title="(s)hell 4">
(???) <span class="cursor"> </span>
(???) </pre>
(???) <pre class="shell" title="(s)hell 5">
(???) <span class="cursor"> </span>
(???) </pre>
(???) <!--
(???)
(???) Wat lost hier van tmux op?
(???) (voors en tegens, overzicht, deels op te lossen met split panels)
(???) -->
(???) </section>
(???) <!-- cheese -->
(???) <!-- <section class="paragraph">
(???) <p class="small">More terminal, less clutter</p>
(???) </section> -->
(???) <section id="about-joris" class="about">
(???) <a href="https://joriszwart.nl" target="_blank">
(???) <img
(???) src="/joriszwart-logo-uluru.png"
(???) alt="Joris Zwart logo"
(???) width="1000"
(???) height="125"
(???) />
(???) </a>
(???) <p class="small uppercase">I code dreams™</p>
(???) </section>
(???) <section class="paragraph">
(???) <pre>
(???) 90s NOHUP
(???) 00s The <em>screen</em> years
(PHO) 025 Late to the party: tmux!
(???) </pre>
(???) </section>
(???) <!-- TODO deze termen aan begin, midden en einde, toetsen ook nog een keer terug laten komen -->
(???) <section class="paragraph terms">
(???) <dl>
(???) <dt>Attach</dt>
(???) <dd>Benader een bestaande sessie</dd>
(???) <dt>Detach</dt>
(???) <dd>Ontkoppel een sessie</dd>
(???) </dl>
(???) </section>
(???) <section>
(???) Demo
(???) <!-- Toon toetsen als overlay in interactieve demo (hoe?) -->
(???) <!-- <p class="small">(Carl Sagan would be proud)</p> -->
(???) <p class="small">(Carl Sagan zou trots zijn)</p>
(???) <!-- Rabbit hole: linux image (DSL doesn't exist any more, Alpine is too bug (300 MB), TinyCore (13 MB)), xterm.js -->
(???) </section>
(???) <section class="paragraph">
(???) <div id="terminal">Immersive Linux</div>
(???) <script>
(???) console.log("Starting terminal...");
(???) const palette = {
(???) black: "#000000",
(???) red: "#cd3131",
(???) green: "#0dbc79",
(???) yellow: "#e5e510",
(???) blue: "#2472c8",
(???) magenta: "#bc3fbc",
(???) cyan: "#11a8cd",
(???) white: "#e5e5e5",
(???) brightBlack: "#666666",
(???) brightRed: "#f14c4c",
(???) brightGreen: "#23d18b",
(???) brightYellow: "#f5f543",
(???) brightBlue: "#3b8eea",
(???) brightMagenta: "#d670d6",
(???) brightCyan: "#29b8db",
(???) brightWhite: "#e5e5e5",
(???) black: "#000000",
(???) // red: "#cd3131",
(???) // green: "#0dbc79",
(???) // yellow: "#e5e510",
(???) // blue: "#2472c8",
(???) // magenta: "#bc3fbc",
(???) // cyan: "#11a8cd",
(???) // white: "#e5e5e5",
(???) // brightBlack: "#666666",
(???) // brightRed: "#f14c4c",
(???) // brightGreen: "#23d18b",
(???) // brightYellow: "#f5f543",
(???) // brightBlue: "#3b8eea",
(???) // brightMagenta: "#d670d6",
(???) // brightCyan: "#29b8db",
(???) // brightWhite: "#e5e5e5",
(???) };
(???) const theme = {
(???) foreground: "#f9f4f2",
(???) background: "#27a2cc",
(???) cursor: "#f9f4f2",
(???) selectionBackground: "#86cfe4",
(???) ...palette,
(???) };
(???) const options = {
(???) cols: 40,
(???) rows: 25,
(???) fontFamily: "monospace",
(???) fontSize: 16,
(???) cursorBlink: true,
(???) theme,
(???) };
(???) const fitAddon = new FitAddon.FitAddon();
(???) const container = document.getElementById("terminal");
(???) const xterm = new Terminal(options);
(???) xterm.open(container);
(???) xterm.loadAddon(fitAddon);
(???) const proposedDimensions = fitAddon.proposeDimensions();
(???) console.log("proposedDimensions", proposedDimensions);
(???) // xterm.resize(proposedDimensions.cols + 1, proposedDimensions.rows + 1);
(???) fitAddon.fit();
(???) xterm.write("Welcome to Alpine Linux!\r\n\r\n");
(???) // styling
(???) // const xtermViewport = container.querySelector("#terminal");
(???) container.classList.add("shell");
(???) container.setAttribute("title", "shell");
(???) // pty setup
(???) const { master, slave } = openpty();
(???) termios = slave.ioctl("TCGETS");
(???) termios.iflag &= ~(
(???) /*IGNBRK | BRKINT | PARMRK |*/ (
(???) ISTRIP |
(???) INLCR |
(???) IGNCR |
(???) ICRNL |
(???) IXON
(???) )
(???) );
(???) termios.oflag &= ~OPOST;
(???) termios.lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
(???) //termios.cflag &= ~(CSIZE | PARENB);
(???) //termios.cflag |= CS8;
(???) slave.ioctl(
(???) "TCSETS",
(???) new Termios(
(???) termios.iflag,
(???) termios.oflag,
(???) termios.cflag,
(???) termios.lflag,
(???) termios.cc
(???) )
(???) );
(???) xterm.loadAddon(master);
(???) const worker = new Worker("./worker.js" + location.search);
(???) var nwStack;
(???) var netParam = getNetParam();
(???) var workerImage = location.origin + "/tmux/alpine-tmux-mc.wasm";
(???) if (netParam) {
(???) if (netParam.mode == "delegate") {
(???) nwStack = delegate(worker, workerImage, netParam.param);
(???) } else if (netParam.mode == "browser") {
(???) nwStack = newStack(
(???) worker,
(???) workerImage,
(???) new Worker("./stack-worker.js" + location.search),
(???) location.origin + "/c2w-net-proxy.wasm"
(???) );
(???) }
(???) }
(???) if (!nwStack) {
(???) worker.postMessage({ type: "init", imagename: workerImage });
(???) }
(???) new TtyServer(slave).start(worker, nwStack);
(???) function getNetParam() {
(???) var vars = location.search.substring(1).split("&");
(???) for (var i = 0; i < vars.length; i++) {
(???) var kv = vars[i].split("=");
(???) // if (despanURIComponent(kv[0]) == "net") {
(???) // return {
(???) // mode: kv[1],
(???) // param: kv[2],
(???) // };
(???) // }
(???) }
(???) return null;
(???) }
(???) </script>
(???) </section>
(???) <section>Install</section>
(???) <section class="paragraph">
(???) <pre class="shell" title="shell">
(???) apt install tmux<span class="cursor"> </span>
(???) </pre>
(???) <!-- of je $favo package manager voor je $OS -->
(???) </section>
(???) <section>Start it up</section>
(???) <section class="paragraph">
(???) <pre class="shell" title="shell">
(???) tmux<span class="cursor"> </span>
(???) </pre>
(???) <!-- this will create a new session -->
(???) </section>
(???) <!-- wat zien we hier? aanwijzen -->
(???) <!-- <section class="paragraph">
(???) [TODO screenshow live terminal]
(???) </section> -->
(???) <section>Key usage</section>
(???) <!-- TODO fix, doesn't work .big, only + is big, not kbd (because kbd has vw font-size) -->
(???) <section class="paragraph">
(???) <p><kbd>CTRL</kbd> + <kbd>B</kbd></p>
(???) <p class="small">En vervolgens...</p>
(???) </section>
(???) <!-- align-left class? table? -->
(???) <section class="paragraph">
(???) <p>
(???) <!-- <kbd>???</kbd> help!<br /> -->
(???) <kbd>C</kbd> nieuw window<br />
(???) <kbd>N</kbd> volgend window<br />
(???) <kbd>P</kbd> vorig window<br />
(???) <kbd>D</kbd> detach<br />
(???) </p>
(???) </section>
(???) <section>Sessions</section>
(???) <section class="paragraph">Attach to session</section>
(???) <section class="paragraph">
(???) <pre class="shell" title="shell">
(???) tmux attach<span class="cursor"> </span>
(???) </pre>
(???) </section>
(???) <section class="paragraph">
(???) <pre class="shell" title="shell">
(???) tmux list-sessions
(TXT) : 1 windows (created Tue Dec 9 21:16:49 2025)
(DIR) : 1 windows (created Tue Dec 9 21:17:55 2025)
(???) <span class="cursor"> </span>
(???) /pre>
(???) </section>
(???) <section class="paragraph">
(???) Name your sessions!
(???) <!-- + demo! -->
(???) </section>
(???) <!-- <section class="paragraph">[TODO keys + demo]</section> -->
(???) <section>
(???) Split panes
(???) <!-- TODO panels, panes of screens? -->
(???) </section>
(???) <section class="paragraph">
(???) <p><kbd>CTRL</kbd> + <kbd>B</kbd></p>
(???) <p class="small">En vervolgens...</p>
(???) </section>
(???) <section class="paragraph">
(???) <p>
(???) <!-- <kbd>???</kbd> help!<br /> -->
(???) <kbd>"</kbd> horizontale split<br />
(???) <kbd>%</kbd> verticale split<br />
(???) <br />
(???) <kbd>←</kbd> <kbd>→</kbd> <kbd>↑</kbd> <kbd>↓</kbd> wissel pane<br />
(???) <!-- (<kbd>CTRL</kbd> + cursor resizen -->
(???) </p>
(???) </section>
(???) <!-- <section class="paragraph">[TODO keys + demo]</section> -->
(???) <section class="paragraph">
(???) <span>tmux list-keys</span>
(???) <!-- demo more -->
(???) </section>
(???) <section>
(???) Commands
(???) <!-- demo -->
(???) </section>
(???) <section class="paragraph">
(???) <span>tmux list-commands</span>
(???) <!-- demo more -->
(???) </section>
(???) <section>Copy & paste</section>
(???) <section>Recap</section>
(???) <section class="paragraph">
(???) <ul>
(???) <li>new session</li>
(???) <li>attach / detach</li>
(???) <li>split panes</li>
(???) <li>copy & paste</li>
(???) </ul>
(???) </section>
(???) <section>Nifty split pane</section>
(???) <!-- <section class="paragraph">
(???) Pane1: sqlite3 mijn_database.db "SELECT * FROM users;" > output.txt
(???) Pane2: watch cat output.txt
(???) </section> -->
(???) <!-- andere optie -->
(???) <!-- <section class="paragraph">
(???) Pane1: sqlite3 mijn_database.db | tee output.log
(???) Pane2: tail -f output.log
(???) </section> -->
(???) <!-- tmux native optie -->
(???) <section class="paragraph">
(???) <pre>
(???) mux pipe-pane -o \
(???) -t 0 'cat > output.log'
(???) </pre
(???) >
(???) </section>
(???) <section class="paragraph">
(???) SSH keys
(???) <p class="small">Easy login</p>
(???) </section>
(???) <section class="paragraph">
(???) Mosh
(???) <p class="small">Roaming</p>
(???) <!--
(???) Combine with mosh (walk around) and/or ssh keys for easy access (not much
(???) difference with working locally)
(???)
(???) -->
(???) </section>
(???) <section class="paragraph">
(???) <pre class="shell" title="shell">
(???) tmux attach
(???) o sessions
(???) *@)^%@)(#&!!11OneZ0r3s<span class="cursor"> </span>
(???) </pre>
(???) </section>
(???) <section>
(???) Attach existing process
(???) <!-- intermediate -->
(???) </section>
(???) <section class="paragraph small">
(???) <!-- # bg // in another terminal? can this do a bg [process-id]? -->
(???) <pre class="shell" title="shell">
(???) su -
(???) ps aux | grep tetris
(???) disown
(???) bg
(???) tmux
(???) reptyr 127581<span class="cursor"> </span>
(???) </pre>
(???) </section>
(???) <!-- TODO deze termen aan begin, midden en einde, toetsen ook nog een keer terug laten komen -->
(???) <!-- <section class="paragraph terms">
(???) <dl>
(???) <dt>Attach</dt>
(???) <dd>Benader een bestaande sessie</dd>
(???) <dt>Detach</dt>
(???) <dd>Ontkoppel een sessie</dd>
(???) </dl>
(???) </section> -->
(???) <!-- <section class="paragraph terms">
(???) <dl>
(???) <dt>Session</dt>
(???) <dd>Definition 1 TODO</dd>
(???) </dl>
(???) </section>
(???) -->
(???) <section>Recap</section>
(???) <section class="paragraph">
(???) <ul>
(???) <li>Session management</li>
(???) <li>Terminal management</li>
(???) <li>Protips</li>
(???) </ul>
(???) </section>
(???) <section class="paragraph">
(???) <a href="https://github.com/tmux">github.com/tmux</a>
(???) </section>
(???) <section>Alternatives</section>
(???) <section class="paragraph">
(???) <!-- sommige hiervan doen wel session management, maar geen panes of v.v., ook niet alle meer maintained, clean up those! -->
(???) <ul>
(???) <li><a href="https://github.com/martanne/abduco">abduco</a></li>
(???) <li><a href="https://www.byobu.org">Byobu</a></li>
(???) <li><a href="https://dtach.sourceforge.net">dtach</a></li>
(???) <li><a href="https://en.wikipedia.org/wiki/Nohup">nohup</a></li>
(???) </ul>
(???) </section>
(???) <section class="paragraph">
(???) <!-- sommige hiervan doen wel session management, maar geen panes of v.v., ook niet alle meer maintained, clean up those! -->
(???) <ul>
(???) <li><a href="https://www.gnu.org/software/screen">Screen</a></li>
(???) <li><a href="https://github.com/shell-pool/shpool">shpool</a></li>
(???) <li><a href="https://zellij.dev">Zellij</a></li>
(???) <li><a href="https://zmx.sh/">zmx</a> (new kid on the block)</li>
(???) </ul>
(???) </section>
(???) <section>Credits</section>
(???) <section class="paragraph">
(???) <a href="https://github.com/container2wasm">
(???) github.com/container2wasm
(???) </a>
(???) </section>
(???) <section class="paragraph">
(???) <a href="https://xtermjs.org">xtermjs.org</a>
(???) </section>
(???) <section>En nu!</section>
(???) <section class="paragraph">$ detach</section>
(???) <section class="paragraph">
(???) <span class="whiteout">Koffie</span>
(???) </section>
(???) <section class="paragraph">
(???) <span class="whiteout">Bier</span>
(???) </section>
(???) <section class="paragraph">of...</section>
(???) <section class="paragraph">
(???) <span class="whiteout">Melk</span>
(???) </section>
(???) <section class="paragraph">
(???) <a href="https://joriszwart.nl/tmux">joriszwart.nl/tmux</a>
(???) </section>
(???) </main>
(???) <aside class="timer" data-timer data-minutes="23"></aside>
(???) </body>
(???) /html>