vim-hexokinase: display colors

highlight color code

TLDR: vim-hexokinase isn't perfect but works. It need works in termguicolors mode. It is better to choose a color scheme which is visualized in gui mode. And it is very tricky to setting colors in termguicolors & notermguicolors the same, which is insane.

It would be convenient, if color code can be visualised in editor, especially in web programming. I found two candidates plugins to achieve this goal, vim-css-color, vim-hexokinase.

Vim-css-color is not compatible with tree-sitter, due to regex based highlight. See Github Issue: Neovim tree sitter support for details. Vim-css-color sometimes cannot render same text color. I need to scroll my vim viewport, then it may render color correctly.

Vim-hexokinase is good, but must depends on termguicolors is turned on. termguicolors will enable 24-bit RGB color, while originally vim uses Base16 color. The result is the color theme you familiar with will be changed.

Here is the visual comparison between vim-css-color and vim-hexokinase. I copy these text as html from my vim.

vccvcc tgcvh tgc
#ff0000#ff0000#ff0000
#ff1111#ff1111#ff1111
#ff2222#ff2222#ff2222
#ff3333#ff3333#ff3333
#ff4444#ff4444#ff4444
#ff5555#ff5555#ff5555
#ff6666#ff6666#ff6666
#ff7777#ff7777#ff7777
#ff8888#ff8888#ff8888
#ff9999#ff9999#ff9999
#ffaaaa#ffaaaa#ffaaaa
#ffbbbb#ffbbbb#ffbbbb
#ffcccc#ffcccc#ffcccc
#ffdddd#ffdddd#ffdddd
#ffeeee#ffeeee#ffeeee
#ffffff#ffffff#ffffff
#000000#000000#000000
#111111#111111#111111
#222222#222222#222222
#333333#333333#333333
#444444#444444#444444
#555555#555555#555555
#666666#666666#666666
#777777#777777#777777
#888888#888888#888888
#999999#999999#999999
#aaaaaa#aaaaaa#aaaaaa
#bbbbbb#bbbbbb#bbbbbb
#cccccc#cccccc#cccccc
#dddddd#dddddd#dddddd
#eeeeee#eeeeee#eeeeee
#ffffff#ffffff#ffffff

Vim-css-color with out termguicolors cannot display color correctly (or say precisely), if you dont believe your eye, see the source code of this page.

I think vim-hexokinase with a termguicolors toggle is a acceptable compromise. Toggle termguicolors by :set termguicolors!. I personally prefer to assign <leader>c to toggle termguicolors.

cterm & gui

TLDR: I still haven't find a elegant solution to keep termguicolors and notermguicolors visually same.

neovim has 2 color schemes cterm & gui, see :h cterm-colors & :h gui-colors. Default sntax colors are different in these two schemes. For example, :verbose highlight Comment returns

Comment        xxx ctermfg=14 guifg=#80a0ff
        Last set from /nix/store/pr1pwjjsm3k45rwi3w0xh2296rpymjlz-neovim-unwrapped-0.5.1/share/nvim/runtime/syntax/syncolor.vim

which means ctermfg uses the 14th color in ANSI colors, while guifg use a hex color code. The detailed setting is located in ${VIMRUNTIME}/syntax/syncolor.vim.

I create a new syncolor.vim based the default one, and modify the all ctermfg and guifg to same color name, like below. The colors in two schemes are still different.

if !exists("syntax_cmd") || syntax_cmd == "on"
  " ":syntax on" works like in Vim 5.7: set colors but keep links
  command -nargs=* SynColor hi <args>
  command -nargs=* SynLink hi link <args>
else
  if syntax_cmd == "enable"
    " ":syntax enable" keeps any existing colors
    command -nargs=* SynColor hi def <args>
    command -nargs=* SynLink hi def link <args>
  elseif syntax_cmd == "reset"
    " ":syntax reset" resets all colors to the default
    command -nargs=* SynColor hi <args>
    command -nargs=* SynLink hi! link <args>
  else
    " User defined syncolor file has already set the colors.
    finish
  endif
endif

" Many terminals can only use six different colors (plus black and white).
" Therefore the number of colors used is kept low. It doesn't look nice with
" too many colors anyway.
" Careful with "cterm=bold", it changes the color to bright for some terminals.
" There are two sets of defaults: for a dark and a light background.
if &background == "dark"
  SynColor Comment	term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE gui=NONE guifg=Cyan guibg=NONE
  SynColor Constant	term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE gui=NONE guifg=Magenta guibg=NONE
  SynColor Special	term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE gui=NONE guifg=LightRed guibg=NONE
  SynColor Identifier	term=underline cterm=bold ctermfg=Cyan ctermbg=NONE gui=bold guifg=Cyan guibg=NONE
  SynColor Statement	term=bold cterm=NONE ctermfg=Yellow ctermbg=NONE gui=NONE guifg=Yellow guibg=NONE
  SynColor PreProc	term=underline cterm=NONE ctermfg=LightBlue ctermbg=NONE gui=NONE guifg=LightBlue guibg=NONE
  SynColor Type		term=underline cterm=NONE ctermfg=LightGreen ctermbg=NONE gui=NONE guifg=LightGreen guibg=NONE
  SynColor Underlined	term=underline cterm=underline ctermfg=LightBlue gui=underline guifg=LightBlue
  SynColor Ignore	term=NONE cterm=NONE ctermfg=black ctermbg=NONE gui=NONE guifg=black guibg=NONE
else
  SynColor Comment	term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE gui=NONE guifg=DarkBlue guibg=NONE
  SynColor Constant	term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE gui=NONE guifg=DarkBlue guibg=NONE
  SynColor Special	term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=DarkMagenta guibg=NONE
  SynColor Identifier	term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE gui=NONE guifg=DarkCyan guibg=NONE
  SynColor Statement	term=bold cterm=NONE ctermfg=Brown ctermbg=NONE gui=bold guifg=Brown guibg=NONE
  SynColor PreProc	term=underline cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=DarkMagenta guibg=NONE
  SynColor Type		term=underline cterm=NONE ctermfg=DarkGreen ctermbg=NONE gui=NONE guifg=DarkGreen guibg=NONE
  SynColor Underlined	term=underline cterm=underline ctermfg=DarkMagenta gui=underline guifg=DarkMagenta
  SynColor Ignore	term=NONE cterm=NONE ctermfg=white ctermbg=NONE gui=NONE guifg=white guibg=NONE
endif
SynColor Error		term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE guifg=White guibg=Red
SynColor Todo		term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE guifg=Black guibg=Yellow

The Magenta is especially dazzling, and cannot change it by below tries.

Refers to Change Vim's terminal colors when termguicolors is set #2353, nvim-terminal-emulator-configuration,

let g:terminal_color_13 = '#AD7FA8' " Magenta doesn't work.

Finally I choose to add a color-scheme manager, and choose a theme which has both cterm & gui color scheme.

{ config, pkgs, stdenv, lib, ... }:
let
  my-vim-hexokinase = {
    plugin = pkgs.vimPlugins.vim-hexokinase;
    config = ''
      let g:Hexokinase_highlighters = ['backgroundfull']
    '';
  };
in {
  programs.neovim = {
    plugins = [
      my-vim-hexokinase
    ];
  };
}