Korgan Rivera
Korgan Rivera

Reputation: 495

What's happening here with vim inside TMUX pane?

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): enter image description here

Pretty new to both vim and TMUX. How can I solve this?

Upvotes: 1

Views: 1037

Answers (1)

user938271
user938271

Reputation: 404

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:

  1. the terminal doesn't support true colors
  2. tmux is not properly configured to support true colors
  3. Vim is not properly configured to support true colors

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:

  • disable 'termguicolors' in your ~/.vimrc; i.e. remove set termguicolors (or make it execute set notermguicolors)
  • try and upgrade your terminal
  • find another terminal which supports true colors

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

Upvotes: 5

Related Questions