Skip to content

Instantly share code, notes, and snippets.

@hmps
Last active July 12, 2024 21:45
Show Gist options
  • Save hmps/3c58f2e75d2d64233c66344561347241 to your computer and use it in GitHub Desktop.
Save hmps/3c58f2e75d2d64233c66344561347241 to your computer and use it in GitHub Desktop.
TMUX config and keybindings

Key bindings

So ~/.tmux.conf overrides default key bindings for many action, to make them more reasonable, easy to recall and comforable to type.

Let's go through them.

If you are an iTerm2 user, third column describes the keybinding of similar "action" in iTerm2. It's possible to reuse very same keys you already get used to and tell iTerm2 to execute analogous tmux actions. See iTerm2 and tmux integration section below.

tmux key Description iTerm2 key
C-a Default prefix, used instead of "C-b". Same prefix is used in screen program, and it's easy to type. The only drawback of "C-a" is that underlying shell does not receive the keystroke to move to the beginning of the line. -
<prefix> C-e Open ~/.tmux.conf file in your $EDITOR -
<prefix> C-r Reload tmux configuration from ~/.tmux.conf file -
<prefix> r Rename current window -
<prefix> R Rename current session -
<prefix> _ Split new pane horizontally ⌘⇧D
<prefix> | Split new pane vertically ⌘D
<prefix> < Select next pane ⌘[
<prefix> > Select previous pane ⌘]
<prefix> ← Select pane on the left ⌘⌥←
<prefix> → Select pane on the right ⌘⌥→
<prefix> ↑ Select pane on the top ⌘⌥↑
<prefix> ↓ Select pane on the bottom ⌘⌥↓
<prefix> C-← Resize pane to the left ^⌘←
<prefix> C-→ Resize pane to the right ^⌘→
<prefix> C-↑ Resize pane to the top ^⌘↑
<prefix> C-↓ Resize pane to the bottom ^⌘↓
<prefix> > Move to next window ⌘⇧]
<prefix> < Move to previous window ⌘⇧[
<prefix> Tab Switch to most recently used window ^Tab
<prefix> L Link window from another session by entering target session and window reference -
<prefix> \ Swap panes back and forth with 1st pane. When in main-horizontal or main-vertical layout, the main panel is always at index 1. This keybinding let you swap secondary pane with main one, and do the opposite. ⌘\
<prefix> C-o Swap current active pane with next one -
<prefix> + Toggle zoom for current pane ⌘⇧Enter
<prefix> x Kill current pane ⌘W
<prefix> X Kill current window ⌘⌥W
<prefix> C-x Kill other windows but current one (with confirmation) -
<prefix> Q Kill current session (with confirmation) -
<prefix> C-u Merge current session with another. Essentially, this moves all windows from current session to another one -
<prefix> d Detach from session -
<prefix> D Detach other clients except current one from session -
<prefix> C-s Toggle status bar visibility -
<prefix> m Monitor current window for activity -
<prefix> M Monitor current window for silence by entering silence period -
<prefix> F12 Switch off all key binding and prefix hanling in current window. See "Nested sessions" paragraph for more info -

Status line

I've started with Powerline as a status line, but then realized it's too fat for my Macbook 15'' display, it hardly can fit all those fancy arrows, widgets and separators, so that I can only see one window "tab".

So I decide to make my feet wet, with the idea to keep it dense, and include essential widgets. Sometimes it tries to replicate OSX topbar (battery, date time).

Left part: status line left

Right part: status line right

The left part contains only current session name.

Window tabs use Powerline arrows glyphs, so you need to install Powerline enabled font to make this work. See Powerline docs for instructions and here is the collection of patched fonts for powerline users

The right part of status line consists of following components:

  • CPU, memory usage, system load average metrics. Powered by tmux-plugin-sysstat (dislaimed, that's my own development, because I haven't managed to find any good plugin with CPU and memory/swap metrics)
  • username and hostname (invaluable when you SSH onto remote host)
  • current date time
  • battery information
  • visual indicator when you press prefix key: [^A].
  • visual indicator when pane is zoomed: [Z]
  • online/offline visual indicator (just pings google.com)

You might want to hide status bar using <prefix> C-s keybinding.

Copy mode

There are some tweaks to copy mode and scrolling behavior, you should be aware of.

There is a root keybinding to enter Copy mode: M-Up. Once in copy mode, you have several scroll controls:

  • scroll by line: M-Up, M-down
  • scroll by half screen: M-PageUp, M-PageDown
  • scroll by whole screen: PageUp, PageDown
  • scroll by mouse wheel, scroll step is changed from 5 lines to 2

Space starts selection, Enter copies selection and exits copy mode. List all items in copy buffer using prefix C-p, and paste most recent item from buffer using prexix p.

y just copies selected text and is equivalent to Enter, Y copies whole line, and D copies by the end of line.

Also, note, that when text is copied any trailing new lines are stripped. So, when you paste buffer in a command prompt, it will not be immediately executed.

You can also select text using mouse. Default behavior is to copy text and immediately cancel copy mode on MouseDragEnd event. This is annoying, because sometimes I select text just to highlight it, but tmux drops me out of copy mode and reset scroll by the end. I've changed this behavior, so MouseDragEnd does not execute copy-selection-and-cancel action. Text is copied, but copy mode is not cancelled and selection is not cleared. You can then reset selection by mouse click.

copy and scroll

iTerm2 and tmux integration

If you're an iTerm use same to me, most likely you already have a muscle memory for most common actions and keybindings (split pane, focus pane, fullscreen pane, move between tabs, create new tab, etc). When I switched to tmux, I found new key table more difficult: more keys to type, don't forget to enter prefix and recall if you've already pressed it or not (compare C-a, c with "⌘T", or C-a -> with "⌘⌥->"). iTerm2 keybinding was so natural to me, so I decided to remap most common keybindings to tell iTerm2 to execute corresponding tmux actions.

You can setup new profile in iTerm preferences to override default keybindings, to tell iTerm to send pre-configured sequences of keys, that will trigger corresponding action in tmux.

iterm preferences

For example, when "^⌘↑" pressed, sequence of bytes 0x01 0x1b 0x5b 0x31 0x3b 0x35 0x41 are sent through terminal to running tmux instance, that interprets them as C-a C-↑ keybinding and triggers resize-pane -U according to our .tmux.conf configuration.

You can get binary representation of any keys, using showkey or od commands

$od -t x1

^A^[[1;5A   // press C-a C-↑ on your keyboard
0000000 01 1b 5b 31 3b 35 41
0000007
$ showkey -a
Press any keys - Ctrl-D will terminate this program

^A        1 0001 0x01
^[[1;5A  27 0033 0x1b
         91 0133 0x5b
         49 0061 0x31
         59 0073 0x3b
         53 0065 0x35
         65 0101 0x41

You can remap whatever key in this way, but I do this only for those ones, which have similar analogous action in tmux and are most common(resize pane, zoom pane, create new window, etc). See table with keybindings above.

As additional step, you can setup this new iTerm profile as default one, and tell it to jump into tmux session right off the start.

iterm tmux default profile

You can then go full screen in iTerm, so iTerm tabs and frame do not distract you (anyway now you're using iTerm just as a tunnel to your tmux, everything else happens inside tmux).

full screen mode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment