xiwal

Generate terminal color schemes
git clone https://git.ce9e.org/xiwal.git

commit
53fa3d7e14da2b0b1dab9c0758d6b097cd779bae
parent
8aea9eb34bff446afcef1e0402c136e67876d9b1
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2026-02-19 12:29
add 256 color support

inspired by https://github.com/jake-stewart/color256/

Diffstat

M xiwal/__main__.py 8 ++++++--
M xiwal/scheme.py 34 ++++++++++++++++++++++++++++++++--
M xiwal/term.py 23 +++++++++++++++++++++++

3 files changed, 61 insertions, 4 deletions


diff --git a/xiwal/__main__.py b/xiwal/__main__.py

@@ -10,6 +10,7 @@ def parse_args():
   10    10     parser = argparse.ArgumentParser()
   11    11     parser.add_argument('--apply', '-a', action='store_true')
   12    12     parser.add_argument('--image', '-i')
   -1    13     parser.add_argument('--256', action='store_true', dest='full')
   13    14     parser.add_argument('-n', type=int, default=8)
   14    15     parser.add_argument('colors', nargs='*')
   15    16     return parser.parse_args()
@@ -26,10 +27,13 @@ def main():
   26    27     if len(colors) < 6:
   27    28         sys.exit('Need at least 6 colors')
   28    29 
   29    -1     s = scheme.colors2scheme(colors)
   -1    30     s = scheme.colors2scheme(colors, full_256=args.full)
   30    31 
   31    32     print(';'.join(s))
   32    -1     term.palette(s)
   -1    33     if args.full:
   -1    34         term.palette_256(s)
   -1    35     else:
   -1    36         term.palette(s)
   33    37     if args.apply:
   34    38         term.apply(s)
   35    39 

diff --git a/xiwal/scheme.py b/xiwal/scheme.py

@@ -96,9 +96,39 @@ def scheme(colors, dominant):
   96    96     yield L_LIGHT[7], c_grey, dominant[2]
   97    97 
   98    98 
   99    -1 def colors2scheme(colors):
   -1    99 def _colors2scheme(colors):
  100   100     colors = [lch.from_hex(c) for c in colors]
  101   101     dominant = colors[0]
  102   102     subset = get_best_subset(colors, 6)
  103    -1     s = scheme(subset, dominant)
   -1   103     return list(scheme(subset, dominant))
   -1   104 
   -1   105 
   -1   106 def expand_to_256(s):
   -1   107     # https://github.com/jake-stewart/color256/
   -1   108     full = [*s]
   -1   109     base8 = [s[0], *[s[i] for i in range(1, 7)], s[15]]
   -1   110 
   -1   111     for r in range(6):
   -1   112         c0 = lch.mix(base8[0], base8[1], r / 5)
   -1   113         c1 = lch.mix(base8[2], base8[3], r / 5)
   -1   114         c2 = lch.mix(base8[4], base8[5], r / 5)
   -1   115         c3 = lch.mix(base8[6], base8[7], r / 5)
   -1   116         for g in range(6):
   -1   117             c4 = lch.mix(c0, c1, g / 5)
   -1   118             c5 = lch.mix(c2, c3, g / 5)
   -1   119             for b in range(6):
   -1   120                 c6 = lch.mix(c4, c5, b / 5)
   -1   121                 full.append(c6)
   -1   122 
   -1   123     for i in range(24):
   -1   124         c = lch.mix(base8[0], base8[7], (i + 1) / 25)
   -1   125         full.append(c)
   -1   126 
   -1   127     return full
   -1   128 
   -1   129 
   -1   130 def colors2scheme(colors, *, full_256=False):
   -1   131     s = _colors2scheme(colors)
   -1   132     if full_256:
   -1   133         s = expand_to_256(s)
  104   134     return [lch.to_hex(c) for c in s]

diff --git a/xiwal/term.py b/xiwal/term.py

@@ -23,3 +23,26 @@ def palette(scheme):
   23    23         s.append('\033[48;2;%i;%i;%im    \033[0m' % (r, g, b))
   24    24     print(''.join(s[:8]))
   25    25     print(''.join(s[8:]))
   -1    26 
   -1    27 
   -1    28 def palette_256(scheme):
   -1    29     palette(scheme)
   -1    30 
   -1    31     print()
   -1    32 
   -1    33     for y in range(6):
   -1    34         line = []
   -1    35         for z in range(6):
   -1    36             for x in range(6):
   -1    37                 r, g, b = lch.parse_hex(scheme[16 + 36 * y + 6 * z + x])
   -1    38                 line.append('\033[48;2;%i;%i;%im    \033[0m' % (r, g, b))
   -1    39             line.append('  ')
   -1    40         print(''.join(line))
   -1    41 
   -1    42     print()
   -1    43 
   -1    44     line = []
   -1    45     for i in range(24):
   -1    46         r, g, b = lch.parse_hex(scheme[232 + i])
   -1    47         line.append('\033[48;2;%i;%i;%im    \033[0m' % (r, g, b))
   -1    48     print(''.join(line))