[vim/vim] Wrong background color detected in tmux and TERM=screen-256color (#7867)

753 views
Skip to first unread message

Haodong DU

unread,
Feb 18, 2021, 7:44:49 PM2/18/21
to vim/vim, Subscribed

Describe the bug
In a terminal with dark background, when you set TERM=screen-256color or really run tmux which requires TERM set to screen-256color, the background is always detected as light. Then default.vim instead of ron.vim is used. default.vim is hard to read in dark background.

To Reproduce
Two way to test, really use tmux or make vim think you are using tmux by setting TERM

  1. Open tmux in a terminal with dark background. In tmux conf set TERM to screen-256color.
  2. Open vim, and query set background? and colorscheme.

OR

  1. Open a terminal with dark background.
  2. export TERM=screen-256color
  3. Open vim, and query set background? and colorscheme.

With terminal.app and alacritty.app background is detected as light in both cases. With iTerm2, background is detected correctly in the second case, but still worn't work when you really use tmux. This is a bit involving, terminal/tmux/vim all could have problems. But currently Vim seems most at fault.

Expected behavior
background dectected as dark and ron.vim color scheme is used(it will still displays as default, i know).

Screenshots
If applicable, copy/paste the text or add screenshots to help explain your problem.

Environment (please complete the following information):

  • Vim version: 8.2.1972
  • OS: macos 11.2.1
  • Terminal: Macos Terminal and Alacritty and iTerm2

Additional context


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.

lacygoill

unread,
Feb 18, 2021, 8:11:51 PM2/18/21
to vim/vim, Subscribed

I wonder whether it would help if tmux supported the OSC 11 sequence to query the terminal background color. Then, maybe Vim could leverage the sequence to correctly set 'background' after receiving the answer. Someone asked for this on the tmux issue tracker, but the OP never tested the patch, nor gave any feedback.

Haodong DU

unread,
Feb 18, 2021, 8:30:46 PM2/18/21
to vim/vim, Subscribed

@lacygoill Thanks for pointing to that issue. It's not only tmux and Vim, it seems Terminal also makes a difference

terminal type tests background correct?
Terminal TERM=screen-256color
Terminal tmux
iTerm2 TERM=screen-256color
iTerm2 tmux
iTerm2 screen
Terminal screen

Hope one of Terminal/tmux/Vim teams could handle this issue. But we do have a working workaround. Probably they won't spend time on this.

Gary Johnson

unread,
Feb 18, 2021, 8:43:33 PM2/18/21
to reply+ACY5DGBP6AZDMAK3CZ...@reply.github.com, vim...@googlegroups.com
On 2021-02-18, Haodong DU wrote:
> Describe the bug
> In a terminal with dark background, when you set TERM=screen-256color or really
> run tmux which requires TERM set to screen-256color, the background is always
> detected as light. Then default.vim instead of ron.vim is used. default.vim is
> hard to read in dark background.
>
> To Reproduce
> Two way to test, really use tmux or make vim think you are using tmux by
> setting TERM
>
> 1. Open tmux in a terminal with dark background. In tmux conf set TERM to
> screen-256color.
> 2. Open vim, and query set background? and colorscheme.
>
> OR
>
> 1. Open a terminal with dark background.
> 2. export TERM=screen-256color
> 3. Open vim, and query set background? and colorscheme.
>
> With terminal.app and alacritty.app background is detected as light in both
> cases. With iTerm2, background is detected correctly in the second case, but
> still worn't work when you really use tmux. This is a bit involving, terminal/
> tmux/vim all could have problems. But currently Vim seems most at fault.
>
> Expected behavior
> background dectected as dark and ron.vim color scheme is used(it will still
> displays as default, i know).
>
> Screenshots
> If applicable, copy/paste the text or add screenshots to help explain your
> problem.
>
> Environment (please complete the following information):
>
> • Vim version: 8.2.1972
> • OS: macos 11.2.1
> • Terminal: Macos Terminal and Alacritty and iTerm2

I see the same behavior in Linux. It appears, though, that Vim is
not detecting a background color from tmux and hence defaults to
'light', as it says in ":help 'background'".

Vim tries to determine the background color from the terminal using
the t_RB option, but if TERM is "screen-256color", that option is
not set. You can verify this by executing any of the following.

:set termcap
:set t_RB?
:echo v:termrbgresp

That last is actually the response Vim received from the t_RB query.

Vim does try to guess the background from the terminal name, but
"screen-256color" is not one of the names it checks.

Your best bet may be to follow the suggestion in ":help
'background'" and put this in your vimrc:

:if &term == "screen-256color"
: set background=dark
:endif

Regards,
Gary

vim-dev ML

unread,
Feb 18, 2021, 8:43:57 PM2/18/21
to vim/vim, vim-dev ML, Your activity

On 2021-02-18, Haodong DU wrote:
> Describe the bug
> In a terminal with dark background, when you set TERM=screen-256color or really
> run tmux which requires TERM set to screen-256color, the background is always
> detected as light. Then default.vim instead of ron.vim is used. default.vim is
> hard to read in dark background.
>
> To Reproduce
> Two way to test, really use tmux or make vim think you are using tmux by
> setting TERM
>
> 1. Open tmux in a terminal with dark background. In tmux conf set TERM to
> screen-256color.
> 2. Open vim, and query set background? and colorscheme.
>
> OR
>
> 1. Open a terminal with dark background.
> 2. export TERM=screen-256color
> 3. Open vim, and query set background? and colorscheme.

>
> With terminal.app and alacritty.app background is detected as light in both
> cases. With iTerm2, background is detected correctly in the second case, but
> still worn't work when you really use tmux. This is a bit involving, terminal/
> tmux/vim all could have problems. But currently Vim seems most at fault.
>
> Expected behavior
> background dectected as dark and ron.vim color scheme is used(it will still
> displays as default, i know).
>
> Screenshots
> If applicable, copy/paste the text or add screenshots to help explain your
> problem.
>
> Environment (please complete the following information):
>
> • Vim version: 8.2.1972
> • OS: macos 11.2.1
> • Terminal: Macos Terminal and Alacritty and iTerm2

I see the same behavior in Linux. It appears, though, that Vim is
not detecting a background color from tmux and hence defaults to
'light', as it says in ":help 'background'".

Vim tries to determine the background color from the terminal using
the t_RB option, but if TERM is "screen-256color", that option is
not set. You can verify this by executing any of the following.

:set termcap
:set t_RB?
:echo v:termrbgresp

That last is actually the response Vim received from the t_RB query.

Vim does try to guess the background from the terminal name, but
"screen-256color" is not one of the names it checks.

Your best bet may be to follow the suggestion in ":help
'background'" and put this in your vimrc:

:if &term == "screen-256color"
: set background=dark
:endif

Regards,
Gary

lacygoill

unread,
Feb 18, 2021, 9:22:38 PM2/18/21
to vim/vim, vim-dev ML, Comment

In a terminal with dark background, when you set TERM=screen-256color or really run tmux which requires TERM set to screen-256color

Not sure it helps, but you're not limited to screen-256color; you can also use tmux-256color, provided that your terminfo is recent enough and contains a matching description. See this comment for how to update it.

If TERM is tmux or tmux-256color, maybe Vim could query the true identity of the outer terminal using the #{client_termname} format:

:echo system("tmux display -p '#{client_termname}'")->trim("\n", 2)

The problem is that system() is slow on startup. Not sure whether it's possible in the C code, but calling tmux display asynchronously should help. Example in Vim script:

vim9script
if &term =~ '^tmux'
    def GetOuterTerm(_c: channel, outer_term: string)
        echom outer_term
    enddef
    job_start('tmux display -p #{client_termname}', {out_cb: GetOuterTerm})
endif

Then, if Vim detects that the outer terminal is on its list of terminals for which 't_RB' can be set, it would set the option as if tmux was not there.

Or maybe we need some new sequence to query the name of the outer terminal from tmux...


You are receiving this because you commented.

Haodong DU

unread,
Feb 18, 2021, 9:33:25 PM2/18/21
to vim/vim, vim-dev ML, Comment

I just tried the patch. It does not work. printf '\e]11;?\007' shows no result. I figured out why different terminals behaves differently, some terminals set COLORFGBG which VIM is also checking. COLORFGBG can help but it's not standard. So terminal is not relevant here.
Your example looks beautiful. But still we need tmux to handle the control sequence, right? Eventually we need tmux developer to add support for the query of bg and Vim developer to add t_RB for tmux.


You are receiving this because you commented.

lacygoill

unread,
Feb 18, 2021, 9:49:06 PM2/18/21
to vim/vim, vim-dev ML, Comment

printf '\e]11;?\007' shows no result.

Maybe because the outer terminal does not support OSC 11.

For example, printf '\e]11;?\007' works in xterm on my machine, but not in st.


However, I have this line in my tmux.conf:

set -gw window-active-style 'bg=#dbd6d1'

If I start tmux from xterm or from st, then in both cases, I get an answer:

11;rgb:db/d6/d1

Eventually we need tmux developer to add support for the query of bg

I guess so, yes.

and Vim developer to add t_RB for tmux.

But I think that would be wrong. From Vim point of view, the fact that $TERM/&term is tmux or some derivative doesn't mean much. The outer terminal could be xterm, st, iTerm, alacritty, or any other terminal. That's why I suggested using the #{client_termname} tmux format, in one way or another.


You are receiving this because you commented.

Gary Johnson

unread,
Feb 18, 2021, 9:53:43 PM2/18/21
to reply+ACY5DGGZ4OFFYLHE36...@reply.github.com, vim...@googlegroups.com
On 2021-02-18, lacygoill wrote:

> Or maybe we need some new sequence to query the name of the outer
> terminal from tmux...

You can prefix the normal escape sequence with <Esc>Ptmux;<Esc> to
go though tmux to the outer terminal. I still have this in my vimrc
from some earlier experiments:

" Released in tmux v1.5 (2011-07-09):
"
" Support passing through escape sequences to the underlying
" terminal by using DCS with a "tmux;" prefix.
"
" Note that this must be set _after_ any setting of 'term'
" because setting 'term' also sets dependent termcap
" variables including 't_RV'.
"
if exists("$TMUX")
let &t_RV = "\ePtmux;\e\e[>c\e\\"
endif

The problem with it is that TMUX is not normally exported by an ssh
server, but if that's not a problem for the OP, then this technique
should work for t_RB as well.

I didn't like that Vim wouldn't know the terminal type until after
vimrc had been processed, so I added the termresponse query to my
.bashrc and set a TERMRESPONSE environment variable to the response.
My vimrc then uses $TERMRESPONSE to make various terminal-dependent
settings.

Regards,
Gary

vim-dev ML

unread,
Feb 18, 2021, 9:54:06 PM2/18/21
to vim/vim, vim-dev ML, Your activity

Haodong DU

unread,
Feb 18, 2021, 10:42:43 PM2/18/21
to vim/vim, vim-dev ML, Comment

Tried this

if exists("$TMUX")
    let &t_RB='\ePtmux;\e\e]11;?\007\e\\'
endif

The sequence is set and works in tmux outside Vim. But echo v:termrbgresp shows no result. Hi @lacygoill , I find this tmux/tmux#2216, did you have any problem passing results from outer terminal to Vim? it does not work in this case.


You are receiving this because you commented.

lacygoill

unread,
Feb 18, 2021, 10:58:42 PM2/18/21
to vim/vim, vim-dev ML, Comment

Tried this

if exists("$TMUX")
    let &t_RB = '\ePtmux;\e\e]11;?\007\e\\'
endif

You need to use double quotes for Vim to translate \e into a literal escape character:

if exists("$TMUX")
    let &t_RB = "\ePtmux;\e\e]11;?\007\e\\"
endif

did you have any problem passing results from outer terminal to Vim?

I don't think so. Using the DCS sequence prefixed with \ePtmux should be used as a last resort. There can pitfalls with it. I should just have set the recent tmux option terminal-features. But I don't think it's relevant to the current issue.


You are receiving this because you commented.

Haodong DU

unread,
Feb 18, 2021, 11:10:16 PM2/18/21
to vim/vim, vim-dev ML, Comment

Closed #7867.


You are receiving this because you commented.

Haodong DU

unread,
Feb 18, 2021, 11:10:17 PM2/18/21
to vim/vim, vim-dev ML, Comment

Thanks. It works like a charm. I've little experience playing with control sequence. Didn't notice the difference. Hope tmux would add support for more control sequences. I will close this issue for now and would reopen/recreate if tmux made changes.


You are receiving this because you commented.

Haodong Du

unread,
Feb 18, 2021, 11:36:41 PM2/18/21
to vim_dev
Thank you Gary. Your explanation is very clear. Indeed with TERM=screen* the query returns nothing.
But I'm still a little confused as it seems Vim can detect background from screen with the same TERM as tmux. But not always, in some terminal apps, it works with screen. Is that the 'guessing'? Sounds like magic.

Regards,
Haodong

Tony Mechelynck

unread,
Feb 18, 2021, 11:52:14 PM2/18/21
to Haodong Du, vim_dev
On Fri, Feb 19, 2021 at 5:36 AM Haodong Du <duhd...@gmail.com> wrote:
Thank you Gary. Your explanation is very clear. Indeed with TERM=screen* the query returns nothing.
But I'm still a little confused as it seems Vim can detect background from screen with the same TERM as tmux. But not always, in some terminal apps, it works with screen. Is that the 'guessing'? Sounds like magic.

Regards,
Haodong

From a certain point of view, it _is_ a kind of magic.

Some terminals define a certain key sequence allowing the application running in them to query (among others) the background color, or at least to determine if it is light or dark. Others don't. It depends not only on the $TERM value but also on the termcap/terminfo for that terminal: at startup, Vim will send a certain number of queries to the terminal and store the answers when (and if) they arrive (asynchronously), see the various entries under ":help term*resp" (without the quotes, and with <Tab> or CTRL-D at the end). The one about the background is v:termbgresp, which the terminal sends in answer to a t_RB key sequence sent by Vim.


Best regards,
Tony.

Haodong DU

unread,
Feb 19, 2021, 10:30:42 AM2/19/21
to vim/vim, vim-dev ML, Comment

Current master branch of tmux can return hex RGB (but it needs to set bg within tmux instead underlying terminal). Maybe it will be available in the next major release. Then Vim can add support for tmux by default(I'm ok to set it manually, just to save people from trouble of searching for solutions)


You are receiving this because you commented.

Haodong DU

unread,
Jun 30, 2022, 3:51:03 PM6/30/22
to vim/vim, vim-dev ML, Comment

After 3.3 update of tmux, you have to set allow-passthrough on to get this working. Haven't worked on improving my config for a while.


Reply to this email directly, view it on GitHub.
You are receiving this because you commented.Message ID: <vim/vim/issues/7867/1171614841@github.com>

Reply all
Reply to author
Forward
0 new messages