When I open vim inside of a TMUX pane, The pane is filled with codes I don't recognise. If I just run vim, I get this:
^[[38;2;165;42;42m 1
^[[38;2;0;0;255m~
If I open a file with vim, I get something like this (top pane):
Pretty new to both vim and TMUX. How can I solve this?
It seems that Vim is sending control sequences to your terminal which the latter doesn't understand.
More specifically, the sequences you mentioned in the OP:
^[[38;2;165;42;42m
^[[38;2;0;0;255m
look like they're encoding foreground true colors for the text.
You can find their syntax here:
CSI Pm m
Where CSI
stands for “Control Sequence Introducer” and is produced by the keys ESC [
, and Pm
stands for:
A multiple numeric parameter composed of any number of single numeric parameters, separated by ; character(s).
If you scroll down the page, you should find a description of a more detailed syntax:
CSI Pm m Character Attributes (SGR).
...
This variation on ISO-8613-6 is supported for compatibility with KDE konsole:
Pm = 3 8 ; 2 ; Pr; Pg; Pb Set foreground color to the closest match in xterm's palette for the given RGB Pr/Pg/Pb. Pm = 4 8 ; 2 ; Pr; Pg; Pb Set background color to the closest match in xterm's palette for the given RGB Pr/Pg/Pb.*
Applied to your first sequence, you can break it down like so:
┌ CSI
│ ┌ Pm
├─┐├────────────┐
^[[38;2;165;42;42m
├─┘ ├┘ ├┘
│ │ └ Pb = amount of blue
│ └ Pg = amount of green
└ Pr = amount of red
If the terminal doesn't understand this sequence, I can see 3 explanations:
To test whether 1.
is the issue, you can write this bash function in your ~/.bashrc
:
truecolor() {
local i r g b
for ((i = 0; i <= 79; i++)); do
b=$((i*255/79))
g=$((2*b))
r=$((255-b))
if [[ $g -gt 255 ]]; then
g=$((2*255 - g))
fi
printf -- '\e[48;2;%d;%d;%dm \e[0m' "$r" "$g" "$b"
done
printf -- '\n'
}
Then execute $ truecolor
in your shell, outside tmux. If you get some kind of rainbow, your terminal supports true colors (at least partially).
If you see some cells which are not colored, and others randomly colored, your terminal doesn't support true colors.
Alternatively, you can try the sequences manually:
$ printf '\e[38;2;%d;%d;%dm this text should be colored \e[0m' 165 42 42
$ printf '\e[38;2;%d;%d;%dm this text should be colored \e[0m' 0 0 255
If $ truecolor
doesn't produce a rainbow, or if the $ printf
commands don't change the foreground color (not the background color) of the text, you'll have to either:
'termguicolors'
in your ~/.vimrc
; i.e. remove set termguicolors
(or make it execute set notermguicolors
)To test whether 2.
is the issue, inside tmux, you can execute this shell command:
$ tmux info | grep Tc
If the output contains [missing]
:
203: Tc: [missing]
^^^^^^^^^
it means that tmux is not configured to support true colors.
In this case, you have to include something like this in ~/.tmux.conf
:
set -as terminal-overrides ',*-256color:Tc'
││ ├────────────────┘ ├────────┘ ├┘
││ │ │ └ tell tmux that the terminal suppors true colors
││ │ └ configure the option only if `$TERM` ends with the string `-256color`
││ └ the option to configure is `terminal-overrides` (see `$ man tmux`)
│└ the next option is a server option
└ append the value to the tmux option instead of overwriting it
Then restart tmux, and execute $ tmux info | grep Tc
. This time the output should contain true
:
203: Tc: (flag) true
^^^^
If it doesn't, have a look at the output of $TERM
outside tmux:
$ echo $TERM
The output should be matched by whatever pattern you write before :Tc
.
In the previous example, I used the pattern *-256color
which will match any terminal whose $TERM
ends with the string -256color
. If it doesn't match your $TERM
, you can try another pattern, or simply write *
to describe any type of terminal:
set -as terminal-overrides ',*:Tc'
To test whether 3.
is the issue, you can write these commands in your ~/.vimrc
:
set termguicolors
let &t_8f = "\<Esc>[38:2:%lu:%lu:%lum"
let &t_8b = "\<Esc>[48:2:%lu:%lu:%lum"
Or:
set termguicolors
let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
The only difference between the 2 versions is the delimiter between the parameters of the sequences. A colon in the first version, a semicolon in the second one. See :h xterm-true-color
for more info.
You can check the current values of these 3 options by executing successively:
:echo &tgc
:echo &t_8f
:echo &t_8b
They should output:
1
^[[38:2:%lu:%lu:%lum
^[[48:2:%lu:%lu:%lum
Or:
1
^[[38;2;%lu;%lu;%lum
^[[48;2;%lu;%lu;%lum