Hacker News new | past | comments | ask | show | jobs | submit login
Getting Started with Tmux (ittavern.com)
302 points by signa11 on Dec 11, 2022 | hide | past | favorite | 154 comments



Tmux becomes more awesome when you use something like Alacritty or Kitty [EDIT: scratch Kitty, this mainly applies to Alacritty] and map your system's key (Apple's command key or... whatever it would be on Linux or Windows) and use that as your "tmux key". That way you can make single-chord bindings for all things tmux and life becomes better. If you use Vim, adding VimTmuxNavigator[0] improves things so much. For example, to seemlessly switch between panes, be they tmux panes or vim panes, I use `cmd-h`, `cmh-j`, `cmd-k`, `cmd-l`.

It's possible to achieve "command as tmux key" with iTerm which I did do for years but I don't recommend it. It's very hacky.

[0] https://github.com/christoomey/vim-tmux-navigator


Interestingly enough, one of the stated goals of kitty is to make the usage of tmux unnecessary.

Considering your comment (and many others like it), I don't think that has quite worked out.

Still, kitty is one of my favorite terminal emulators and I'd urge anyone who hasn't tried it to give it a shot.


Yes, I mentioned in another comment that I only brought up Kitty for diplomatic reasons (which was weird of me, lol). I don't really know anything about Kitty other than it's often brought up as an alternative to Alacritty. I should have just left it at Alacritty!


I use kitty locally and only usr tmux on remote servers where I would not like to lose my session.

Running remote tmux inside a local tmux is just to error prone and forces you to remember different bindings.


There is an approach to use tmux inside tmux without using different set of keybindings. That's what I have been using for couple years and I really like the setup. I have the following binding in my local machine:

    bind -T root F3 \
      set prefix None \;\
      set key-table off \;\
      set status-left '#[bg=#C678DD,fg=#2C323C](pass-#S)' \;\
      set status-style bg=#E06C75 \;\
      set window-status-current-style bg=magenta,fg=black \;\
      refresh-client -S;

    bind -T off F3 \
      set -u prefix \;\
      set -u key-table \;\
      set -u status-left \;\
      set -u status-style \;\
      set -u window-status-current-style \;\
      refresh-client -S;
This way, pressing F3 in local machine disables the prefix and I can use remote tmux as if it is local. When I want to get to local tmux, I press F3 once and I am back to local tmux. I use highlighting to easily show that local prefix is disabled.


Thanks, this is excellent!


Reading more about Kitty now is peaking my interest. I feel like there is a reason I ignored Kitty in the past but I can't remember.


Piquing, not peaking :)


lol, yes, thanks :)


For me it was the excessively minimal defaults. I also forget the exact issues, but I remember Alacrity felt usable even before editing the conf file; Kitty didn't.


The author has a hatred of bitmap fonts for some reason.


I've been using kitty for 3 years now and I love how fast it is. It's the first time I read of other people using it. At my job nobody knows of it.


For what it's worth, you can just do this using Alt (i.e. 'meta'). No special terminal required. Just use `bind -n M-<X>` to say 'no prefix' and use meta-<X>.

For example, `bind -n M-1 select-window -t 1` means Alt-1 goes to Window 1 for me.

I use Alt-h, Alt-j, Alt-k, Alt-l for vim-aware pane switching (with some vim config too), e.g. via `bind -n 'M-h' if-shell "$is_vim" 'send-keys M-h' 'select-pane -L'`. I have a load of Alt-<X> mappings.

I use iTerm and Windows Terminal primarily, but it works on everything, really. Though sometimes you need to adjust what 'alt' means; in iTerm, you need to make Alt be Esc+ (I think).


Meta interferes with some of my vim bindings, though, as well as some readline bindings (`alt-f`, `alt-b`). I like using the system key because it's essentially unused in Alacritty and it provides a clean separation between tools.

And actually, I didn't mention that my VinTmuxNav commands are bound to `alt-j` and the like so that I can still use `ctrl-h` and `ctrl-l` on the command line. [EDIT: ...and then alacritty binds `cmd-j` and friends to the meta version when inside vim]

And yes, can confirm you do need to make Alt be Esc+ in iTerm!


I'm personally a fan of byobu - it moves the shortcuts to function keys.


Byoby looks good, though I never use function keys. I like to keep (almost) everything as close to the homerow as possible, so I don't think I'll ever abandon tmux.

For example, to jump to specific windows within a tab, instead of number keys, I use `cmd-a`, `cmd-s`, `cmd-d`, `cmd-f`, `cmd-q`, `cmd-w`, `cmd-e`, and `cmd-r` for windows 1-8 respectively (I don't have one for 9 since if I ever get past 8 windows, they are usually throwaways).


The main reason for having function keys is that you can have their labels on the screen, and that's intuitive. You can see it with IBM's CICS. Otherwise they are not that useful, and you can see it in eg laptops making Fn a secondary function, with the primary being adjustment of brightness or volume.


Oh ya, I'm not against function keys or anything, just not for me. Switching to vim 10+ years ago made all my RSI problems go away so now I just like to keep my fingers on the letter keys as much as possible. I don't even like stretching to number row when I can avoid it (though I do all the time, of course).


This sounds silly when I say it out loud, but reaching for the number row always felt like a chore. Of course, when I had to input numbers, I'd still have to reach for the number row. But when numbers were optional, say for vim bindings that take a `[count]`, I opted to look for alternatives instead.

A few months ago however, I bought a moonlander keyboard. Now, I've got one of it's keys that, when held, maps the right side to a full traditional numpad. Typing numbers is much more seamless now. Besides numbers, other keys that always broke my flow (looking at you right curly brace) are much easier to type.

Just thought I'd share as it really elevated my overall typing/vim experience.


I don't think that's silly at all—I hate reaching for number keys and not afraid to say it :D

Another comment in here made think about using Karabiner to give myself a keypad with uiojklnm,. (or something). I actually did this when I used to use a flash-able mechanical keyboard, but I like working on my couch too much so I've been all-in on the short-scale apple keyboards for several years now.


Can you elaborate on Kitty or Alacritty? I couldn't find anything. In fact, the documentation is hostile again tmux [0].

[0] https://sw.kovidgoyal.net/kitty/faq/#i-am-using-tmux-and-hav...


Oh my—I actually just mentioned Kitty for diplomatic reasons as some folks feel it's a friendlier alternative to Alacritty. I've personally never used it myself. Alacritty has recommended using tmux from the beginning (originally it planned to never even implementing scrollback and recommended tmux instead, but they caved and now there is native scrollback).

I believe I used this article when I switched over from iTerm to Alacritty: https://arslan.io/2018/02/05/gpu-accelerated-terminal-alacri...

Otherwise, here's my alacritty config: https://github.com/sodapopcan/dotfiles/blob/f9eba86bf292aa3b.... Line 57 is where the keybindings start (They are annoying to read since they use escape sequences). I make my tmux prefix `ctrl-space` (because `ctrl-b` is useful), then in Alacritty pressing `cmd` sends `ctrl-space` to tmux.


I would add foot to the list: https://github.com/DanteAlighierin/foot


Just tried Alacritty on my Mac. With no special config. At first glance I find the fonts don’t look as nice as on iTerm. Maybe I’m missing something as to why this is supposed to be better than iTerm.


Among many tricks and tips, I recommend mapping `|` and `-` to split panes:

  bind-key | split-window -h
  bind-key - split-window -v
More on my wiki: https://wiki.rsapkf.org/notes/unix/tmux/


As an alternative for vertical splitting, using _ (instead of -) means both types of splitting require a `shift` which keeps it a little more symmetrical if that's how your brain works!


Depends on your keyboard layout. On my (Finnish) keyboard, | requires alt.


I switched from a German layout to a US layout, mainly because of objective-c with its []. Most default key bindings feel natural that way.


Ah right, fair enough!


I've bound the keys 'v' and 's' for vertical and horizontal splitting to match Vim's default bindings.

What tmux calls horizontal and vertical splits is inverse of those in Vim - hence -h flag for what most would call as vertical split. I suspect one of the authors was Australian!


There is ambiguity in vertical / horizontal split. Does it refer to the "cut" or the result?

In Sway and i3 if I make a vertical split and open a new window, it appears below (thus vertical), but the split was like a cut horizontally across. I've seen some people use the - and | keys for tmux splits which kind of avoids the language issues and turns it into which way the new line is drawn.


I recognize the ambiguity. I tend to think in terms of the result; so, in vim, I do vertical splitting because I want that result where the cleaving line runs vertically.


I don't use it a lot, but it's super handy to have this binding.


My favorite antipattern is, you can just leave a script that does an event loop running in the foreground, detatch tmux, and voila, you have a 'server'. Works great in a pinch or when you just don't need to finish it.


Add it within a infinitive loop + `sleep 10` and now it automatically restarts if it crashes too! :)


haha, exactly what I've been doing (yes, sleep 10 as well!) I also added bubblewrap for security and wrapped it all up in a nice script to list/stop/start services, see https://tobykurien.com/simpler-linux-selfhosting/


I've started doing this with a few programs using sleep 1 and a while loop. First was ncmpcpp as it would declare itself too small and quit sometimes when my terminal with tmux resized, this way it'd either reopen when I adjusted pane sizes to fix it or when I restored the whole window to the other size. Next I did it for stig because I'd often press q to quit by accident or because it occasionally hits an issue where you can't view a torrent's detailed info anymore, fixed by a restart. Lastly for the aerc mail client which will frequently stop being able to reach mail servers and tell me I can't archive mail or something, so I just quit it and now it restarts (not sure if there's another way to make it reconnect).


Also been doing this for years. And always wondered about possible disadvantages, or is there any reason why it is not used like this by everyone?


Oh I've definitely been doing it for years, but only for things I don't care very much about. For example, I used to have a password protected livestream of a camera that was literally an ffmpeg command running in a tmux session that would pipe MJPEG data to an nginx instance, and tmux was by far the easiest way to get it going. But the moment I want reliability, automatic restarts, or something easily reproducible, I switch to systemd or a Docker container.


Main disadvantages: restart services if they crash (so run them in a loop); security and isolation of services from each other and the OS; restart services on reboot. I've solved these problems: https://tobykurien.com/simpler-linux-selfhosting/


+1 Been running my servers this way, for years.


I've only recently started running my servers this way, and I've taken this to the next level with bubblewrap: https://tobykurien.com/simpler-linux-selfhosting/


Nice! From my experience, really what you want next is a working tmux-resurrect. Or, at least, all your services runners to be in .sh scripts (and not just in your so evanescant bash history)


Hmm, "evanescant" seems wrong... sure enough, that's an obscure Latin word, vs intended "evanescent" (~synonymous w/ "ephemeral", ie soon-disappearing).

PS comment is in spirit of knowlege-sharing not pedantry. :)


True.

[to be limpid, I just meant that a reboot could kill that server-in-tmux strategy ;P ]


Not sure if you read the linked article, but there is a strategy to restart services on boot, using crontab's @reboot feature


lol a startup I worked at literally have a prod web server deployed through tmux like this.


why? (actually curious)


Maybe never heard of systemd


I do this all the time to run data acquisition systems for accelerator experiments. It also allows multiple users to connect at once. We have our whole analysis pipeline hosted in tmux sessions too.


But... why not nohup then? Should work just as well, and it's POSIX


The best way to use tmux is with -CC, which iTerm maps to native UI. tmux tabs and panes become native tabs and panes and your session is immortal, and it’s a far better experience than mosh or whatever the latest thing in this area is. I have never bothered to figure out how the keybindings actually work and I probably never will, but I enjoy using it all the time because of this.


I had trouble getting the tmux setup working in iterm.

The main page suggests -CC, but the best practices wiki[0] says to use `-CC new -A -s main`, but this causes iterm to warn that a session is already started and doesn't actually create or reattach like I expected. I also had trouble getting the tmux select-layout to work: when I tried it all my panes just exited with an error. I would like to have iterm behave similarly to Kitty's tall layout[1] which I think is the same thing as tmux's main layout, but haven't figured out how to make it work. Anybody have tips on making these wek?

[0]: https://gitlab.com/gnachman/iterm2/-/wikis/tmux-Integration-... [1]: https://sw.kovidgoyal.net/kitty/layouts/#the-tall-layout


The other great reason to use iTerm to run tmux is that copy and paste work correctly.

I started doing this last week along with tmuxp for managing window sets. It works great.


Is there yet any linux terminal that supports tmux -CC mode? iTerm is not coming to Linux, and using tmux on anything else feels really meh.


https://github.com/wez/wezterm/issues/336 is tracking that for wezterm although I can attest that they're right, it's pretty rough right now

I thought there was another one, but searching for "tmux" in the issues of the major terminal emulators is worthless since there are so many pages


Agreed 100%. This is iTerm2's killer feature IMO, and it's the only thing that keeps me on a Mac for my work laptop.


does all of this work with the tmux keyboard shortcuts? the main reason I use tmux is to avoid the mouse...


You use iTerm shortcuts instead. You can customize those as you like. So it feels just like using iTerm, but the panes are running in tmux.

The main reason to do this (for me) is to use (tmuxp)[https://tmuxp.git-pull.com] to configure window sets for different projects / clients and start them up quickly.


Indeed — one of the best tips I learned from HN is to use iTerm2’s Tmux integration so I never have to even think about tmux commands other than tmux -CC to start a session and tmux -CC attach to reattach.


Oh hey there, I wrote a whole book with the same title of this post. Love to see more tmux love!

If you dig this and want a whole book that goes into more depth, check out Getting Started with tmux (the book, not the ittavern.com blog post :P)

https://gettingstartedwithtmux.com/


I've used Tmux/Screen the few times I've had to be in an actual terminal, but don't really see the use for them when using a GUI terminal emulator. I just open new tabs or (rarely) windows as needed.

Could anyone using these explain what it provides that you find useful in practice? I rarely ever need persistence of shell when I close the console, is that a common need? Familiarity/muscle memory of shortcuts is a valid answer, but I'm wondering if there's more to it than that.


Say you have a document you are working on in LaTeX over a few weeks. You might have the command line for compiling, bibtex, and git in one pane, then vim or equivalent in another.

Now say you will be moving between home, office, and traveling. If the tmux session is hosted at work you can connect from anywhere and be in the same workspace with the same command history. If you have a dozen other projects happening at once this system can also be a big help as far as organization.


Thanks, connecting to a remote tmux session makes a lot of sense to me. It hasn't been a significant need in my work so far, but it's something useful to keep in mind when those scenarios arise.


Working locally: When you want multiple windows configured more compactly or more customization than any gui emulators. But it really shines for remote work where you’re not running a vnc, where u have a persistent terminal session, maintain all windows etc if you get disconnected.


Doesn't it drive you crazy to lose your work whenever X11/Wayland crashes, or you have to kill your display server to diagnose a problem, or you accidentally close a terminal window?

tmux preserves everything for you unless you explicitly kill it, or you have to reboot.

I started using Screen like 20 years ago (and later moved to tmux) and I can't go back to doing real work in a "bare" terminal window. It would feel like walking on a thin layer of ice on a lake; as soon as something goes wrong, it's a minor disaster.


Well I use Mac these days, but I've used FreeBSD and Linux in the past as a desktop and don't remember this at all.

In the unlikely event everything locks up and dies then mostly I'll just lose vim sessions, and I can vim -r to recover the data. This is rare, and vim complains at you when you start it up on a file after it has crashed.

You'd lose the window layouts, but I don't use crazy window layouts, generally no more than two panes for code+tests (running tests I let it flip to fullscreen and scroll and I've got that bound to a key combo in .vimrc). If I had crazy window layouts I'd probably setup a command alias to make it easy to pop them up.

When it comes to commands and such, I just use the command history which is my memory. When it comes to running daemon process I would detach them if I cared (and generally I've got command history so I don't care, I'll just restart it, no matter how arbitrarily complicated it was to get the command running).

Similarly, though, I don't horde tabs and I HATE it when the O/S starts popping open all the windows I had open after a reboot to upgrade the O/S or whatever. I try to run pretty much "statelessly" so that I can wipe everything and start over from nothing easily enough (obviously not really "statelessly" since e.g. slack remembers all kinds of state about what I've done in the past, but I don't have to remember any of that)

And my memory does suck, but I know how to pull things out of command history, internet search, google history, etc. If I need to track stuff, then I use a tool to track it so that it becomes persistent (Zotero has now replaced my folder full of PDFs, I take notes in Obsidian). I don't know what I would ever lose in a terminal window that I fundamentally couldn't get back (and if I ever really needed something such as some unique failure I'd probably take a quick screen shot or copypasta into a note file somewhere -- I'll commonly copy test failures into code comments temporarily while I'm working on them -- sometimes these get promoted to documentation in particularly hairy edge cases).

So I literally just pulled up iTerm in activity window and force killed it and I have no idea what disappeared, but I don't care... Based on the saved command history I can see I likely didn't lose anything at all...


In roles like research it happens that one spends tons of time on the command line. It's normal for me to have spent more time in a week running commands in the terminal than writing code.


I use tmux in a GUI terminal emulator (KDE's Konsole) for a force of habit. It's nice to have split views, tabs and sessions, though Konsole offers tabs and splits, but it's nice to have them when you need to go to a TTY and having your session running there too as if nothing had happened.


As a heavy GNU Screen user for the last 2 decades it’s always in the back of my mind if I should be switching to tmux. Maybe there is a compatibility mode.

For those who switched from screen what was the biggest benefit?


I used screen for about a decade before switching to tmux. The biggest immediate benefit was that terminal configuration across systems was much less brittle. My backspace key backspaced, color consistently worked, etc. Over the past 10+ years of tmux use I've become increasingly more sophisticated in my usage (in particular 1) nested tmux sessions, 2) heavy use of the kakoune text editor's tmux integration), yet my .tmux.conf file has all of 15 lines of content. One other thing: tmux has yet to crash on me, but screen certainly did so numerous times.


For me it was that tmux worked out of the box the way I spent many hours getting screen to work the way I wanted. And then from there, just in general the docs were better, it was updated more often, and in general was a bit less obscure in how it was configured.


Here is my .tmux.conf file. It has a small tutorial at the top of the file and also maps the PREFIX key to ctrl-a so that it feels like screen key bindings.

https://github.com/jftuga/universe/blob/master/tmux.conf

What I like about this config is the "mouse mode". When you split a windows into multiple panes, you can press ctrl-m to go into mouse mode. Within mouse mode, you can use the mouse to resize panes. Outside of mouse mode, copy/paste works better.


This was me. At first it was just like “Hey, prefix is C-b instead of a C-a, so it messes with less” (i.e readline, emacs), then I started to understand the windowing better and it feels a bit more natural with modern terminal emulators. And yes, I know the prefix can be changed.

Overall, I’m still comfortable switching back and forth, but it seems like tmux is the new hotness, so I’m using that most of the time. It’s a bit easier to style, etc.


I like the ergonomics of tmux, but one thing I like about screen is it works as a terminal for serial devices. It's something I use for connecting to my HP and Cisco switches; also Raspberry Pi and Beaglebone boards. Tmux doesn't do that.


tmux can't do anything related to real serial lines. And if you do launch tmux via serial line, tmux is hard-coded to disable software flow control. Its basically for utf8-capable terminal emulators only.


I wrote a decent amount about that here https://www.victorquinn.com/tmux-tutorial

tl;dr tmux has much easier configuration, it is more actively developed and maintained, and now (this isn't in my post) a richer add-on/plugin ecosystem


i switched a long time ago after one too many weird screen bugs, and i've never looked back. at this point i couldn't say why it's better, but you won't regret switching unless you regularly find yourself using boxes without screen.


For me, it was tmux mouse mode, The window names in the status bar become clickable.


I use iTerm locally and tmux on a dev instance and it's great. The built-in tmux integration[1] is a pleasure to use. On my end, I see a terminal with tabs; if my ssh connection drops, I can just reconnect and magically all the tabs and their states are persisted. In lieu of this integration, I enable the tmux mouse mode which lets me highlight text with the mouse, navigate around splits by clicking in them... great piece of software :)

[1] https://iterm2.com/documentation-tmux-integration.html


does the integration work fully with tmux key commands?


This is my single most repeated action on a normal terminal window:

* Clear and discard all scrollback history: Ctrl+Shift+K

* Start a program run

* Select all output: Ctrl+Shift+A

* Copy it: Ctrl+Shift+C

* Paste it somewhere else

A total of 3 key combinations, that are now second nature.

When I installed Tmux and tried to replicate this, I only found a sea of gotchas. No key binding by default for clearing the scroll; similarly, no way to select all text with one single keypress; no way to copy the selected text so I can paste it in other applications.

Given enough time, of course, all of these can be solved one by one, assuming enough motivation and free time (use custom configs, configure xclip, etc) but the default onboarding experience was a bit poor, to be honest.

This is not a fault specifically of Tmux, but more of the typical lack of cohesion between different components that are considered independent tools albeit from the user pow they are arguably part of the same thing.

I might have to revisit Tmux by means of Byobu [0] and see if this time it clicks.

[0]: https://www.byobu.org/


Why are you copy pasting? I'm sure you know about stdout redirection, so I'm intrigued why this process is required. I'm guessing you're pasting logs into some gui system?


I like starting from a clean slate and having only the output from last run of my program, so that's why the clearing screen step.

Then, the copy-paste is not done always, but it's done a lot when analyzing logs or debugging some issue. I prefer to read that output with the much more advanced filtering and searching tools that I have installed in my VSCode editor.


After years of wrestling with configurations and dot files, I have finally realised that if you use a new tool, you should learn to use it properly and as intended by the author instead of trying to make it behave similar to some other tool you know well. At least for the first couple of years


I've only used tmux for about <year now but I immensely enjoy it.

One of my favorite scripts to run is a tmux script that creates a new session with about 7 windows of running my company's project (one window for notes, 3 windows for the backend (runner, code, tests), and 3 windows for the client (runner, code, tests). It's even tweaked further to open up the code in vim, and when used in conjunction with something like harpoon.nvim I have access to my most used files with a few keystrokes. I now create similar scripts for all projects I work on for lengthy periods.

One script builds and runs the environment in the way I prefer to work. Tailored to my taste, for me.

Probably the best advice that I always took to heart was a co worker telling me to "just learn the command line." He really took the phrase "learn your tools" seriously. Now, after some decent experience, I finally feel like I have a decent box of specialty tools when heading to any job site.


Also check out tmux-resurrect to save and restore tmux window/pane config including working directories and scrollback. It can also restore running programs, which is sometimes a reasonable thing to do.

https://github.com/tmux-plugins/tmux-resurrect


I have been wanting this for years! Thanks for sharing


This is exactly how I was introduced to tmux and learned to love it. Joined a web dev company who’s workflow was to start a swath of back-end servers each in a tmux pane. There were more than a dozen, so the tmux launch script made it simple and manageable. It’s nice to have the outputs in separate terminals, and to be able to restart them because the command’s in bash history, among many other little niceties.


This sounds like my setup! I literally have 1 button startup for starting all my normal programs (including split tmux windows, each running appropriate startup commands for what ever process they need) and it moves all my windows into their regular positions. I usually get into to work, plug in the laptop, press my button and go make coffee :)


Did you check out tmuxinator? Sounds like you reinvented it, cool, but maybe there’s some inspiration to be had.


> Sounds like you reinvented it

Tmux comes with the ability to script it, intentionally and by design, and it’s very straightforward and simple to open several windows that launch commands in them. Tmuxinator doesn’t reinvent that, and it does add another dependency, and another layer of options and flags and project syntax to learn.

The suggestion to check it out is great, but saying that people who don’t use it are reinventing it is a tad heavy handed. There are good reasons and legitimate scenarios to keep it simple with tmux scripting alone.


Absolutely. I think it depends on ruby, too, which is unusual. It’s anyway got some good ideas - declarative config files, etc.


I have not! I'll have to investigate more, because my little shell script is pretty basic (like 20 lines total, most of which was done for readability).

https://github.com/tmuxinator/tmuxinator


Not the OP, but I did riff off of tmuxinator recently. tmuxed talks to tmux directly out-of-band to avoid running over user input and supports things like "wait before sending more input" for cases where `sleep` isn't desirable. I envisioned it being an orchestrator layer over tmux rather than a "new thing" to learn; while it's largely finished for my normal use cases I've been thinking about how sometimes it'd be awfully useful to be able to orchestrate tmux commands and not just send-keys.

Single binary, too, so no Ruby dependency. I really should get it into Homebrew one of these days...

https://github.com/eropple/tmuxed


I do this too! [1]

It's amazing how well tmux works as a project setup tool.

[1]: https://gavinhoward.com/2020/12/my-development-environment-a...


And just like learn your tools, also “make your tools”. This is what we do all the time. This is why we compare ourselves with craftspeople. We have in common that working on the craft includes improving and making your own tools to get the best result.


Yes! I'm slowly moving towards these steps, it's my excuse for learning go and rust. There are some CLTs that don't exist for my need and I'm working towards creating them.

I don't know if you've heard of charmbracelet [1] but they are a company that makes a lot of cool go libraries to assist creating CLTs and TUIs. One of which was on HN recently, VHS [2].

[1] https://github.com/charmbracelet

[2] https://github.com/charmbracelet/vhs


Could you please share your script?


Can't post the specifics but something like this as a bash script, if you have any Qs LMK:

#!/usr/bin/env bash

tmux new-session -d -s sessionname

tmux rename-window todo

tmux send-keys -t todo "vim todo" Enter

tmux new-window -d -n dot

tmux send-keys -t dot "cd " Enter

tmux new-window -d -n windowname

tmux send-keys -t windowname "cd ~/reponame" Enter

tmux send-keys -t windowname "commands to run" Enter

tmux attach-session -d -t sessionname


I would add Prefix + z for temporarily maximizing/minimizing pane to the full windows is very useful.

Config doesn't have to be very complicated, I've used this for a while.

  set -g mouse on                # allow mouse
  set -g history-limit 999999999 # unlimited history
  set -sg escape-time 0          # vim esc response faster


If you're used to Vim key binding, you should feel at home with tmux after setting up Vim-like keybindings to move around (select panes/windows and resize):

  bind h select-pane -L
  bind l select-pane -R
  bind k select-pane -U
  bind j select-pane -D

  bind -r C-h select-window -t :-
  bind -r C-l select-window -t :+
  
  bind -r H resize-pane -L 5
  bind -r J resize-pane -D 5
  bind -r K resize-pane -U 5
  bind -r L resize-pane -R 5

I read Brian Hogan's 2012 edition of "tmux: Productive Mouse-Free Development". It was short and made me comfortable enough with tmux that since then I rarely ever use the terminal without starting a tmux session first. I see now that the book has been revised in 2016 for tmux 2 and perhaps I'll re-read it to see what I've missed.


I've been using tmux daily for more than a decade and didn't know prefix+! converted a pane to a new window.


I recommend to everyone, if you are using a tool regularly, take half an hour of time to study its man page. This way you'll learn about all the things that your tool supports but you haven't been aware of yet.


I agree, and would like to add: do this once in a while with all your tools, even ones you have read the manpage for. Even ones you have a high level of proficiency in... New features get added that you might miss. When you first read the manual there's a good chance you either missed something or didn't understand how cool feature xyz is (e.g. because it's a feature that only makes sense once you are proficient with the basics).


I’ve been using it for years as well and had the exact same thought!


I use URxvt and a systemd-run to daemonize tmux even if I close my graphical session.

I use a function for the local tmux session and an alias for remote ssh tmux sessions, with a different bindings (MOD+x & MOD+w).

Like that I am always in tmux localy and remotely just by launching URxvt.

    # open a new tmux session named ssh_tmux or attach to it
    alias tmuxs='tmux new-session -A -s ssh_tmux && exit'
    # open a new default tmux session with a named default or attach if it exist
    tmuxa () {
        systemd-run -q --scope --user tmux new-session -A -s default "$@"
        exit
    }

    # run tmux if TMUX variable is null
    if [[ "${TERM-}" != tmux* ]] && [[ -z "${TMUX}" ]] && [[ -z "${SSH_CONNECTION}" ]]; then
        tmuxa
    elif [[ -z "${TMUX}" ]] && [[ -n "${SSH_CONNECTION}" ]]; then
        tmuxs
    fi


My favorite mod is something simple as renumbering the windows/tabs to range starting at 1, rather than being zero indexed, this way they align with the digits on my keyboard.


Yup! That is such a major improvement. I just wish there was a way to start sessions with 1 index. The inconsistency drives me nuts!


yeah, this helps immensely. I also remap the leader key to backtick so that it's a single handed, two-key motion to switch windows.


Since no one's mentioned it in the comments, I occasionally use tmux's pane synchronization to run the same command across multiple panes: CTRL-B, then "set synchronize-panes". I've done this to do things like log into multiple different servers and startup some process all at the same time. 'set synchronize-panes' toggles this behavior, so when you're done, run the same command again to disable it.


The only extra thing I want from tmux is to persist sessions across reboots and shutdowns.

I found a plugin called tmux-resurrect but it would be nice as a base feature.


I use https://github.com/tmuxinator/tmuxinator for my workspaces. Doesn't save ad-hoc layouts, but usually I find one layout that works per project, then create a tmuxinator config for it, so after reboot, it's a short "tmuxinator start $my-project" away to get back to how I want it to be.


https://tmuxp.git-pull.com/ does the same thing, but I think it's smoother to work with. It does support freezing current panes. yaml config


I like tmux a lot more once I started using ` as prefix


There are dozens of us! Dozens! :}


Tmux is the one tool I use every day at every company I've been with. At my current employer we have a lot of new grads and I strongly encourage them all to use tmux. We have a about a third of our devs on tmux now and they all love it. I have converted many devs, young and old, to use tmux. Once you get the hang of things you are hooked and you can learn 80% of tmux in 10 minutes.


Here's a kind of dumb question:

Are the primary usecases of this for SSH, or for non-tiling desktop environments? People say a lot of good stuff about it, but I struggle to figure out what it can do for me when I'm just doing stuff on a local computer, where I can just create new terminal windows.


To some extent it's mostly equivalent to using terminal windows. You can do other stuff w/ it but most of the time it's for managing lots of panes/windows. Personally I really just like its UI and it works really well w/ my workflows. I actually used to run tmux + vim splits + i3wm and managed to find myself really using the heck out of some really gnarly tiling schemes at times. Talking 10+ panes of really tiny windows at once, just on the fly. And then when I need to zoom in on one file in some pane, boom, ctrl+b+z and it's maximized.


These days I mostly stopped using tmux over ssh. If one can install software on a remote system, then I just run a VNC server and use a GUI editor or IDE to edit things. The big plus of this is that copy-paste just works and I can use various shortcuts that are problematic inside a terminal emulator. And if one can use xpra, then running a GUI terminal remotely over a fat but high-latency link can be faster than using tmux on a remote system. The terminal protocol was originally designed for slow but low latency links and is not good at latency hiding.

And if I cannot install, then it is likely that tmux is not available either. So I use lsyncd to edit locally and transfer the edits to the remote system. For running commands I just run ssh host command then.


> For running commands I just run ssh host command then

That's fine, right up until the point you're running a command (or a series of commands) that change things on the machine and your connection gets broken. When that happens there's a very good chance the command being executed will fail in some fashion. If you're very lucky it won't be a big deal, but depending on what you're doing it could be dangerous.

I would strongly advocate for using either screen or tmux as a matter of course on any remote server when you're executing commands on it. You don't need to do anything more with them other than just have a single window in it. You just don't want the command execution to be specifically tied to your SSH session.

At the very least, screen or tmux enables you to get right back to what you were doing with no loss of output, and at the most it enables whatever commands you were executing to finish executing without risk of broken pipes killing them mid-flow or whatever else might end up being catastrophic.


Typically the commands that I run this way were idempotent so it does not matter if they fail. On the other hand having them in the local shell history is nice since I can preserve that while the remote system can be a transient container where history is not preserved between restarts or it may not even have bash in the first place, just a minimal shell with no history saving support. Plus tmux or screen even when available still sucks at quickly scrolling with mouse and copying the selected text.


> That's fine, right up until the point you're running a command (or a series of commands) that change things on the machine and your connection gets broken. When that happens there's a very good chance the command being executed will fail in some fashion. If you're very lucky it won't be a big deal, but depending on what you're doing it could be dangerous.

I spent 5 years at Amazon (back a long time ago) being incredibly aggressive with command line root-trust from the old bastion host they had there, working up to regularly executing ssh commands to all 30,000 servers (like I said it was a long time ago, but that's still a considerable stack) every single day. It is the kind of idea that gives a lot of people the vapours to think about, and I wouldn't recommend it if you had good alternatives. But Amazon never turned into a smoking hole, and I never once saw this kind of problem. I certainly had to deal with network issues, and the scripts I used were pretty robust against problems. Most often servers would be crashed and fail to ping, packets would get lost but retransmissions would succeed, or the kernel would be hung only responding to interrupts and userspace was all deadlocked, but sometimes the servers had some resource starvation issues and it would just be very slow and the command would timeout. Nothing bad every happened. I occupy some weird space though where I'm stupid enough to try these kinds of things and just careful enough to not get bitten by them. I've also been a trained cave diver for over a decade now as well (if you get the training and follow the rules, it is safer than driving on the roads in Mexico).

And really you should always be using configuration management to change the state of servers and should have some kind of agent doing that automatically for you (although I've broken that rule probably a thousand times myself), and you should also ensure that what you're doing is 'idempotent', so that if it fails due to some transient error then you can just keep on hammering on the server and the next time or the time after that or whatever it will fix itself. This is the "self-healing" or "computer immunology" concept of configuration management that Mark Burgess came up with back in 1998 or so. If the process gets interrupted just run the process again. That may require some care taken around intermediate states and recovery from intermediate states, but that is just config management 101.


My favourite tmux trick only works on an apple gb keyboard:

    set -g prefix `
    bind-key e send-prefix
Then, all your tmux controls are one left pinky press away (` is beside z on uk Mac keyboards).

(`e sends a ` for when you need it, rare though, $() is better for sub shells :})


Unless you already took that mentality to the next step, and put your Esc key where the most people have their backtick key, with the (comparatively rarely used) backtick key on a second layer.

But then again those types of users are also likely already hyper aware of hotkey modifications and optimizations.


esc is caps lock (vim user) -- although this has the unfortunate effect of making other devs machines virtually impossible to use since for 20+ years I've used caps-lock-as-escape and it's muscle memory now...


I use backtick as my prefix as well, plus 1-indexed window numbers. I guess it's a bit farther away than yours, but it's still wonderful.


I’ve had to stop using tmux on macOS (MacBook Pro 2018).

For some reason I kept getting extreme slowdowns/laggy behaviour when using neovim.

I’ve seen this thread: https://github.com/tmux/tmux/issues/353

I tried everything in the thread and still end up with a laggy terminal. For now I just use iterm2 with tabs but I miss my tmux.

On my personal Linux laptop, I never encounter the same lag with the same setup.


iTerm2 actually offers nice interfacing with tmux. If you run `tmux -CC` it will start a tmux session that iTerm abstracts away letting you split and switch panes as you normally would in iTerm, but still allowing you to join the tmux session on another terminal.

https://iterm2.com/documentation-tmux-integration.html


That looks interesting, I’ll have to give that a try thanks!


Favorite tmux conf change: new pane/window in cwd

    # split in pane cwd
    bind '"' split-window -c "#{pane_current_path}"
    bind % split-window -h -c "#{pane_current_path}"
    bind c new-window -c "#{pane_current_path}"


Yes!! I've terrible memory ... these are my mnemonics instead

"|" -- for vertical split

"-" -- for horizontal split


If you use a WM with multiple named workspaces/tags - it is nice to have a key binding to run a terminal with a startup script (instead of the default shell) that creates or attaches to a tmux session with same name as the currently active workspace.


I recently decided to give terminal multiplexer a try. I first used tmux for a couple of weeks and then discovered zellij. It felt much more user-friendly, but I don't know how much I am missing out in terms of useful features compared to tmux.


I like zellij, it has some bugs and seems to leak memory for me. I think it’s a it easier to get configured and set up though. Seems like it might be great one day though.


Tmux made my first months with linux on server way easier

Great tool

I just wish that eg windows' (os) terminal was smarter when you have eg two windows in tmux next to eachother and try to select line or text with mouse then it was just selecting from one window, not many or all


Looks like no one has mentioned https://github.com/gpakosz/.tmux

You still need to learn the basics but this lowers the learning curve a lot.


For Windows users: Install Windows Terminal and enable WSL. WSL or WSL2 are both fine (I use both). I have like 10 tmux sessions going in 2 or 3 tabs. It's a whole new level of CLI on a Windows box. Loving it.


One important feature is to enter copy mode, select and copy text without using mouse

enter copy mode: LEADER [

highlight text to copy: press space and then arrow w and b to highlight words (like vi editor)

exit copy mode: press enter key or Q

paste copied text: LEADER ] OR cmd+V


I used to use TMUX user, back in the days when I could SSH to servers. Now days, using a containorized stack (K8s) with cloud native deployment infra/tooling, cli's for accessing the remote resources, rigid access restrictions, etc. I found that I was only using it for managing multiple windows/panes for my local tooling. And have simplified my setup to just doing that inside local Terminal software (iTerm for me right now). (No more configuring copy/paste, scrolling buffers, custom key-bindings so they don't interfere with other emacs, shell bindings, configuring the prefix binding because hitting ctrl-b before each command is annoying, etc.). I used to also use tmux resurrect to persist between sessions, etc. but it often failed me as much as remembered where I left off.

My TL;DR: sure, use Tmux if you're directly accessing remote resources often, otherwise there's probably simpler solutions that might get you 95% of the way there.


Is there any way to make it look “real purdy” like Windows Terminal with the git profile. ls shines and vim pops with gorgeous magentas - pure terminal nirvanasphere.


One of the best software I've ever used, it's addictive. Did anyone manage to get it set up on windows? And if you did is it buggy or does it run smooth?


I use TMUX all the time inside Gitbash for Windows. Some panes are SSH sessions into Linux servers etc. While other panes I use vim to edit local Windows txt files or just run other local Windows things. (This mightn't be what you were looking for)


If I could get that in cmd and powershell it would be perfect. I have to use cmd at work. I use gitbash for other stuff like you do but cmd is where I really need tmux.


I love tmux but there is one thing that really bugs me: why isn't mouse support enabled by default?

Annoys the hell out of me every time I used it on new machine.


I wish the 256 colour setting was enabled by default. I always end up adding the following to my .tmux.conf file:

set -g default-terminal "screen-256color"


Hint for more advanced users: Tmux inside tmux works not that bad. (Ctrl-B Ctrl-B becoming the prefix for the inner Tmux-es)


Even better IMO is to use different prefixes for outer vs inner tmux sessions. These are the first lines of my .tmux.conf:

    # Use C-a for outer sessions, and C-x for nested sessions.
    unbind-key C-b
    set-option -g prefix C-a
    bind-key -n C-x send-prefix


Great crib article. Would be nice to adapt the webpage for mobile screens a little bit better.


Done. Thanks for the feedback. Desktop simulation didn't catch that.


just got introduced to it whilst traversing this course which I highly recommend regardless of technical level https://missing.csail.mit.edu/


Does someone know about a way to get autocomplete into tmux? Something like iterm2 has


iTerm2 has a native tmux integration mode, where tmux windows become native tabs/windows, with native scroll back etc.

https://iterm2.com/documentation-tmux-integration.html


is there a text based window manager that's browsable and uses the arrow keys?




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: