I sit at my desk, boot my computer and fire up a terminal window. Cd into a project directory, start, and SSH into a VM. Open a new terminal window, cd again into the same project directory, change the terminal window, type, click again, drag, click…
The mouse! While it was introduced to make things easier when interacting with a computer, from a developer point of view, it turns out to be the devil in disguise, an eternal enemy to productivity. But there is an alternative.
I discovered tmux when browsing 'The Pragmatic Bookshelf'. Tmux allows you to switch between multiple programs in one terminal and detach/reattach them as required – all without the hassle of using a mouse.
I read I could use tmux to multiplex several virtual consoles inside a single terminal window, how tmux is scriptable, extensively configurable, and how it could automate the starting up of development environments.
I decided to give it a go. Here I share my experiences and tips for killing the mouse and boost your productivity.
- Setting up Vundle
- Solarized Colour Scheme for Vim
- Tmux installation via Homebrew
While it is possible to install only tmux via homebrew, you will encounter a problem with colours when using vim within a tmux session.
VIM in default terminal
VIM in tmux session
To solve this, I firstly installed Vundle and the Solarized colour scheme. Vundle is plugin management utility for vim.
Vundle allows you to...
- keep track of and configure your plugins right in the .vimrc
- install configured plugins (a.k.a. scripts/bundle)
- update configured plugins
- search by name all available Vim scripts
- clean unused plugins up
- run the above actions in a single keypress with interactive mode
- manages the runtime path of your installed scripts
- regenerates help tags after installing and updating
For more information on Vundle, visit this Github repository.
- Clone vundle repository into ~/.vim/bundle/vundle
clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle
- Configure Vundle by editing your .vimrc file and add the following:
set nocompatible filetype off set rtp+=~/.vim/bundle/vundle/ call vundle#rc() Bundle 'gmarik/vundle' filetype plugin indent on
- With the above set up, open a new vim instance and run : BundleInstall
$ vim #any file will do :BundleInstall
If all goes well you’ll get a 'Done' message.
Solarized colour theme
The next step is to add the Solarized color theme. Edit your ~/.vimrc file and add the following:
Bundle 'altercation/vim-colors-solarized' syntax enable set background=dark colorscheme solarized let g:solarized_termcolors = 256
We can now install tmux. It can be done on a Mac with Homebrew.
brew install tmux
To verify all went well, open a terminal window and start tmux by typing:
Then terminate the session by typing:
- Starting tmux named sessions
- Detaching and re-attaching from a session
- Killing a session
Tmux allows naming sessions. Named sessions come in handy when we want to leave tmux running in the background and re-attach to a session at a later stage.
For example, let’s say we need to start the 'tail' program on a remote host and then switch to a completely different task. Most of the times we would execute a program in a different terminal window, minimise it and start the following task on a different terminal window or tab.
With tmux sessions, we can start a new named session, detach from it, and start a new session all in the same terminal window, without even touching the mouse.
To start a new named session:
$ tmux new-session -s <SESSION NAME>
$ tmux new -s <SESSION NAME>
To detach from this session:
$ tmux detach -s <SESSION NAME>
To re-attach to a session:
$ tmux attach -t <SESSION NAME>
To kill a session:
$ tmux kill-session -t <SESSION NAME>
The PREFIX is a keystroke combination used to send commands to tmux. It is by default set to CTRL-b and is the way to tell tmux that the command we’re typing is for tmux.
Note that we don’t hold all these keys down together, but we instead first press CTRL-b simultaneously, release, and then immediately press the key for the command we want to send to tmux.
I’ll explain later how we can change the default prefix to an easier-to-reach key combination, e.g. CTRL-a.
Tmux was originally designed to be an improvement of GNU-Screen which was already using CTRL-a as its PREFIX, thus the choice to set it to CTRL-b.
Windows and panes
Within tmux sessions, we can create windows, name, rename, and split them into panes. No matter how many panes we have, we can easily navigate to a pane and zoom in, making it a full screen window.
To start a new session with a named window:
$ tmux new-session -s <SESSION NAME> -n <WINDOW NAME>
$ tmux new -s <SESSION NAME> -n <WINDOW NAME> #short command
Author’s note: allowing me to easily name and rename terminal windows it’s something I find extremely useful.
To close a window:
Either type one of the following:
- PREFIX &.
The only difference is that when using PREFIX & we are prompted with a confirmation message before closing the window.
We can split windows vertically or horizontally, thus dividing them into panes. Subsequently, we can further split each pane horizontally or vertically.
To split a window or pane vertically use PREFIX %
To split a window or pane horizontally use PREFIX “
To cycle through panes:
Either use PREFIX o or PREFIX followed by the UP, DOWN, LEFT, or RIGHT keys.
PREFIX q shows temporarily panes numbers and PREFIX z zooms in a pane. To zoom out, is PREFIX z again.
When we want to switch to another pane and we know the number we can do:
PREFIX q followed by the pane number.
Tmux comes with a few default layouts you can use out-of-the-box and we can cycle through them by simply hitting the PREFIX followed by Spacebar keys.
- even-horizontal stacks all panes horizontally, left to right.
- even-vertical stacks all panes vertically, top to bottom.
- main-horizontal creates one large pane on the top and smaller panes underneath.
- main-vertical creates one large pane on the left side of the screen, and stacks the rest of the panes vertically on the right.
- tiled arranges all panes evenly on the screen.
Most of the time, default layouts are sufficient, but for more complex layouts panes can be resized using incremental resizing. We are also able to configure tmux and specify PREFIX + <KEY> combinations for incremental resigning.
PREFIX t shows the time in a window/pane and to kill a pane either type exit or CTRL-D or PREFIX x. The difference here is similar to closing windows. When using PREFIX x we are prompted with a confirmation message before killing the pane.
Obviously, if a window has only one pane, i.e. the window itself, using PREFIX & or PREFIX x will both kill the window.
Fun with tmux layouts
tmux send-keys -t xx-development "cd ~/Sites/project-a/tools/vagrant" C-m tmux send-keys -t xx-development "vagrant resume" C-m tmux send-keys -t xx-development "vagrant vm ssh" C-m tmux send-keys -t xx-development "cd /vagrant" C-m # start second window. tmux new-window -n xx-local -t xx-development tmux send-keys -t xx-development:2 "cd ~/Sites/project-a" C-m fi tmux attach -t xx-development
- send-keys sends the command to the targeted tmux session
- -t target a session name.
- -d start a session and immediately detach from it.
- C-m at the end of a line sends the return carriage key to the standard output.
Here is just a small example of the powerful scripting capability tmux has. There are commands to set layouts, resize panes, and more…
Scripting environments with Tmuxinator
Tmuxinator is a simple yet very useful tool we can use to write and manage different tmux environments. We define our window layouts and commands in a simple YAML format, and then launch them with the tmuxinator command.
Tmuxinator is shipped as a Ruby gem. To install it:
$ gem install tmuxinator
To start a new tmuxinator environment (this will create a dummy YAML file in the directory ~/.tmuxinator):
$ tmuxinator open <PROJECT NAME>
To bootstrap an environment:
$ tmuxinator <PROJECT NAME>
name: dummy root: ~/Sites/dummy.development.local windows: - dummy: layout: main-horizontal panes: - dummy_vm: - hem vm start - # empty pane
- hem vm ssh - dummy_local: - git status - dummy logs: layout: main-horizontal panes: - system: - cd public/var/log - tail -n100 -f system.log - exceptions: - cd public/var/log - tail -n100 -f exception.log - all logs: - cd public/var - tail -n100 -f log/* - dummy selenium: panes: - start: - cd tools/assets/development - java -jar server-standalone.jar
Tmux is a modern BSD-licensed multiplexer which can do magic in terms of improving productivity when working at the terminal. We have cover how to install and configure tmux; how to start, kill, attach and detach from sessions; how to re-configure tmux and set up your own PREFIX and key-strokes combinations, and how it can be scripted to quickly bootstrap development environments.
There is surely far more to be said about tmux, such as how it can be used for Pair Programming, even remotely, or how it can facilitate working with the terminal buffer for copy and paste operations, but I will save this for another blog post.
I hope you found this article convincing enough to give tmux a try.
About the author:
Carlo Tasca is an experienced developer with over 10 years of commercial experience. He specialises in Magento and is one of Inviqa’s Magento Developer Plus Certified developers as well as a Zend PHP certified engineer. Carlo has a strong passion for pragmatic programming and clean coding, and outside of work he loves developing new skills and learning new programming languages and techniques.