1import {
2 chroma,
3 colorRamp,
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 licenseType: ThemeLicenseType.MIT,
15 licenseUrl: "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 darkNeutrals = [
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 lightNeutrals = [
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
122const darkHardNeutral = [color.dark0_hard, ...darkNeutrals]
123const darkNeutral = [color.dark0, ...darkNeutrals]
124const darkSoftNeutral = [color.dark0_soft, ...darkNeutrals]
125
126const lightHardNeutral = [color.light0_hard, ...lightNeutrals]
127const lightNeutral = [color.light0, ...lightNeutrals]
128const lightSoftNeutral = [color.light0_soft, ...lightNeutrals]
129
130interface Variant {
131 name: string
132 appearance: "light" | "dark"
133 colors: ThemeColors
134}
135
136const variant: Variant[] = [
137 {
138 name: "Dark Hard",
139 appearance: "dark",
140 colors: dark,
141 },
142 {
143 name: "Dark",
144 appearance: "dark",
145 colors: dark,
146 },
147 {
148 name: "Dark Soft",
149 appearance: "dark",
150 colors: dark,
151 },
152 {
153 name: "Light Hard",
154 appearance: "light",
155 colors: light,
156 },
157 {
158 name: "Light",
159 appearance: "light",
160
161 colors: light,
162 },
163 {
164 name: "Light Soft",
165 appearance: "light",
166 colors: light,
167 },
168]
169
170const buildVariant = (variant: Variant): ThemeConfig => {
171 const { colors } = variant
172
173 const name = `Gruvbox ${variant.name}`
174
175 const isLight = variant.appearance === "light"
176
177 let neutral: string[] = []
178
179 switch (variant.name) {
180 case "Dark Hard": {
181 neutral = darkHardNeutral
182 break
183 }
184 case "Dark": {
185 neutral = darkNeutral
186 break
187 }
188 case "Dark Soft": {
189 neutral = darkSoftNeutral
190 break
191 }
192 case "Light Hard": {
193 neutral = lightHardNeutral
194 break
195 }
196 case "Light": {
197 neutral = lightNeutral
198 break
199 }
200 case "Light Soft": {
201 neutral = lightSoftNeutral
202 break
203 }
204 }
205
206 const ramps = {
207 neutral: chroma.scale(isLight ? neutral.reverse() : neutral),
208 red: colorRamp(chroma(variant.colors.red)),
209 orange: colorRamp(chroma(variant.colors.orange)),
210 yellow: colorRamp(chroma(variant.colors.yellow)),
211 green: colorRamp(chroma(variant.colors.green)),
212 cyan: colorRamp(chroma(variant.colors.aqua)),
213 blue: colorRamp(chroma(variant.colors.blue)),
214 violet: colorRamp(chroma(variant.colors.purple)),
215 magenta: colorRamp(chroma(variant.colors.gray)),
216 }
217
218 const syntax: ThemeSyntax = {
219 primary: { color: neutral[isLight ? 0 : 8] },
220 "text.literal": { color: colors.blue },
221 comment: { color: colors.gray },
222 punctuation: { color: neutral[isLight ? 1 : 7] },
223 "punctuation.bracket": { color: neutral[isLight ? 3 : 5] },
224 "punctuation.list_marker": { color: neutral[isLight ? 0 : 8] },
225 operator: { color: colors.aqua },
226 boolean: { color: colors.purple },
227 number: { color: colors.purple },
228 string: { color: colors.green },
229 "string.special": { color: colors.purple },
230 "string.special.symbol": { color: colors.aqua },
231 "string.regex": { color: colors.orange },
232 type: { color: colors.yellow },
233 enum: { color: colors.orange },
234 tag: { color: colors.aqua },
235 constant: { color: colors.yellow },
236 keyword: { color: colors.red },
237 function: { color: colors.green },
238 "function.builtin": { color: colors.red },
239 variable: { color: colors.blue },
240 property: { color: neutral[isLight ? 0 : 8] },
241 embedded: { color: colors.aqua },
242 linkText: { color: colors.aqua },
243 linkUri: { color: colors.purple },
244 title: { color: colors.green },
245 }
246
247 return {
248 name,
249 author: meta.author,
250 appearance: variant.appearance as ThemeAppearance,
251 licenseType: meta.licenseType,
252 licenseUrl: meta.licenseUrl,
253 licenseFile: `${__dirname}/LICENSE`,
254 inputColor: ramps,
255 override: { syntax },
256 }
257}
258
259// Variants
260export const darkHard = buildVariant(variant[0])
261export const darkDefault = buildVariant(variant[1])
262export const darkSoft = buildVariant(variant[2])
263export const lightHard = buildVariant(variant[3])
264export const lightDefault = buildVariant(variant[4])
265export const lightSoft = buildVariant(variant[5])