1import {
2 chroma,
3 color_ramp,
4 ThemeAppearance,
5 ThemeLicenseType,
6 ThemeConfig,
7 ThemeSyntax,
8 ThemeFamilyMeta,
9} from "../../common"
10
11const meta: ThemeFamilyMeta = {
12 name: "Gruvbox",
13 author: "morhetz <morhetz@gmail.com>",
14 license_type: ThemeLicenseType.MIT,
15 license_url: "https://github.com/morhetz/gruvbox",
16}
17
18const color = {
19 dark0_hard: "#1d2021",
20 dark0: "#282828",
21 dark0_soft: "#32302f",
22 dark1: "#3c3836",
23 dark2: "#504945",
24 dark3: "#665c54",
25 dark4: "#7c6f64",
26 dark4_256: "#7c6f64",
27
28 gray_245: "#928374",
29 gray_244: "#928374",
30
31 light0_hard: "#f9f5d7",
32 light0: "#fbf1c7",
33 light0_soft: "#f2e5bc",
34 light1: "#ebdbb2",
35 light2: "#d5c4a1",
36 light3: "#bdae93",
37 light4: "#a89984",
38 light4_256: "#a89984",
39
40 bright_red: "#fb4934",
41 bright_green: "#b8bb26",
42 bright_yellow: "#fabd2f",
43 bright_blue: "#83a598",
44 bright_purple: "#d3869b",
45 bright_aqua: "#8ec07c",
46 bright_orange: "#fe8019",
47
48 neutral_red: "#cc241d",
49 neutral_green: "#98971a",
50 neutral_yellow: "#d79921",
51 neutral_blue: "#458588",
52 neutral_purple: "#b16286",
53 neutral_aqua: "#689d6a",
54 neutral_orange: "#d65d0e",
55
56 faded_red: "#9d0006",
57 faded_green: "#79740e",
58 faded_yellow: "#b57614",
59 faded_blue: "#076678",
60 faded_purple: "#8f3f71",
61 faded_aqua: "#427b58",
62 faded_orange: "#af3a03",
63}
64
65interface ThemeColors {
66 red: string
67 green: string
68 yellow: string
69 blue: string
70 purple: string
71 aqua: string
72 orange: string
73 gray: string
74}
75
76const dark_neutrals = [
77 color.dark1,
78 color.dark2,
79 color.dark3,
80 color.dark4,
81 color.light4,
82 color.light3,
83 color.light2,
84 color.light1,
85 color.light0,
86]
87
88const dark: ThemeColors = {
89 red: color.bright_red,
90 green: color.bright_green,
91 yellow: color.bright_yellow,
92 blue: color.bright_blue,
93 purple: color.bright_purple,
94 aqua: color.bright_aqua,
95 orange: color.bright_orange,
96 gray: color.light4,
97}
98
99const light_neutrals = [
100 color.light1,
101 color.light2,
102 color.light3,
103 color.light4,
104 color.dark4,
105 color.dark3,
106 color.dark2,
107 color.dark1,
108 color.dark0,
109]
110
111const light: ThemeColors = {
112 red: color.faded_red,
113 green: color.faded_green,
114 yellow: color.faded_yellow,
115 blue: color.faded_blue,
116 purple: color.faded_purple,
117 aqua: color.faded_aqua,
118 orange: color.faded_orange,
119 gray: color.dark4,
120}
121
122interface Variant {
123 name: string
124 appearance: "light" | "dark"
125 colors: ThemeColors
126}
127
128const variant: Variant[] = [
129 {
130 name: "Dark Hard",
131 appearance: "dark",
132 colors: dark,
133 },
134 {
135 name: "Dark",
136 appearance: "dark",
137 colors: dark,
138 },
139 {
140 name: "Dark Soft",
141 appearance: "dark",
142 colors: dark,
143 },
144 {
145 name: "Light Hard",
146 appearance: "light",
147 colors: light,
148 },
149 {
150 name: "Light",
151 appearance: "light",
152
153 colors: light,
154 },
155 {
156 name: "Light Soft",
157 appearance: "light",
158 colors: light,
159 },
160]
161
162const dark_hard_neutral = [color.dark0_hard, ...dark_neutrals]
163const dark_neutral = [color.dark0, ...dark_neutrals]
164const dark_soft_neutral = [color.dark0_soft, ...dark_neutrals]
165
166const light_hard_neutral = [color.light0_hard, ...light_neutrals]
167const light_neutral = [color.light0, ...light_neutrals]
168const light_soft_neutral = [color.light0_soft, ...light_neutrals]
169
170const build_variant = (variant: Variant): ThemeConfig => {
171 const { colors } = variant
172
173 const name = `Gruvbox ${variant.name}`
174
175 const is_light = variant.appearance === "light"
176
177 let neutral: string[] = []
178
179 switch (variant.name) {
180 case "Dark Hard":
181 neutral = dark_hard_neutral
182 break
183
184 case "Dark":
185 neutral = dark_neutral
186 break
187
188 case "Dark Soft":
189 neutral = dark_soft_neutral
190 break
191
192 case "Light Hard":
193 neutral = light_hard_neutral
194 break
195
196 case "Light":
197 neutral = light_neutral
198 break
199
200 case "Light Soft":
201 neutral = light_soft_neutral
202 break
203 }
204
205 const ramps = {
206 neutral: chroma.scale(is_light ? neutral.reverse() : neutral),
207 red: color_ramp(chroma(variant.colors.red)),
208 orange: color_ramp(chroma(variant.colors.orange)),
209 yellow: color_ramp(chroma(variant.colors.yellow)),
210 green: color_ramp(chroma(variant.colors.green)),
211 cyan: color_ramp(chroma(variant.colors.aqua)),
212 blue: color_ramp(chroma(variant.colors.blue)),
213 violet: color_ramp(chroma(variant.colors.purple)),
214 magenta: color_ramp(chroma(variant.colors.gray)),
215 }
216
217 const syntax: ThemeSyntax = {
218 primary: { color: neutral[is_light ? 0 : 8] },
219 "text.literal": { color: colors.blue },
220 comment: { color: colors.gray },
221 punctuation: { color: neutral[is_light ? 1 : 7] },
222 "punctuation.bracket": { color: neutral[is_light ? 3 : 5] },
223 "punctuation.list_marker": { color: neutral[is_light ? 0 : 8] },
224 operator: { color: colors.aqua },
225 boolean: { color: colors.purple },
226 number: { color: colors.purple },
227 string: { color: colors.green },
228 "string.special": { color: colors.purple },
229 "string.special.symbol": { color: colors.aqua },
230 "string.regex": { color: colors.orange },
231 type: { color: colors.yellow },
232 enum: { color: colors.orange },
233 tag: { color: colors.aqua },
234 constant: { color: colors.yellow },
235 keyword: { color: colors.red },
236 function: { color: colors.green },
237 "function.builtin": { color: colors.red },
238 variable: { color: colors.blue },
239 property: { color: neutral[is_light ? 0 : 8] },
240 embedded: { color: colors.aqua },
241 link_text: { color: colors.aqua },
242 link_uri: { color: colors.purple },
243 title: { color: colors.green },
244 }
245
246 return {
247 name,
248 author: meta.author,
249 appearance: variant.appearance as ThemeAppearance,
250 license_type: meta.license_type,
251 license_url: meta.license_url,
252 license_file: `${__dirname}/LICENSE`,
253 input_color: ramps,
254 override: { syntax },
255 }
256}
257
258// Variants
259export const dark_hard = build_variant(variant[0])
260export const dark_default = build_variant(variant[1])
261export const dark_soft = build_variant(variant[2])
262export const light_hard = build_variant(variant[3])
263export const light_default = build_variant(variant[4])
264export const light_soft = build_variant(variant[5])