gruvbox-common.ts

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