Skip to content

Store extended colors in v:colornames dict.#8502

Closed
dvogel wants to merge 4 commits intovim:masterfrom
dvogel:namecolor-dict
Closed

Store extended colors in v:colornames dict.#8502
dvogel wants to merge 4 commits intovim:masterfrom
dvogel:namecolor-dict

Conversation

@dvogel
Copy link

@dvogel dvogel commented Jul 2, 2021

Problem solved: Remembering RGB colors is difficult.
Solution: Allow user to (re-)define new color names.


This is a follow-up to a previous pull request (#8426). The aim is the same but
this implementation tries to follow @brammool's suggestion to use a builtin dictionary to make manipulation
and examination of the color table more natural.

One point of friction with this approach relates to the casing of color names. The names loaded from rgb.txt
are converted to lowercase when they are read into the table. The lookups are also done in lowercase. This
satisfies all of the existing mixed-case uses of the color names. However, it could be slightly confusing for
users accustomed to the casing found in rgb.txt. It should be apparent upon examination of the dictionary,
such as with let v:colornames.

The color lookup will accommodate numeric values in v:colornames but the expectation is to use hex color
strings. The hex strings only require decoding when used in conjunction with a highlight command, so the
cost is minimal and the usability improvement is substantial.

Problem solved: Remembering RGB colors is difficult.
Solution: Allow user to (re-)define new color names.
@brammool
Copy link
Contributor

brammool commented Jul 3, 2021

I'll leave this open for others to give comments.

The code can probably go in src/highlight.c, instead of adding a new colornames.c file.

@codecov
Copy link

codecov bot commented Jul 3, 2021

Codecov Report

Merging #8502 (bb0d4ca) into master (72463f8) will increase coverage by 0.24%.
The diff coverage is 73.68%.

❗ Current head bb0d4ca differs from pull request most recent head 18cd11b. Consider uploading reports for the commit 18cd11b to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##           master    #8502      +/-   ##
==========================================
+ Coverage   89.70%   89.94%   +0.24%     
==========================================
  Files         149      146       -3     
  Lines      167979   166975    -1004     
==========================================
- Hits       150679   150189     -490     
+ Misses      17300    16786     -514     
Flag Coverage Δ
huge-clang-none 89.12% <73.68%> (+0.08%) ⬆️
huge-gcc-none 89.50% <73.68%> (-0.01%) ⬇️
huge-gcc-testgui 88.12% <69.47%> (?)
huge-gcc-unittests ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/highlight.c 90.46% <ø> (+3.82%) ⬆️
src/term.c 83.63% <ø> (+1.34%) ⬆️
src/colornames.c 73.40% <73.40%> (ø)
src/evalvars.c 96.34% <100.00%> (+<0.01%) ⬆️
src/json.c 91.65% <0.00%> (-1.13%) ⬇️
src/message.c 89.08% <0.00%> (-0.71%) ⬇️
src/if_python.c 82.65% <0.00%> (-0.62%) ⬇️
src/syntax.c 86.58% <0.00%> (-0.43%) ⬇️
src/ops.c 95.58% <0.00%> (-0.42%) ⬇️
src/if_cscope.c 82.06% <0.00%> (-0.37%) ⬇️
... and 61 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 72463f8...18cd11b. Read the comment docs.

*v:colornames*
v:colornames A dictionary that maps color names to hex color strings. These
color names can be used with the |highlight-guifg| and
|highlight-guibg| parameters. The dictionary is provided only
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

|highlight-guisp| is missing.

@romainl
Copy link
Contributor

romainl commented Jul 4, 2021

What would be the expected outcome when the user does something like:

:let v:colornames = {}

or something of the sort? I understand that it wouldn't change anything for a colorscheme using those special names that is already sourced but what if you remove all those names and source that colorscheme again? I guess we are expecting that list to be an explicit part of colorschemes, a bit like with g:terminal_ansi_colors, right?

Another question: suppose users source two colorschemes that use that mechanism, shouldn't we devise something that clears g:colornames before defining it with our own palette? Or some "merging"strategy? In that case, what would happen to the default values that could be used in default, for example, or highlight groups forgotten by the author?

@dvogel
Copy link
Author

dvogel commented Jul 5, 2021

What would be the expected outcome when the user does something like:

:let v:colornames = {}

or something of the sort?

Thanks for the feedback @romainl. Since v:colornames is a read-only variable (in the vim var sense) the user will get an error if they try to assign a new dict to it. The elements are over-writable and can be removed with unlet. I've just pushed a new commit that adds these to src/testdir/test_colornames.vim.

what if you remove all those names and source that colorscheme again? I guess we are expecting that list to be an explicit part of colorschemes, a bit like with g:terminal_ansi_colors, right?

...

Another question: suppose users source two colorschemes that use that mechanism, shouldn't we devise something that clears g:colornames before defining it with our own palette? Or some "merging"strategy? In that case, what would happen to the default values that could be used in default, for example, or highlight groups forgotten by the author?

The last script to write before a highlight command will "win". There's two ideas here:

  • The idea is for colorschemes that want a very specific color to use a very specific color name and include the color definition in the colorscheme file. I've been using this with my color names prefixed with "drew_" to avoid collisions.
  • Conversely, colorschemes that want to rely on common color names can avoid defining the colors in the colorscheme file, and rely on vim runtime files (such as runtime/plugins/csscolors.vim) to define those colors. In this case colorscheme scripts would either need to source the common color definition scripts or the user would need to trigger their colorscheme after the common colors have been loaded (e.g. by creating an after/plugin/csscolors.vim).

In theory a script could clear the dictionary using normal vimscript:

for k in keys(v:colornames)
    unlet v:colornames[k]
endfor

This would cause havoc for the rgb.txt colors since those are only loaded once. Outside of debugging, I'm not sure of a reason to clear the dictionary though since any script that might clear it would be able to overwrite an existing entry the script wanted to control. We could easily make the code re-load the rgb.txt colors anytime one is not found if we foresee good reasons people might clear the dictionary.

@dvogel
Copy link
Author

dvogel commented Jul 5, 2021

I'll leave this open for others to give comments.

The code can probably go in src/highlight.c, instead of adding a new colornames.c file.

Sounds good. I will move the colornames.c code into hightlight.c once I incorporate the other feedback, just to keep churn low.

@chrisbra
Copy link
Member

chrisbra commented Jul 5, 2021

The last script to write before a highlight command will "win". There's two ideas here:

So what happens, with an existing highlighting command, when I change the color definition later?

for k in keys(v:colornames)
unlet v:colornames[k]
endfor

Hm, does it make sense to check, that the dictionary contains at least xxx entries? Or that at least the default colors (whatever they are...) are always defined?

@dvogel
Copy link
Author

dvogel commented Jul 7, 2021

The last script to write before a highlight command will "win". There's two ideas here:

So what happens, with an existing highlighting command, when I change the color definition later?

Nothing changes at that time. The only time the highlight table is updated is when the highlight command is executed. The v:colornames dict is only for allowing system-defined colors and user-defined colors to be referenced in the same way.

Hm, does it make sense to check, that the dictionary contains at least xxx entries? Or that at least the default colors (whatever they are...) are always defined?

Personally, I don't think so. That would be one way to retain the current behavior (rgb.txt colors cannot be unloaded once they are loaded in the current implementation). However, I find the new malleability of those colors to be a benefit. I hope to be able to more easily override the definition of those colors (my eyes benefit from higher saturation). It would take considerable intent to decide to clear the v:colornames dict without intending to override default behaviors.

@brammool
Copy link
Contributor

brammool commented Jul 7, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants