Tmux: Difference between revisions

From miki
Jump to navigation Jump to search
(Created page with "== Overview == '''tmux''' is actually a mix of ''screen'' and ''Gnome-Terminator''. It is a terminal multiplexer: it enables a number of terminals to...")
 
 
(19 intermediate revisions by the same user not shown)
Line 23: Line 23:
{{kb|C-b}} {{kb|C-o}}<br/>
{{kb|C-b}} {{kb|C-o}}<br/>
{{kb|C-b}} {{kbkey|&larr;&#124;&rarr;&#124;&uarr;&#124;&darr;}}<br/>
{{kb|C-b}} {{kbkey|&larr;&#124;&rarr;&#124;&uarr;&#124;&darr;}}<br/>
{{kb|C-b}} {{kbkey|Alt-&larr;&#124;&rarr;&#124;&uarr;&#124;&darr;}}<br/>


|Split horizontally<br/>
|Split horizontally<br/>
Line 28: Line 29:
Go to next pane<br/>
Go to next pane<br/>
Go to previous active pane<br/>
Go to previous active pane<br/>
Go to &larr;, &rarr;, &uarr; or &darr; pane
Go to &larr;, &rarr;, &uarr; or &darr; pane<br/>
Resize pane
|-
|-
|{{kb|C-b}} {{kbkey|q}}<br/>
|{{kb|C-b}} {{kbkey|q}}<br/>
Line 39: Line 41:
== References ==
== References ==
* [http://www.youtube.com/watch?v=9jzWDr24UHQ tmux & vim] ([http://goo.gl/98M96 Example of .tmux.conf] or [https://github.com/chrishunt/dot-files/blob/master/.tmux.conf])
* [http://www.youtube.com/watch?v=9jzWDr24UHQ tmux & vim] ([http://goo.gl/98M96 Example of .tmux.conf] or [https://github.com/chrishunt/dot-files/blob/master/.tmux.conf])
* [https://leimao.github.io/blog/Tmux-Tutorial/ Tmux tutorial]
: Some cool tips on tmux. Mention plugin manager, and ''tmux resurrect'' as plugin.
* [https://github.com/tmux-plugins/tpm Plugin - Tmux plugin manager]
* [https://github.com/tmux-plugins/tmux-resurrect Plugin - Tmux resurrect]

;Tools
* [https://eternalterminal.dev/ Ethernal Terminal]
: maintains connections alive even on disconnect. Works better than autossh or mosh [https://news.ycombinator.com/item?id=21640200].

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

== Tmuxinator ==

=== Install ===
[https://github.com/tmuxinator/tmuxinator tmuxinator] is a powerful tmux session manager. It allows for saving / restoring tmux session easily.

<source lang=bash>
gem install tmuxinator
</source>

Also:
* Make sure your {{file|~/.tmux.conf}} '''DOES NOT SET''' <code>base-index</code> or <code>pane-base-index</code>.

<source lang=bash>
# 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
</source>

* Add to your {{file|~/.bashrc}}. This gives access to TAB completion, and alias <code>mux</code>:

<source lang=bash>
#### 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
</source>

=== Usage ===
<source lang=bash>
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
</source>

=== Pass command-line arguments ===
Use Ruby ERB to pass command arguments:
<source lang=bash>
name: voltron
windows:
- madhax:
panes:
- gdb <% @args.each do |val| -%>"<%= val %>" <% end -%>
</source>

=== Capture a layout ===
<source lang=bash>
tmux list-windows
# 1: madhax* (6 panes) [169x41] [layout 15a8,169x41,0,0{147...
</source>


== Tips ==
== Tips ==
Line 112: Line 179:
#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).
#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
@reboot /usr/bin/tmux new-session -d ~pi/bin/autonoekeon.sh \; new-window ~pi/bin/local/netconsole-log.sh
</source>

=== Change background color of split ===

<source lang=bash>
tmux select-pane -t:.0 -P 'fg=blue,bg=red'
</source>

=== Copy session scrollback in clipboard / file ===
;Use tmux commands
* Enter command mode with {{kb|^b :}}, then <code>capture-pane -S -</code> (since tmux 2.0), or <code>capture-pane -S -3000</code>.
* Save buffer with {{kb|^b :}} and <code>save-buffer filename.txt</code>.
;Use custom binding
* Add to {{file|~/.tmux.conf}} [https://unix.stackexchange.com/questions/26548/write-all-tmux-scrollback-to-a-file]:
<source lang="bash">
bind-key P command-prompt -p 'save history to filename:' -I '~/tmux.history' 'capture-pane -S - ; save-buffer %1 ; delete-buffer'
</source>
;Using standard tmux binding
* First yank the buffer with {{kb|^b [}}, {{kb|V}}, {{kb|gg}}, {{kb|^j}}.
* Then in '''same''' tmux, open a new windows and paste into it with {{kb|^b c}}, <code>vim</code>, <code>:set paste</code>, {{kb|i}}, {{kb|^b ]}}.

=== Vim-like binding for copy-paste ===
Add to {{file|.tmux.conf}} [https://www.rushiagr.com/blog/2016/06/16/everything-you-need-to-know-about-tmux-copy-pasting-ubuntu/]:
<source lang="bash">
#----------------------------------------------------------
# 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"
</source>

=== Session jumper through fzf ===
From [https://waylonwalker.com/tmux-fzf-session-jump/ 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:
<source lang="bash">
ssh server tmux
</source>

Use ssh option <code>-t</code> to force pseudo-TTy allocation:

<source lang="bash">
ssh server -t tmux
</source>
</source>

Latest revision as of 14:55, 12 May 2022

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