diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c8f8f878..de4bc944 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,8 +19,10 @@ The repository is structured so different components live as independently as po | `assets` | Auto-generated previews. | | `icons` | Icon SVG files for each flavour. | | `scripts` | Scripts for optimizing icons, generating flavoured icons, building previews and building the extension. | +| `src/constants` | Values used throughout the extension, mostly config-related. | | `src/defaults` | Default file/folder icon associations. | | `src/hooks` | Extension runtime code (commands). | +| `src/utils` | Helper functions independant from VSCode API. | ### Setup @@ -38,9 +40,7 @@ We provide a set of npm scripts to make development and contribution easier: |---|---| | `build` | Builds the extension and themes to `dist`. | | `catwalk` | Generates the main preview (requires `catwalk`). | -| `icons:generate` | Generates missing flavoured icon SVGs in their respective flavour folder. | -| `icons:optimize` | Runs all SVGs through `@iconify/tools/cleanupSVG` and `svgo`. | -| `icons:preview` | Generates complete flavour previews from existing icons. | +| `icons` | CLI to optimize/generate icons and icon previews. | | `pack` | Generates VSIX extension file. | ### Notes @@ -77,9 +77,7 @@ _Make sure to run `pnpm install` to ensure dependencies are installed and up to - `src/defaults/fileIcons.ts` for files. - `src/defaults/folderIcons.ts` for folders. -4. Run `pnpm icons:optimize` and `pnpm icons:generate` and other flavours will be automatically created in their respective folders! - -5. You can run `pnpm icons:preview` to regenerate flavour previews and ensure everything is looking fine. +4. Run `pnpm icons -a` to optimize the SVGs, generate other flavors and generate previews. You can also proceed step by step (run `pnpm icons --help` for more info). ### Running the extension locally diff --git a/package.json b/package.json index 2dd674c7..ba7cafe9 100644 --- a/package.json +++ b/package.json @@ -119,9 +119,7 @@ "scripts": { "build": "tsx scripts/build.ts", "catwalk": "tsx scripts/catwalk.ts", - "icons:generate": "tsx scripts/generate.ts", - "icons:optimize": "tsx scripts/optimize.ts", - "icons:preview": "tsx scripts/preview.ts", + "icons": "tsx scripts/icons.ts", "lint": "eslint .", "lint:fix": "eslint . --fix", "pack": "vsce package --no-dependencies", @@ -138,6 +136,8 @@ "@vscode/vsce": "^2.24.0", "bumpp": "^9.3.0", "changelogen": "^0.5.5", + "cleye": "^1.3.2", + "consola": "^3.2.3", "defu": "^6.1.4", "eslint": "^8.57.0", "lint-staged": "^15.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bfb27198..ad56b48a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,12 @@ devDependencies: changelogen: specifier: ^0.5.5 version: 0.5.5 + cleye: + specifier: ^1.3.2 + version: 1.3.2 + consola: + specifier: ^3.2.3 + version: 3.2.3 defu: specifier: ^6.1.4 version: 6.1.4 @@ -1596,6 +1602,13 @@ packages: escape-string-regexp: 1.0.5 dev: true + /cleye@1.3.2: + resolution: {integrity: sha512-MngIC2izcCz07iRKr3Pe8Z6ZBv4zbKFl/YnQEN/aMHis6PpH+MxI2e6n0bMUAmSVlMoAyQkdBCSTbfDmtcSovQ==} + dependencies: + terminal-columns: 1.4.1 + type-flag: 3.0.0 + dev: true + /cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4692,6 +4705,10 @@ packages: unique-string: 3.0.0 dev: true + /terminal-columns@1.4.1: + resolution: {integrity: sha512-IKVL/itiMy947XWVv4IHV7a0KQXvKjj4ptbi7Ew9MPMcOLzkiQeyx3Gyvh62hKrfJ0RZc4M1nbhzjNM39Kyujw==} + dev: true + /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -4881,6 +4898,10 @@ packages: engines: {node: '>=14.16'} dev: true + /type-flag@3.0.0: + resolution: {integrity: sha512-3YaYwMseXCAhBB14RXW5cRQfJQlEknS6i4C8fCfeUdS3ihG9EdccdR9kt3vP73ZdeTGmPb4bZtkDn5XMIn1DLA==} + dev: true + /type-level-regexp@0.1.17: resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==} dev: true diff --git a/scripts/build.ts b/scripts/build.ts index a03d0514..36509f6a 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -1,49 +1,91 @@ import { cp, readdir, writeFile } from 'node:fs/promises' import { basename, join } from 'node:path' +import { exit } from 'node:process' import { flavorEntries } from '@catppuccin/palette' import { build } from 'tsup' import { rimraf } from 'rimraf' +import { consola } from 'consola' import { compileTheme } from '~/utils/themes' const DIST = 'dist' const flavors = flavorEntries.map(([f]) => f) -// cleanup -await rimraf(DIST) - -// copy icons to dist -await Promise.all(flavors.map(async (f) => { - await cp(join('icons', f), join(DIST, f, 'icons'), { recursive: true }) -})) - -// copy css-vars/unflavored icons to dist -await cp(join('icons', 'css-variables'), join(DIST, 'unflavored'), { recursive: true }) - -// generate iconDefinitions.json file and save to dist -const icons = await readdir(join(DIST, flavors[0], 'icons')) -const iconDefinitions = icons.reduce((d, i) => ({ - ...d, - [basename(i, '.svg')]: { iconPath: `./icons/${i}` }, -}), {} as Record) -await writeFile( - join(DIST, 'iconDefinitions.json'), - JSON.stringify(iconDefinitions, null, 2), -) - -// compile theme.json and write to dist -const theme = compileTheme({}, iconDefinitions) -await Promise.all(flavors.map(async (f) => { +try { + consola.info('Deleting previous build...') + + // cleanup + await rimraf(DIST) + + consola.success('Deleted previous build.') +} +catch (error) { + consola.error('Failed to delete previous build: ', error) + exit(1) +} + +try { + consola.info('Copying icon SVGs to dist...') + + // copy icons to dist + await Promise.all(flavors.map(async (f) => { + await cp(join('icons', f), join(DIST, f, 'icons'), { recursive: true }) + })) + + // copy css-vars/unflavored icons to dist + await cp(join('icons', 'css-variables'), join(DIST, 'unflavored'), { recursive: true }) + + consola.success('Copied icon SVGs to dist.') +} +catch (error) { + consola.error('Failed to copy icon SVGs: ', error) + exit(1) +} + +try { + consola.info('Building themes and icon definitions...') + + // generate iconDefinitions.json file and save to dist + const icons = await readdir(join(DIST, flavors[0], 'icons')) + const iconDefinitions = icons.reduce((d, i) => ({ + ...d, + [basename(i, '.svg')]: { iconPath: `./icons/${i}` }, + }), {} as Record) await writeFile( - join(DIST, f, 'theme.json'), - JSON.stringify(theme, null, 2), + join(DIST, 'iconDefinitions.json'), + JSON.stringify(iconDefinitions, null, 2), ) -})) - -// build extension runtime -await build({ - entry: ['src/main.ts', 'src/browser.ts'], - format: ['cjs'], - external: ['vscode'], - minify: true, - shims: true, -}) + + // compile theme.json and write to dist + const theme = compileTheme({}, iconDefinitions) + await Promise.all(flavors.map(async (f) => { + await writeFile( + join(DIST, f, 'theme.json'), + JSON.stringify(theme, null, 2), + ) + })) + + consola.success('Built themes and icon definitions.') +} +catch (error) { + consola.error('Failed to build themes or icon definitions: ', error) + exit(1) +} + +try { + consola.info('Building VSC extension...') + + // build extension runtime + await build({ + entry: ['src/main.ts', 'src/browser.ts'], + format: ['cjs'], + external: ['vscode'], + minify: true, + shims: true, + }) + + consola.success('Built VSC extension.') +} +catch (error) { + consola.error('Failed to build VSC extension: ', error) + exit(1) +} diff --git a/scripts/catwalk.ts b/scripts/catwalk.ts index b7e7d519..6f1ff00f 100644 --- a/scripts/catwalk.ts +++ b/scripts/catwalk.ts @@ -3,14 +3,14 @@ import { readdir, writeFile } from 'node:fs/promises' import { join, resolve } from 'node:path' import { exit } from 'node:process' import { promisify } from 'node:util' -import type { FlavorName } from '@catppuccin/palette' -import { flavorEntries, flavors } from '@catppuccin/palette' +import { type FlavorName, flavorEntries, flavors } from '@catppuccin/palette' +import { consola } from 'consola' import { lookpath } from 'lookpath' import { launch } from 'puppeteer' import { temporaryDirectoryTask } from 'tempy' if (!await lookpath('catwalk')) { - console.error('Catwalk not installed.') + consola.error('Catwalk not installed.') exit() } @@ -61,22 +61,29 @@ function generateHtml(flavor: FlavorName) { ` } -await temporaryDirectoryTask(async (tmp) => { - const images = await Promise.all(flavorEntries.map(async ([flavor]) => { - const htmlPath = join(tmp, `${flavor}.html`) - const screenshotPath = join(tmp, `${flavor}.png`) - await writeFile(htmlPath, generateHtml(flavor)) - const browser = await launch({ headless: 'new' }) - const page = await browser.newPage() - await page.setViewport({ - height: 400, - width: 700, - deviceScaleFactor: 3, - }) - await page.goto(join('file:', htmlPath)) - await page.screenshot({ path: screenshotPath }) - await browser.close() - return screenshotPath - })) - await promisify(exec)(`catwalk ${images.join(' ')} --output="${OUT}"`) -}) +try { + consola.info('Generating Catwalk preview...') + await temporaryDirectoryTask(async (tmp) => { + const images = await Promise.all(flavorEntries.map(async ([flavor]) => { + const htmlPath = join(tmp, `${flavor}.html`) + const screenshotPath = join(tmp, `${flavor}.png`) + await writeFile(htmlPath, generateHtml(flavor)) + const browser = await launch() + const page = await browser.newPage() + await page.setViewport({ + height: 400, + width: 700, + deviceScaleFactor: 3, + }) + await page.goto(join('file:', htmlPath)) + await page.screenshot({ path: screenshotPath }) + await browser.close() + return screenshotPath + })) + await promisify(exec)(`catwalk ${images.join(' ')} --output="${OUT}"`) + }) + consola.success('Catwalk preview generated.') +} +catch (error) { + consola.error('Catwalk preview generation failed: ', error) +} diff --git a/scripts/generate.ts b/scripts/generate.ts deleted file mode 100644 index 3575114c..00000000 --- a/scripts/generate.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Generate missing icons from existing ones from other palettes. - * If an icon exists in `icons/latte`, it will create its counterparts for other palettes. - */ - -import { readFileSync, readdirSync, writeFileSync } from 'node:fs' -import { resolve } from 'node:path' -import { SVG, parseColors } from '@iconify/tools' -import { palettes } from '~/utils/palettes' - -const flavors = [ - 'css-variables', - 'frappe', - 'latte', - 'macchiato', - 'mocha', -] satisfies Array - -for (const origin of flavors) { - const originPath = resolve('icons', origin) - const originSvgs = readdirSync(originPath) - - for (const dest of flavors.filter(f => f !== origin)) { - const destPath = resolve('icons', dest) - const destSvgs = readdirSync(destPath) - originSvgs.filter(s => !destSvgs.includes(s)).forEach(async (i) => { - const svg = new SVG(readFileSync(resolve(originPath, i), 'utf8')) - parseColors(svg, { - callback(attr, color) { - if (attr === 'stroke') { - const newColorName = palettes[origin].find(v => v[1] === color.toLowerCase())?.[0] - const newColor = palettes[dest].find(v => v[0] === newColorName)?.[1] - if (!newColor) - throw new Error(`Color '${color}' found in '${i}' is not in ${origin} palette.`) - return newColor - } - return color - }, - }) - writeFileSync(resolve(destPath, i), svg.toPrettyString()) - }) - } -} diff --git a/scripts/icons.ts b/scripts/icons.ts new file mode 100644 index 00000000..95a8a7e7 --- /dev/null +++ b/scripts/icons.ts @@ -0,0 +1,273 @@ +import { readFileSync, readdirSync, writeFileSync } from 'node:fs' +import { readFile, readdir, writeFile } from 'node:fs/promises' +import { join, resolve } from 'node:path' +import { type FlavorName, flavorEntries, flavors } from '@catppuccin/palette' +import { SVG, cleanupSVG, parseColors, runSVGO } from '@iconify/tools' +import { temporaryDirectoryTask } from 'tempy' +import { cli } from 'cleye' +import { consola } from 'consola' +import { launch } from 'puppeteer' +import { palettes } from '~/utils/palettes' + +/** + * Optimizes SVGs by running them through SVGO + Iconify cleanup. + */ +async function optimizeIcons() { + try { + consola.info('Optimizing SVG files...') + Promise.all(flavorEntries.map(async ([flavor]) => { + const flavorPath = resolve('icons', flavor) + const svgs = await readdir(flavorPath) + await Promise.all(svgs.map(async (s) => { + const svgPath = resolve(flavorPath, s) + const str = await readFile(svgPath, 'utf8') + const svg = new SVG(str) + cleanupSVG(svg) + runSVGO(svg, { plugins: [ + 'cleanupAttrs', + 'cleanupEnableBackground', + 'cleanupIds', + 'cleanupListOfValues', + 'cleanupNumericValues', + 'collapseGroups', + 'convertColors', + 'convertEllipseToCircle', + 'convertShapeToPath', + 'convertStyleToAttrs', + 'convertTransform', + 'inlineStyles', + 'mergePaths', + 'mergeStyles', + 'minifyStyles', + 'moveElemsAttrsToGroup', + 'removeComments', + 'removeDesc', + 'removeDoctype', + 'removeEditorsNSData', + 'removeEmptyAttrs', + 'removeEmptyContainers', + 'removeEmptyText', + 'removeHiddenElems', + 'removeMetadata', + 'removeNonInheritableGroupAttrs', + 'removeRasterImages', + 'removeScriptElement', + 'removeStyleElement', + 'removeTitle', + 'removeUnknownsAndDefaults', + 'removeUnusedNS', + 'removeUselessDefs', + 'removeUselessStrokeAndFill', + 'removeXMLProcInst', + 'sortAttrs', + 'sortDefsChildren', + ] }) + await writeFile( + svgPath, + svg.toPrettyString() + .replaceAll(/#[A-Fa-f0-9]{6}/g, s => s.toLowerCase()), + ) + })) + })) + consola.success('Optimized SVG files.') + } + catch (error) { + consola.error('Optimization failed: ', error) + } +} + +/** + * Generates missing icons from existing ones from other palettes. + * If an icon exists in `icons/latte`, it will create its counterparts for other palettes. + */ +function generateIcons() { + const flavors = [ + 'css-variables', + 'frappe', + 'latte', + 'macchiato', + 'mocha', + ] satisfies Array + + try { + consola.info('Generating icons...') + let generated = 0 + for (const origin of flavors) { + const originPath = resolve('icons', origin) + const originSvgs = readdirSync(originPath) + + for (const dest of flavors.filter(f => f !== origin)) { + const destPath = resolve('icons', dest) + const destSvgs = readdirSync(destPath) + originSvgs.filter(s => !destSvgs.includes(s)).forEach(async (i) => { + const svg = new SVG(readFileSync(resolve(originPath, i), 'utf8')) + parseColors(svg, { + callback(attr, color) { + if (attr === 'stroke') { + const newColorName = palettes[origin].find(v => v[1] === color.toLowerCase())?.[0] + const newColor = palettes[dest].find(v => v[0] === newColorName)?.[1] + if (!newColor) + throw new Error(`Color '${color}' found in '${i}' is not in ${origin} palette.`) + return newColor + } + return color + }, + }) + writeFileSync(resolve(destPath, i), svg.toPrettyString()) + generated++ + }) + } + } + consola.success(`Generated ${generated} icons.`) + } + catch (error) { + consola.error('Generation failed: ', error) + } +} + +/** + * Generates previews (.webp) for all flavors. + */ +async function previewIcons() { + try { + consola.info('Generating previews...') + + const allIcons = await readdir('icons/latte') + const fileIcons = allIcons.filter(i => !i.startsWith('folder_') && !i.startsWith('_')) + const folderIcons = allIcons.filter(i => i.startsWith('folder_') && !i.endsWith('_open.svg')) + + function iconPath(icon: string, flavor: FlavorName) { + return `${resolve(join('icons', flavor, icon))}` + } + + function generateHtml(flavor: FlavorName) { + return ` + + + + + + +
+
+ ${fileIcons.map(i => ` +
+ + ${i.slice(0, -4)} +
+ `).join('\n')} +
+
+ ${folderIcons.map(i => ` +
+ + ${i.slice(0, -4)} +
+ `).join('\n')} +
+
+ + + ` + } + + await temporaryDirectoryTask(async (tmp) => { + await Promise.all(flavorEntries.map(async ([flavor]) => { + const htmlPath = join(tmp, `${flavor}.html`) + const screenshotPath = join('assets', `${flavor}.webp`) + await writeFile(htmlPath, generateHtml(flavor)) + const browser = await launch() + const page = await browser.newPage() + await page.goto(join('file:', htmlPath)) + await page.screenshot({ + type: 'webp', + path: screenshotPath, + fullPage: true, + omitBackground: true, + }) + await browser.close() + })) + }) + + consola.success('Previews generated.') + } + catch (error) { + consola.error('Preview generation failed: ', error) + } +} + +const argv = cli({ + flags: { + optimize: { + alias: 'o', + type: Boolean, + default: false, + description: 'Run SVGO + Iconify optimization', + }, + generate: { + alias: 'g', + type: Boolean, + default: false, + description: 'Generate missing icons from existing ones from other palettes', + }, + preview: { + alias: 'p', + type: Boolean, + default: false, + description: 'Generate previews for all flavors', + }, + all: { + alias: 'a', + type: Boolean, + default: false, + description: 'Run optimize + generate + preview', + }, + }, +}) + +if (!argv.flags.all && !argv.flags.optimize && !argv.flags.generate && !argv.flags.preview) + consola.warn('No flag passed, nothing was done. Run with `--help` to get flag info.') + +if (argv.flags.all || argv.flags.optimize) + await optimizeIcons() + +if (argv.flags.all || argv.flags.generate) + generateIcons() + +if (argv.flags.all || argv.flags.preview) + await previewIcons() diff --git a/scripts/optimize.ts b/scripts/optimize.ts deleted file mode 100644 index 321878f2..00000000 --- a/scripts/optimize.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Optimizes SVGs by running them through SVGO + Iconify cleanup - */ - -import { readFile, readdir, writeFile } from 'node:fs/promises' -import { resolve } from 'node:path' -import { flavorEntries } from '@catppuccin/palette' -import { SVG, cleanupSVG, runSVGO } from '@iconify/tools' - -Promise.all(flavorEntries.map(async ([flavor]) => { - const flavorPath = resolve('icons', flavor) - const svgs = await readdir(flavorPath) - await Promise.all(svgs.map(async (s) => { - const svgPath = resolve(flavorPath, s) - const str = await readFile(svgPath, 'utf8') - const svg = new SVG(str) - cleanupSVG(svg) - runSVGO(svg, { plugins: [ - 'cleanupAttrs', - 'cleanupEnableBackground', - 'cleanupIds', - 'cleanupListOfValues', - 'cleanupNumericValues', - 'collapseGroups', - 'convertColors', - 'convertEllipseToCircle', - 'convertShapeToPath', - 'convertStyleToAttrs', - 'convertTransform', - 'inlineStyles', - 'mergePaths', - 'mergeStyles', - 'minifyStyles', - 'moveElemsAttrsToGroup', - 'removeComments', - 'removeDesc', - 'removeDoctype', - 'removeEditorsNSData', - 'removeEmptyAttrs', - 'removeEmptyContainers', - 'removeEmptyText', - 'removeHiddenElems', - 'removeMetadata', - 'removeNonInheritableGroupAttrs', - 'removeRasterImages', - 'removeScriptElement', - 'removeStyleElement', - 'removeTitle', - 'removeUnknownsAndDefaults', - 'removeUnusedNS', - 'removeUselessDefs', - 'removeUselessStrokeAndFill', - 'removeXMLProcInst', - 'sortAttrs', - 'sortDefsChildren', - ] }) - await writeFile( - svgPath, - svg.toPrettyString() - .replaceAll(/#[A-Fa-f0-9]{6}/g, s => s.toLowerCase()), - ) - })) -})) diff --git a/scripts/preview.ts b/scripts/preview.ts deleted file mode 100644 index 8575f0dd..00000000 --- a/scripts/preview.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { readdir, writeFile } from 'node:fs/promises' -import { join, resolve } from 'node:path' -import type { FlavorName } from '@catppuccin/palette' -import { flavorEntries, flavors } from '@catppuccin/palette' -import { launch } from 'puppeteer' -import { temporaryDirectoryTask } from 'tempy' - -const allIcons = await readdir('icons/latte') -const fileIcons = allIcons.filter(i => !i.startsWith('folder_') && !i.startsWith('_')) -const folderIcons = allIcons.filter(i => i.startsWith('folder_') && !i.endsWith('_open.svg')) - -function iconPath(icon: string, flavor: FlavorName) { - return `${resolve(join('icons', flavor, icon))}` -} - -function generateHtml(flavor: FlavorName) { - return ` - - - - - - -
-
- ${fileIcons.map(i => ` -
- - ${i.slice(0, -4)} -
- `).join('\n')} -
-
- ${folderIcons.map(i => ` -
- - ${i.slice(0, -4)} -
- `).join('\n')} -
-
- - -` -} - -await temporaryDirectoryTask(async (tmp) => { - await Promise.all(flavorEntries.map(async ([flavor]) => { - const htmlPath = join(tmp, `${flavor}.html`) - const screenshotPath = join('assets', `${flavor}.webp`) - await writeFile(htmlPath, generateHtml(flavor)) - const browser = await launch({ headless: 'new' }) - const page = await browser.newPage() - await page.goto(join('file:', htmlPath)) - await page.screenshot({ - type: 'webp', - path: screenshotPath, - fullPage: true, - omitBackground: true, - }) - await browser.close() - })) -}) diff --git a/src/browser.ts b/src/browser.ts index eaa8b90a..d8142d3a 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -1,5 +1,4 @@ -import type { ConfigurationChangeEvent, ExtensionContext } from 'vscode' -import { window, workspace } from 'vscode' +import { type ConfigurationChangeEvent, type ExtensionContext, window, workspace } from 'vscode' import { CONFIG_ROOT } from '~/constants' /** diff --git a/src/hooks/iconDefinitions.ts b/src/hooks/iconDefinitions.ts index e48ee051..3f181736 100644 --- a/src/hooks/iconDefinitions.ts +++ b/src/hooks/iconDefinitions.ts @@ -1,5 +1,4 @@ -import { Uri, workspace } from 'vscode' -import type { ExtensionContext } from 'vscode' +import { type ExtensionContext, Uri, workspace } from 'vscode' import type { IconDefinitions } from '~/types' /** diff --git a/src/hooks/interactions.ts b/src/hooks/interactions.ts index d925c017..43da7cac 100644 --- a/src/hooks/interactions.ts +++ b/src/hooks/interactions.ts @@ -1,6 +1,5 @@ import { Buffer } from 'node:buffer' -import { Uri, commands, window, workspace } from 'vscode' -import type { ExtensionContext } from 'vscode' +import { type ExtensionContext, Uri, commands, window, workspace } from 'vscode' /** * Inform the user changes happened and reload is required diff --git a/src/hooks/paths.ts b/src/hooks/paths.ts index f0da45d9..b488c024 100644 --- a/src/hooks/paths.ts +++ b/src/hooks/paths.ts @@ -1,5 +1,4 @@ -import { Uri } from 'vscode' -import type { ExtensionContext } from 'vscode' +import { type ExtensionContext, Uri } from 'vscode' import type { ThemePaths } from '~/types' /** diff --git a/src/hooks/updateThemes.ts b/src/hooks/updateThemes.ts index 43b122e7..8a9058b1 100644 --- a/src/hooks/updateThemes.ts +++ b/src/hooks/updateThemes.ts @@ -1,5 +1,4 @@ -import type { ExtensionContext } from 'vscode' -import { Uri, window, workspace } from 'vscode' +import { type ExtensionContext, Uri, window, workspace } from 'vscode' import { flavorEntries } from '@catppuccin/palette' import { readFile, writeFile, writeJsonFile } from '~/hooks/interactions' import { getConfig } from '~/hooks/configuration' diff --git a/src/main.ts b/src/main.ts index 3ad1faba..5cf66f80 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,4 @@ -import type { ExtensionContext } from 'vscode' -import { commands, workspace } from 'vscode' +import { type ExtensionContext, commands, workspace } from 'vscode' import { COMMANDS, CONFIG_KEYS, CONFIG_ROOT } from '~/constants' import { updateThemes } from '~/hooks/updateThemes' import { isFreshInstall, promptToReload } from '~/hooks/interactions' diff --git a/src/utils/icons.ts b/src/utils/icons.ts index 733f4832..73f9ac82 100644 --- a/src/utils/icons.ts +++ b/src/utils/icons.ts @@ -1,5 +1,4 @@ -import type { ColorName, FlavorName } from '@catppuccin/palette' -import { flavors } from '@catppuccin/palette' +import { type ColorName, type FlavorName, flavors } from '@catppuccin/palette' import defu from 'defu' import { defaultConfig } from '~/defaults' import type { IconsConfig } from '~/types' diff --git a/src/utils/palettes.ts b/src/utils/palettes.ts index 1d1c15a4..c1892393 100644 --- a/src/utils/palettes.ts +++ b/src/utils/palettes.ts @@ -1,5 +1,10 @@ -import type { AccentName, FlavorName, MonochromaticName } from '@catppuccin/palette' -import { flavorEntries, flavors } from '@catppuccin/palette' +import { + type AccentName, + type FlavorName, + type MonochromaticName, + flavorEntries, + flavors, +} from '@catppuccin/palette' export type ColorName = AccentName | Extract