Mastering tmux‘s Scrollback and Copy Mode

If you spend a lot of time in the terminal, you‘ve likely encountered tmux – the ubiquitous terminal multiplexer. tmux allows you to manage multiple terminal sessions within a single window, detach and re-attach to sessions, and customize your terminal environment.

One aspect of tmux that often trips up new users is how it handles scrollback compared to a regular terminal. In this guide, we‘ll take an in-depth look at tmux‘s scrollback behavior, learn how to make it more intuitive, and pick up some handy tips and tricks along the way. Let‘s dive in!

Understanding tmux‘s Scrollback Buffer

A typical terminal emulator implements a scrollback buffer to allow you to view output that has disappeared off-screen. For example, you can scroll up in your terminal using keyboard shortcuts like Shift-PageUp or your mouse wheel to access the scrollback history.

tmux, on the other hand, runs in the alternate screen buffer of your terminal. This is a special mode that applications can enable to gain more control over what is displayed. For example, when you launch vim, it switches to the alternate screen to show the editor interface.

The alternate screen has the same dimensions as your terminal window. Any output that exceeds the visible area is not accessible via the regular terminal scrollback. In effect, tmux is like a "window manager for your terminal" – it takes over the entire screen and implements its own scrollback buffer.

tmux overview

This behavior has a few important consequences:

  1. Output that gets scrolled off-screen in tmux is not added to the terminal‘s scrollback history. If you exit tmux, that output is lost forever.

  2. You can‘t access tmux‘s scrollback using the typical terminal shortcuts or your mouse wheel. tmux uses a separate mechanism called copy mode.

  3. When you detach from a tmux session, the contents of the tmux window are not dumped into the terminal‘s history. You pick up right where you left off when you re-attach.

So while tmux‘s scrollback system might feel foreign at first, it‘s really just a consequence of how tmux interacts with the terminal. Luckily, tmux provides a rich set of features for working with its scrollback buffer.

Navigating tmux‘s Scrollback with Copy Mode

To access tmux‘s scrollback buffer, you use a special mode called copy mode. To enter copy mode, press Prefix [ (that‘s Ctrl-b then [). You‘ll see a message like [0/55] at the top, indicating your current position and the size of the scrollback buffer.

tmux copy mode

Once in copy mode, you can navigate the scrollback using these keys:

  • Up or k: Scroll up one line
  • Down or j: Scroll down one line
  • Ctrl-u: Scroll up half a page
  • Ctrl-d: Scroll down half a page
  • PageUp or Ctrl-b: Scroll up a full page
  • PageDown or Ctrl-f: Scroll down a full page

To exit copy mode and return to the current pane, press q or Enter.

These keybindings follow the vi-style and are enabled by default in tmux 2.4 onwards. If you‘re on an older version, it uses emacs-style keybindings. You can customize the keys used in copy mode with the bind-key -T copy-mode command.

Making tmux‘s Copy Mode More Intuitive

One gripe I have with tmux‘s default copy mode keys is that Prefix [ feels clunky to type. Since I use iTerm2, I‘m used to the Cmd-UpArrow shortcut to enter scroll mode. We can replicate that in tmux by adding this to our ~/.tmux.conf file:

# Use Alt-UpArrow to enter copy mode
bind -n M-Up copy-mode

Now when we press Alt-UpArrow, we enter copy mode with our cursor at the bottom ready to scroll up. We can keep hitting Alt-Up to scroll line-by-line, or use any of the other navigation shortcuts.

Next up, I find tmux‘s default scroll speed too fast – each tick of the mouse wheel scrolls 5 lines at a time. Here‘s how we can slow it down to a more manageable 2 lines per tick:

bind -T copy-mode-vi WheelUpPane select-pane \; send-keys -X -N 2 scroll-up
bind -T copy-mode-vi WheelDownPane select-pane \; send-keys -X -N 2 scroll-down

Slow down tmux mouse scrolling speed

Selecting and Copying Text

Copy mode isn‘t just for scrolling through output – you can also use it to select and copy text. First, make sure mouse mode is enabled:

set -g mouse on

This allows you to select text by dragging with your mouse. However, the default behavior is a bit odd:

  • When you finish dragging with the mouse button, tmux drops you out of copy mode
  • The selected text is immediately copied to tmux‘s internal buffer
  • Your scroll position resets to the bottom

I prefer to stay in copy mode after selecting text with the mouse, so I can continue scrolling if needed. We can override the default like so:

# Stay in copy mode when dragging with mouse
unbind -T copy-mode-vi MouseDragEnd1Pane
bind -T copy-mode-vi MouseDown1Pane select-pane \; send-keys -X copy-pipe "pbcopy" \; send-keys -X clear-selection

Now dragging with the mouse selects text but keeps us in copy mode. To actually copy the text, just click with the mouse – this copies the current selection to the clipboard and clears the selection.

Selecting text with mouse in tmux copy mode

Pasting Copied Text

When you copy text in tmux using copy mode, it gets added to a paste buffer. tmux maintains a stack of buffers, so you can copy multiple things and paste them later.

To paste the most recently copied text, use the paste-buffer command:

bind p paste-buffer

To view a list of all copied buffers, use the choose-buffer command:

bind C-p choose-buffer

This opens an interactive list of buffers that you can select from:

tmux choose buffer

Accessing tmux Scrollback from iTerm2

Ideally, you‘d be able to use the same keybindings to access tmux‘s scrollback as you use in plain iTerm. For example, I‘d love to keep using Cmd-UpArrow to enter scroll mode, even from inside tmux.

This is possible using iTerm2‘s ability to bind keys to send hex codes. Essentially, we configure iTerm to send the same M-Up sequence that we bound to tmux‘s copy mode earlier when we press Cmd-UpArrow.

Here are the steps:

  1. Open iTerm2 preferences and create a new profile for tmux
  2. In the Keys section, click the + icon to add a new keymapping
  3. Set the shortcut to Cmd-UpArrow (⌘↑)
  4. Select "Send Hex Code" and enter 0x1b 0x5b 0x31 0x3b 0x35 0x41
  5. Repeat for Cmd-DownArrow (⌘↓) with code 0x1b 0x5b 0x31 0x3b 0x35 0x42

iterm2 profile for tmux scrollback

Now when you press Cmd-Up/DownArrow in iTerm2 while inside tmux, it sends the right sequence to activate tmux‘s copy mode and you can keep using all your muscle memory for scrolling!

Note this only works for scrolling – to select text you‘ll still need to use tmux‘s built-in selection mechanism that we set up earlier. A small price to pay for the convenience of familiar scroll keys.

Quickly Copying to the Clipboard

Even with all these tweaks, selecting text in tmux with the mouse can feel a bit fiddly. Sometimes you just want to make a quick copy without entering copy mode.

Here‘s a handy trick: hold Option while dragging with the mouse to bypass tmux‘s mouse handling. The selection will happen in iTerm2 instead, so you can quickly copy to the clipboard.

Select text in tmux by holding Option

This is a good fallback for those times when you don‘t need tmux‘s more advanced copy mode features and just want to grab some text in a hurry.

Persisting tmux‘s Scrollback

By default, tmux only keeps around 2000 lines of scrollback. If you want to save more, you can adjust the history-limit setting:

set -g history-limit 10000

This tells tmux to keep 10,000 lines of history per pane. You can tweak this number depending on your needs and how much memory you‘re willing to dedicate to tmux.

An alternative approach is to use a terminal logging tool like script to record all your tmux sessions to disk. You can then search through the logs later if you need to dig up some output.

Conclusion

tmux‘s scrollback system is a powerhouse once you learn how to use it effectively. With a few tweaks, you can mould it to fit your workflows and build muscle memory for quickly navigating and copying output.

The configuration examples we‘ve covered are just the tip of the iceberg – there‘s so much more you can do to customize tmux to your liking. I encourage you to explore the official docs, read through other people‘s configs, and experiment to see what works for you.

Hopefully this deep-dive has given you a solid foundation for making the most of tmux‘s scrollback features. Feel free to hit me up in the comments if you have any other neat tricks to share!

Similar Posts