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)
} catch (error) {
console.info('Kitty: Previous build already removed')
}
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 return outputFile
} catch (error) {
throw error
}
} }

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) function getData(): any {
await appendToTOML(headerTOML()) return {
if (isVerbose) console.info('Writing author info to file', file) name,
await appendToTOML(authorTOML()) version,
if (isVerbose) console.info('Writing color palette to file', file) license,
await appendToTOML(colorHeaderTOML()) url,
for (let index = 0; index < colors.length; index++) { author,
const color = colors[index] colors: colors.map(getDataColors)
if (isVerbose) console.info(`${color.name}`, file)
await appendToTOML(colorTOML(color))
} }
return file
} }
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) function getData(): any {
await appendToYAML(headerYAML()) return {
if (isVerbose) console.info('Writing author info to file', file) name,
await appendToYAML(authorYAML()) version,
if (isVerbose) console.info('Writing color palette to file', file) license,
await appendToYAML(colorHeaderYAML()) url,
for (let index = 0; index < colors.length; index++) { author,
const color = colors[index] colors: colors.map(getDataColors)
if (isVerbose) console.info(`${color.name}`, file)
await appendToYAML(colorYAML(color))
} }
return file
} }
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,