web-dev-qa-db-fra.com

Comment écrire l'instruction if dans .tmux.conf pour définir différentes options pour différentes versions de tmux?

J'ai un .tmux.conf que j'utilise sur différentes machines avec différentes versions de tmux installées.

Je veux définir différentes options de souris, selon la version de tmux. Sur une machine, j'ai la version 2.0 de l'autre 2.1.

Je ne comprends pas son rôle

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"

Quand je source le fichier

$ tmux source-file .tmux.conf

Je reçois ce message

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

La machine sur laquelle je l'exécute a la version 2.1 donc il ne devrait pas définir les quatre options.

Je veux définir les quatre options lors de l'exécution de tmux 2.0 ou moins ou la seule option lors de l'exécution de tmux 2.1.

Cette instruction bash fonctionne

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

Sur la base de réponse de @ ericx et réponse de @ thiagowfx j'ai rassemblé les éléments suivants qui couvrent la plupart des incompatibilités répertoriées à partir de la version 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"

J'ai soulevé un problème concernant les problèmes de non-rétrocompatibilité de tmuxici . Le résumé est que les développeurs tmux ne prendront pas en charge la compatibilité descendante, ni n'adopteront un schéma de numérotation des versions qui met en évidence les versions qui contiennent des changements de rupture. ????

J'ai posé un problème à prend en charge les comparateurs numériques pour %if qui était implémenté dans la v3. .

37
Tom Hale

if-Shell ne fonctionne pas toujours. À la place, j'utilise un script Shell pour charger la bonne version de tmux.conf:

Dans .tmux.conf:

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

Dans 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

Pour plus de détails: https://Gist.github.com/vincenthsu/6847a8f2a94e61735034e65d17ca0d66

19
Vincent Hsu

C'est une sorte de hâte. La façon correcte de le faire dans tmux (ne s'appuyant pas sur un script Shell externe) combine les fonctionnalités des réponses de Vincent et de jdloft.

Le if-Shell la commande dans tmux est utilisée comme

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).

Notez que l'extension tmux Shell-command étendra les variables de la forme #{pane_current_path} mais sinon, la commande restera inchangée.

Plus important encore, notez que tmux tilise/bin/sh -c pour exécuter la commande Shell que nous spécifions. Ainsi, la commande doit être compatible POSIX , donc des tests de la forme [[ ne sont pas garantis portables. Systèmes Ubuntu et Debian modernes, par exemple, symlink /bin/sh à dash.

Nous voulons exécuter une commande Shell compatible POSIX qui teste la version tmux et renvoie 0 (vrai) si la version souhaitée est trouvée.

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

Exemple:

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' 

Cela traite correctement le fait que nous faisons de l'arithmétique à virgule flottante, donc bcest requis . De plus, il n'y a pas besoin d'une construction if/then/else/fi, car le [ L'opérateur produit lui-même une valeur véridique.

Quelques notes

  • Les lignes qui continuent sur la ligne suivante ne peuvent pas avoir de commentaires de fin ou tmux affichera un message d'erreur "commande inconnue".
  • La "commande si faux" peut être omise.
  • Plusieurs commandes pour true ou false peuvent être combinées à l'aide de ;
  • La commande est exécutée sur le shell sous-jacent à l'aide de /bin/sh -c. Autres approches utilisant [[ ou toute autre syntaxe non POSIX ne sont pas garantis pour fonctionner.

[~ # ~] modifier [~ # ~] : une version précédente de cette réponse utilisait [[, qui ne fonctionne pas sur les systèmes qui n'utilisent pas bash. Remplacement par [ résout ce problème.

17
Micah Smith

Je suis également tombé sur des asymétries de configuration dans différentes versions de tmux. Après avoir examiné toutes les solutions ici et dans cette question connexe sur SuperUser , j'ai implémenté la variante suivante:

# 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"

Avec cela, la configuration spécifique à la version peut être placée dans (plusieurs) extraits de configuration pour une version particulière. Ceci est similaire à la solution de @VincentHsu, mais:

  • Il ne nécessite pas de script Shell externe.
  • Il ne se divise pas en plages de versions fixes (.../1.9 à 2.0/2.1 ...). Au lieu de cela, on peut utiliser des liens (sym) pour partager un extrait de configuration entre plusieurs versions de tmux.
  • Il ne code pas en dur un nom de fichier unique pour une version. En autorisant plusieurs extraits de configuration pour chaque version, les parties peuvent être partagées entre les versions tandis que d'autres sont spécifiques à la version. Cela devrait offrir la plus grande flexibilité.
  • Il n'y a qu'un seul élément de configuration dans l'original ~/.tmux.conf. D'autres solutions comme celle de @TomHale dupliquent le test de version pour chaque élément de configuration.
8
Ingo Karkat

Le if-Shell De Tmux peut être utilisé pour vérifier la version ZSH.

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

vérifie si la version tmux est supérieure ou égale à 2.1. En utilisant cela, nous pouvons définir les commandes de votre souris en fonction de la version 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'

Et définissez-le pour les versions ultérieures de tmux:

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

Sur certaines machines, j'obtenais un résultat faussement positif avec la syntaxe à double crochet ('[['). J'ai donc trouvé une alternative en utilisant 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

J'ai combiné des solutions suggérées à une solution fonctionnelle (testée sur tmux 1.8 et 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

La dernière version actuelle est 2.9a, qui supprime bon nombre des comparaisons directes utilisées ici.

Mon alternative utilise sort -V, qui est beaucoup plus robuste pour gérer les comparaisons de versions.

# 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