Workflow in Tmux
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 tmux-?
.
sessions
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 :new
, then cd
to the folder I need, and run tspace
to name it after the project and set the folder defaults.
windows
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 [session]:[window]
syntax.
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.
panes
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.
final thoughts
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.
Written by Evan Travers
Related protips
14 Responses
Check out tmuxinator gem for that setup script
I use teamocil (https://github.com/remiprev/teamocil) to quickly spin up windows and panes when I load up a new session.
Also check out tmuxstart (http://github.com/treyhunner/tmuxstart). I made it because I didn't like teamocil or tmuxinator. I like your tspace script shortcut. I need to add default-path to tmuxstart.
Hey, can you tell me what vim colorscheme you are using?
Probably the silliest question, but I totally want the breadcrumbs-like separators for the status bar and I'm wondering if you're using a special font or something, because I can't figure those triangles out.
@bogdan-dumitru See powerline (https://github.com/Lokaltog/powerline).
@tapanpandita Solarized (http://ethanschoonover.com/solarized).
@cstrahan Awesome, thanks a lot! Totally pimped out my workflow now :)
Personally I use my own Tmuxifier project to load up complex window/session setups for different projects/clients... https://github.com/jimeh/tmuxifier
What terminal program are you using? I can't get solarized to fully work in terminal.app for the life of me. I've tried ANSI and xterm-256. I even did an environment dot-file wipe and installed your polka, and still it didn't work right.
iTerm2 is the only way to go on mac.
@pj brunet: there are mouse options with tmux:
Enable mouse support
set -g mode-mouse on
set -g mouse-select-pane on
set -g mouse-resize-pane on
set -g mouse-select-window on
Rather then maintain a separate script like "tspace", it seems cleaner to me to add this directly to your .tmux.conf via a bind-key assignment to run-shell. For the (second part of) the "tspace" script you can use:
bind-key S run-shell "tmux rename-session $(basename $(pwd))
@joefortier Now that is wise. Thanks!
I'm really addicted to Tmux. One of the best tools Linux has to offer.