`set t_Co=16` in vimrc file has no effect

161 views
Skip to first unread message

Nikolay Belikov

unread,
Sep 28, 2020, 6:32:24 PM9/28/20
to v...@vim.org
Hello all,

I've stumbled upon strange behavior in Vim 8.2 regarding `t_Co`
variable. This might be a bug, but more probably is just a case of
PEBCAK, so maybe someone could point me towards what I'm doing wrong.

Background: I want to use my terminal emulator (which is plain old
`xterm`) color scheme across all TUI programs, including Vim. I've
added `set t_Co=16` to my `.vim/vimrc` file and expected Vim to limit
itself to 16 base colors (at least this is what all sources on Internet
say to do, which I managed to find). However, it appears that Vim does
not honor my will and resets `t_Co` to 256, unless I manually type `:set
t_Co=16` in command-line mode.

I reduced my `vimrc` to the bare minimum needed to reproduce the
problem, and now it contains a single line:

set t_Co=16

At this point I'm unsure what to do and ask for your assistance. I
attach a log captured by running `vim -V100vim.log` as well as version
info (`vim --version >vim.version`), and I'm willing to provide any
other info that may be of help.

Best regards,
NB
vim.tar.gz

Tony Mechelynck

unread,
Sep 28, 2020, 7:03:36 PM9/28/20
to vim_use

I wouldn't expect Vim to overide that setting, but maybe some script (for instance some "system vimrc" installed by your sysadmin or your software distributor) does it behind your back.

The command
        :verbose set t_Co?
should tell you both the current value and where it was set.

If that still doesn't help you, you might try to replace your "set t_Co=16" statement by

        if has('autocmd') && !has('gui_running')
                au VimEnter set t_Co=16 | syntax enable
        endif

(which would set that setting at the very end of startup, except in gvim which uses 16777216 colours no matter what you set t_Co to) and see if it changes anything.

Best regards,
Tony.
Tony.

Gary Johnson

unread,
Sep 29, 2020, 11:06:51 AM9/29/20
to vim...@googlegroups.com
Vim may change t_Co when it receives a terminal's termresponse.
I noticed the same strange behavior some years ago with Vim setting
t_Co to 256 in an xterm. See

:help v:termresponse
:help t_RV
:helpgrep termresponse

You can test this by adding this to your vimrc,

set t_RV=

and seeing if t_Co is still mysteriously reset to 256.

You may be able to reset t_Co to 16 with this in your vimrc:

autocmd TermResponse * set t_Co=16

I say "may" because I've found that not everything works as I would
expect it to in the environment of a TermResponse autocommand.

See

:help TermResponse

Regards,
Gary

Bram Moolenaar

unread,
Sep 29, 2020, 2:35:17 PM9/29/20
to vim...@googlegroups.com, Gary Johnson
Vim has a special mechanism to request the actual termcap codes from
xterm. This happens after receiving the termresponse. Using the
TermResponse autocommand may do this too early.

There is actually no way to disable this mechanism without also
disabling some other stuff. It might be helpful to add an option to
disable the mechanism. 'termgetcodes', default on?
The function that sends the requests is req_more_codes_from_term().

--
hundred-and-one symptoms of being an internet addict:
15. Your heart races faster and beats irregularly each time you see a new WWW
site address in print or on TV, even though you've never had heart
problems before.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Gary Johnson

unread,
Sep 29, 2020, 3:27:42 PM9/29/20
to vim...@googlegroups.com
I'm too busy at the moment to give this a very thoughtful response,
and it was a while ago that I looked at that code, but it seems that
there were several things done in response to receiving the
termresponse, so I don't know that one option would serve all needs.
In the present case, the only problem seems to be the setting of
t_Co.

The problem I've had is that I want to set various options and
highlights depending on the terminal type, but the type is not
accurately known when vimrc is read, and when the TermResponse event
is triggered, not everything can be set correctly.

I've resorted to having the termresponse queried in my ~/.bashrc,
which sets an environment variable that vimrc can then read. It
works very well for making terminal-dependent settings in my vimrc
and colorscheme files. When vim queries and receives the
termresponse itself, it then makes the additional settings you
mentioned. It would be nice, though, if this could all be done
within Vim.

I think maybe the whole termresponse behavior should be thought
through and made more useful, perhaps by adding a later
TermResponse-like event. I'll try to find some time.

Regards,
Gary

Christian Brabandt

unread,
Sep 30, 2020, 4:26:44 AM9/30/20
to vim...@googlegroups.com

On Di, 29 Sep 2020, Gary Johnson wrote:

> I'm too busy at the moment to give this a very thoughtful response,
> and it was a while ago that I looked at that code, but it seems that
> there were several things done in response to receiving the
> termresponse, so I don't know that one option would serve all needs.
> In the present case, the only problem seems to be the setting of
> t_Co.
>
> The problem I've had is that I want to set various options and
> highlights depending on the terminal type, but the type is not
> accurately known when vimrc is read, and when the TermResponse event
> is triggered, not everything can be set correctly.
>
> I've resorted to having the termresponse queried in my ~/.bashrc,
> which sets an environment variable that vimrc can then read. It
> works very well for making terminal-dependent settings in my vimrc
> and colorscheme files. When vim queries and receives the
> termresponse itself, it then makes the additional settings you
> mentioned. It would be nice, though, if this could all be done
> within Vim.
>
> I think maybe the whole termresponse behavior should be thought
> through and made more useful, perhaps by adding a later
> TermResponse-like event. I'll try to find some time.

I think this was suggested before. Also the todo file contains a couple
of statements regarding termresponse, e.g.

,----
| Add another autocommand like TermResponse that is fired for the other terminal
| responses, such as bg and fg. Use "bg", "fg", "blink", etc. for the name.
`----

I think Bram also suggested to add additional TermResponse<Event> for
the various term events before.

BTW: Why wouldn't the VimEnter autocommand work? Is that, because
changing terminal options would then require some more initialization or
is that triggered too early?

Best,
Christian
--
Nie in die ferne Zeit verliere dich! Den Augenblick ergreife! Der ist dein.
-- Friedrich Schiller

Gary Johnson

unread,
Sep 30, 2020, 1:25:04 PM9/30/20
to vim...@googlegroups.com
Thanks for the pointers.

I had been thinking of having a single TermResponsePost event, but
having multiple events might be better, especially if each of the
other responses is sent separately.

As I recall, VimEnter is too early.

I often work remotely, with a terminal on my desktop at home or in
an office and the host on which Vim is running many miles away,
often through a relatively slow network. For a while, after either
my xterm changed or Vim changed so that t_Co was reset after
receiving the termresponse, my vim screen would flash at startup
because it would first be drawn using t_Co=16 as set in my vimrc,
then be redrawn a moment later at t_Co=256 when the termresponse was
received.

I am currently working from home and all my Vim sessions are local
or within my home network, so I don't have the delay problem. I'll
have to determine which of the VimEnter and TermResponse events
occurs first, but a general solution should assume that TermResponse
occurs later.

Regards,
Gary

Bram Moolenaar

unread,
Sep 30, 2020, 4:50:29 PM9/30/20
to vim...@googlegroups.com, Gary Johnson
Talking back and forth with xterm can take some time. I have thought of
another mechanism that would exchange a hash code of all the codes. If
Vim recognizes it (cashed response) it's done quickly. If not then Vim
would request the termcap/terminfo settings from the terminal. This way
you have a delay only once and accurate codes all the time. But no work
has been done for it, and it would require talking to xterm clones and
other program authors to get it widely accepted.

> I often work remotely, with a terminal on my desktop at home or in
> an office and the host on which Vim is running many miles away,
> often through a relatively slow network. For a while, after either
> my xterm changed or Vim changed so that t_Co was reset after
> receiving the termresponse, my vim screen would flash at startup
> because it would first be drawn using t_Co=16 as set in my vimrc,
> then be redrawn a moment later at t_Co=256 when the termresponse was
> received.

That's why I was thinking of disabling the mechanism, to avoid the
flicker. Of course you then need to manually set the value.

> I am currently working from home and all my Vim sessions are local
> or within my home network, so I don't have the delay problem. I'll
> have to determine which of the VimEnter and TermResponse events
> occurs first, but a general solution should assume that TermResponse
> occurs later.

It's possible, but the flicker would still happen.

--
Q: What is the difference between open-source and commercial software?
A: If you have a problem with commercial software you can call a phone
number and they will tell you it might be solved in a future version.
For open-source software there isn't a phone number to call, but you
get the solution within a day.

Christian Brabandt

unread,
Oct 1, 2020, 2:48:39 AM10/1/20
to vim...@googlegroups.com

On Mi, 30 Sep 2020, Bram Moolenaar wrote:

> > As I recall, VimEnter is too early.

Would a timer work?

> > I often work remotely, with a terminal on my desktop at home or in
> > an office and the host on which Vim is running many miles away,
> > often through a relatively slow network. For a while, after either
> > my xterm changed or Vim changed so that t_Co was reset after
> > receiving the termresponse, my vim screen would flash at startup
> > because it would first be drawn using t_Co=16 as set in my vimrc,
> > then be redrawn a moment later at t_Co=256 when the termresponse was
> > received.
>
> That's why I was thinking of disabling the mechanism, to avoid the
> flicker. Of course you then need to manually set the value.

Do you mean, if the option is set manually in vimrc, disable the
termresponse? That would be a good compromise, I think.


Mit freundlichen Grüßen
Christian
--
Man kann alle Leute einige Zeit zum Narren halten und einige Leute allezeit,
aber alle Leute allezeit zum Narren halten kann man nicht.
-- Abraham Lincoln

Gary Johnson

unread,
Oct 1, 2020, 4:07:43 AM10/1/20
to vim...@googlegroups.com
On 2020-10-01, Christian Brabandt wrote:
> On Mi, 30 Sep 2020, Bram Moolenaar wrote:
>
> > > As I recall, VimEnter is too early.
>
> Would a timer work?

Perhaps. And it might be better than nothing. But timers carry the
risk that you wait too long on fast systems/connections and not long
enough on slow systems/connections.

> > > I often work remotely, with a terminal on my desktop at home or in
> > > an office and the host on which Vim is running many miles away,
> > > often through a relatively slow network. For a while, after either
> > > my xterm changed or Vim changed so that t_Co was reset after
> > > receiving the termresponse, my vim screen would flash at startup
> > > because it would first be drawn using t_Co=16 as set in my vimrc,
> > > then be redrawn a moment later at t_Co=256 when the termresponse was
> > > received.
> >
> > That's why I was thinking of disabling the mechanism, to avoid the
> > flicker. Of course you then need to manually set the value.
>
> Do you mean, if the option is set manually in vimrc, disable the
> termresponse? That would be a good compromise, I think.

The problem is, in my case, that I use a variety of terminals
running in a variety of operating systems to access vim on a variety
of hosts. Sometimes I run vim locally while at other times I run it
over an ssh connection. TERM is unreliable--almost every terminal
claims it's an xterm. The termresponse has been for me an excellent
means of determining the terminal type. It's just a little slow.
Disabling it would leave me as if back in pre-termresponse days with
terminal-dependent settings that weren't optimum and colors that
were often unreadable.

What I would like to be able to do--although I haven't tried this so
I might not like it after all--is to send t_RV at the start of my
vimrc, wait for the response (with a timeout), let Vim do what it
normally does upon receiving a termresponse, then continue with
the processing of the rest of my vimrc. The termresponse exchange
normally happens in a fraction of a second, before I can type my
first keystroke anyway, and in less time than it takes to start Vim
on Windows, and the delay would prevent the flickering of a second
display refresh.

Regards,
Gary

Bram Moolenaar

unread,
Oct 1, 2020, 10:38:11 AM10/1/20
to vim...@googlegroups.com, Christian Brabandt

Christian wrote:

> On Mi, 30 Sep 2020, Bram Moolenaar wrote:
>
> > > As I recall, VimEnter is too early.
>
> Would a timer work?
>
> > > I often work remotely, with a terminal on my desktop at home or in
> > > an office and the host on which Vim is running many miles away,
> > > often through a relatively slow network. For a while, after either
> > > my xterm changed or Vim changed so that t_Co was reset after
> > > receiving the termresponse, my vim screen would flash at startup
> > > because it would first be drawn using t_Co=16 as set in my vimrc,
> > > then be redrawn a moment later at t_Co=256 when the termresponse was
> > > received.
> >
> > That's why I was thinking of disabling the mechanism, to avoid the
> > flicker. Of course you then need to manually set the value.
>
> Do you mean, if the option is set manually in vimrc, disable the
> termresponse? That would be a good compromise, I think.

Not the termresponse, it is used for several other things, but disabling
the mechanism to fetch the values from xterm, which is what causes t_Co
to change later, at an unpredictable time.

--
Don't Panic!
-- The Hitchhiker's Guide to the Galaxy
Reply all
Reply to author
Forward
0 new messages