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        license_text:
252            "Copyright <YEAR> <COPYRIGHT HOLDER>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/ or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
253    },
254    author: "morhetz <morhetz@gmail.com>",
255    url: "https://github.com/morhetz/gruvbox",
256}