17

I don't have a full understanding of how my color scheme is interacting with the term setting in vim and this is impeding my ability to get it to display correctly in neovim.

In my .vimrc file, correct behavior of the color scheme in question requires setting

set term=xterm
set t_Co=256

Omitting either of those settings results in incorrect display of the color scheme:

correct Correct Color Display incorrect Incorrect Color Display different incorrect Different Incorrect Color Display

The scheme looks like this:

set background=dark
hi clear
if exists("syntax_on")
    syntax reset
endif
let g:colors_name="impact3"

if exists("g:impact_transbg")
    hi Normal       ctermfg=255 ctermbg=none
    hi NonText      ctermfg=DarkGray  ctermbg=none

    hi Statement    ctermfg=Blue      ctermbg=none
    hi Comment      ctermfg=DarkGray  ctermbg=none cterm=bold term=bold
    hi Constant     ctermfg=173  ctermbg=none
    hi Identifier   ctermfg=Cyan      ctermbg=none
    hi Type         ctermfg=DarkGreen ctermbg=none
    hi Folded       ctermfg=0 ctermbg=235 cterm=underline term=none
    hi Special      ctermfg=Blue      ctermbg=none
    hi PreProc      ctermfg=LightGray ctermbg=none cterm=bold term=bold
    hi Scrollbar    ctermfg=Blue      ctermbg=none
    hi Cursor       ctermfg=white     ctermbg=none
    hi ErrorMsg     ctermfg=Red       ctermbg=none cterm=bold term=bold
    hi WarningMsg   ctermfg=Yellow    ctermbg=none
    hi VertSplit    ctermfg=0     ctermbg=0
    hi Directory    ctermfg=Cyan      ctermbg=DarkBlue
    hi Visual       ctermfg=White     ctermbg=Gray cterm=underline term=none
    hi Title        ctermfg=255     ctermbg=Blue
    hi String       ctermfg=Blue   ctermbg=none

    hi StatusLine   term=bold cterm=bold,underline ctermfg=White ctermbg=Black
    hi StatusLineNC term=bold cterm=bold,underline ctermfg=Gray  ctermbg=Black
    hi LineNr       term=bold cterm=bold ctermfg=2 ctermbg=None
    hi Search       ctermfg=Black ctermbg=2
    hi TabLine      ctermfg=0 ctermbg=DarkGray
    hi TabLineFill  ctermfg=DarkGray ctermbg=DarkGray
else
    hi Normal       ctermfg=White ctermbg=Black
    hi NonText      ctermfg=DarkGray  ctermbg=Black

    hi Statement    ctermfg=Blue      ctermbg=Black
    hi Comment      ctermfg=DarkGray  ctermbg=Black cterm=bold term=bold
    hi Constant     ctermfg=DarkCyan  ctermbg=Black
    hi Identifier   ctermfg=Cyan      ctermbg=Black
    hi Type         ctermfg=DarkGreen ctermbg=Black
    hi Folded       ctermfg=DarkGreen ctermbg=Black cterm=underline term=none
    hi Special      ctermfg=Blue      ctermbg=Black
    hi PreProc      ctermfg=LightGray ctermbg=Black cterm=bold term=bold
    hi Scrollbar    ctermfg=Blue      ctermbg=Black
    hi Cursor       ctermfg=white     ctermbg=Black
    hi ErrorMsg     ctermfg=Red       ctermbg=Black cterm=bold term=bold
    hi WarningMsg   ctermfg=Yellow    ctermbg=Black
    hi VertSplit    ctermfg=White     ctermbg=Black
    hi Directory    ctermfg=Cyan      ctermbg=DarkBlue
    hi Visual       ctermfg=White     ctermbg=DarkGray cterm=underline term=none
    hi Title        ctermfg=White     ctermbg=DarkBlue

    hi StatusLine   term=bold cterm=bold,underline ctermfg=White ctermbg=Black
    hi StatusLineNC term=bold cterm=bold,underline ctermfg=Gray  ctermbg=Black
    hi LineNr       term=bold cterm=bold ctermfg=White ctermbg=Black
endif

In neovim, term cannot be set. I tried invoking neovim with a manually set $TERM like so:

TERM=xterm nvim

This produced the correct display of colors in regular vim (i.e. equivalent to setting term in .vimrc), but in neovim it looks like this:

enter image description here

Why is the combination of set term=xterm and set t_Co=256 necessary to produce the correct display of this color scheme in vim and why does the equivalent combination of settings produce a different result in neovim?

Edit:

The default is $TERM=xterm256-color, which for some reason has to be overridden to xterm in regular vim to make the color display correctly. With the environment variable at the 256 default, neovim looks like this:

enter image description here

This is identical to regular vim with xterm256-color, but not as intended. My goal is to understand why the xterm hack is necessary/working in vim, and why it doesn't look the same in neovim.

Note that many of the colors appear correctly with the above term env variable setting, notable exceptions being line numbers and background. I suspect that the way the colors are specified in this specific color scheme may be involved.

3
  • 1
    Your $TERM is already set to what is generally considered 'correct' on modern systems - 256-color enabled. So the t_Co option, which is normally for compatibility with older terminals, shouldn't be necessary. What if you comment out both configuration lines?
    – David Lord
    Jun 14, 2015 at 0:01
  • @David Commenting out both config lines looks the same as commenting out set term=xterm.
    – Gall
    Jun 14, 2015 at 2:06
  • Could you include a screenshot of the iTerm color configuration that you use when the theme is rendered correctly as well as the output from running this script? Jun 22, 2015 at 0:12

8 Answers 8

12

Main Issue

The main problem you are experiencing is caused by the ordering of the commands in your .vimrc.

You set the g:impact_transbg variable after you load the colorscheme, and so the variable does not exist when checked by the colorscheme's if statement, and the second version of the colorscheme (in the else block) is used.

To fix, you simply need to move the line that sets the variable above the line where you load the colorscheme:

let g:impact_transbg=1
colorscheme impact3

You can (and should!) then remove the unnecessary lines from your .vimrc:

set term=xterm
set background=dark
set t_Co=256

Other Issues

I can also clear up a few other misconceptions/confusions you might have about how this all works:

Explaining the behaviour of 'term' & 't_Co'

Your $TERM is set to xterm256-color. Vim reads this, and queries terminfo (or termcap) to find out how many colours the terminal supports, and then sets 't_Co' accordingly. Presuming your $TERM is correct (yours is) and your terminfo database contains the correct information for that terminal (yours does) you should never need to manually reset 't_Co'.

However, you are then manually setting Vim's 'term' to xterm. Your terminfo tells Vim that this terminal only supports 8 colours, so adding this will cause 't_Co' to be incorrectly set to 8. You are manually setting 't_Co' back to 256, but if you had left the 'term' setting at the correct value, you would not have needed to.

Incidentally, when you change 't_Co' manually after setting g:impact_transbg, it causes the colorscheme to be reloaded (to allow the colorscheme to adapt to the new number of colours), and because g:impact_transbg is now set, you get the colours you desire.

(With the line setting 'term' omitted, 't_Co' is already set to 256 when you get to the latter line in your .vimrc, and so the colorscheme is not reloaded: hence wrong colours.)

So, to recap:

term=xterm
colorscheme impact3
let g:impact_transbg=1
set t_Co=256

Result: Colorscheme is reloaded when 't_Co' is set to 256, colours are correct.

"term=xterm
colorscheme impact3
let g:impact_transbg=1
set t_Co=256

Result: Colorscheme is loaded by colorscheme command, variable does not exist, colours are wrong.

term=xterm
colorscheme impact3
let g:impact_transbg=1
"set t_Co=256

Result: Colorscheme is loaded by colorscheme command, variable does not exist and Vim only uses 8 colours, colours are wrong.

"term=xterm
colorscheme impact3
let g:impact_transbg=1
"set t_Co=256

Result: Colorscheme is loaded by colorscheme command, variable does not exist, colours are wrong.

let g:impact_transbg=1
colorscheme impact3

Result: Colorscheme is loaded by colorscheme command, variable does exist, so colours are correct. (And as a bonus 'term' and 't_Co' are also correct!)

The behaviour is different in NeoVim simply because the call to set 't_Co' is ignored, as other answerers have already mentioned.

'background'

After setting the colorscheme, you also set 'background'. For this particular colorscheme, this is completely unnecessary, because the first thing the colorscheme does is to set 'background' to 'dark'.

Note that I disagree with the other answerer who suggests that you should set 'background' after loading your colorscheme. The colorscheme may use the value of 'background' to adjust its colors, so setting 'background' before loading the colorscheme is the more obvious ordering. (Although note that if you change the 'background' setting, Vim will reload any loaded colorschemes, so setting it 'background' afterwards would also work: it's just non-optimal.)

2
  • 1
    Thanks, this is extremely thorough and I appreciate the additional context. Dec 7, 2019 at 6:48
  • @ConradMeyer I’m glad it was helpful for you!
    – Rich
    Dec 8, 2019 at 21:35
7

In the case of Neovim, t_Co and TERM make no difference.

You are calling set background=darkbefore and after the call to colorscheme impact3. Move set background=dark to the bottom of the colorscheme, and remove the other call from your vimrc.

From :help 'background':

When 'background' is set Vim will adjust the default color 
groups for the new value.
...
When a color scheme is loaded (the "g:colors_name" variable 
is set) setting 'background' will cause the color scheme to 
be reloaded.

See also: https://github.com/justinmk/molokai/commit/aa1cc201c743dd7d1b80bb2e2b5fbb7894ebfe5f

My goal is to understand why the xterm hack is necessary/working in vim, and why it doesn't look the same in neovim.

  • Neovim doesn't care about t_Co because it assumes 256 unless you enable "true color".
    • In fact Neovim ignores all t_* options, see :help t_xx.
  • Neovim doesn't allow &term to be set because it is meaningless. Neovim uses unibilium and other mechanisms to detect terminal capabilities.
1
  • thanks a lot for your insights regarding neovim term capability detection and ` t_*` settings. Removing the redundant copy of and repositioning the set background=dark statement didn't have an effect, but those details about the underlying implementation are much more valuable to me.
    – Gall
    Jun 15, 2015 at 3:09
2

I see you use iTerm2, so you can try this:

  1. Open prefernces window +,
  2. Go to profiles tab
  3. Check your current profile in the left list
  4. Click on the tab terminal at right
  5. In the Report terminal type choose xterm-256color
  6. Done.
1
  • Thanks for your suggestion. I edited the above with remarks regarding xterm-256color. I followed through with your procedure to find terminal type already set thus.
    – Gall
    Jun 13, 2015 at 23:08
2

You're missing an awesome NeoVim feature. There's an env var that helps with this stuff. Try putting this in your nvimrc:

let $NVIM_TUI_ENABLE_TRUE_COLOR=1 " True gui colors in terminal

Or

export NVIM_TUI_ENABLE_TRUE_COLOR=1

in the shell.

2
  • FYI: this will require the use of guifg and guibg. OP's colorscheme uses ctermfg and ctermbg. Jun 14, 2015 at 17:42
  • Oh, you're right. Sorry! Jun 19, 2015 at 4:35
2

You need to set up options

let $NVIM_TUI_ENABLE_TRUE_COLOR=1 
set termguicolors

in your .config/nvim/init.vim.

2
  • Those options are for using guifg and guibg RGB values for color. The question's color scheme only uses ctermfg and ctermbg.
    – Tommy A
    Jul 4, 2016 at 14:30
  • 1
    This did it for me. TERM was already xterm-256color. Thanks! Dec 3, 2016 at 11:41
1

Note that the specific color scheme is really two sets of color schemes within an if-else clause. The existence of the variableg:impact_transbg selects the desired set of colors, and was originally intended to account for transparent backgrounds in the color scheme from which this is derived.

Commenting out the 2nd color scheme and the if-else statement (leaving only the desired color scheme and doing away with g:impact_transbg) yields the intended behavior in both vim and neovim even with set term=xterm and set t_Co=256 removed.

This implies that with $TERM=xterm-256colors in both vim and neovim, the conditional if exists("g:impact_transbg") fails, but that the combination of setting

set term=xterm
set t_co=256

allowed the conditional to succeed. Removing the if-else clause as described above solves the material issue, but there's still a mystery regarding the interaction between the pair of .vimrc term settings and g:impact_transbg.

0

Try setting your $TERMenvironment variable like this:

TERM=xterm-256color

Also try starting nvim like this:

export TERM=xterm-256color; nvim

If that works, set the $TERM variable in your shell permanently.

1
  • Thanks for the idea, Jeff. I edited my question with remarks regarding xterm-256color. Setting $TERM via export had no effect.
    – Gall
    Jun 13, 2015 at 23:09
0

I had this issue recently with the solarized theme. The problem did come from the TERM env variable.

I fixed it by telling my terminal emulator (terminator in my case) to run env TERM=xterm-256color zsh instead of just starting up zsh as normal.

1
  • The OPs TERM is already set to xterm-256color. I think you were experiencing a different issue.
    – Rich
    Oct 25, 2016 at 14:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.