Tmux is a terminal multiplexor for Unix, which allows users to open and access multiple terminal sessions within one window. When you start using tmux, you may think that some of its keys are unintuitive or uncomfortable to reach.
For example, I never understood why tmux uses ctrl + b
as a prefix. The letter “b” is positioned at a weird distance from the ctrl button. I also found commands like the split commands Prefix + "
and Prefix + %
are not intuitive. There is nothing about "
and %
that are associable to horizontal and vertical splits.
13 Tmux Configurations to Know
- Change the default prefix
- Mouse usage
- Increase history
- Jumping to a marked pane
- Numbering windows and panes
- More intuitive split commands
- Swapping windows
- Keeping the current path
- Toggling windows and sessions
- Resizing
- Breaking and joining panes
- Quick pane creation
- General key-binding
- Changing the config file path
It would be nice to be able to change some of the default configs into something that is more intuitive to me, the user. To do this, we need to configure the tmux config file.
When you start a tmux session, tmux looks for a file named .tmux.conf
in the HOME
path ~/.tmux.conf
. Technically, tmux looks for /etc/tmux.conf
first, then ~/.tmux.conf
, but the former is best left untouched.
Let’s look at how to configure tmux to match your own preferences.
How to Modify a Tmux Config File
A .tmux.conf
file to tmux is like .zshrc
to Z-Shell and .vimrc
to vim. It’s a path to a file where you enter your own configurations so that the next time you launch tmux, it executes everything inside that config file.
So, what can you put inside the tmux config file? Anything. The possibilities are endless.
Tmux has a set of commands that you can run from the terminal inside a tmux session. For example, to display a message, you can use tmux’s display-message
command. Type this from the terminal inside a tmux session:
tmux display-message "Hello my tmux friends"
You should see “Hello my tmux friends”
displayed on the bottom of the screen.
If you find that display-message
is too long to type, display
works the same way, plus it is shorter.
tmux display "Hello my tmux friends"
If you want to display the message on the terminal instead of the status bar, pass the -p
flag. Try:
tmux display -p "Hello tmux"
To run the tmux command from the terminal, you need to precede it with the tmux command.
Another way to run a tmux command is to use the command-line mode. To enter the command-line mode, press Prefix + :
. Vim users might notice striking similarities with vim’s EX mode. In this mode, you can enter any tmux commands without prepending it with tmux.
If you haven’t already, run:
Prefix + :
Your cursor should now be at the bottom of the tmux window. Type:
display "Hello my tmux friends"
Again, with this approach you don’t have to type tmux display anymore. display is enough. If you look at the status bar (bottom of the screen), you’ll see the “Hello my tmux friends”
text.
One advantage of the command-line mode is that you can run any tmux command while having another program running. For example, if you need to run display "hello"
and you currently have vim open, instead of exiting vim then typing tmux display "hello"
, with the command-line mode, you can just press Prefix + :
and type display-message "hello"
without exiting vim.
How to Quick Source the Tmux Config File
When you edit your tmux config file, you will need to reload it for the change to take place. To reload tmux, run tmux source-file~/.tmux.conf
from the terminal, or run source-file~/.tmux.conf
from tmux’s command-line mode. Tmux will re-execute all the codes inside the ~/.tmux.conf
file.
If you’re a tinkerer, a shortcut to quickly source your config file can be useful. Add the following inside ~/.tmux.conf
:
bind r source-file ~/.tmux.conf \; display "Reloaded!"
The bind
command, short for bind-key, binds the letter “r” to perform the following. Note, this actually binds Prefix + r
, not just the letter “r” by itself.
- Config file source:
source-file ~/.tmux.conf
. - Display message:
display "Reloaded!"
The semicolon (;
) lets you sequentially combine multiple tmux commands. It’s a great way to bind a single key with multiple commands.
Each time you make changes to the config file, save the tmux config and run Prefix + r
.
Some configs won’t take place even after you reload the config file. Usually these are the UI-related commands. If you don’t see your changes after reloading the tmux config, you need to restart the tmux server:
- Detach from the session:
Prefix + d
- Kill the server:
tmux kill-server
- Start a new session:
tmux new -s MY_SESSION
Alternatively, you can also run Prefix + I
. The “I” is uppercased to reload the tmux environment. In short, if running Prefix + r
doesn't do anything, try running Prefix + I
or restarting your server.
Commenting in Tmux
Tmux uses #
to comment out any subsequent texts. Commented lines won’t be executed by tmux config. I like to use comments to explain obscure code. For example:
# Add binding to reload tmux.conf for fast, iterative development
bind r source-file ~/.tmux.conf \; display "Reloaded!"
You can also put a comment at the end of the same line:
bind r source-file ~/.tmux.conf \; display "Reloaded!" # quick reload
13 Useful Tmux Configurations to Know
Here are some configurations that I find useful:
1. Changing the Default Prefix
I’m not a big fan of tmux’s ctrl + b
default prefix. Let’s change it to something more intuitive. Some popular tmux prefix alternatives are:
Ctrl + a
Ctrl + Space
Ctrl + s
Ctrl + u
- Backticks
- Tab + key variation instead of
Ctrl + KEY
I personally use Ctrl + Space
mainly because my vim leader key is the space key. To change my prefix to Ctrl + Space
, I add this in the tmux config file:
unbind C-Space
set -g prefix C-Space
bind C-Space send-prefix
What each does:
unbind
unbinds whatever functionalityC-space
had (if any).set -g prefix line
informs tmux that the prefix will now beC-Space
.bind ... send-prefix
allowsCtrl + Space
to perform the send-prefix command. The send-prefix command sends the prefix keystroke to a window. This is useful with nested tmux sessions.
2. Mouse Usage
Although I’m not a big fan of using a mouse extensively, there are times when I need to use it. Tmux’s default configs are not mouse friendly. Let’s change that. To enable scrolling, clicking and resizing, add the following inside the tmux config file:
set -g mouse on
If you want to see more, check out the MOUSE SUPPORT
section inside man tmux
.
3. Increase History
By default, tmux keeps the previous 2,000 lines of window history. You can scroll up 2,000 lines above your current terminal line. Sometimes 2,000 isn't enough. To increase it to 5,000 lines, add this inside the config file:
set-option -g history-limit 5000
I never needed more than 5,000, so I never went higher. Of course, you can make it higher if you need to.
4. Jump to a Marked Pane
If you’re a vim user, you may be aware that you can create a mark with m + identifier
. You can then return to that mark at any time. You can do the same with tmux.
To mark the pane you are currently on, press:
Prefix + m
In vim, to return to a marked location, you use a single-quote or a backtick. Since we already have the single-quote shortcut taken (recall that Prefix + '
is used to jump to a window number by index), let’s use backtick. To jump to a mark using a backtick, add this config:
bind \` switch-client -t'{marked}'
Try this: Mark a pane, then go to a different window. Observe that you can quickly return to the previous pane with Prefix + backtick
. I find it useful to mark the pane I always find myself returning into, usually the pane where the main codebase is.
To remove a mark, press Prefix + m
again while you’re on that marked pane or just press Prefix + M
anywhere.
In vim you can have up to 26 marks, in tmux, you can only have one, so choose wisely which pane to mark.
5. Numbering Windows and Panes
Recall that tmux windows and panes are zero-based. I don’t find them intuitive. I prefer to have my first windows and panes to start with one.
set -g base-index 1
setw -g pane-base-index 1
Suppose that I have four windows in a session: call them window A, B, C and D. If I close the third window, window C, I end up with window A in position one, B in position two and D in position four. I have a gap in position three. This behavior causes a friction in my workflow because I have to keep in the back of my mind that position three window is vacant. Wouldn’t it be better to automatically move window D to the third position after deleting window C? To get this behavior, add:
set -g renumber-windows on
Now, when I delete window C in position three, window D automatically moves to position three. The next window I create will become window four. Little things like this free up your mental real estate. The fewer things I have to remember in my head, the more I can use my head to think about the important things.
6. More Intuitive Split Commands
Tmux’s default split pane shortcuts, Prefix + %
and Prefix + "
are not intuitive. |
and -
are better symbols to represent vertical and horizontal splits. Why not use them instead?
bind | split-window -hc "#{pane_current_path}"
bind - split-window -vc "#{pane_current_path}"
Now, when I press Prefix + |
, tmux does a vertical split, and when I press Prefix + -
, tmux does a horizontal split.
I find that having to press the Shift
key to do Prefix + |
is mildly inconvenient. So, I have these mappings:
bind-key "|" split-window -h -c "#{pane_current_path}"
bind-key "\\" split-window -fh -c "#{pane_current_path}"
bind-key "-" split-window -v -c "#{pane_current_path}"
bind-key "_" split-window -fv -c "#{pane_current_path}"
This allows me to press either the uppercased version of that key to get the vertical and horizontal splits.
7. Swapping Windows
Sometimes I need to swap windows around. Maybe I want to have the docker-compose to window one from window two. I think >
and <
make good, intuitive keys to swap the current window to the right and left, respectively.
bind -r "<" swap-window -d -t -1
bind -r ">" swap-window -d -t +1
Now, if I want to move the current window to the right, I can do Prefix + >
. To move the current window to the left, do Prefix + <
.
8. Keeping Current Path
When you create a new window (Prefix + c
), tmux resets the path. Wait, what are you talking about? Suppose when I start a new tmux session, I was on the HOME
path (~/
). After coding and doing stuff, I end up in ~/some/directory/
.
Now, I need to create a new window. When I run Prefix + c
, the new window will be back on the HOME
directory, not whatever path I was on. Tmux automatically resets the path in the new window you just created to the path you were on when you started the current session. Most of the time, when I create a new window, I want to stay in whatever path I am on. To preserve the path in the new window, add:
bind c new-window -c "#{pane_current_path}"
Now, when I create a new window, the new window will also be on ~/some/directory/
.
9. Toggling Windows and Sessions
I find myself needing to toggle between the current and previous window a lot. To quickly toggle between windows:
bind Space last-window
Now, I can type Prefix + Space
to toggle between the current and previous windows.
Recall that Prefix + Space
was originally the toggle layout tmux shortcut. If you use this, you’ll lose that layout toggle shortcut. I personally never use the layout toggle functionality at all. I also chose Space
because my Prefix is Ctrl + Space
, making it intuitive. If you use a different prefix, you may consider a different shortcut key.
Moreover, sometimes I also need to toggle between the current and the previous session. Add this:
bind-key C-Space switch-client -l
Again, I chose Ctrl + Space
because Ctrl + Space
is also my Prefix
. So it’s like pressing Prefix
twice. If you use a different prefix, consider using that prefix keys instead.
10. Resizing
Recall that we can run tmux resize-pane -D
/U
/L
/R
commands to resize the panes. Unfortunately, tmux doesn’t come with the shortcuts to quickly resize panes. No worries, let’s add our own. The shortcuts that I use are Prefix + Ctrl-h
/j
/k
/l
:
bind -r C-j resize-pane -D 15
bind -r C-k resize-pane -U 15
bind -r C-h resize-pane -L 15
bind -r C-l resize-pane -R 15
The 15 above is the tmux cell unit. I find 15 unit increments to be perfect. I also find Ctrl-h
/j
/k
/l
to be good keys to do this because it resembles vim navigation.
Other resizing alternatives are the arrow keys, Ctrl + arrow keys
, or <
/>
/-
/+
.
11. Breaking and Joining Panes
Maybe you are on a window with multiple panes and you want to break the current pane out into its own window. To do this, tmux has a built-in break-pane command:
Prefix + !
Conversely, what if you want to join a pane from another window into a different window? There is no native keybinding, but tmux has a join-pane command. Add the following:
bind j choose-window 'join-pane -h -s "%%"'
bind J choose-window 'join-pane -s "%%"'
Press Prefix + j
to choose which window you want to join.
Notice that I have two shortcuts: j
and J
. The former joins a window horizontally, and the latter vertically.
12. Quick Pane Creation
I don't know when inspiration strikes, but when it strikes, I want to have quick access to my notes.
bind-key h split-window -h "vim ~/scratch/notes.md"
Now, whenever I think of a billion-dollar startup idea, I can just press Prefix + h
to open a new horizontal split window and launch ~/scratch/notes.md
in vim. Who says that learning tmux doesn’t pay?
12. General Key-Binding
All the tmux shortcuts you’ve seen so far have used the prefix key. What if you need to create a shortcut that does not use prefix? What if, instead of Prefix + j
, you want to use Ctrl + j
to join windows?
You can do this bypassing the -n option to the bind command in your config file. Instead of bind j YOUR_COMMAND
, you use bind -n C-j YOUR_COMMAND
:
bind -n C-j choose-window 'join-pane -h -s "%%"'
Now it will use Ctrl + j
Instead of Prefix + j
.
13. Changing the Config File Path
By default, your config path is in the HOME
directory (in my case, it is ~/.tmux.conf
). But you can always put it somewhere else. If you run tmux with tmux -f /path/to/your/new/tmux.conf
, it will use whatever path you point instead of the default HOME
path.
Personally, I keep my config path in HOME
(~/.tmux.conf
), but it’s symlinked to my dotfiles repo (~/Projects/dotfiles/tmux.conf
). With this, I can edit either ~/Projects/dotfiles/tmux.conf
or ~/.tmux.conf
, and these two files will remain in sync. I like to keep my config files portable.
How to Use a Tmux Plugin Manager (TPM)
At some point, you’ll need to use a more complicated setup instead of one-liner configurations. TPM is a good tool for that. It stands for tmux plugin manager. It allows you to create and install tmux plugins easily.
In the following section, I will briefly go over TPM. If you want to learn more, feel free to check the repository.
How to Install TPM
To install TPM, you need to:
- Git clone TPM to a HOME directory (
~/.tmux/plugins/tpm
) - Add any plugins with
set -g @plugin 'YOUR/PLUGIN'
in your tmux config file. Don’t forget to precede it with set-g @plugin 'tmux-plugins/tpm'
. - Point the run command to the TPM repository location (by default it points to
~/.tmux/tpm/tpm
).
Adding a TPM package
Let’s go over how to install a package. I really like the dracula theme plugin. To install it, I have the following in my tmux config:
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'dracula/tmux'
run '~/.tmux/plugins/tpm/tpm'
Recall that the first plugin in the list, tmux-plugins/tpm
, is required as part of TPM. The next one on the list, dracula/tmux
, is the plugin that you're trying to install. Finally, the run '~/.tmux/plugins/tpm/tpm
, is also a required code to make TPM work.
You can add as many plugins as you want. Once you add the list of plugins, save and source tmux, then run Prefix + I
(reload environment). The dracula plugin should activate.
How to Use Tmux and Vim
I use tmux and vim a lot. There are some configurations that you can add to make them work together even better.
Vim-Tmux Navigation
One of the biggest improvements you can make to vim and tmux is to synchronize their navigations. In my regular workflow, I normally have multiple vim windows and tmux panes on my screen.
In vim, you move around different windows with Ctrl + w + h
/j
/k
/l
. In tmux, you move around different panes with Prefix + left
/down
/up
/right
. Wouldn’t it be great if you can move your cursor between vim windows and tmux panes using the same key sets?
That sure would make life a lot simpler. This would mean you don’t have to pause to think if you’re in vim or tmux, or ask yourself: “Should I press Ctrl + w
or Prefix
?” Using only one set of keys eliminates navigation context-switching. The less context-switching you need to do, the more flow you have. The more flow you have, the more brain power you can allocate to actually accomplish the important tasks.
To accomplish this, you need to install the vim-tmux-navigator plugin for vim and tmux. Technically, this is just one plugin, but it needs to be installed in both vim and tmux.
Install the vim-tmux-navigator plugin in vim. I personally use the vim-plug plugin manager, so I only need to add the following:
Plug 'christoomey/vim-tmux-navigator'
Save and source the vimrc, run :PlugInstall
.
Next, install the vim-tmux-navigator
plugin in tmux. Add this in the tmux config file:
set -g @plugin 'christoomey/vim-tmux-navigator'
Save and source the tmux config file. Don’t forget to reload tmux (Prefix + I
).
Let’s try it. Inside a tmux session, split your window into multiple panes. Inside one pane, open up vim and split it into multiple windows. You can navigate to the next vim window or tmux pane with Ctrl + h
/j
/k
/l
.
What Is Tmuxinator?
Once you use tmux for a while, you will realize that most of the time, you perform the same sequence of commands.
For example, for work, I almost always:
- Create a new session called
work
. - Rename this window
servers
. - Launch the rails server.
- Launch the sidekiq server on a split pane.
- Launch redis on a split pane.
- Create a new window named
codes
. - Launch vim.
- Horizontal split adjusted at about 30 percent for random terminal needs.
- Create a new window named
consoles
for Rails/MySQL console. - Create a new window named
notes
to take notes/scratchpads.
I do this almost every single day. Let’s automate it. One way to do it is to use tmux templating library like tmuxinator.
Tmuxinator lets you to set up your tmux sessions/windows/panes to run specific commands. Set them up once. Reuse any time.
To get started, install tmuxinator. If you have a Mac, you can just run:
brew install tmuxinator
Tmuxinator Commands
There are a number of available tmuxinator commands, but the following three are the most important ones. You can create, edit and launch a tmuxinator template with:
tmuxinator new PROJECT
tmuxinator edit PROJECT
tmunxinator PROJECT
I find that the name tmunxinator too long to type. I prefer shorter name, like mux. In my zshrc, or bashrc if you use bash, add:
alias mux=tmuxinator
Now, I can just run mux new PROJECT
instead of tmuxinator new PROJECT
. Let’s call our project “work”. Run:
mux new work
Tmuxinator will create a new file work.yml
somewhere inside the config directory. Inside you can configure your settings for your tmux work project. Mine looks something like this:
# /Users/iggy/.config/tmuxinator/work.yml
name: work
root: ~/
# lots of stuff...
windows:
- editor:
layout: main-vertical
panes:
- vim
- guard
- server: bundle exec rails s
- logs: tail -f log/development.log
The name:
attribute is the project name and root is the root
directory. windows
represents tmux windows for this project, in this case we have three windows:
editor
window using themain-vertical
layout. It is split into two with two panes, one runningvim
and another runningguard
.server
that runs bundleexec rails s
,logs
to display development log.
Let’s edit this template to fit my workflow. First, I’m going to update my root to be my work project. Change them to your work directory:
root: ~/Work/is/awesome/
Now, each time I run mux work
, it will automatically use ~/Work/is/awesome/
as the root path in my session.
Next, modify our windows:
# /Users/iggy/.config/tmuxinator/work.yml
name: work
root: ~/Work/is/awesome/
windows:
- server_stuff:
layout: tiled
panes:
- bundle exec rails s
- bundle exec sidekiq
- redis-server
- code_stuff: vim
- misc_stuff:
- notes:
- cd ~/Dropbox
- vim
I have four windows defined:
- The first,
server_stuff
, has the layout set to betiled
. It consists of three panes. The first pane runs the rails server, the second sidekiq server, and the third runs redis server. - The second,
code_stuff
, runs vim. - The third window is just an empty window for whatever comes up (rails console, mysql console, ssh, git workflow, etc)
- The fourth window is my scratchpad. I have it pointed to my Dropbox directory where I store my notes. I take my notes with vim.
Once you’re done, save the yml file. If I ever want to edit it, I just need to run mux edit work
. To launch this tmuxinator project, run:
mux work
That’s it! It’s convenient and easy to set up. This can save you five-to-10 minutes everyday.
If you need to close it, since all this is just a tmux session, all you need to do is detach from the work session (Prefix + d
), then kill it with tmux kill-session -t work
.
By the way, earlier I said that for my codebase window, I like having a window with horizontal split at about 70/30, with the top part running vim while the bottom one for random terminal work. One way is to use tmux’s main-horizontal
layout, but it would be nice if I could fine-tune the length of the top and bottom panes.
There is no clean way to do it, but you can use this trick:
- First, create a tmux window and split them horizontally.
- Second, you adjust the height to about 70/30 (using
resize-pane
). - Third, when you're happy with the proportions, run
tmux list-windows
. - It will print something like this:
test* (2 panes) [278x70] [layout edac,278x70,0,0[278x50,0,0,1,278x19,0,51,15]] @1 (active)
. Your numbers will probably be different from mine. - The ambiguous-looking number is the tmux's window proportions. Copy that. Inside tmuxinator, paste that number in the
layout
section.
My tmuxinator work.yml
file now looks like this:
# /Users/iggy/.config/tmuxinator/work.yml
name: work
root: ~/Work/is/awesome/
windows:
- server_stuff:
layout: tiled
panes:
- bundle exec rails s
- bundle exec sidekiq
- redis-server
- code_stuff:
layout: edac,278x70,0,0[278x50,0,0,1,278x19,0,51,15]
panes:
- vim
- echo "empty"
- misc_stuff:
- notes:
- cd ~/Dropbox
- vim
When I run the mux work
command, the second window will be split horizontally with the same proportion as what we had before.
By the way, tmuxinator is not the only tmux manager in town. There are two other alternatives:
Your turn now - think of your work / personal project workflows, then create your own tmuxinator/tmuxp / teamocil template!
You’ve now learned different examples of how you can modify your tmux config. They are by no means exhaustive. If you want to see what I use, you can review my dotfiles. There are many more combinations you can implement to make your tmux more powerful.
Tmux is a simple, powerful tool. Used correctly, it allows you to organize your workflows and reduce context-switching, allowing you to focus more on the current task at hand.
Frequently Asked Questions
Where is the tmux config file?
The tmux config file establishes the keys and shortcuts users can access in tmux. The default tmux config file is found at /etc/tmux
, while a user created version is found at ~/.tmux.conf
.
How do you reload tmux config?
To reload tmux, run tmux source-file ~/.tmux.conf
from the terminal, or run source-file ~/.tmux.conf
from tmux’s command-line mode.
If you want to quickly reload tmux conif, you can create the shortcut:
bind r source-file ~/.tmux.conf \; display "Reloaded!"