Linux
tmux

linuxにおけるtmuxの設定(クリップボード, ステータスバー)

コマンド

set : set-option
setw : set-window-option
bind : bind-key -T prefix
bind -n : bind-key -T root

動作環境

  • cat /etc/os-release | sed '/^PRETTY_NAME/!d;s/.*"\(.*\)".*/\1/' Arch Linux
  • uname -r 4.14.15-1-ARCH
  • tmux -V tmux 2.6
  • ターミナルがTrue Colorをサポートしている。gnome-terminal, mlterm, ...
  • フォントが特殊文字(三角形を90度傾けたやつ)をサポートしている。Hack, FiraCode, ...
  • pulseaudioがインストールされている。サウンドに関するパッケージ。
  • xselがインストールされている。Xのクリップボードと連携するのにxselを使っています。

概要

  • powerlineを使わずにpowerlineみたいな表示にしてます。そのため特殊文字を使います。
    2018-01-18_10_10_39.png
    2018-01-28_11_52_55.png
    2018-01-28_11_57_19.png

  • setw -g window-active-style fg='#C5C8C6',bg='#cc8f88'setw -g window-style fg='#C5C8C6',bg='#4286f4'で背景を変えれる。あんまり見ないので書いておきます。
    2018-01-31_21_39_06.png

  • ステータスバーの表示をシェルスクリプトで行ってます。メモリ消費量、ロードアベレージ、信号強度、音量、電池残量と時間を表示しています。

  • ステータスバーがウィンドウを狭めると完全に消えるのが悲しいので、画面幅によって表示を変えています。画面幅はtput colsというコマンドでわかります。

  • Xのクリップボードとtmuxのbufferを連携させています。

  • 音量をステータスバーに表示しています。ですが、tmuxのステータスバーはn秒で更新するので、それにより音量を変えたときの表示がもっさりします。解決策として、音量を変えるキーバインドにステータスバーを更新するコマンドを&&で繋いで書きます。&& tmux refresh -S

  • 左側のステータスバーはtmuxのセッションとzshのモードを表示しています。その処理は.zshrcに書いてます。

.tmux.conf

set -g prefix C-q
unbind-key C-b
#設定ファイルをリロード
bind-key -T prefix r source-file ~/.tmux.conf \; display "再読み込み"
# True Colorを使用する
set -g default-terminal "screen-256color"
set -ga terminal-overrides ",xterm-256color:Tc"
#ESCの反応を早くする
set -g escape-time 1
#添字を1から始める
set -g base-index 1
setw -g pane-base-index 1
#マウスを有効
setw -g mouse on
#ステータスバーの更新間隔を1秒にする
set -g status-interval 1
#ウィンドウを閉じた際に番号を詰める
set -g renumber-windows on
#連続でキーが効く時間をミリ秒で指定(bind-key -r)
set -g repeat-time 400

#キーバインド------------------------------------
#ペイン間の移動
bind-key -T prefix -r h select-pane -L
bind-key -T prefix -r j select-pane -D
bind-key -T prefix -r k select-pane -U
bind-key -T prefix -r l select-pane -R
bind-key -T root -r M-h select-pane -L
bind-key -T root -r M-j select-pane -D
bind-key -T root -r M-k select-pane -U
bind-key -T root -r M-l select-pane -R
#ウィンドウ間の移動
bind-key -T prefix -r u select-window -t :-
bind-key -T prefix -r i select-window -t :+
bind-key -T root -r M-u select-window -t :-
bind-key -T root -r M-i select-window -t :+
#新しいウィンドウ(ディレクトリを引き継ぐ
bind-key -T prefix c new-window -c "#{pane_current_path}"
#ペインの大きさを調整
bind-key -T prefix -r < resize-pane -L 5
bind-key -T prefix -r > resize-pane -R 5
bind-key -T prefix -r - resize-pane -D 5
bind-key -T prefix -r + resize-pane -U 5
#ペインを区切る(ディレクトリを引き継ぐ
bind-key -T prefix v split-window -h -c "#{pane_current_path}"
bind-key -T prefix s split-window -v -c "#{pane_current_path}"
#ペインの移動(右回り)
bind-key -T prefix -r N swap-pane -D
#ペインの移動(左回り)
bind-key -T prefix -r P swap-pane -U
#ウィンドウの削除
bind-key -T prefix X confirm-before -p "kill-window #I? (y/n)" kill-window
#ペインを指定したウィンドウに移動
bind-key -T prefix ! join-pane -t :1
bind-key -T prefix '"' join-pane -t :2
bind-key -T prefix '#' join-pane -t :3
bind-key -T prefix '$' join-pane -t :4
bind-key -T prefix % join-pane -t :5
bind-key -T prefix & join-pane -t :6
bind-key -T prefix "'" join-pane -t :7
bind-key -T prefix ( join-pane -t :8
bind-key -T prefix ) join-pane -t :9

#ステータスバーを設定------------------------------
set -g status on
set -g status-keys vi
#window-statusの位置を中央にする
set -g status-justify centre
setw -g window-status-format "#W.#I"
setw -g window-status-current-format "#W.#I"

# 左右のステータスバーの最大長を指定
set -g status-left-length 160
set -g status-right-length 160

# 右のステータスバー
# 画面の横幅で表示項目を変える。
set -g status-right "#{?#{==:1,#([[ $(echo #{client_width}) -ge 160 ]] && echo 1 || echo 0)},#(source ${HOME}/dotfiles/tmux/tmux_right_status.sh),#(source ${HOME}/dotfiles/tmux/tmux_right_status.sh short)}"

#色の設定----------------------------------------
set -g status-style "fg=default,bg=default"
set -g message-command-style fg=default,bg=default
set -g message-style fg=blue,reverse,bg=default
set -g mode-style fg=black,bg=blue
set -g pane-active-border-style fg=green,bg=default
set -g pane-border-style fg=default,bg=default
setw -g window-status-current-style fg=colour25,bold,bg=default
setw -g window-status-style fg=default,bg=default
setw -g window-active-style fg='#C5C8C6',bg='#1D1F21'
setw -g window-style fg='#C5C8C6',bg='#121216'

#コピーモードの設定--------------------------------
#キーバインドをviにする
setw -g mode-keys vi
bind-key -T copy-mode-vi v send-keys -X begin-selection
#tmuxのbufferとxのclipboardを連携させる
%if #{!=:3,#(which xsel | awk '{print NF}')}
    bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xsel -ib"
    bind-key -T copy-mode-vi Y send-keys -X copy-pipe "xsel -ib"
    bind-key -T prefix ] run-shell "xsel -ob | sed 's/\"/\\\"/g' | xargs -0 tmux set-buffer && tmux paste-buffer"
%endif

set -g status-rightの行で画面の横幅が160以下ならスクリプトファイルにshortという引数を渡して表示を変えています。
コピーモードのあたりのif文はxselが存在しているかの確認です。

tmux_right_status.sh

#!/usr/bin/bash

# 区切り文字
sep=''

# メモリ使用量
memory="#[fg=blue]${sep}#[fg=black,bg=blue] $(free -h | sed '/^Mem:/!d;s/  */ /g' | cut -d' ' -f3) #[default]"

# ロードアベレージ
la="#[fg=black,bg=blue]${sep}#[default]#[fg=blue,bg=black] $(uptime | sed -E 's/.*load average: ([0-9]\.[0-9][0-9]).*/\1/g')/$(cat /proc/cpuinfo | grep processor | wc -l) #[default]"

# ネットワーク
[[ $(iw dev wlp4s0 link) != 'Not connected.' ]] && signal="-$(iw dev wlp4s0 link | grep signal | grep -o '[0-9]*')dBm" || signal='---'
signal="#[fg=blue,bg=black]${sep}#[default]#[fg=black,bg=blue] ${signal} #[default]"

# 音量
if type pactl > /dev/null 2>&1;then
  if [[ $(pactl list sinks | grep 'RUNNING') != '' ]];then
    run="grep -A 10 'RUNNING'"
  else
    run='tee'
  fi
  if [[ $(pactl list sinks | eval ${run} | grep 'Mute:' | cut -d' ' -f2) == 'no' ]];then
    volMeter='#[fg=blue,bg=black] '
  else
    volMeter='#[fg=colour237,bg=black] '
  fi
  volume=$(expr $(pactl list sinks | eval ${run} | grep -o '[0-9]*%' | head -1 | sed 's/%//g') / 5)
  volMeter="${volMeter}["
  for i in $(seq 1 ${volume});do
    volMeter="${volMeter}■"
  done
  for i in $(seq ${volume} 20);do
    volMeter="${volMeter} "
  done
  volMeter="${volMeter}] "
else
  volMeter='#[fg=blue,bg=black] × #[default]'
fi
volMeter="#[fg=black,bg=blue]${sep}#[default]${volMeter}#[default]"

# 時刻
date="#[fg=blue,bg=black]${sep}#[fg=black,bg=blue] $(date +%H:%M) #[default]"

# バッテリー残量
batteryColor=#[fg=black,bg=blue]${sep}#[default]
if [[ $(cat /sys/class/power_supply/ADP1/online) = "1" ]];then
  declare -a char=('◜' '◝' '◟' '◞')
  i=$(expr $(date +%S) % 4)
  batteryColor="${batteryColor}#[fg=blue,bg=black] ${char[i]} #[default]"
fi
if [[ -e /sys/class/power_supply/BAT1 ]];then
  battery=$(cat /sys/class/power_supply/BAT1/capacity)
  if [[ ${battery} -gt 79 ]];then
    batteryColor="${batteryColor}#[fg=#08d137,bg=black]"
  elif [[ ${battery} -gt 20 ]];then
    batteryColor="${batteryColor}#[fg=#509de0,bg=black]"
  else
    batteryColor="${batteryColor}#[fg=#f73525,bg=black]"
  fi
  batteryColor="${batteryColor} ${battery}% #[default]"
fi

if [[ $1 = 'short' ]];then
  echo "${memory}${la}"
else
  echo "${memory}${la}${signal}${volMeter}${date}${batteryColor}"
fi

.zshrc

function _tmux_status() {
  [[ -z ${TMUX} ]] && return
  typeset -r sep=''
  [[ ${KEYMAP} == 'vicmd' ]] \
  && typeset -r mode="#[fg=black,bg=green]#{?#{==:#{pane_current_command},zsh}, -- NORM -- #[default]#[fg=green]#[bg=blue]#{?client_prefix,#[bg=yellow],}${sep},}" \
  || typeset -r mode="#[fg=blue,bg=black]#{?#{==:#{pane_current_command},zsh}, -- INS -- #[default]#[fg=black]#[bg=blue]#{?client_prefix,#[bg=yellow],}${sep},}"

  tmux set -g status-left "${mode}#[fg=black,bg=blue]#{?client_prefix,#[bg=yellow],} S/#S #[default]#[fg=blue]#{?client_prefix,#[fg=yellow],}${sep}"
}
zle -N zle-line-init _tmux_status
zle -N zle-keymap-select _tmux_status