Compare commits

...

5 commits

Author SHA1 Message Date
Ava Gaiety W
1363787086 handlebars for kitty 2025-09-23 22:30:21 -06:00
Ava Gaiety W
211b5ae702 handlebars for yaml and toml gen 2025-09-23 22:03:20 -06:00
Ava Gaiety W
3fb0a2360a remove estilo, will switch to handlebars 2025-09-23 22:03:11 -06:00
Ava Gaiety W
a66364abb6 neovim port 2025-09-20 13:11:31 -06:00
Ava Gaiety W
b49c2f4e84 function casing 2025-09-20 12:35:13 -06:00
22 changed files with 329 additions and 326 deletions

BIN
bun.lockb

Binary file not shown.

View file

@ -6,6 +6,7 @@ import previewSnippet from './src/preview/cli-snippet'
import buildTOML from './src/build/toml' import buildTOML from './src/build/toml'
import buildYAML from './src/build/yaml' import buildYAML from './src/build/yaml'
import buildKitty from './ports/kitty/src/build' import buildKitty from './ports/kitty/src/build'
import buildNeovim from './ports/neovim/src/build'
const program = new Command(); const program = new Command();
@ -46,6 +47,7 @@ program
if (options.verbose) console.info('Building Ports...') if (options.verbose) console.info('Building Ports...')
log(options.verbose, await buildKitty(), timer) log(options.verbose, await buildKitty(), timer)
// log(options.verbose, await buildNeovim(), timer)
}); });
program.parse(); program.parse();

View file

@ -16,7 +16,7 @@
"chalk": "^5.6.2", "chalk": "^5.6.2",
"color-convert": "^3.1.2", "color-convert": "^3.1.2",
"commander": "^14.0.1", "commander": "^14.0.1",
"estilo": "^2.1.3", "handlebars": "^4.7.8"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "^5.0.0" "typescript": "^5.0.0"

View file

@ -25,6 +25,25 @@ cursor_trail_color #E1B392
url_color #8CC8E0 url_color #8CC8E0
#################### ####################
#########################
# window border colors and terminal bell colors
active_border_color #23DBC1
inactive_border_color #4E6872
bell_border_color #FF9F6F
# visual_bell_color none
####################
#########################
# Tab bar colors
active_tab_foreground #C6E4F0
active_tab_background #19323B
inactive_tab_foreground #C6E4F0
inactive_tab_background #4E6872
# tab_bar_background #00040B
# tab_bar_margin_color none
####################
######################### #########################
# Marks colors # Marks colors
# mark1_foreground black # mark1_foreground black
@ -35,23 +54,6 @@ url_color #8CC8E0
# mark3_background #f274bc # mark3_background #f274bc
#################### ####################
#########################
# Tab bar colors
active_tab_foreground #C6E4F0
active_tab_background #19323B
inactive_tab_foreground #C6E4F0
inactive_tab_background #4E6872
# tab_bar_background #{pit.toHex()}
# tab_bar_margin_color none
####################
#########################
# window border colors and terminal bell colors
active_border_color #23DBC1
inactive_border_color #4E6872
bell_border_color #FF9F6F
# visual_bell_color none
####################
######################### #########################
# The basic 16 colors # The basic 16 colors

View file

@ -1,6 +0,0 @@
#########################
# verdigris for kitty
# 0.0.1
# GPL-3.0-only
# https://git.basking.monster/gaiety/verdigris
####################

View file

@ -1,3 +1,3 @@
import BuildKitty from './src/build' import buildKitty from './src/build'
await BuildKitty() await buildKitty()

View file

@ -1,31 +1,17 @@
import appRoot from 'app-root-path' import appRoot from 'app-root-path'
import { rmFile, mkFilePath, appendToFile } from "../../../src/helpers/file" import { renderToFile } from "../../../src/helpers/file"
import { headerInfo, colorsBasic, colorsURLs, colorsCursor, colorsMarks, colorsTabBar, colorsBordersAndAlerts, colorsBasic16 } from './data' import getData from './data'
const file = appRoot + '/ports/kitty/dist/kitty.conf' const templateFile = appRoot + '/ports/kitty/src/templates/kitty.conf.hbs'
const outputFile = appRoot + '/ports/kitty/dist/kitty.conf'
const appendToKittyConf = async (content: string) => await appendToFile(file, content)
export default async function(isVerbose = false): Promise<string> { export default async function(isVerbose = false): Promise<string> {
if (isVerbose) console.info('Kitty: Removing previous build', file)
try { try {
await rmFile(file) await renderToFile(templateFile, outputFile, getData(), isVerbose)
return outputFile
} catch (error) { } catch (error) {
console.info('Kitty: Previous build already removed') throw error
} }
if (isVerbose) console.info('Kitty: Ensuring path and file exist', file)
await mkFilePath(file)
if (isVerbose) console.info('Kitty: Writing header info to file', file)
await appendToKittyConf(headerInfo())
if (isVerbose) console.info('Kitty: Writing color palette into file', file)
await appendToKittyConf(colorsBasic())
await appendToKittyConf(colorsCursor())
await appendToKittyConf(colorsURLs())
await appendToKittyConf(colorsMarks())
await appendToKittyConf(colorsTabBar())
await appendToKittyConf(colorsBordersAndAlerts())
await appendToKittyConf(colorsBasic16())
return file
} }

View file

@ -1,136 +1,24 @@
import { name, version } from '../info.toml' import { name, version } from '../info.toml'
import { license, url } from '../../../package.json' import { license, url } from '../../../package.json'
import { import colors from '../../../src/palette'
pit, import type { Colors } from '../../../src/palette'
depths, import Color from '../../../src/helpers/color'
stope,
text,
orange,
teal,
red,
yellow,
green,
blue,
purple,
} from '../../../src/palette'
export function headerInfo(): string { export default function(): any {
return `######################### return {
# ${name} for kitty name,
# ${version} version,
# ${license} license,
# ${url} url,
#################### ...flattenColorsToHex(),
}
`
} }
export function colorsBasic(): string { function flattenColorsToHex(): Colors {
return `######################### return colors.reduce((acc, color) => {
# The basic colors return {
foreground ${text.toHex()} [color.nameSnakeCase]: color.toHex(),
background ${pit.toHex()} ...acc,
selection_foreground ${depths.toHex()}
selection_background ${text.toHex()}
####################
`
} }
}, {})
export function colorsCursor(): string {
return `#########################
# Cursor colors
cursor ${text.toHex()}
cursor_text_color ${depths.toHex()}
cursor_trail_color ${yellow.toHex()}
####################
`
} }
export function colorsURLs(): string {
return `#########################
# URL colors
url_color ${blue.toHex()}
####################
`
}
export function colorsBordersAndAlerts(): string {
return `#########################
# window border colors and terminal bell colors
active_border_color ${teal.toHex()}
inactive_border_color ${stope.toHex()}
bell_border_color ${orange.toHex()}
# visual_bell_color none
####################
`
}
export function colorsTabBar(): string {
return `#########################
# Tab bar colors
active_tab_foreground ${text.toHex()}
active_tab_background ${depths.toHex()}
inactive_tab_foreground ${text.toHex()}
inactive_tab_background ${stope.toHex()}
# tab_bar_background #{pit.toHex()}
# tab_bar_margin_color none
####################
`
}
export function colorsMarks(): string {
return `#########################
# Marks colors
# mark1_foreground black
# mark1_background #98d3cb
# mark2_foreground black
# mark2_background #f2dcd3
# mark3_foreground black
# mark3_background #f274bc
####################
`
}
export function colorsBasic16(): string {
return `#########################
# The basic 16 colors
#: black
color0 ${pit.toHex()}
color8 ${stope.toHex()}
#: red
color1 ${red.toHex()}
color9 ${red.toHex()}
#: green
color2 ${green.toHex()}
color10 ${green.toHex()}
#: yellow
color3 ${yellow.toHex()}
color11 ${yellow.toHex()}
#: blue
color4 ${blue.toHex()}
color12 ${blue.toHex()}
#: magenta
color5 ${purple.toHex()}
color13 ${purple.toHex()}
#: cyan
color6 ${teal.toHex()}
color14 ${teal.toHex()}
#: white
color7 ${text.toHex()}
color15 ${text.toHex()}
####################`
}

View file

@ -0,0 +1,91 @@
#########################
# {{name}} for kitty
# {{version}}
# {{license}}
# {{url}}
####################
#########################
# The basic colors
foreground {{text}}
background {{pit}}
selection_foreground {{depths}}
selection_background {{text}}
####################
#########################
# Cursor colors
cursor {{text}}
cursor_text_color {{depths}}
cursor_trail_color {{yellow}}
####################
#########################
# URL colors
url_color {{blue}}
####################
#########################
# window border colors and terminal bell colors
active_border_color {{teal}}
inactive_border_color {{stope}}
bell_border_color {{orange}}
# visual_bell_color none
####################
#########################
# Tab bar colors
active_tab_foreground {{text}}
active_tab_background {{depths}}
inactive_tab_foreground {{text}}
inactive_tab_background {{stope}}
# tab_bar_background {{pit}}
# tab_bar_margin_color none
####################
#########################
# Marks colors
# mark1_foreground black
# mark1_background #98d3cb
# mark2_foreground black
# mark2_background #f2dcd3
# mark3_foreground black
# mark3_background #f274bc
####################
#########################
# The basic 16 colors
#: black
color0 {{pit}}
color8 {{stope}}
#: red
color1 {{red}}
color9 {{red}}
#: green
color2 {{green}}
color10 {{green}}
#: yellow
color3 {{yellow}}
color11 {{yellow}}
#: blue
color4 {{blue}}
color12 {{blue}}
#: magenta
color5 {{purple}}
color13 {{purple}}
#: cyan
color6 {{teal}}
color14 {{teal}}
#: white
color7 {{text}}
color15 {{text}}
####################

1
ports/neovim/README.md Normal file
View file

@ -0,0 +1 @@
https://neovim.io/doc/user/syntax.html

3
ports/neovim/index.ts Normal file
View file

@ -0,0 +1,3 @@
import buildNeovim from './src/build'
await buildNeovim()

38
ports/neovim/src/build.ts Normal file
View file

@ -0,0 +1,38 @@
import appRoot from 'app-root-path'
import { rmFile, mkFilePath, appendToFile } from "../../../src/helpers/file"
import { common } from '../../../dist/palette.yml'
import { spawn } from 'bun'
const file = appRoot + '/ports/neovim/estilos/palettes/verdigris.yml'
const appendToEstilosPalette = async (content: string) => await appendToFile(file, content)
export default async function(isVerbose = false) {
if (isVerbose) console.info('Neovim: Removing previous build', file)
try {
await rmFile(file)
} catch (error) {
console.info('Neovim: Previous build already removed')
}
if (isVerbose) console.info('Neovim: Ensuring path and file exist', file)
await mkFilePath(file)
if (isVerbose) console.info('Neovim: Writing color palette into file', file)
await appendToEstilosPalette(colors())
if (isVerbose) console.info('Neovim: Running estilo to compile `.vim`', file)
await runEstilo(isVerbose)
return appRoot + '/ports/neovim/colors/verdigris.vim'
}
function colors(): string {
return Object
.keys(common)
.reduce((acc, key) => acc += `${key}: "${common[key]}"\n`, '')
}
async function runEstilo(isVerbose: boolean) {
const proc = spawn(['bun', 'estilo', 'render', appRoot + '/ports/neovim/'], {
cwd: appRoot.toString(),
});
const output = await proc.stdout.text();
if (isVerbose) console.info(output)
}

View file

@ -0,0 +1,21 @@
name = "{{name}}"
version = "{{version}}"
license = "{{license}}"
sourcecode = "{{url}}"
[author]
name = "{{author.name}}"
email = "{{author.email}}"
url = "{{author.url}}"
[colors]
{{#each colors}}
[colors.{{this.nameSnakeCase}}]
name = "{{this.name}}"
l = {{this.l}}
c = {{this.c}}
h = {{this.h}}
hex = "{{this.hex}}"
{{/each}}

View file

@ -0,0 +1,14 @@
name: "{{name}}"
version: "{{version}}"
license: "{{license}}"
sourcecode: "{{url}}"
author:
name: "{{author.name}}"
email: "{{author.email}}"
url: "{{author.url}}"
common:
{{#each colors}}
{{this.nameSnakeCase}}: "{{this.hex}}"
{{/each}}

View file

@ -1,70 +1,42 @@
import { name, version, license, url, author } from '../../package.json' import { name, version, license, url, author } from '../../package.json'
import appRoot from 'app-root-path' import appRoot from 'app-root-path'
import { rmFile, mkFilePath, appendToFile } from "../helpers/file" import { renderToFile } from "../helpers/file"
import colors from '../palette' import colors from '../palette'
import type color from '../helpers/color' import Color from '../helpers/color'
import { toSnakeCase } from '../helpers/string'
const file = appRoot + '/dist/palette.toml' const templateFile = appRoot + '/src/build/templates/toml.hbs'
const appendToTOML = async (content: string) => await appendToFile(file, content) const outputFile = appRoot + '/dist/palette.toml'
export default async function(isVerbose = false): Promise<string> { export default async function(isVerbose = false): Promise<string> {
if (isVerbose) console.info('Removing previous build', file)
try { try {
await rmFile(file) await renderToFile(templateFile, outputFile, getData(), isVerbose)
return outputFile
} catch (error) { } catch (error) {
console.info('TOML: Previous build already removed') throw error
} }
if (isVerbose) console.info('Ensuring path and file exist', file)
await mkFilePath(file)
if (isVerbose) console.info('Writing header info to file', file)
await appendToTOML(headerTOML())
if (isVerbose) console.info('Writing author info to file', file)
await appendToTOML(authorTOML())
if (isVerbose) console.info('Writing color palette to file', file)
await appendToTOML(colorHeaderTOML())
for (let index = 0; index < colors.length; index++) {
const color = colors[index]
if (isVerbose) console.info(`${color.name}`, file)
await appendToTOML(colorTOML(color))
} }
return file function getData(): any {
return {
name,
version,
license,
url,
author,
colors: colors.map(getDataColors)
}
} }
function headerTOML(): string { function getDataColors(color: Color): any {
return `name = "${name}" const { name, nameSnakeCase, l, c, h } = color
version = "${version}"
license = "${license}"
sourcecode = "${url}"
`
}
function authorTOML(): string { return {
const { name, email, url } = author name,
nameSnakeCase,
return ` l,
[author] c,
name = "${name}" h,
email = "${email}" hex: color.toHex()
url = "${url}"
`
} }
function colorHeaderTOML(): string {
return `
[colors]
`
}
function colorTOML(color: color): string {
const { name, l, c, h } = color
return `
[colors.${toSnakeCase(name)}]
name = "${name}"
l = ${l}
c = ${c}
h = ${h}
hex = "${color.toHex()}"
`
} }

View file

@ -1,62 +1,38 @@
import { name, version, license, url, author } from '../../package.json' import { name, version, license, url, author } from '../../package.json'
import appRoot from 'app-root-path' import appRoot from 'app-root-path'
import { rmFile, mkFilePath, appendToFile } from "../helpers/file"
import { toSnakeCase } from '../helpers/string'
import colors from '../palette' import colors from '../palette'
import type color from '../helpers/color' import Color from '../helpers/color'
import { renderToFile } from '../helpers/file'
const file = appRoot + '/dist/palette.yml' const templateFile = appRoot + '/src/build/templates/yaml.hbs'
const appendToYAML = async (content: string) => await appendToFile(file, content) const outputFile = appRoot + '/dist/palette.yml'
export default async function(isVerbose = false): Promise<string> { export default async function(isVerbose = false): Promise<string> {
if (isVerbose) console.info('Removing previous build', file)
try { try {
await rmFile(file) await renderToFile(templateFile, outputFile, getData(), isVerbose)
return outputFile
} catch (error) { } catch (error) {
console.info('YAML: Previous build already removed') throw error
} }
if (isVerbose) console.info('Ensuring path and file exist', file)
await mkFilePath(file)
if (isVerbose) console.info('Writing header info to file', file)
await appendToYAML(headerYAML())
if (isVerbose) console.info('Writing author info to file', file)
await appendToYAML(authorYAML())
if (isVerbose) console.info('Writing color palette to file', file)
await appendToYAML(colorHeaderYAML())
for (let index = 0; index < colors.length; index++) {
const color = colors[index]
if (isVerbose) console.info(`${color.name}`, file)
await appendToYAML(colorYAML(color))
} }
return file function getData(): any {
return {
name,
version,
license,
url,
author,
colors: colors.map(getDataColors)
}
} }
function headerYAML(): string { function getDataColors(color: Color): any {
return `name: "${name}" const { nameSnakeCase } = color
version: "${version}"
license: "${license}"
sourcecode: "${url}"
`
}
function authorYAML(): string { return {
const { name, email, url } = author nameSnakeCase,
hex: color.toHex()
return `
author:
name: "${name}"
email: "${email}"
url: "${url}"
`
} }
function colorHeaderYAML(): string {
return `
common:`
}
function colorYAML(color: color): string {
return `
${toSnakeCase(color.name)}: "${color.toHex()}"`
} }

View file

@ -1,4 +1,5 @@
import convert from 'color-convert' import convert from 'color-convert'
import { toSnakeCase } from './string'
export interface OklchInterface { export interface OklchInterface {
l: number, l: number,
@ -31,6 +32,8 @@ export default class {
return true return true
} }
get nameSnakeCase() { return toSnakeCase(this.#name) }
get l() { return this.#l } get l() { return this.#l }
set l(value: number) { set l(value: number) {
if (this._isLValid(value)) this.#l = value if (this._isLValid(value)) this.#l = value

View file

@ -1,25 +1,36 @@
import { appendFile, mkdir, rm } from 'node:fs/promises'; import { compile } from 'handlebars';
import { appendFile, mkdir, rm, readFile, writeFile } from 'node:fs/promises';
import { dirname } from 'node:path' import { dirname } from 'node:path'
export async function mkFilePath(file: string) { const log = (isVerbose = true, ...rest: any[]) => {
if (isVerbose) console.info(...rest)
}
export async function mkFilePath(file: string, isVerbose = false) {
try { try {
log(isVerbose, 'Ensuring path and file exist', file)
await mkdir(dirname(file), { recursive: true }) await mkdir(dirname(file), { recursive: true })
} catch (error) { } catch (error) {
throw error throw error
} }
} }
export async function rmFile(file: string) { export async function renderToFile(
templateFile: string, outputFile: string, data: any, isVerbose = false
): Promise<string> {
try { try {
await rm(file) await mkFilePath(outputFile, isVerbose)
} catch (error) {
throw error log(isVerbose, 'Reading in template', templateFile)
} const template = (await readFile(templateFile)).toString()
}
log(isVerbose, 'Compiling template', templateFile, 'with data', data)
export async function appendToFile(file: string, content: string) { const result = compile(template)(data)
try {
await appendFile(file, content) log(isVerbose, 'Saving result', outputFile)
await writeFile(outputFile, result)
return result
} catch (error) { } catch (error) {
throw error throw error
} }

View file

@ -1,13 +0,0 @@
name = "verdigris"
version = "0.0.1"
[author]
name = "Gaiety"
email = "ava+verdigris@gaiety.me"
[colors]
[colors.bg]
l = 0.2
c = 0.02
h =

View file

@ -91,6 +91,20 @@ export const purple = new Color('Purple', {
h: absDegrees(hueLevels.teal + (hueOffset * 5)), h: absDegrees(hueLevels.teal + (hueOffset * 5)),
}) })
export type Colors = {
pit: string;
depths: string;
stope: string;
text: string;
orange: string;
teal: string;
red: string;
yellow: string;
green: string;
blue: string;
purple: string;
}
export default [ export default [
pit, pit,
depths, depths,