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