问题
I have a .tmux.conf which I use on different machines with different tmux versions installed.
I want to set different mouse options, depending on the tmux version.
On one machine I have version 2.0
on the other 2.1
.
I do not get his part right
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"
When I source the file
$ tmux source-file .tmux.conf
I get this message
.tmux.conf:12: unknown command: set -g mouse-resize-pane on
The machine where I run it has version 2.1
so it shouldn't set the four options.
I want to set the four options when running tmux 2.0 or less or the one option when running tmux 2.1.
This bash statement works
$ tmux -V
tmux 2.1
$ if [[(( $(tmux -V | cut -c 6-) < 2.1 ))]];then echo $?;else echo $?;fi
1
回答1:
Based on @ericx's answer and @thiagowfx's answer I put the following together which covers many of the listed incompatibilties from version 2.0 onwards:
# 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"
I raised an issue about the problems with tmux
's non-backward-compatibility here. The summary is that the tmux
devs will not support backward compatibility, nor will they adopt a version numbering scheme which highlights which versions contain breaking changes. 😢
I raised an issue to support numeric comparators for %if which was implemented in v3.0.
回答2:
if-shell
doesn't always work. Instead, I use a shell script for loading the correct version of tmux.conf:
In .tmux.conf:
run-shell "bash ~/.tmux/verify_tmux_version.sh"
In 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
For more details: https://gist.github.com/vincenthsu/6847a8f2a94e61735034e65d17ca0d66
回答3:
This is kind of a hastle. The correct way to do this within tmux (not relying on an external shell script) combines features of both Vincent and jdloft's responses.
The if-shell
command in tmux is used as
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).
Note that tmux shell-command expansion will expand variables of the form #{pane_current_path}
but otherwise will leave the command alone.
More importantly, note that tmux uses /bin/sh -c
to execute the shell command we specify. Thus, the command must be POSIX compliant, so tests of the form [[
are not guaranteed to be portable. Modern Ubuntu and Debian systems, for example, symlink /bin/sh
to dash
.
We want to run a POSIX compliant shell command that tests the tmux version and returns 0 (true) if the desired version is found.
if-shell '[ $(echo "$(tmux -V | cut -d" " -f2) >= 2.1" | bc) -eq 1 ]' \
'command if true' \
'command if false'
Example:
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'
This correctly deals with the fact that we are doing floating point arithmetic, so bc
is required. Additionally, there is no need for an if/then/else/fi construct, as the [
operator produces a truthy value by itself.
A couple notes
- Lines continuing onto the next line cannot have trailing comments or tmux will give an "unknown command" error message.
- The "command if false" can be omitted.
- Multiple commands for either true or false can be combined using
;
- The command is run on the underlying shell using
/bin/sh -c
. Other approaches that use[[
or other non-POSIX syntax are not guaranteed to work.
EDIT: A previous version of this answer used [[
, which doesn't work on systems that don't use bash. Replacing with [
solves this.
回答4:
I also stumbled over configuration mismatches in different tmux versions. After reviewing all the solutions here and in this related question on SuperUser, I've implemented the following variant:
# 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"
With this, version-specific configuration can be put in (multiple) configuration snippets for a particular version. This is similar to the solution of @VincentHsu, but:
- It does not require an external shell script.
- It does not segregate into fixed version ranges (... / 1.9 to 2.0 / 2.1 ...). Instead, one can use (sym)links to share a configuration snippet among multiple tmux versions.
- It does not hardcode a single filename for a version. By allowing multiple configuration snippets for each version, parts can be shared among versions while others are kept version-specific. This should offer the utmost flexibility.
- There's just a single configuration element in the original
~/.tmux.conf
. Other solutions like the one from @TomHale duplicate the version test for each configuration element.
回答5:
On some machines I was getting a false-positive result with the double bracket ('[[') syntax. So I came up with an alternative using 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 ;"
回答6:
Tmux's if-shell
can be used to check the ZSH version.
[[ `tmux -V | cut -d' ' -f2` -lt 2.1 ]]
checks whether or not the tmux version is greater than or equal to 2.1. Using this we can set your mouse commands depending on the ZSH version.
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'
And set it for later versions of tmux:
if-shell "[[ `tmux -V | cut -d' ' -f2` -ge 2.1 ]]" \
'set -g mouse on; set -g mouse-utf8 on'
回答7:
I have combined suggested solutions to a working one (tested on tmux 1.8 and 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"
回答8:
Current latest release is 2.9a
, which throws off many of the direct comparisons used here.
My alternative makes use of sort -V
, which is much more robust for handling version comparisons.
# 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"
来源:https://stackoverflow.com/questions/35016458/how-to-write-if-statement-in-tmux-conf-to-set-different-options-for-different-t