web-dev-qa-db-ja.com

.tmux.confにifステートメントを記述して、異なるtmuxバージョンに異なるオプションを設定する方法は?

さまざまなtmuxバージョンがインストールされているさまざまなマシンで使用する.tmux.confがあります。

Tmuxのバージョンに応じて、異なるマウスオプションを設定したい。 1台のマシンでバージョン2.0 もう一方の 2.1

私は彼の部分が正しくない

if "[[(( $(tmux -V | cut -c 6-) < 2.1 ))]]" \
  "set -g mode-mouse on;" \
  "set -g mouse-resize-pane on;" \
  "set -g select-pane on;" \
  "set -g select-window on" "set -g mouse on"

ファイルを入手するとき

$ tmux source-file .tmux.conf

私はこのメッセージを受け取ります

.tmux.conf:12: unknown command: set -g mouse-resize-pane on

実行するマシンのバージョンは2.1そのため、4つのオプションを設定しないでください。

Tmux 2.0以下を実行する場合は4つのオプションを、tmux 2.1を実行する場合は1つのオプションを設定します。

このbashステートメントは機能します

$ tmux -V
tmux 2.1
$ if [[(( $(tmux -V | cut -c 6-) < 2.1 ))]];then echo $?;else echo $?;fi
1
33
mrt181

@ ericx's answer および @ thiagowfx's answer に基づいて、バージョン2.0以降の多くの リストされた非互換性 をカバーする以下をまとめます。

# Version-specific commands [grumble, grumble]
# See: https://github.com/tmux/tmux/blob/master/CHANGES
run-Shell 'tmux setenv -g TMUX_VERSION $(tmux -V | \
                            sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'

if-Shell -b '[ "$(echo "$TMUX_VERSION < 2.1" | bc)" = 1 ]' " \
    set -g mouse-select-pane on; set -g mode-mouse on; \
    set -g mouse-resize-pane on; set -g mouse-select-window on; \
    set -g message-fg red; \
    set -g message-bg black; \
    set -g message-attr bright; \
    set -g window-status-bg default; \
    set -g window-status-fg default; \
    set -g window-status-current-attr bold; \
    set -g window-status-current-bg cyan; \
    set -g window-status-current-fg default; \
    set -g window-status-bell-fg red; \
    set -g window-status-bell-bg black; \
    set -g window-status-activity-fg white; \
    set -g window-status-activity-bg black"

# In version 2.1 "mouse" replaced the previous 4 mouse options
if-Shell -b '[ "$(echo "$TMUX_VERSION >= 2.1" | bc)" = 1 ]' \
  "set -g mouse on"

# UTF8 is autodetected in 2.2 onwards, but errors if explicitly set
if-Shell -b '[ "$(echo "$TMUX_VERSION < 2.2" | bc)" = 1 ]' \
  "set -g utf8 on; set -g status-utf8 on; set -g mouse-utf8 on"

# bind-key syntax changed in 2.4 -- selection / copy / paste
if-Shell -b '[ "$(echo "$TMUX_VERSION < 2.4" | bc)" = 1 ]' " \
   bind-key -t vi-copy v   begin-selection; \
   bind-key -t vi-copy V   send -X select-line; \
   bind-key -t vi-copy C-v rectangle-toggle; \
   bind-key -t vi-copy y   copy-pipe 'xclip -selection clipboard -in'"

# Newer versions
if-Shell -b '[ "$(echo "$TMUX_VERSION < 2.9" | bc)" = 1 ]' " \
   bind-key -T copy-mode-vi v   send -X begin-selection; \
   bind-key -T copy-mode-vi V   send -X select-line; \
   bind-key -T copy-mode-vi C-v send -X rectangle-toggle; \
   bind-key -T copy-mode-vi y   send -X copy-pipe-and-cancel 'xclip -selection clipboard -in'"

if-Shell -b '[ "$(echo "$TMUX_VERSION >= 2.9" | bc)" = 1 ]' \
   "set -g message-style fg=red,bg=black; \
    set -g message-style bright; \
    set -g window-status-style          fg=default,bg=default; \
    set -g window-status-current-style  fg=default,bg=cyan,bold; \
    set -g window-status-bell-style     fg=red,bg=black; \
    set -g window-status-activity-style fg=white,bg=black"

tmuxの非互換性 here の問題に関する問題を提起しました。要約すると、tmux devsは後方互換性をサポートせず、どのバージョンに重大な変更が含まれているかを強調するバージョン番号付けスキームを採用しません。 ????

私は %if これは v3.0で実装 でした。

37
Tom Hale

if-Shellは常に機能するとは限りません。代わりに、シェルスクリプトを使用して、正しいバージョンのtmux.confをロードします。

.tmux.conf内:

run-Shell "bash ~/.tmux/verify_tmux_version.sh"

Verify_tmux_version.shで:

#!/bin/bash

verify_tmux_version () {
    tmux_home=~/.tmux
    tmux_version="$(tmux -V | cut -c 6-)"

    if [[ $(echo "$tmux_version >= 2.1" | bc) -eq 1 ]] ; then
        tmux source-file "$tmux_home/tmux_2.1_up.conf"
        exit
    Elif [[ $(echo "$tmux_version >= 1.9" | bc) -eq 1 ]] ; then
        tmux source-file "$tmux_home/tmux_1.9_to_2.1.conf"
        exit
    else
        tmux source-file "$tmux_home/tmux_1.9_down.conf"
        exit
    fi
}

verify_tmux_version

詳細: https://Gist.github.com/vincenthsu/6847a8f2a94e61735034e65d17ca0d66

19
Vincent Hsu

これは一種の手間です。これを行う正しい方法tmux内(外部シェルスクリプトに依存しない)は、Vincentとjdloftの両方の応答の機能を組み合わせます。

Tmuxのif-Shellコマンドは次のように使用されます

if-Shell [-bF] [-t target-pane] Shell-command command [command]
               (alias: if)
    Execute the first command if Shell-command returns success or the second command otherwise.  Before
    being executed, Shell-command is expanded using the rules specified in the FORMATS section, including
    those relevant to target-pane.  With -b, Shell-command is run in the background.

    If -F is given, Shell-command is not executed but considered success if neither empty nor zero (after
         formats are expanded).

Tmuxシェルコマンドを展開すると、#{pane_current_path}という形式の変数が展開されますが、それ以外の場合はコマンドはそのままになります。

さらに重要なことに、tmux ses/bin/sh -cを使用して、指定したシェルコマンドを実行します。したがって、コマンド はPOSIXに準拠する必要があります であるため、[[形式のテストは移植性が保証されません。最新のUbuntuおよびDebianシステム。たとえば、シンボリックリンク/bin/shからdashへ。

Tmuxバージョンをテストし、目的のバージョンが見つかった場合は0(true)を返すPOSIX準拠のシェルコマンドを実行します。

if-Shell '[ $(echo "$(tmux -V | cut -d" " -f2) >= 2.1" | bc) -eq 1 ]' \
    'command if true' \
    'command if false'

例:

if-Shell '[ $(echo "$(tmux -V | cut -d" " -f2) >= 2.1" | bc) -eq 1 ]' \
    'set -g mouse on; set -g mouse-utf8 on' \
    'set -g mode-mouse on; set -g mouse-resize-pane on; set -g mouse-select-pane on; set -g mouse-select-window on' 

これは、浮動小数点演算を行っているという事実を正しく処理するため、bc必須 です。さらに、[演算子はそれ自体で真理値を生成するため、if/then/else/fi構造は必要ありません。

いくつかのメモ

  • 次の行に続く行にコメントを付けることはできません。そうしないと、tmuxは「不明なコマンド」エラーメッセージを表示します。
  • 「falseの場合のコマンド」は省略できます。
  • ;を使用して、trueまたはfalseの複数のコマンドを組み合わせることができます
  • コマンドは、/bin/sh -cを使用して、基礎となるシェルで実行されます。 [[または他のPOSIX以外の構文を使用する他のアプローチは、動作が保証されていません。

[〜#〜] edit [〜#〜]:この回答の以前のバージョンでは[[を使用していましたが、システムでは機能しませんbashを使用しません。 [に置き換えるとこれが解決します。

17
Micah Smith

また、さまざまなtmuxバージョンの構成の不一致につまずきました。ここと SuperUserのこの関連質問 ですべてのソリューションを確認した後、次のバリアントを実装しました。

# Version-specific configuration can be placed in ~/.tmux/${TMUX_VERSION}/*.conf
run-Shell "for conf in ~/.tmux/$(tmux -V | cut -d' ' -f2)/*.conf; do tmux source-file \"\$conf\"; done"

これにより、バージョン固有の構成を特定のバージョンの(複数の)構成スニペットに入れることができます。これは@VincentHsuのソリューションに似ていますが、次のとおりです。

  • 外部シェルスクリプトは必要ありません。
  • 固定バージョン範囲に分離されません(.../1.9から2.0/2.1 ...)。代わりに、(シンボル)リンクを使用して、構成スニペットを複数のtmuxバージョン間で共有できます。
  • バージョンの単一のファイル名をハードコードしません。バージョンごとに複数の構成スニペットを許可することで、バージョン間でパーツを共有し、他のバージョンをバージョン固有に維持できます。これにより、最大限の柔軟性が得られます。
  • 元の~/.tmux.confには構成要素が1つだけあります。 @TomHaleのような他のソリューションは、各構成要素のバージョンテストを複製します。
8
Ingo Karkat

Tmuxのif-Shellを使用して、ZSHバージョンを確認できます。

[[ `tmux -V | cut -d' ' -f2` -lt 2.1 ]]

tmuxバージョンが2.1以上かどうかを確認します。これを使用して、ZSHバージョンに応じてマウスコマンドを設定できます。

if-Shell "[[ `tmux -V | cut -d' ' -f2` -lt 2.1 ]]" \
    'set -g mode-mouse on; set -g mouse-resize-pane on; set -g mouse-select-pane on; set -g mouse-select-window on'

そして、tmuxの以降のバージョン用に設定します。

if-Shell "[[ `tmux -V | cut -d' ' -f2` -ge 2.1 ]]" \
    'set -g mouse on; set -g mouse-utf8 on'
7
jdloft

一部のマシンでは、二重括弧( '[[')構文で誤検知の結果が得られました。そこで、awkを使用した代替案を思い付きました。

# Enable mouse for different versions of tmux
# (If 'awk' exits with status 0, 'if-Shell' evaluates to true)
# tmux < v2.1:
if-Shell "tmux -V | awk '{exit !($2 < \"2.1\")}'" \
    "setw -g mode-mouse on ; set -g mouse-select-pane on ; set -g mouse-resize-pane on ; set -g mouse-select-window on ;"
# tmux >= v2.1:
if-Shell "tmux -V | awk '{exit !($2 >= \"2.1\")}'" \
    "set -g mouse on ;"
7
bdellaterra

私は提案されたソリューションを動作するソリューションに結合しました(tmux 1.8および2.7でテスト済み):

run-Shell "tmux setenv -g TMUX_VERSION $(tmux -V | cut -c 6-)"

if-Shell -b '[[ "$TMUX_VERSION" < "2.6" ]]' \
  "bind w choose-tree -u"

if-Shell -b '[[ "$TMUX_VERSION" < "2.2" ]]' \
  "set -g status-utf8 on"
0
e-pirate

現在の最新リリースは2.9a、ここで使用されている多くの直接比較を無効にします。

私の代替手段はsort -V。これは、バージョン比較を処理するためにはるかに堅牢です。

# ver >= 2.3
[ ! "$(printf "%s\n%s" "$TMUX_VERSION" "2.3" | sort -V | head -n1)" == "$TMUX_VERSION" ]' \
    "command"

# ver > 2.3
[ ! "$(printf "%s\n%s" "$TMUX_VERSION" "2.4" | sort -V | head -n1)" == "$TMUX_VERSION" ]' \
    "command"

# ver < 2.3
[ "$(printf "%s\n%s" "$TMUX_VERSION" "2.3" | sort -V | head -n1)" == "$TMUX_VERSION" ]' \
    "command"
0
BlueDrink9