Tmux

From miki
Jump to navigation Jump to search

Overview

tmux is actually a mix of screen and Gnome-Terminator. It is a terminal multiplexer: it enables a number of terminals to be created, accessed, and controlled from a single screen. Terminals can be organised in multiple panes in the same window.

Launch with

tmux                 # Start tmux (assume command 'new')
tmux attach          # Start tmux and reattach to previous session

tmux complains if it is launched as an ssh command (error not a terminal), but this is fixed with option -t:

ssh -t server tmux attach     # Launch tmux directly, require forcing terminal emulation

Useful shortcuts:

key description
C-b "

C-b %
C-b o
C-b C-o
C-b ←|→|↑|↓
C-b Alt-←|→|↑|↓

Split horizontally

Split vertically
Go to next pane
Go to previous active pane
Go to ←, →, ↑ or ↓ pane
Resize pane

C-b q
Display pane id briefly
C-b d
Detach from tmux. Reattach later with tmux attach

References

Some cool tips on tmux. Mention plugin manager, and tmux resurrect as plugin.
Tools
maintains connections alive even on disconnect. Works better than autossh or mosh [2].

Byobu

Byobu is an easy-to-use wrapper around the tmux (or screen) terminal multiplexer. See Byobu page.

Tmuxinator

Install

tmuxinator is a powerful tmux session manager. It allows for saving / restoring tmux session easily.

gem install tmuxinator

Also:

  • Make sure your ~/.tmux.conf DOES NOT SET base-index or pane-base-index.
# THESE MUST BE REMOVED OR COMMENTED!

# set -g base-index 1
# set-window-option -g pane-base-index 1
# set-option -g base-index 1 
# set-option -g pane-base-index 1 
# set -g pane-base-index 1 
# set-window-option -g pane-base-index 1
  • Add to your ~/.bashrc. This gives access to TAB completion, and alias mux:
#### tmuxinator
[ -f /var/lib/gems/2.3.0/gems/tmuxinator-0.9.0/completion/tmuxinator.bash ] && source /var/lib/gems/2.3.0/gems/tmuxinator-0.9.0/completion/tmuxinator.bash

Usage

mux new PROJECT                               # Create a new project named PROJECT
mux start PROJECT                             # Start a project
mux PROJECT                                   # ... same
mux PROJECT ARG1 ARG2 "ARG3 with space"       # ... with arguments

Pass command-line arguments

Use Ruby ERB to pass command arguments:

name: voltron
windows:
  - madhax:
      panes:
        - gdb <% @args.each do |val| -%>"<%= val %>" <% end -%>

Capture a layout

tmux list-windows
# 1: madhax* (6 panes) [169x41] [layout 15a8,169x41,0,0{147...

Tips

Attach automatically

One can configure tmux to attach automatically to an existing session, or create one if none exists:

  1. Add to ~/.tmux.conf
  2. new-session
    
  3. Add to ~/.bashrc
  4. # tmux - always attach (or pass given command and parameters)
    #        This solution requires to have the line "new-session" in ~/.tmux.conf
    function tmux() {
        T=/usr/bin/tmux
        if [ $# -eq 0 ]; then $T attach; else $T "$@"; fi
    }
    

Another solution (but not atomic) that does not require editing .tmux.conf is to use tmux attach || tmux new. This solutions also allows to use named sessions (see [3]).

Zoom on a pane

version 1.8 adds the zoom feature like terminator (see flag -Z to command resize-pane). Here a work-around for previous versions that binds the feature to C-b z (from [4]):

  1. Edit ~/.tmux.conf
  2. unbind z
    bind z run ". ~/.tmux/zoom"
    
  3. Edit ~/.tmux/zoom
  4. #!/bin/bash -f
    currentwindow=`tmux list-window | tr '\t' ' ' | sed -n -e '/(active)/s/^[^:]*: *\([^ ]*\) .*/\1/gp'`;
    currentpane=`tmux list-panes | sed -n -e '/(active)/s/^\([^:]*\):.*/\1/gp'`;
    panecount=`tmux list-panes | wc | sed -e 's/^ *//g' -e 's/ .*$//g'`;
    inzoom=`echo $currentwindow | sed -n -e '/^zoom/p'`;
    if [ $panecount -ne 1 ]; then
        inzoom="";
    fi
    if [ $inzoom ]; then
        lastpane=`echo $currentwindow | rev | cut -f 1 -d '@' | rev`;
        lastwindow=`echo $currentwindow | cut -f 2- -d '@' | rev | cut -f 2- -d '@' | rev`;
        tmux select-window -t $lastwindow;
        tmux select-pane -t $lastpane;
        tmux swap-pane -s $currentwindow;
        tmux kill-window -t $currentwindow;
    else
        newwindowname=zoom@$currentwindow@$currentpane;
        tmux new-window -d -n $newwindowname;
        tmux swap-pane -s $newwindowname;
        tmux select-window -t $newwindowname;
    fi
    

Scroll with mouse wheel

Add to ~/.tmux.conf:

#set-window-option -g mode-mouse on                  # Does not work when ssh from cygwin
set -g terminal-overrides 'xterm*:smcup@:rmcup@'

Start automatically with several command

Using cron, it is easy to launch tmux with one or several commands. Example of crontab line:

#Run both given script in separate window in the same tmux session. '-d' tells tmux to not attach to current terminal (which will fail in cron).
@reboot      /usr/bin/tmux new-session -d ~pi/bin/autonoekeon.sh \; new-window ~pi/bin/local/netconsole-log.sh

Change background color of split

tmux select-pane -t:.0 -P 'fg=blue,bg=red'

Copy session scrollback in clipboard / file

Use tmux commands
  • Enter command mode with ^b :, then capture-pane -S - (since tmux 2.0), or capture-pane -S -3000.
  • Save buffer with ^b : and save-buffer filename.txt.
Use custom binding
  • Add to ~/.tmux.conf [5]:
bind-key P command-prompt -p 'save history to filename:' -I '~/tmux.history' 'capture-pane -S - ; save-buffer %1 ; delete-buffer'
Using standard tmux binding
  • First yank the buffer with ^b [, V, gg, ^j.
  • Then in same tmux, open a new windows and paste into it with ^b c, vim, :set paste, i, ^b ].

Vim-like binding for copy-paste

Add to .tmux.conf [6]:

#----------------------------------------------------------
# Vim-like copy-paste
# https://www.rushiagr.com/blog/2016/06/16/everything-you-need-to-know-about-tmux-copy-pasting-ubuntu/
# - 'Ctrl-b [' to start copy mode. 'v' to start selection, then 'y'/'enter' to yank
# - Then 'Ctrl-b P' to paste in another pane.
bind P paste-buffer
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi y send-keys -X copy-selection
bind-key -T copy-mode-vi r send-keys -X rectangle-toggle

# Copy to system buffer (clipboard, but requires X fwding in ssh)
# bind-key -T copy-mode-vi Y send-keys -X copy-pipe-and-cancel "xclip -sel clip -i"

Session jumper through fzf

From here:

# Fullscreen:
bind C-j new-window -n "session-switcher" "tmux list-sessions | sed -E 's/:.*$//' | grep -v \"^$(tmux display-message -p '#S')\$\" | fzf --reverse | xargs tmux switch-client -t"
# With popup window:
bind C-j display-popup -E "tmux list-sessions | sed -E 's/:.*$//' | grep -v \"^$(tmux display-message -p '#S')\$\" | fzf --reverse | xargs tmux switch-client -t"

Troubleshoot

Not a terminal in SSH

This typically occurs when running tmux directly in ssh:

ssh server tmux

Use ssh option -t to force pseudo-TTy allocation:

ssh server -t tmux