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