1{ lib, ... }:
2
3let
4 inherit (lib.strings) concatStrings;
5 inherit (lib.attrsets) mapAttrsToList;
6 inherit (lib.lists) last init;
7 inherit (lib.trivial) boolToString;
8 inherit (builtins) hasAttr isAttrs length head concatStringsSep isInt isBool;
9
10 mkColor = gui: cterm: cterm16: { gui=gui; cterm=cterm; cterm16=cterm16; };
11in rec {
12 shell = "rgba(40, 44, 46, 0.6)";
13 lightStroke = "rgba(248, 248, 241, 0.2)";
14 darkStroke = "rgba(22, 23, 29, 0.2)";
15
16 hex = {
17 # for sidebars / sidenavs / passive UI elements
18 gutter = "161622";
19 # for selection / cursors
20 cursor = "242738";
21 # for overlays / large popups / hint / codelens UIs
22 element = "050B12";
23 # for borders and thin lines, e.g. to separate panes
24 split = "2A2D46";
25
26 # (ANSI: 0 Black) background colour
27 black = "070D14";
28 # (ANSI: 7 White) foreground colour, identifiers, variables
29 white = "EDF0F2";
30 # (ANSI: 8 Bright Black) ghost text / suggestion text
31 grey = "323744";
32 # (ANSI: 15 Bright White) comment text
33 muted = "585D79";
34
35 # (ANSI: 1 Red) conditional, boolean, return keywords
36 red = "F84F6B";
37 # (ANSI: 9 Bright Red) errors
38 brightRed = "E93434";
39 # (ANSI: 2 Green) strings
40 green = "7DD486";
41 # (ANSI: 10 Bright Green) special chars
42 brightGreen = "05AE48";
43 # (ANSI: 3 Yellow) warnings & structures
44 yellow = "D7C046";
45 # (ANSI: 11 Bright Yellow) constants & numbers
46 orange = "F95A10";
47 # (ANSI: 4 Blue) functions, search, and some selections
48 blue = "98BDFB";
49 # (ANSI: 12 Bright Blue) todos & URL/links
50 brightBlue = "6A78F6";
51 # (ANSI: 5 Purple) keywords, statements
52 magenta = "F651A6";
53 # (ANSI: 13 Bright Purple) operators, tags, properties
54 pink = "F2B0C0";
55 # (ANSI: 6 Cyan) types
56 aqua = "14B6C8";
57 # (ANSI: 14 Bright Cyan) delimiters & labels
58 cyan = "02B394";
59 };
60
61 colors = {
62 gutter = (mkColor "#${hex.gutter}" 233 15);
63 cursor = (mkColor "#${hex.cursor}" 235 8);
64 element = (mkColor "#${hex.element}" 233 15);
65 split = (mkColor "#${hex.split}" 236 15);
66
67 black = (mkColor "#${hex.black}" 233 0);
68 grey = (mkColor "#${hex.grey}" 237 15);
69
70 red = (mkColor "#${hex.red}" 204 1);
71 brightRed = (mkColor "#${hex.brightRed}" 203 9);
72
73 green = (mkColor "#${hex.green}" 114 2);
74 brightGreen = (mkColor "#${hex.brightGreen}" 35 10);
75
76 yellow = (mkColor "#${hex.yellow}" 221 3);
77 orange = (mkColor "#${hex.orange}" 202 11);
78
79 blue = (mkColor "#${hex.blue}" 111 4);
80 brightBlue = (mkColor "#${hex.brightBlue}" 105 12);
81
82 pink = (mkColor "#${hex.pink}" 217 5);
83 magenta = (mkColor "#${hex.magenta}" 205 13);
84
85 aqua = (mkColor "#${hex.aqua}" 37 6);
86 cyan = (mkColor "#${hex.cyan}" 36 14);
87
88 white = (mkColor "#${hex.white}" 255 7);
89 muted = (mkColor "#${hex.muted}" 60 15);
90 };
91
92 transparent = (mkColor "NONE" "NONE" 0);
93
94 mkHighlight = { fg ? transparent, bg ? transparent, style ? "NONE" }: { fg=fg; bg=bg; style=style; };
95 mkVimHighlight = group: { fg ? transparent, bg ? transparent, style ? "NONE" }:
96 "highlight ${group} guifg=${fg.gui} guibg=${bg.gui} gui=${style} ctermfg=${toString fg.cterm} ctermbg=${toString bg.cterm} cterm=${style}";
97 mkLuaVariable = name: { gui, ... }: "${name} = \"${gui}\",";
98 mkScssVariable = name: { gui, ... }: "\$color-${name}: ${gui};";
99
100 mkNeovimHighlights = let
101 isValue = value:
102 isAttrs value && (
103 (hasAttr "link" value) ||
104 (hasAttr "fg" value) ||
105 (hasAttr "bg" value) ||
106 (hasAttr "sp" value) ||
107 (hasAttr "bold" value) ||
108 (hasAttr "italic" value) ||
109 (hasAttr "underline" value) ||
110 (hasAttr "strikethrough" value) ||
111 (hasAttr "reverse" value) ||
112 (hasAttr "default" value) ||
113 (hasAttr "force" value)
114 );
115 recurse = path: value:
116 if isAttrs value && !(isValue value) then
117 mapAttrsToList
118 (name: value: recurse (path ++ (if name != "base" then [name] else [])) value)
119 value
120 else {
121 ${concatStrings path} = value;
122 };
123 toFlatAttrs = attrs:
124 lib.foldl lib.recursiveUpdate {} (lib.flatten (recurse [] attrs));
125 toValueString = value:
126 if value == "NONE" then
127 "\"NONE\""
128 else if isInt value then
129 "${toString value}"
130 else if isBool value then
131 "${boolToString value}"
132 else
133 "\"${toString value}\"";
134 toValueAttribute = name: value:
135 if name == "sp" then
136 "${name} = ${toValueString value.gui}"
137 else if name == "fg" || name == "bg" then
138 "${name} = ${toValueString value.gui}, cterm${name} = ${toValueString value.cterm}"
139 else
140 "${name} = ${toValueString value}";
141 withDefaults = value: { fg = transparent; bg = transparent; } // value;
142 toValue = name: value:
143 if (hasAttr "force" value) && value.force then
144 "vim.api.nvim_set_hl(0, \"${name}\", { fg = \"NONE\", bg = \"NONE\", ctermfg = \"NONE\", ctermbg = \"NONE\" })"
145 else
146 "vim.api.nvim_set_hl(0, \"${name}\", { ${concatStringsSep ", " (mapAttrsToList toValueAttribute (withDefaults value))} })";
147 in
148 colors: (concatStringsSep "\n" (mapAttrsToList toValue (toFlatAttrs colors)));
149
150 mkZedStyles = let
151 valueToString = value: "${value.gui}";
152 isValue = value: isAttrs value && hasAttr "gui" value;
153 recurse = path: value:
154 if isAttrs value && !(isValue value) then
155 mapAttrsToList
156 (name: value: recurse (path ++ (if name != "base" then [name] else [])) value)
157 value
158 else {
159 ${concatStringsSep "." path} = valueToString value;
160 };
161 in
162 styles: lib.foldl lib.recursiveUpdate {} (lib.flatten (recurse [] styles));
163
164 mkVimHardlineColors = colors:
165 with colors; ''
166 {
167 text = {gui = "${element.gui}", cterm = "${toString element.cterm}", cterm16 = "${toString element.cterm16}"},
168 normal = {gui = "${green.gui}", cterm = "${toString green.cterm}", cterm16 = "${toString green.cterm16}"},
169 insert = {gui = "${blue.gui}", cterm = "${toString blue.cterm}", cterm16 = "${toString blue.cterm16}"},
170 replace = {gui = "${yellow.gui}", cterm = "${toString yellow.cterm}", cterm16 = "${toString yellow.cterm16}"},
171 inactive_comment = {gui = "${muted.gui}", cterm = "${toString muted.cterm}", cterm16 = "${toString muted.cterm16}"},
172 inactive_cursor = {gui = "NONE", cterm = "NONE", cterm16 = "0"},
173 inactive_menu = {gui = "${gutter.gui}", cterm = "${toString gutter.cterm}", cterm16 = "${toString gutter.cterm16}"},
174 visual = {gui = "${aqua.gui}", cterm = "${toString aqua.cterm}", cterm16 = "${toString aqua.cterm16}"},
175 command = {gui = "${magenta.gui}", cterm = "${toString magenta.cterm}", cterm16 = "${toString magenta.cterm16}"},
176 alt_text = {gui = "${white.gui}", cterm = "${toString white.cterm}", cterm16 = "${toString white.cterm16}"},
177 warning = {gui = "${orange.gui}", cterm = "${toString orange.cterm}", cterm16 = "${toString orange.cterm16}"},
178 }
179 '';
180
181 mkLuaSyntax = let
182 recurse = path: value:
183 if isAttrs value && !(hasAttr "gui" value) then
184 mapAttrsToList
185 (name: value: recurse (path ++ (if name != "base" then [name] else [])) value)
186 value
187 else {
188 ${concatStrings path} = value;
189 };
190 toFlatAttrs = attrs:
191 lib.foldl lib.recursiveUpdate {} (lib.flatten (recurse [] attrs));
192 in colors:
193 ''
194 { ${concatStringsSep "\n" (mapAttrsToList mkLuaVariable (toFlatAttrs colors))} }
195 '';
196
197 mkScssSyntax = let
198 recurse = path: value:
199 if isAttrs value && !(hasAttr "gui" value) then
200 mapAttrsToList
201 (name: value: recurse (path ++ (if name != "base" then [name] else [])) value)
202 value
203 else {
204 ${concatStrings path} = value;
205 };
206 toFlatAttrs = attrs:
207 lib.foldl lib.recursiveUpdate {} (lib.flatten (recurse [] attrs));
208 in colors:
209 (concatStringsSep "\n" (mapAttrsToList mkScssVariable (toFlatAttrs colors)));
210
211 mkVimSyntax = let
212 recurse = path: value:
213 if isAttrs value && !(hasAttr "fg" value) && !(hasAttr "bg" value) && !(hasAttr "style" value) then
214 mapAttrsToList
215 (name: value: recurse (path ++ (if name != "base" then [name] else [])) value)
216 value
217 else {
218 ${concatStrings path} = value;
219 };
220 toFlatAttrs = attrs:
221 lib.foldl lib.recursiveUpdate {} (lib.flatten (recurse [] attrs));
222 in name: attrs:
223 ''
224 highlight clear
225
226 if exists("syntax_on")
227 syntax reset
228 endif
229
230 set t_Co=256
231 let g:colors_name="${name}"
232
233 ${concatStringsSep "\n" (mapAttrsToList mkVimHighlight (toFlatAttrs attrs))}
234 '' + "\nset background=dark";
235}