tmux configuration stanzas based on Tmux version

5

1

This question is loosely related to this one.

So I am using a range of Tmux versions between 1.5 and 2.2 on various operating systems (and Linux distros).

My ~/.tmux.conf which had been tailored to earlier versions shows the following three lines of warning on Tmux 2.2:

/home/username/.tmux.conf:34: unknown option: mode-mouse
/home/username/.tmux.conf:70: unknown option: status-utf8
/home/username/.tmux.conf:71: unknown option: utf8

A cursory look into the man page suggests that these configuration options have been discontinued. However, instead of silently ignoring them, Tmux complains about the "unknown" options.

The lines corresponding to the above warnings are:

set-window-option -g mode-mouse off
set-option -g status-utf8 on
set-window-option -g utf8 on

The option mode-mouse was discontinued in Tmux 2.1, status-utf8 and utf8 were discontinued in Tmux 2.2. The CHANGES file in the source tree details the options that have been removed, along with a brief description.

Is there a method by which I can suppress this output? Better yet, is it perhaps possible to conditionally execute configuration file stanzas based on the Tmux version without separate configuration file snippets (which would have to be source-d)?

In short: what's the straightforward way to use the exact same .tmux.conf across multiple Tmux versions?


Rationale: the reason this bothers me is that Tmux will show these warnings whenever a session gets started. And the it takes an action on my part (pressing a key) to get dropped into the shell. However, on older Tmux versions I do not have the problems, but I'd like to set the respective options on these older Tmux versions.


From the old man page:

status-utf8 [on | off]

Instruct tmux to treat top-bit-set characters in the status-left and status-right strings as UTF-8; notably, this is important for wide characters. This option defaults to off.

and:

utf8 [on | off]

Instructs tmux to expect UTF-8 sequences to appear in this window.

0xC0000022L

Posted 2016-04-26T10:51:50.717

Reputation: 5 091

When it comes to Debian, I prefer just installing 2.2 from jessie-backports. Surprised that some distros still have 1.5 though. – user1686 – 2016-04-26T10:55:26.617

@grawity: it's not necessarily the distro (also, I am not just using Linux), but also the fact that I do not have superuser everywhere, so it makes it impossible to build and install my own (new and compatible) Tmux. Some of these systems are intentionally kept without updates, for others it's probably negligence :) – 0xC0000022L – 2016-04-26T10:58:11.387

Answers

3

Is there a method by which I can suppress this output?

Yes. The set-option and set-window-option commands take a -q ("quiet") flag, which suppresses errors about unknown options. This should cover you:

set-window-option -gq mouse off
set-window-option -gq mode-mouse off
set-option -gq status-utf8 on
set-window-option -gq utf8 on

Z.G.M.

Posted 2016-04-26T10:51:50.717

Reputation: 336

Aha! Thanks. I'll give this a try and report back. For mode-mouse versus mouse it still needs something similar to my workaround, or a separate line to have both. – 0xC0000022L – 2016-05-10T15:03:36.073

3

Based on @ericx's answer and @thiagowfx's answer I put the following together which covers 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 | cut -c 6-)"

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 also raised an issue to support numeric comparators for %if.

Tom Hale

Posted 2016-04-26T10:51:50.717

Reputation: 1 348

0

This is my favorite solution to the problem, which also dodges the issue that if-shell was less reliable on older Tmux versions.


As a temporary workaround I was using the following configuration stanzas:

if-shell "tmux -V|awk '{if($2 < 2.1) {exit 0} else {exit 1}}'" "set-window-option -g mode-mouse off" "set-window-option -g mouse off"
if-shell "tmux -V|awk '{if($2 < 2.2) {exit 0} else {exit 1}}'" "set-option -g status-utf8 on"
if-shell "tmux -V|awk '{if($2 < 2.2) {exit 0} else {exit 1}}'" "set-window-option -g utf8 on"

in place of the original stanzas:

set-window-option -g mode-mouse off
set-option -g status-utf8 on
set-window-option -g utf8 on

I am not sure whether this will work with all awk flavors on all the operating systems and Linux distros I am using, but perhaps it helps someone else who can rely on a narrow set of awk flavors (e.g. only gawk and mawk for which I have tested the command).

Please note the comments to this answer for some issues with this approach.

0xC0000022L

Posted 2016-04-26T10:51:50.717

Reputation: 5 091

tmux -V|awk '{if($2 < 2.2) {exit 0}}' -- this will ALWAYS exit with 0 (hence if-shell is not really conditional). If the condition is true, then because of that, if not, then because awk always exits with 0 unless an explicit exit specifies differently. – Gombai Sándor – 2016-04-26T13:07:52.250

This will break if versions ever get to 2.10 since awk will find 2.10 to be "less" then 2.2. See below for a separate answer with formatted text. – ericx – 2016-05-22T17:52:39.430

0

I like @tom-hale 's answer, but I find using "expr" more brief in my use-case:

run-shell "tmux setenv -g TMUX_VERSION $(tmux -V | cut -c 6-)"
if-shell 'expr $TMUX_VERSION ">=" 1.7' 'bind-key R move-window -r'

This exploits the fact that the comparison with expr will ignore trailing letters, can compare floats and "Exit status is 0 if EXPRESSION is neither null nor 0, 1 if EXPRESSION is null or 0 [...]" according to the manpage.

TauPan

Posted 2016-04-26T10:51:50.717

Reputation: 1

-1

In this case, I like the "quiet" answer suggested above; but if you have genuine version conditional config changes, consider this solution similar to your own answer:

# grab version info about the tmux currently running
run-shell "tmux setenv -g TMUX_VERSION_MAJOR $(tmux -V | cut -d' ' -f2 | cut -d'.' -f1 | sed 's/[^0-9]*//g')"
run-shell "tmux setenv -g TMUX_VERSION_MINOR $(tmux -V | cut -d' ' -f2 | cut -d'.' -f2 | sed 's/[^0-9]*//g')"

I then have various if-shell checks; so in this case:

if-shell \
    '[ $TMUX_VERSION_MAJOR -le 1 -o \
         \( $TMUX_VERSION_MAJOR -eq 2 -a $TMUX_VERSION_MINOR -lt 1 \) ]' \
    "set-window-option -g mode-mouse off" \
    "set-window-option -g mouse off"

if-shell \
    '[ $TMUX_VERSION_MAJOR -le 1 -o \
         \( $TMUX_VERSION_MAJOR -eq 2 -a $TMUX_VERSION_MINOR -lt 2 \) ]' \
    "set-option -g status-utf8 on; set-window-option -g utf8 on" \
    ""

I don't remember where I found this; but someone else gets the credit.

ericx

Posted 2016-04-26T10:51:50.717

Reputation: 157

You'll need a ; between the two commands in the first stanza, see my answer for a continuation within a continuation.

– Tom Hale – 2016-12-01T03:43:50.890

Re credit, your continuation syntax looks a lot like the one in this answer.

– Tom Hale – 2016-12-01T04:00:54.880