Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions apps/web/src/vscodeThemeImport.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,36 @@ describe("VS Code theme import", () => {
);
});

it("moves reserved VS Code names to a non-reserved id", () => {
const darkPlus = parseVsCodeThemeFile({
name: "Dark+",
type: "dark",
colors: { "editor.background": "#1e1e1e" },
});
expect(darkPlus.label).toBe("Dark+");
expect(darkPlus.id).not.toBe("dark");
expect(darkPlus.id).toBe("dark-vscode");
});

it("keeps Dark+ and Light+ as separate themes instead of pairing them as +", () => {
const themes = pairVsCodeThemes([
parseVsCodeThemeFile({
name: "Light+",
type: "light",
colors: { "editor.background": "#ffffff" },
}),
parseVsCodeThemeFile({
name: "Dark+",
type: "dark",
colors: { "editor.background": "#1e1e1e" },
}),
]);
expect(themes.map((theme) => [theme.id, theme.label])).toEqual([
["light-vscode", "Light+"],
["dark-vscode", "Dark+"],
]);
});

it("fills every role the file omits with a readable derived value", () => {
const theme = parseVsCodeThemeFile(VSCODE_DARK);
const colors = getThemeColorsForMode(theme, "dark")!;
Expand Down
13 changes: 10 additions & 3 deletions apps/web/src/vscodeThemeImport.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {
createVividThemeColors,
getThemeModes,
isReservedThemeId,
parseThemeFile,
themeColorToHex,
themeIdFromName,
THEME_FILE_VERSION,
type ThemeAppearance,
type ThemeColorRole,
Expand Down Expand Up @@ -321,9 +323,12 @@ export function parseVsCodeThemeFile(value: unknown): ThemeDefinition {

// Reuse the theme-file parser so ids, names, and color values go through the
// same validation as a hand-written file.
const name = resolveName(value);
const generatedId = themeIdFromName(name);
return parseThemeFile({
version: THEME_FILE_VERSION,
name: resolveName(value),
...(isReservedThemeId(generatedId) ? { id: `${generatedId}-vscode` } : {}),
Comment thread
macroscopeapp[bot] marked this conversation as resolved.
name,
appearance,
colors: { ...derived, ...overrides },
});
Expand Down Expand Up @@ -352,9 +357,11 @@ export function pairVsCodeThemes(
const passthrough: Array<{ theme: ThemeDefinition; order: number }> = [];
themes.forEach((theme, order) => {
// Only single-appearance themes with an appearance word in the name can
// pair; anything else is already what the user asked for.
// pair, and only when the rest of the name can still identify the pair
// ("Dark+" and "Light+" would pair as "+"); anything else is already
// what the user asked for.
const key = stripAppearance(theme.label);
if (getThemeModes(theme).length !== 1 || key === theme.label || key.length === 0) {
if (getThemeModes(theme).length !== 1 || key === theme.label || !/[a-z0-9]/i.test(key)) {
passthrough.push({ theme, order });
return;
}
Expand Down
Loading