Making your command line effective and enjoyable — Part 2: tmux
clitmuxtmux-resurrecttmux-continuumWhy is tmux awesome? #
- It brings organization to your console windows!
- Name Windows
- Switch between them with hotkeys
- Group windows into sessions (e.g., per-project)
- Save sessions - all your windows, working directories, etc. are available when you return from another project, a restart, etc.
- Split windows into panes!
- Use the mouse less, keep your hands the on keyboard
Resources #
Outline #
- Install tmux:
sudo apt-get install tmux
- Setup tmux (you may skip this step and configure tmux to your liking, these are just some recommendations)
Notes on tmux usage #
Please read the great crash course guide before getting started. It will explain the basics quite well.
Here is a quick reference of some useful commands and hotkeys.
Sessions #
I think of sessions as "workspaces" - I typically have one per project and name them accordingly. If you are using tmux-continuum
as specified in the example .tmux.conf
(which I strongly recommend - if there is only one part of my config you copy, it is that), your sessions will be saved and restored even after restarting your machine. This is extremely useful since it preserves all your open windows and panes with their working directories and such. This makes context switching between projects far less painless, and makes jumping back into a project after a reboot a breeze as well.
I strongly recommend you use tmux-continuum and name your sessions well so that you can easily return to the appropriate session for whatever you are working on at any given time.
- create new session:
tmux new-session -s SESSION_NAME
- session name is optional, but is very useful for knowing which session is which!
- detach from current session:
prefix + d
- if using my
.tmux.conf
, this isctrl+a + d
- if using my
- list all sessions:
tmux list-sessions
- attach to target session:
tmux attach-session -t SESSION_NAME
Windows #
Windows are great. Think of them like tabs in a typical GUI console, but better. Windows will be saved when you detach from your session (and since you're using tmux-continuum, they are saved until you decide to close them!) which is very useful. There are also several hotkeys for navigating through windows.
- create new window:
tmux new-window -n WINDOW_NAME
- again window name is optional, and you can access windows by index
- however, meaningful window names can be quite useful:
- at a glance, you can see which windows you have open and what they are
- you can also find a window by name:
tmux find-window MATCH_STRING
- also,
tmux f
for short
- also,
- however, naming your windows is only useful if you have
set-option -g allow-rename off
set in your.tmux.conf
- switch to window
- by index:
prefix + index
- example, going to window 1:
prefix + 2
- example, going to window 1:
- by name:
tmux find-window MATCH_STRING
- also,
tmux f MATCH_STRING
for short
- also,
- by index:
- close window:
- to kill a window, you must kill the final pane in the windows
- default to kill pane is
prefix + x
Usage Example #
My default window setup when working in a local VM is something like this:
- window 0: directory on my host machine where my VM is located
- window 1 (hostsrc): source directory of the application I'm working on (on my host machine)
- I typically use this for
git
commands, since my git config lives on my host and not my guest VM
- I typically use this for
- window 2 (vssh): SSH session in my guest VM, with working directory set to the source directory of the application I'm working on
- I typically use this for running build commands or scripts that require dependencies within the VM, such as
npm
,composer
,php
, etc.
- I typically use this for running build commands or scripts that require dependencies within the VM, such as
- window 3 (mysql): SSH session in my guest VM, running
mysql
logged into the DB of the app I'm working on- I don't always use this (mostly when doing data driven work), but this is useful for quick DB queries without having to open a new session since you already have one
While I could just have these windows open in traditional tabs in a GUI console, I like tmux windows better for a few reasons:
- If I close my session to work on another project or reboot my machine, all my windows are preserved in the session and I don't have to recreate them
- Hotkeys for jumping between windows (okay GUI console has this too, but I find tmux to be more easily configurable)
Of coure this is just an example of how tmux has improved my workflow, but you should adopt whatever makes you the most productive and comfortable!
Panes #
Panes are really awesome. They allow you to split a window into multiple shells. You can see each of the shells running in the panes of your active window and you can quickly switch between panes with hotkeys.
note: this section assumes you're using the example .tmux.conf
- create panes:
- split vertical:
ctrl + down
orctrl + up
- split horizontal:
ctrl + left
orctrl + right
- split vertical:
- switch panes:
- move right:
prefix + right
- move left:
prefix + left
- move up:
prefix + up
- move down:
prefix + down
- move right:
- kill pane:
prefix + x
Clipboard #
- to copy text, hold
SHIFT
and select text with mouse - to paste text, hold
SHIFT
and right click, use context menu to select "paste"
Example .tmux.conf #
# remap prefix to Control + a (change this to whatever you are most comfortable with!)
set -g prefix C-a
unbind C-b
bind C-a send-prefix
# List of plugins
set -g @plugin 'tmux-plugins/tpm'
#set -g @plugin 'tmux-plugins/tmux-sensible'
# continuum
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @continuum-restore 'on'
# Control arrow to create panes
bind -n C-Down split-window -v
bind -n C-Up split-window -v -b
bind -n C-Right split-window -h
bind -n C-Left split-window -h -b
# Easier window navigation
bind -n C-Tab next-window
bind -n C-S-Tab previous-window
bind -n C-S-Left previous-window
bind -n C-S-Right next-window
# Ctrl + Alt + Left/Right to move windows
bind-key -n C-M-Left swap-window -t -1
bind-key -n C-M-Right swap-window -t +1
# Terminal improvements
set -g mouse on
set-option -g allow-rename off # keep window names as you set them; turn this off to have window name update based on the process running in it
# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'