gruvbox-common.ts

  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}