gruvbox-common.ts

  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])