From 38c88a62479944eeb1c32b8004a3bdae483911ed Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sun, 17 Dec 2023 18:58:17 +0100 Subject: [PATCH] perf: cleanup unused attribute in themes and langs --- .gitignore | 1 + packages/shikiji-core/src/types.ts | 29 +++-- packages/shikiji/scripts/prepare.ts | 2 + .../shikiji/scripts/prepare/injections.ts | 9 +- packages/shikiji/scripts/prepare/langs.ts | 17 +-- packages/shikiji/scripts/prepare/themes.ts | 38 +++--- packages/shikiji/scripts/prepare/utils.ts | 64 ++++++++++ packages/shikiji/src/assets/themes.ts | 116 +++++++++--------- 8 files changed, 179 insertions(+), 97 deletions(-) create mode 100644 packages/shikiji/scripts/prepare/utils.ts diff --git a/.gitignore b/.gitignore index 23e8a4b0..b0d72834 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,6 @@ logs node_modules temp packages/shikiji/src/assets/langs +packages/shikiji/src/assets/themes packages/shikiji/src/assets/*.json cache diff --git a/packages/shikiji-core/src/types.ts b/packages/shikiji-core/src/types.ts index 4c2344ce..5565e574 100644 --- a/packages/shikiji-core/src/types.ts +++ b/packages/shikiji-core/src/types.ts @@ -198,6 +198,9 @@ export interface LanguageRegistration extends RawGrammar { balancedBracketSelectors?: string[] unbalancedBracketSelectors?: string[] + foldingStopMarker?: string + foldingStartMarker?: string + /** * Inject this language to other scopes. * Same as `injectTo` in VSCode's `contributes.grammars`. @@ -354,40 +357,48 @@ export interface ThemeRegistrationRaw extends RawTheme {} export interface ThemeRegistration extends ThemeRegistrationRaw { /** - * @description theme name + * Theme name */ name: string /** - * @description light/dark theme + * Display name */ - type: 'light' | 'dark' | 'css' + displayName?: string /** - * @description tokenColors of the theme file + * Light/dark theme + */ + type: 'light' | 'dark' + + /** + * TokenColors of the theme file */ settings: IRawThemeSetting[] /** - * @description text default foreground color + * Text default foreground color */ fg: string /** - * @description text default background color + * Text default background color */ bg: string /** - * @description relative path of included theme + * Relative path of included theme */ include?: string /** - * - * @description color map of the theme file + * Color map of the theme file */ colors?: Record + + tokenColors?: any[] + semanticHighlighting?: boolean + semanticTokenColors?: any[] } export interface ShikijiTransformerContextMeta {} diff --git a/packages/shikiji/scripts/prepare.ts b/packages/shikiji/scripts/prepare.ts index dd102bd7..5fd28788 100644 --- a/packages/shikiji/scripts/prepare.ts +++ b/packages/shikiji/scripts/prepare.ts @@ -4,5 +4,7 @@ import { prepareTheme } from './prepare/themes' await fs.ensureDir('./src/assets/langs') await fs.emptyDir('./src/assets/langs') +await fs.ensureDir('./src/assets/themes') +await fs.emptyDir('./src/assets/themes') await prepareLangs() await prepareTheme() diff --git a/packages/shikiji/scripts/prepare/injections.ts b/packages/shikiji/scripts/prepare/injections.ts index 55332a07..f4a500c2 100644 --- a/packages/shikiji/scripts/prepare/injections.ts +++ b/packages/shikiji/scripts/prepare/injections.ts @@ -3,6 +3,7 @@ import fs from 'fs-extra' import { fetch } from 'ofetch' import { COMMENT_HEAD } from './constants' +import { cleanupLanguageReg } from './utils' interface Injection { name: string @@ -24,7 +25,9 @@ export async function prepareInjections() { `${COMMENT_HEAD} import type { LanguageRegistration } from 'shikiji-core' -export default ${JSON.stringify(injection.contents, null, 2)} as unknown as LanguageRegistration[] +export default [ + ${injection.contents.map(i => `Object.freeze(${JSON.stringify(i, null, 2)})`).join(',\n')} +] as unknown as LanguageRegistration[] `, 'utf-8', ) @@ -41,11 +44,11 @@ export async function prepareVueInjections(): Promise { .filter(i => i.injectTo) .map(async (i) => { const content = await fetchJson(`${new URL(i.path, base).href}?raw=true`) - return { + return cleanupLanguageReg({ ...content, name: i.language, injectTo: i.injectTo, - } + }) }), ) diff --git a/packages/shikiji/scripts/prepare/langs.ts b/packages/shikiji/scripts/prepare/langs.ts index b9ab232e..1101963d 100644 --- a/packages/shikiji/scripts/prepare/langs.ts +++ b/packages/shikiji/scripts/prepare/langs.ts @@ -3,6 +3,7 @@ import { BUNDLED_LANGUAGES } from 'shiki' import fg from 'fast-glob' import type { LanguageRegistration } from 'shikiji-core' import { COMMENT_HEAD } from './constants' +import { cleanupLanguageReg } from './utils' import { prepareInjections } from './injections' export async function prepareLangs() { @@ -24,7 +25,7 @@ export async function prepareLangs() { continue } - const json: LanguageRegistration = { + const json: LanguageRegistration = cleanupLanguageReg({ ...content, name: content.name || lang.id, scopeName: content.scopeName || lang.scopeName, @@ -33,7 +34,7 @@ export async function prepareLangs() { embeddedLangs: lang.embeddedLangs, balancedBracketSelectors: lang.balancedBracketSelectors, unbalancedBracketSelectors: lang.unbalancedBracketSelectors, - } + }) // F# and Markdown has circular dependency if (lang.id === 'fsharp' && json.embeddedLangs) @@ -49,7 +50,7 @@ import type { LanguageRegistration } from 'shikiji-core' ${deps.map(i => `import ${i.replace(/[^\w]/g, '_')} from './${i}'`).join('\n')} -const lang = Object.freeze(${JSON.stringify(json)}) as unknown as LanguageRegistration +const lang = Object.freeze(${JSON.stringify(json, null, 2)}) as unknown as LanguageRegistration export default [ ${[ @@ -102,16 +103,6 @@ export const bundledLanguages = { `, 'utf-8', ) - - await fs.writeJSON( - `src/assets/${fileName}.json`, - BUNDLED_LANGUAGES.map(i => ({ - id: i.id, - name: i.displayName, - aliases: i.aliases, - })), - { spaces: 2 }, - ) } await writeLanguageBundleIndex('langs', BUNDLED_LANGUAGES.map(i => i.id)) diff --git a/packages/shikiji/scripts/prepare/themes.ts b/packages/shikiji/scripts/prepare/themes.ts index 3c0abf49..ff39a659 100644 --- a/packages/shikiji/scripts/prepare/themes.ts +++ b/packages/shikiji/scripts/prepare/themes.ts @@ -1,23 +1,37 @@ import fs from 'fs-extra' import { BUNDLED_THEMES } from 'shiki' import { COMMENT_HEAD } from './constants' +import { cleanupThemeReg } from './utils' const allThemes = BUNDLED_THEMES .sort() .filter(i => i !== 'css-variables') export async function prepareTheme() { - const themes = allThemes - .map((id) => { - const theme = fs.readJSONSync(`./node_modules/shiki/themes/${id}.json`) + const themes = await Promise.all(allThemes + .map(async (id) => { + const theme = cleanupThemeReg(await fs.readJSON(`./node_modules/shiki/themes/${id}.json`)) + + theme.displayName = guessThemeName(id, theme) + theme.type = guessThemeType(id, theme) + + await fs.writeFile( + `./src/assets/themes/${id}.ts`, + `${COMMENT_HEAD} +import type { ThemeRegistration } from 'shikiji-core' + +export default Object.freeze(${JSON.stringify(theme, null, 2)}) as unknown as ThemeRegistration +`, + 'utf-8', + ) return { id, - name: guessThemeName(id, theme), - type: guessThemeType(id, theme), - import: `__(() => import('shiki/themes/${id}.json')) as unknown as DynamicThemeReg__`, + displayName: theme.displayName, + type: theme.type, + import: `__(() => import('./themes/${id}')) as unknown as DynamicThemeReg__`, } - }) + })) await fs.writeFile( 'src/assets/themes.ts', `${COMMENT_HEAD} @@ -27,7 +41,7 @@ type DynamicThemeReg = () => Promise<{ default: ThemeRegistrationRaw }> export interface BundledThemeInfo { id: string - name: string + displayName: string type: 'light' | 'dark' import: DynamicThemeReg } @@ -40,12 +54,6 @@ export const bundledThemes = Object.fromEntries(bundledThemesInfo.map(i => [i.id `, 'utf-8', ) - await fs.writeJSON( - 'src/assets/themes.json', - allThemes - .map(i => ({ id: i })), - { spaces: 2 }, - ) } function isLightColor(hex: string) { @@ -54,6 +62,8 @@ function isLightColor(hex: string) { } function guessThemeType(id: string, theme: any) { + if ('type' in theme) + return theme.type let color if (id.includes('dark') || id.includes('dimmed') || id.includes('black')) color = 'dark' diff --git a/packages/shikiji/scripts/prepare/utils.ts b/packages/shikiji/scripts/prepare/utils.ts new file mode 100644 index 00000000..76cc0bae --- /dev/null +++ b/packages/shikiji/scripts/prepare/utils.ts @@ -0,0 +1,64 @@ +import type { LanguageRegistration, ThemeRegistration } from 'shikiji-core' + +export function objectPick>( + obj: T, + keys: (keyof T)[], + onRemoval?: (obj: T, key: string, value: any) => void, +): T { + return Object.fromEntries( + Array.from( + Object.entries(obj) + .filter((i) => { + if (keys.includes(i[0])) + return true + onRemoval?.(obj, ...i) + return false + }), + ), + ) as T +} + +export function cleanupLanguageReg(lang: LanguageRegistration) { + return objectPick( + lang, + [ + 'aliases', + 'balancedBracketSelectors', + 'displayName', + 'embeddedLangs', + 'fileTypes', + 'firstLineMatch', + 'injections', + 'injectionSelector', + 'injectTo', + 'name', + 'patterns', + 'repository', + 'scopeName', + 'foldingStopMarker', + 'foldingStartMarker', + 'unbalancedBracketSelectors', + ], + // (_, key, value) => console.log('lang key removal', key, '|', value), + ) +} + +export function cleanupThemeReg(theme: ThemeRegistration) { + return objectPick( + theme, + [ + 'name', + 'type', + 'colors', + 'fg', + 'bg', + 'include', + 'settings', + + 'tokenColors', + 'semanticHighlighting', + 'semanticTokenColors', + ], + // (_, key, value) => console.log('theme key removal', key, value), + ) +} diff --git a/packages/shikiji/src/assets/themes.ts b/packages/shikiji/src/assets/themes.ts index 23e9ebaa..dbae470e 100644 --- a/packages/shikiji/src/assets/themes.ts +++ b/packages/shikiji/src/assets/themes.ts @@ -7,7 +7,7 @@ type DynamicThemeReg = () => Promise<{ default: ThemeRegistrationRaw }> export interface BundledThemeInfo { id: string - name: string + displayName: string type: 'light' | 'dark' import: DynamicThemeReg } @@ -15,171 +15,171 @@ export interface BundledThemeInfo { export const bundledThemesInfo: BundledThemeInfo[] = [ { "id": "dark-plus", - "name": "Dark Plus", + "displayName": "Dark Plus", "type": "dark", - "import": (() => import('shiki/themes/dark-plus.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/dark-plus')) as unknown as DynamicThemeReg }, { "id": "dracula", - "name": "Dracula", + "displayName": "Dracula", "type": "dark", - "import": (() => import('shiki/themes/dracula.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/dracula')) as unknown as DynamicThemeReg }, { "id": "dracula-soft", - "name": "Dracula Soft", + "displayName": "Dracula Soft", "type": "dark", - "import": (() => import('shiki/themes/dracula-soft.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/dracula-soft')) as unknown as DynamicThemeReg }, { "id": "github-dark", - "name": "GitHub Dark", + "displayName": "GitHub Dark", "type": "dark", - "import": (() => import('shiki/themes/github-dark.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/github-dark')) as unknown as DynamicThemeReg }, { "id": "github-dark-dimmed", - "name": "GitHub Dark Dimmed", + "displayName": "GitHub Dark Dimmed", "type": "dark", - "import": (() => import('shiki/themes/github-dark-dimmed.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/github-dark-dimmed')) as unknown as DynamicThemeReg }, { "id": "github-light", - "name": "GitHub Light", + "displayName": "GitHub Light", "type": "light", - "import": (() => import('shiki/themes/github-light.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/github-light')) as unknown as DynamicThemeReg }, { "id": "light-plus", - "name": "Light Plus", + "displayName": "Light Plus", "type": "light", - "import": (() => import('shiki/themes/light-plus.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/light-plus')) as unknown as DynamicThemeReg }, { "id": "material-theme", - "name": "Material Theme", + "displayName": "Material Theme", "type": "dark", - "import": (() => import('shiki/themes/material-theme.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/material-theme')) as unknown as DynamicThemeReg }, { "id": "material-theme-darker", - "name": "Material Theme Darker", + "displayName": "Material Theme Darker", "type": "dark", - "import": (() => import('shiki/themes/material-theme-darker.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/material-theme-darker')) as unknown as DynamicThemeReg }, { "id": "material-theme-lighter", - "name": "Material Theme Lighter", + "displayName": "Material Theme Lighter", "type": "light", - "import": (() => import('shiki/themes/material-theme-lighter.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/material-theme-lighter')) as unknown as DynamicThemeReg }, { "id": "material-theme-ocean", - "name": "Material Theme Ocean", + "displayName": "Material Theme Ocean", "type": "dark", - "import": (() => import('shiki/themes/material-theme-ocean.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/material-theme-ocean')) as unknown as DynamicThemeReg }, { "id": "material-theme-palenight", - "name": "Material Theme Palenight", + "displayName": "Material Theme Palenight", "type": "dark", - "import": (() => import('shiki/themes/material-theme-palenight.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/material-theme-palenight')) as unknown as DynamicThemeReg }, { "id": "min-dark", - "name": "Min Dark", + "displayName": "Min Dark", "type": "dark", - "import": (() => import('shiki/themes/min-dark.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/min-dark')) as unknown as DynamicThemeReg }, { "id": "min-light", - "name": "Min Light", + "displayName": "Min Light", "type": "light", - "import": (() => import('shiki/themes/min-light.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/min-light')) as unknown as DynamicThemeReg }, { "id": "monokai", - "name": "Monokai", + "displayName": "Monokai", "type": "dark", - "import": (() => import('shiki/themes/monokai.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/monokai')) as unknown as DynamicThemeReg }, { "id": "nord", - "name": "Nord", + "displayName": "Nord", "type": "dark", - "import": (() => import('shiki/themes/nord.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/nord')) as unknown as DynamicThemeReg }, { "id": "one-dark-pro", - "name": "One Dark Pro", + "displayName": "One Dark Pro", "type": "dark", - "import": (() => import('shiki/themes/one-dark-pro.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/one-dark-pro')) as unknown as DynamicThemeReg }, { "id": "poimandres", - "name": "Poimandres", + "displayName": "Poimandres", "type": "dark", - "import": (() => import('shiki/themes/poimandres.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/poimandres')) as unknown as DynamicThemeReg }, { "id": "rose-pine", - "name": "Rosé Pine", + "displayName": "Rosé Pine", "type": "dark", - "import": (() => import('shiki/themes/rose-pine.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/rose-pine')) as unknown as DynamicThemeReg }, { "id": "rose-pine-dawn", - "name": "Rosé Pine Dawn", + "displayName": "Rosé Pine Dawn", "type": "light", - "import": (() => import('shiki/themes/rose-pine-dawn.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/rose-pine-dawn')) as unknown as DynamicThemeReg }, { "id": "rose-pine-moon", - "name": "Rosé Pine Moon", + "displayName": "Rosé Pine Moon", "type": "dark", - "import": (() => import('shiki/themes/rose-pine-moon.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/rose-pine-moon')) as unknown as DynamicThemeReg }, { "id": "slack-dark", - "name": "Slack Dark", + "displayName": "Slack Dark", "type": "dark", - "import": (() => import('shiki/themes/slack-dark.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/slack-dark')) as unknown as DynamicThemeReg }, { "id": "slack-ochin", - "name": "Slack Ochin", - "type": "light", - "import": (() => import('shiki/themes/slack-ochin.json')) as unknown as DynamicThemeReg + "displayName": "Slack Ochin", + "type": "dark", + "import": (() => import('./themes/slack-ochin')) as unknown as DynamicThemeReg }, { "id": "solarized-dark", - "name": "Solarized Dark", + "displayName": "Solarized Dark", "type": "dark", - "import": (() => import('shiki/themes/solarized-dark.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/solarized-dark')) as unknown as DynamicThemeReg }, { "id": "solarized-light", - "name": "Solarized Light", + "displayName": "Solarized Light", "type": "light", - "import": (() => import('shiki/themes/solarized-light.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/solarized-light')) as unknown as DynamicThemeReg }, { "id": "vitesse-black", - "name": "Vitesse Black", + "displayName": "Vitesse Black", "type": "dark", - "import": (() => import('shiki/themes/vitesse-black.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/vitesse-black')) as unknown as DynamicThemeReg }, { "id": "vitesse-dark", - "name": "Vitesse Dark", + "displayName": "Vitesse Dark", "type": "dark", - "import": (() => import('shiki/themes/vitesse-dark.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/vitesse-dark')) as unknown as DynamicThemeReg }, { "id": "vitesse-light", - "name": "Vitesse Light", + "displayName": "Vitesse Light", "type": "light", - "import": (() => import('shiki/themes/vitesse-light.json')) as unknown as DynamicThemeReg + "import": (() => import('./themes/vitesse-light')) as unknown as DynamicThemeReg } ]