diff --git a/src/main.ts b/src/main.ts index acf93506..29fa301f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ import { ExtensionContext, Uri, workspace } from "vscode"; -import utils, { UpdateTrigger } from "./utils"; +import * as utils from "./utils"; import type { ThemePaths } from "./types"; export const activate = async (ctx: ExtensionContext) => { @@ -16,7 +16,7 @@ export const activate = async (ctx: ExtensionContext) => { utils.updateThemes( utils.getConfiguration(), paths, - UpdateTrigger.FRESH_INSTALL, + utils.UpdateTrigger.FRESH_INSTALL, ); } @@ -27,7 +27,7 @@ export const activate = async (ctx: ExtensionContext) => { utils.updateThemes( utils.getConfiguration(), paths, - UpdateTrigger.CONFIG_CHANGE, + utils.UpdateTrigger.CONFIG_CHANGE, ); } // call the icon pack sync when the theme changes diff --git a/src/utils.ts b/src/utils.ts index f004c03b..7ee2d90c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -27,138 +27,143 @@ export enum UpdateTrigger { FRESH_INSTALL = "Update detected", } -class Utils { - private promptToReload = (trigger: UpdateTrigger) => { - const msg = `Catppuccin: ${trigger} - Reload required.`; - const action = "Reload window"; - window.showInformationMessage(msg, action).then((selectedAction) => { - if (selectedAction === action) { - commands.executeCommand("workbench.action.reloadWindow"); - } - }); - }; - private writeThemeFile = async (uri: Uri, data: any): Promise => { - return workspace.fs - .writeFile(uri, Buffer.from(JSON.stringify(data, null, 2))) - .then( - () => {}, - (err) => { - window.showErrorMessage(err.message); - }, - ); - }; - private fileExists = async (uri: Uri): Promise => { - return workspace.fs.stat(uri).then( - () => true, - () => false, +type Entry = { [K in keyof T]: [K, T[K]] }[keyof T]; + +const filterObject = ( + obj: T, + fn: (entry: Entry, i: number, arr: Entry[]) => boolean, +) => { + return Object.fromEntries( + (Object.entries(obj) as Entry[]).filter(fn), + ) as Partial; +}; + +export const promptToReload = (trigger: UpdateTrigger) => { + const msg = `Catppuccin: ${trigger} - Reload required.`; + const action = "Reload window"; + window.showInformationMessage(msg, action).then((selectedAction) => { + if (selectedAction === action) { + commands.executeCommand("workbench.action.reloadWindow"); + } + }); +}; + +const writeThemeFile = async (uri: Uri, data: any): Promise => { + return workspace.fs + .writeFile(uri, Buffer.from(JSON.stringify(data, null, 2))) + .then( + () => {}, + (err) => { + window.showErrorMessage(err.message); + }, ); - }; - isMutable = async (uri: Uri): Promise => { - return workspace.fs.stat(uri).then( - (stat) => stat.permissions !== FilePermission.Readonly, - (err) => err, +}; + +const fileExists = async (uri: Uri): Promise => { + return workspace.fs.stat(uri).then( + () => true, + () => false, + ); +}; + +// TODO: listen to this to determine if a user is using Nix, redirect to README +export const isMutable = async (uri: Uri): Promise => { + return workspace.fs.stat(uri).then( + (stat) => stat.permissions !== FilePermission.Readonly, + (err) => err, + ); +}; + +export const isFreshInstall = async ( + ctx: ExtensionContext, +): Promise => { + console.log("Checking if catppuccin is installed for the first time."); + const flagUri = Uri.file(ctx.asAbsolutePath("themes/.flag")); + if (await fileExists(flagUri)) { + console.log("Catppuccin has been installed before."); + return false; + } else { + console.log("Catppuccin is installed for the first time!"); + return workspace.fs.writeFile(flagUri, Buffer.from("")).then( + () => true, + () => "error", ); + } +}; + +export const isDefaultConfig = (): boolean => { + console.log("Checking if catppuccin is using default config."); + const state = + JSON.stringify(getConfiguration()) === JSON.stringify(defaultOptions); + console.log(`Catppuccin is using ${state ? "default" : "custom"} config.`); + + return state; +}; + +export const getConfiguration = (): ThemeOptions => { + const conf = workspace.getConfiguration("catppuccin"); + const options = { + accent: conf.get("accentColor"), + boldKeywords: conf.get("boldKeywords"), + italicKeywords: conf.get("italicKeywords"), + italicComments: conf.get("italicComments"), + colorOverrides: conf.get("colorOverrides"), + workbenchMode: conf.get("workbenchMode"), + bracketMode: conf.get("bracketMode"), + extraBordersEnabled: conf.get("extraBordersEnabled"), + customUIColors: conf.get("customUIColors"), }; - isFreshInstall = async ( - ctx: ExtensionContext, - ): Promise => { - console.log("Checking if catppuccin is installed for the first time."); - const flagUri = Uri.file(ctx.asAbsolutePath("themes/.flag")); - if (await this.fileExists(flagUri)) { - console.log("Catppuccin has been installed before."); - return false; - } else { - console.log("Catppuccin is installed for the first time!"); - return workspace.fs.writeFile(flagUri, Buffer.from("")).then( - () => true, - () => "error", - ); - } - }; - isDefaultConfig = (): boolean => { - console.log("Checking if catppuccin is using default config."); - const state = - JSON.stringify(this.getConfiguration()) === - JSON.stringify(defaultOptions); - console.log(`Catppuccin is using ${state ? "default" : "custom"} config.`); - - return state; - }; - getConfiguration = (): ThemeOptions => { - const conf = workspace.getConfiguration("catppuccin"); - return { - accent: - conf.get("accentColor") ?? defaultOptions.accent, - boldKeywords: - conf.get("boldKeywords") ?? defaultOptions.boldKeywords, - italicKeywords: - conf.get("italicKeywords") ?? defaultOptions.italicKeywords, - italicComments: - conf.get("italicComments") ?? defaultOptions.italicComments, - colorOverrides: - conf.get("colorOverrides") ?? - defaultOptions.colorOverrides, - workbenchMode: - conf.get("workbenchMode") ?? - defaultOptions.workbenchMode, - bracketMode: - conf.get("bracketMode") ?? - defaultOptions.bracketMode, - extraBordersEnabled: - conf.get("extraBordersEnabled") ?? - defaultOptions.extraBordersEnabled, - customUIColors: - conf.get("customUIColors") ?? - defaultOptions.customUIColors, - }; - }; - updateThemes = async ( - options: ThemeOptions, - paths: ThemePaths, - trigger: UpdateTrigger, - ) => { - const flavors = Object.keys(variants) as CatppuccinFlavor[]; - - const promises = flavors.map(async (flavor): Promise => { - const theme = compileTheme(flavor, options); - return this.writeThemeFile(paths[flavor], theme); - }); - - Promise.all(promises).then(() => { - this.promptToReload(trigger); - }); + return { + ...defaultOptions, + ...filterObject(options, ([, value]) => value !== undefined), }; - syncToIconPack = () => { - const id = "catppuccin.catppuccin-vsc-icons"; - // bail if the icon pack isn't installed - if (extensions.getExtension(id) === undefined) return; - - // mapping the Catppuccin Theme names to the icon pack names - const uiThemesToIconThemes = { - "Catppuccin Latte": "catppuccin-latte", - "Catppuccin Frappé": "catppuccin-frappe", - "Catppuccin Macchiato": "catppuccin-macchiato", - "Catppuccin Mocha": "catppuccin-mocha", - }; - - // check if the current editor theme is a Catppuccin theme - const uiTheme = - workspace.getConfiguration("workbench").get("colorTheme") ?? ""; - const ctpThemeActive = Object.keys(uiThemesToIconThemes).includes(uiTheme); - - // and only sync to a Catppuccin icon flavor if the user's currently using Catppuccin for icons - const ctpIconsActive = Object.values(uiThemesToIconThemes).includes( - workspace.getConfiguration("workbench").get("iconTheme") ?? "", - ); +}; - if (ctpThemeActive && ctpIconsActive) { - const iconTheme = - uiThemesToIconThemes[uiTheme as keyof typeof uiThemesToIconThemes]; - workspace - .getConfiguration("workbench") - .update("iconTheme", iconTheme, ConfigurationTarget.Global); - } +export const updateThemes = async ( + options: ThemeOptions, + paths: ThemePaths, + trigger: UpdateTrigger, +) => { + const flavors = Object.keys(variants) as CatppuccinFlavor[]; + + const promises = flavors.map(async (flavor): Promise => { + const theme = compileTheme(flavor, options); + return writeThemeFile(paths[flavor], theme); + }); + + Promise.all(promises).then(() => { + promptToReload(trigger); + }); +}; + +export const syncToIconPack = () => { + const id = "catppuccin.catppuccin-vsc-icons"; + // bail if the icon pack isn't installed + if (extensions.getExtension(id) === undefined) return; + + // mapping the Catppuccin Theme names to the icon pack names + const uiThemesToIconThemes = { + "Catppuccin Latte": "catppuccin-latte", + "Catppuccin Frappé": "catppuccin-frappe", + "Catppuccin Macchiato": "catppuccin-macchiato", + "Catppuccin Mocha": "catppuccin-mocha", }; -} -export default new Utils(); + // check if the current editor theme is a Catppuccin theme + const uiTheme = + workspace.getConfiguration("workbench").get("colorTheme") ?? ""; + const ctpThemeActive = Object.keys(uiThemesToIconThemes).includes(uiTheme); + + // and only sync to a Catppuccin icon flavor if the user's currently using Catppuccin for icons + const ctpIconsActive = Object.values(uiThemesToIconThemes).includes( + workspace.getConfiguration("workbench").get("iconTheme") ?? "", + ); + + if (ctpThemeActive && ctpIconsActive) { + const iconTheme = + uiThemesToIconThemes[uiTheme as keyof typeof uiThemesToIconThemes]; + workspace + .getConfiguration("workbench") + .update("iconTheme", iconTheme, ConfigurationTarget.Global); + } +};