Skip to content

Instantly share code, notes, and snippets.

@drofp
Created March 30, 2021 16:49
Show Gist options
  • Save drofp/a0255cfb8b65e086039838f34dc43de0 to your computer and use it in GitHub Desktop.
Save drofp/a0255cfb8b65e086039838f34dc43de0 to your computer and use it in GitHub Desktop.
Tmux iterm integration tips and best practices

Change scrollback limit for tmux buffer on iterm

Original stackoverflow post here

Solution

  • iTerm2 build 1.0.0.20130302 has an preference which enables it to capture scrollback even when a so-called hard status line is present:
    • https://i.stack.imgur.com/QS1vB.png
    • Preferences -> Terminal -> check "Save lines to scrollback when an app status bar is present"
    • maybe also check "Save lines to scrollback in alternate screen mode"

How to use tmux with iterm

Original document here


tmux Integration Best Practices

This document describes how best to use the tmux integration feature for common use cases. There are a number of settings in far-flung places that are worth customizing.

What tmux command should I use?

Most users have one tmux session per machine that they wish to either create (if needed) or attach to (if possible). Use this command:

tmux -CC new -A -s main

What ssh command should I use?

If you wish to run tmux on a remote host over ssh, use this command:

ssh -t example.com 'tmux -CC new -A -s main'

The -t argument says to use a TTY, which tmux needs to be happy.

I keep having to reattach because my ssh connection dies when my IP address changes

Use Eternal Terminal. It tunnels ssh connections over a more reliable transport and just works. Then the command is:

et -c "tmux -CC new -A -s main" example.com

I want to use mosh

Don't use mosh for tmux integration. It's not meant to tunnel traffic, and will cause you horrible agony.

How do I use shell integration?

Shell integration works with tmux integration, but does not work well with plain-old-tmux (henceforth, POT). For that reason, it is disabled by default. You can enable shell integration in tmux by adding this to your login script (.bash_profile, .profile, .zshrc, .config/fish/config.fish, or .login) prior to where shell integration is loaded:

export ITERM_ENABLE_SHELL_INTEGRATION_WITH_TMUX=YES

tcsh and fish users should modify the above as needed for their shells.

I get random commands after tmux detaches

When you run tmux -CC at the command line, iTerm2 communicates with tmux using in-band signaling. This means that if tmux suddenly exits or your ssh session dies, iTerm2 will send commands that reach the shell rather than tmux. While there are mitigations in place to minimize the extent of this problem it cannot be completely fixed. To prevent it, do not run tmux -CC from the command line. Instead, configure your profile to run it. See below.

How do I configure my profile?

Use iTerm2 version 3.3.6 or later. To run tmux locally set the profile’s command like this: https://gitlab.com/gnachman/iterm2/-/wikis/uploads/657077a13095287bd60abf25e1e39816/image.png

For remote hosts, create a new profile for each machine you run tmux on. Set the profile’s command like this: https://gitlab.com/gnachman/iterm2/-/wikis/uploads/5f0ca5365f2a4cd55b282e324a1e8eb0/image.png

If you use ssh instead of Eternal Terminal, configure the session to restart automatically: https://gitlab.com/gnachman/iterm2/-/wikis/uploads/baf5ca2d8ec9fae5f19171745ada17fe/image.png

What other settings are relevant?

Check Prefs > General > tmux. Here's how I like to configure it: https://gitlab.com/gnachman/iterm2/-/wikis/uploads/e2e5ec850f0258905f97286d4b439566/image.png

Buried sessions are removed from the window and go in the menu under Session > Buried Sessions. You probably don't need to interact with the tmux gateway session (the one where tmux -CC was run) very often, so it's nice to hide it away.

I have a lot of windows. How can I get them all to open?

If you have more than ten tabs or windows, the dashboard will open. If you have a thousand windows, this is probably convenient. If you have eleven, it might just be annoying. The threshold is adjustable in the dashboard itself: https://gitlab.com/gnachman/iterm2/-/wikis/uploads/ff170f69ff75978e475d7c162a8d1866/image.png

I want to see tmux window titles as tab/window titles in iTerm2

The way tmux uses window names and window titles is confusing and kind of an impedance mismatch for iTerm2. First, tmux makes a distinction between window names and window titles, which is surprising. The window name is its identifier for applying changes to the window via tmux commands. The window title is meant to be the human-readable name that's present in the user interface. Prior to iTerm2 3.3.0, only the window name was ever used in the UI. In iTerm2 3.3.0 and later with tmux 2.9 or later, you can choose to show tmux window titles in native tab and window titles. Put this in your ~/.tmux.conf file:

set-option -g set-titles on
set-option -g set-titles-string '#T'

After changing the value of set-titles you must detach and reattach to tmux for the change to take effect, as it's only checked once by iTerm2 when tmux integration is begun. The tmux option set-titles-string defines the contents of the title. The default value doesn't make much sense in tmux integration since it includes a bunch of information you might not care about, like the window number. See the tmux man page for more information on this. If you have an older version of tmux you can show window names in tab titles, and you can change them with a control sequence. Put this in your ~/.tmux.conf:

set -g allow-rename on

And then you can use this control sequence to set the title:

echo -ne "\033kYour title goes here\007”

How do session names work?

The previous section described window names and window titles. Tmux has a concept of a "window pane" which maps onto an iTerm2 "session", sometimes referred to as a "split pane". In iTerm2, a session has a name. In tmux, a window pane has a name. You can edit the name of both in Edit Session > Session Name. In a tmux integration session this is surfaced in the per-pane titlebar, which is visible only when there are split panes (if the feature is enabled). When you open Edit Session in tmux integration, you can choose to edit either the Session Name or the Tab Title. Editing the Session Name will not have an effect on the tab title. Control sequences in tmux (like \e]0;title\\\e) modify the session name.

I want tabs/windows of different sizes.

Turn on Prefs > Advanced > Allow variable window sizes in tmux integration. Ensure you have the most recent version of tmux installed. As of the 10/31/2019 nightly build or 3.3.7beta3 this should work reasonably well but there might be bugs. Please report them at https://iterm2.com/bugs and attach an as-minimal-as-possible debug log.

Italics show up as reverse video, whole-screen reverse video isn't working, or my $TERM variable is not what I wish

First, some background:

  • Your terminal type is determined by the TERM environment variable.
  • There are two families of terminals: xterm and screen. They vary in small ways. For example, the control sequence that indicates italic text in xterm is used for reverse video in screen.
  • iTerm2 supports xterm-family control sequences.
  • By default tmux uses screen.
  • Within tmux integration, iTerm2 attempts to detect your TERM and translate screen-style codes into xterm-style codes before processing them. For example, it rewrites italic -> reverse video.

Some users prefer to use TERM=xterm-256color (or any other xterm-family terminal) in tmux. In order for this to work well, you'll want to disable the screen->xterm translation in iTerm2. iTerm2 automatically determines what terminal tmux is configured to use by querying tmux's default-terminal setting. If it contains the string "screen" then control sequences get translated. If you change your TERM to xterm (or an xterm-family terminal) in your .bashrc or equivalent, neither tmux nor iTerm2 will be aware of it. Consequently, it will appear to be screen to iTerm2 but xterm to the program that is sending control sequences. iTerm2 will the translate them when it oughtn’t. To set your TERM properly you should set tmux's default-terminal property, ideally in ~/.tmux.conf. This makes it visible to iTerm2 and solves the problem. To do so, place this in your ~/.tmux.conf:

set -g default-terminal "xterm-256color"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment