| author | |
| committer | |
| log | 1905846e03226582f64fec16e1500ddffa151fdf |
| tree | 8df3ec7100f8b2d26b5868184735269e10f15279 |
| parent | 9da066dbe906310671b86290b09df0b56a88ffa5 |
| signature | Signed by PGP key B5690EEEBB952194 |
2 files changed, 40 insertions(+), 3 deletions(-)
apps/web/src/vscodeThemeImport.test.ts+30| ... | ... | @@ -112,6 +112,36 @@ describe("VS Code theme import", () => { |
| 112 | 112 | ); |
| 113 | 113 | }); |
| 114 | 114 | |
| 115 | it("moves reserved VS Code names to a non-reserved id", () => { | |
| 116 | const darkPlus = parseVsCodeThemeFile({ | |
| 117 | name: "Dark+", | |
| 118 | type: "dark", | |
| 119 | colors: { "editor.background": "#1e1e1e" }, | |
| 120 | }); | |
| 121 | expect(darkPlus.label).toBe("Dark+"); | |
| 122 | expect(darkPlus.id).not.toBe("dark"); | |
| 123 | expect(darkPlus.id).toBe("dark-vscode"); | |
| 124 | }); | |
| 125 | ||
| 126 | it("keeps Dark+ and Light+ as separate themes instead of pairing them as +", () => { | |
| 127 | const themes = pairVsCodeThemes([ | |
| 128 | parseVsCodeThemeFile({ | |
| 129 | name: "Light+", | |
| 130 | type: "light", | |
| 131 | colors: { "editor.background": "#ffffff" }, | |
| 132 | }), | |
| 133 | parseVsCodeThemeFile({ | |
| 134 | name: "Dark+", | |
| 135 | type: "dark", | |
| 136 | colors: { "editor.background": "#1e1e1e" }, | |
| 137 | }), | |
| 138 | ]); | |
| 139 | expect(themes.map((theme) => [theme.id, theme.label])).toEqual([ | |
| 140 | ["light-vscode", "Light+"], | |
| 141 | ["dark-vscode", "Dark+"], | |
| 142 | ]); | |
| 143 | }); | |
| 144 | ||
| 115 | 145 | it("fills every role the file omits with a readable derived value", () => { |
| 116 | 146 | const theme = parseVsCodeThemeFile(VSCODE_DARK); |
| 117 | 147 | const colors = getThemeColorsForMode(theme, "dark")!; |
apps/web/src/vscodeThemeImport.ts+10-3| ... | ... | @@ -1,8 +1,10 @@ |
| 1 | 1 | import { |
| 2 | 2 | createVividThemeColors, |
| 3 | 3 | getThemeModes, |
| 4 | isReservedThemeId, | |
| 4 | 5 | parseThemeFile, |
| 5 | 6 | themeColorToHex, |
| 7 | themeIdFromName, | |
| 6 | 8 | THEME_FILE_VERSION, |
| 7 | 9 | type ThemeAppearance, |
| 8 | 10 | type ThemeColorRole, |
| ... | ... | @@ -321,9 +323,12 @@ export function parseVsCodeThemeFile(value: unknown): ThemeDefinition { |
| 321 | 323 | |
| 322 | 324 | // Reuse the theme-file parser so ids, names, and color values go through the |
| 323 | 325 | // same validation as a hand-written file. |
| 326 | const name = resolveName(value); | |
| 327 | const generatedId = themeIdFromName(name); | |
| 324 | 328 | return parseThemeFile({ |
| 325 | 329 | version: THEME_FILE_VERSION, |
| 326 | name: resolveName(value), | |
| 330 | ...(isReservedThemeId(generatedId) ? { id: `${generatedId}-vscode` } : {}), | |
| 331 | name, | |
| 327 | 332 | appearance, |
| 328 | 333 | colors: { ...derived, ...overrides }, |
| 329 | 334 | }); |
| ... | ... | @@ -352,9 +357,11 @@ export function pairVsCodeThemes( |
| 352 | 357 | const passthrough: Array<{ theme: ThemeDefinition; order: number }> = []; |
| 353 | 358 | themes.forEach((theme, order) => { |
| 354 | 359 | // Only single-appearance themes with an appearance word in the name can |
| 355 | // pair; anything else is already what the user asked for. | |
| 360 | // pair, and only when the rest of the name can still identify the pair | |
| 361 | // ("Dark+" and "Light+" would pair as "+"); anything else is already | |
| 362 | // what the user asked for. | |
| 356 | 363 | const key = stripAppearance(theme.label); |
| 357 | if (getThemeModes(theme).length !== 1 || key === theme.label || key.length === 0) { | |
| 364 | if (getThemeModes(theme).length !== 1 || key === theme.label || !/[a-z0-9]/i.test(key)) { | |
| 358 | 365 | passthrough.push({ theme, order }); |
| 359 | 366 | return; |
| 360 | 367 | } |