Skip to content

Introduce namecolor ex command.#8426

Closed
dvogel wants to merge 1 commit intovim:masterfrom
dvogel:namecolor
Closed

Introduce namecolor ex command.#8426
dvogel wants to merge 1 commit intovim:masterfrom
dvogel:namecolor

Conversation

@dvogel
Copy link

@dvogel dvogel commented Jun 22, 2021

This patch introduces a new ex command: namecolor. This command allows users to
map arbitrary names to RGB values and then use those names where the GUI color
names are used. Users are able to introduce new custom names as well as
overwrite the color values for the names defined in rgb.txt (but not standard
names, e.g. DarkRed).


The problems this PR attempts to solve:

  • Ease the burden of maintaining complex color schemes.

    I maintain my own custom colorscheme with many non-standard colors. For the
    past decade I've been using sed to substitute color names for RGB values.
    For example:

    sed -r -e 's/CornflowerBlue/#6495ED/g' drew.vim.txt > drew.vim

    Many colorscheme files link syntax-specific match groups to generic groups
    such as 'Identifier' or 'Number' and then assign colors to those groups. I
    maintain my own colorscheme in part because this arrangement doesn't work
    well for my visual perception. This tends to require more colors and more
    unique uses of those colors throughout a colorscheme, which in turn makes it
    difficult to track raw RGB values, hence my sed approach.

    This works well enough for my purposes but it makes it difficult to share the
    scheme with others. It also requires a multi-step testing process. Native
    support for custom color names will make it easier to manually maintain my
    colorscheme.

  • Make custom color schemes more forkable.

    In order to achieve high fidelity with colorschemes made popular by other
    editors, some colorscheme maintainers have created templating systems to
    allow for a similar style of color aliasing:

    https://github.com/lifepillar/vim-colortemplate

    While a remarkable advancement for building high quality colorschemes, the
    resultant schemes still include raw RGB values and, as such, are harder to
    fork and tweak following the guidelines provided by the :syn-default-override
    docs.

    Native support for custom color names will also allow tools like
    vim-colortemplate to retain color names in the schemes they produce, making
    them more forkable by end-users.

  • Renewal of the value of rgb.txt.

    One of the original purposes of rgb.txt was to allow hardware vendors to
    correct for poor color performance of early display technology by tuning the
    X software that came with the hardware system. Over time hardware color
    performance has improved and what color correction is still required has been
    moved to other parts of the stack. As such, modern X distributions have
    deprecated rgb.txt.

    Since many vim users became reliant on those color names, vim adopted rgb.txt
    to prevent existing colorschemes from breaking. It was at this point that vim
    stopped deferring to X vendors and/or users and became the de facto authority
    for these color values wrt vim colorschemes.

    I believe that vim should continue to defer precise definition of these color
    values to the user. While most modern hardware has good color response
    performance, the same is not true for our eyes. As such, it can be useful to
    override some popular color names across all colorschemes. The namecolor
    command will allow such customization without having to modify rgb.txt.

  • Introduction of additional color lists.

    Since the advent of rgb.txt some alternative color lists have been developed.
    For example, the CSS standard includes a color list that extends and modifies
    the historical X color choices. Many users are more familiar with this list
    but the uniqueness of rgb.txt creates friction in adopting an alternative
    list. With this patch, I've included a plugin that allows users can 'let
    g:css_colors_load=1' to load the standard CSS color list in addition to the X
    colors. This is mostly for demonstration. It could be distributed separately
    and/or be changed to load differently.

  • Long-term replacement of rgb.txt.

    This patch continues to load rgb.txt but paves the way to replace it in the
    future. When vim adopted the rgb.txt into the runtime directory, the precise
    file format became irrelevant. While many users have come to rely on the
    color names defined there, it includes 700+ names, most of them
    typos/duplicates. That is somewhat wasteful for users who do not use any of
    those color names (but use an unrecognized name, causing it to load).

    The conventional way for vim users to customize their vim experience is
    vimscripts in their home directory. If a user wants to avoid loading rgb.txt
    colors, they would need to delete the file out of $VIMRUNTIME. Future patches
    could build on the namecolor command to move the rgb.txt color definitions
    list into a plugin that would make the X colors optional.


This is my first vim patch, so consider it a draft. I tried my best to follow
the guidance under ':h development' but being new to the project it is
difficult to know how well I've achieved the balance between priorities that
document encourages. In particular:

  • The colornames_table array used to be declared static within the definition
    of gui_get_color_cmn. Since I've pulled it out to the global level and
    extracted additional functions, perhaps these should be moved into a new
    file src/colornames.c?

  • Should ex_namecolor be implemented in ex_docmd.c? It seems many ex commands
    are fully implemented within ex_docmd.c while some (e.g. ex_highlight)
    primarily defer to an implementation in another file. It was difficult for me
    to infer which considerations were most important in these decisions.

  • Most errors in vim have error number prefixes while others do not. For
    example: "E254: Cannot allocate color %s". I gather these error numbers are
    primarily used for linking to the runtime/doc/message.txt docs. However, it
    was unclear to me how these numbers are chosen. I would appreciate guidance
    on this.

  • In an attempt to keep things simple and encourage cooperation among
    colorscheme designers, I've avoided implementing a few features. These could
    all be useful debugging tools but they could also lead to complex color
    management systems. I'd be happy to implement any or all of these if this
    group finds them more in line with the project's design goals:

    (a) a vimscript function to query the current color value for a name.
    (b) a namecolor option to clear the name color table.
    (c) a namecolor option to display the current color table, similar to a bare
    :highlight.

  • Should the the maximum size of the colornames_table be lowered to something
    less than 10000? The prior treatment of rgb.txt colors attempted to allocate
    no more than 10000 elements, as a failsafe. In the normal case it expected
    <1000 elements. This implementation uses dynamic allocation, slightly
    increasing the chance that a user will reach the upper limit Given that 10000
    elements could make for extremely slow color lookups, should the failsafe max
    capacity be lowered?

Problem solved: Remembering RGB colors is difficult.
Solution: Allow user to define new color names.
@codecov
Copy link

codecov bot commented Jun 22, 2021

Codecov Report

Merging #8426 (c91f2e8) into master (419a40a) will decrease coverage by 87.45%.
The diff coverage is 0.00%.

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

@@             Coverage Diff             @@
##           master    #8426       +/-   ##
===========================================
- Coverage   89.95%    2.50%   -87.46%     
===========================================
  Files         149      147        -2     
  Lines      167781   162692     -5089     
===========================================
- Hits       150931     4068   -146863     
- Misses      16850   158624   +141774     
Flag Coverage Δ
huge-clang-none ?
huge-gcc-none ?
huge-gcc-testgui ?
huge-gcc-unittests 2.50% <0.00%> (-0.01%) ⬇️

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

Impacted Files Coverage Δ
src/cmdexpand.c 0.00% <0.00%> (-93.76%) ⬇️
src/ex_docmd.c 0.00% <0.00%> (-95.02%) ⬇️
src/highlight.c 8.00% <ø> (-82.46%) ⬇️
src/term.c 0.00% <0.00%> (-83.45%) ⬇️
src/float.c 0.00% <0.00%> (-98.91%) ⬇️
src/digraph.c 0.00% <0.00%> (-97.78%) ⬇️
src/gui_gtk_f.c 0.00% <0.00%> (-97.54%) ⬇️
src/match.c 0.00% <0.00%> (-97.13%) ⬇️
src/crypt_zip.c 0.00% <0.00%> (-97.06%) ⬇️
src/sound.c 0.00% <0.00%> (-97.00%) ⬇️
... and 139 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 419a40a...ddd7bef. Read the comment docs.

@brammool
Copy link
Contributor

I like the idea of naming colors. But I wonder if we should use an Ex command for this. I don't see the patch providing a way to show the current names.
It looks like this will actually fit very well in a dictionary. Since it's unlikely the list of colors will be typed, using builtin functions to manipulate the table seems like a better way.

@dvogel
Copy link
Author

dvogel commented Jun 22, 2021

Thanks for the feedback @brammool. I'll explore in that direction. I had considered something like that but I wasn't aware of any dicts that were written to by both the C code and vimscript code. If there is prior art you could point me to in the code I'd be happy to follow suit.

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.

2 participants