Tmux has three levels of hierarchy when it comes to organizing views: Sessions, windows, and panes. Sessions are groups of windows, and a window is a layout of panes. Windows and panes are to a certain degree interchangeable as we will see, but sessions are fairly immutable. I use sessions to separate workspaces, almost like the spaces in osx. Windows and panes I use as is convenient.
I recently have been digging into some of the neater features in tmux's layout system, and here's what I've come up with to help me work harder better faster stronger.
A couple notes: I have set the tmux key to be
ctrl-g, but you can use whatever you want. For the course of this article, I will use
tmux+[whatever] to avoid confusion when describing tmux shortcuts. My tmux config can be found here, and there are some other theme settings here. When I refer to starting the tmux console, I mean keying in
tmux-:. Never forget that you always have access to your current shortcuts by typing
Because I tend to isolate projects to a single session, allowing me to have a complete context switch when needed, I tend to name them the project I am working on, and force their default folder to the project folder. You can switch between sessions using
tmux-s, rename them using
tmux-$, and set their default folder by running
tmux set default-folder $(pwd) inside the session. This last command means that any split or new window inside that session opens in your current folder, which is handy for making a split so you can run a rake task or a script console for your rails project.
I got tired of doing this every time I made a context switch, so I wrote a little script to do this for me. Super simple, every time I need a new session now I simply
tmux-: to get the tmux console, type
cd to the folder I need, and run
tspace to name it after the project and set the folder defaults.
Windows in tmux have a name, and a sort number. They live in the bar at the bottom of the screen, ordered by their sort number. You can refer to them in tmux by name or number, which is kind of handy. By default,
tmux-, is rename window,
tmux-. is move window, and
tmux-[number key] lets you jump around your first ten windows. I used to think that move window only let you set a new order number for your window, but I have since learned that you can pass windows between sessions fairly easily using the
If I want to move a window containing my irc session (named irssi) from my current session
foo to the new context session I've created (
bar), I can either invoke the console and type out
:move-window or type
tmux-. to get the same thing, then pass the argument
bar:irssi. By default, tmux accepts your current window as the argument, but you can move a window you are not currently on by using the
-t -s arguments to specify the target and source of the move.
So I've been juggling my irc channel around for a couple of months, before I stumbled on
link-window. If you invoke the tmux console, type in link-window, and you can share a window between two sessions, using the same target/source syntax as move. That means I can have the same shell, or the same program shared between multiple sessions. No more juggling the irc window, I can simply have it everywhere.
Splits are usually the reason people find tmux in the first place, as the version of GNU screen that OSX ships with doesn't do vertical splits for some unknown reason. Horizontal splits are
tmux-", and vertical are
tmux-%. You can rotate your splits around using
tmux-space, though I've never found a good use for it. More useful is the select layout options available by using
tmux-[meta+1-5] options, letting you select a variety of layouts. I tend to keep things fairly simple w/ only one or two splits, so I haven't dived heavily into this yet.
Of course, moving between panes is usually
tmux-[arrow-key], but in my polka config I've set it to the vim keybindings, naturally.
One neat trick you can do, is pulling a window into your current setup as a pane using
join-pane. Once again using that cryptic -t/-s syntax, you can do some useful things with it. One example I use occasionally is pulling in the window containing the rails server into my dev window so I can access the
binding.pry session for debugging. For this, I would use
join-pane -t 1 (assuming it's number is 1, I could also use it's name). I can even yank it from another session using the
[session]:[number|pane] syntax. When I'm done, and I want this pane to go back to being another window, you can use
break-pane to break the pane back out to being a window.
Because all the tmux commands are also available in the console, and because everything you type in the tmux console is also available by running
tmux [command] in your terminal, you can script out workspaces and split setups. I'm considering writing a script to set up my splits and windows for a rails project the way I like them, and building perhaps an argument into the tspace script for different layouts. As with all your tools in the command line, think about what you do constantly over and over again, and consider how could script that into being one step. These tools are powerful not because you can use the keyboard instead of a mouse, they are powerful because you can combine them in new ways.
I've also been playing around with wemux, which is a nice little wrapper on top of tmux to allow remote pairing using tmux. It's pretty nice, and if you like doing pair programming in your office I recommend you check it out.
If you have any questions, or any amazing tips you'd like to add to this post, hit me up on twitter at @evantravers. Please let me know if this was helpful, and if some of these tricks help you focus on your work as you make amazing things.