lifepillar/vim-colortemplate

Clarify documentation on Variant

cideM opened this issue · 4 comments

cideM commented

I don't understand what the documentation on the Variant feature is supposed to mean

For example, if you
declare:

Variant: 256 88
<
then you may use only base-256 colors between 0 and 87. On the other hand,
if you declare:

Variant: 256 8 4
<
you will be able to use all base-256 colors, but only the first four base-16
colors.

When 256 88 means base-256 but only the first 87, then why doesn't 256 8 4 mean base-256 but only the first 4? Later on it's explained what output is generated from these values, but here it seems that declaring multiple values just renders multiple t_Co blocks. That would imply that declaring multiple number values for the same Variant is redundant since if color definitions apply to a t_Co >= 8 they automatically also apply for 256. Meaning 256 8 4 wouldn't make much sense since the >= 4 includes the 8 and 256 anyway.

Buuuuuuuuuuuuuut I'm guessing I'm misunderstanding something here.

When 256 88 means base-256 but only the first 87, then why doesn't 256 8 4 mean base-256 but only the first 4?

It makes sense (I believe) if you keep in mind that each Color declaration has three values:

  1. a “GUI” value for terminals supporting millions of colors;
  2. an “xterm” value for terminals supporting more than 16 colors (but not millions of colors);
  3. and an ANSI color value for terminal with no more than 16 colors.

When you write Variant: 256 88 you are instructing Colortemplate to apply the definitions following that directive to terminals supporting 256 colors and 88 colors, that is, terminals of category 2. Similarly, Variant: 256 8 4 means that Colortemplate should generate definitions for terminals supporting 256 colors (category 2) and terminals supporting 8 and 4 colors (category 3). When two or more variants fall in the same category, the one with least colors is the one that limits you.

Consider this (incorrect) example:

Color: foo #fafafa 236 7
Variant: 256 88 8 4
Normal foo foo

Simplifying a bit, this would generate the following code:

if &t_Co >= 256
  hi Normal ctermfg=236 ctermbg=236 cterm=NONE
  finish
endif

if &t_Co >= 88
  " This is out of range:
  hi Normal ctermfg=236 ctermbg=236 cterm=NONE
  finish
endif

if &t_Co >= 8
  hi Normal ctermfg=7 ctermbg=7 cterm=NONE
  finish
endif

if &t_Co >= 4
  " This is out of range:
  hi Normal ctermfg=7 ctermbg=7 cterm=NONE
  finish
endif

But the following is fine:

Color: foo #fafafa 87 3
Variant: 256 88 8 4
Normal foo foo

and results in something like:

if &t_Co >= 256
  hi Normal ctermfg=87 ctermbg=87 cterm=NONE
  finish
endif

if &t_Co >= 88
  hi Normal ctermfg=87 ctermbg=87 cterm=NONE
  finish
endif

if &t_Co >= 8
  hi Normal ctermfg=3 ctermbg=3 cterm=NONE
  finish
endif

if &t_Co >= 4
  hi Normal ctermfg=3 ctermbg=3 cterm=NONE
  finish
endif

declaring multiple values just renders multiple t_Co blocks.

Correct.

That would imply that declaring multiple number values for the same Variant is redundant since if color definitions apply to a t_Co >= 8 they automatically also apply for 256.

The value that applies for ≤16 colors is not necessarily the same as the value that applies for 256 colors (see above). For example:

Color: foo #fafafa 236 7
Variant: 8
Normal foo foo

generates only:

if &t_Co >= 8
  hi Normal ctermfg=7 ctermbg=7 cterm=NONE
  finish
endif

Compare with:

Color: foo #fafafa 236 7
Variant: 256 8
Normal foo foo

which generates:

if &t_Co >= 256
  hi Normal ctermfg=236 ctermbg=236 cterm=NONE
  finish
endif

if &t_Co >= 8
  hi Normal ctermfg=7 ctermbg=7 cterm=NONE
  finish
endif

Meaning 256 8 4 wouldn't make much sense since the >= 4 includes the 8 and 256 anyway.

The difference between 4/8 and 256 should be clear from the previous example. Declaring 4 and 8 together is just for convenience. Consider the following example:

Color: foo #fafafa 236 3
Color: bar #00000 0  1
Variant: 8 4
Normal foo foo
Variant: 8
Debug foo bar
Variant: 4
Debug bar foo

which expands to:

if &t_Co >= 8
  hi Normal ctermfg=3 ctermbg=3 cterm=NONE
  hi Debug ctermfg=3 ctermbg=1 cterm=NONE
  finish
endif

if &t_Co >= 4
  hi Normal ctermfg=3 ctermbg=3 cterm=NONE
  hi Debug ctermfg=1 ctermbg=3 cterm=NONE
  finish
endif

In this case, declaring multiple variants allows you to avoid repeating the same definition for the Normal group.

cideM commented

Hm alright but I still don't see how the code below, taken from the docs, would apply:

        if &t_Co >= 256
	  hi Normal ctermfg=231 ctermbg=16 cterm=NONE
	  finish
	endif

	if &t_Co >= 8
	  hi Normal ctermfg=LightGray ctermbg=Brown cterm=NONE
	  finish
	endif

If t_Co is 256 then the 2nd if block would also apply and thereby generate a competing Normal highlight group.

If t_Co is 256 then the 2nd if block would also apply and thereby generate a competing Normal highlight group.

No, the finish command ends the script at that point, so the if blocks are mutually exclusive. Using finish is a just an optimization to make the color scheme load faster.

cideM commented

Oh wow I totally overlooked that, sorry! Thank you for clarifying this 👍