Файли
openidea/scripts/theme/import-intellij-theme.ts
T
l0ng-ai 30310810e6 feat(plugins): Theme plugin template, theme docs and IntelliJ theme import (#54)
Per the maintainer's decision for #24, no third-party themes are bundled; instead a theme plugin template and docs let the community port themes (IntelliJ also ships few themes, the rest are plugins).
- templates/theme-plugin: manifest-only plugin with an original example (Harbor Night) covering every UI token and an editor scheme (.icls equivalent).
- docs/plugins/themes.md: format, IntelliJ / VS Code porting tables, generated token reference (pnpm gen:theme-docs); drift test fails when tokens.css and the template/reference disagree.
- pnpm theme:import-intellij: dependency-free converter for IntelliJ .theme.json (+ .icls).
- Plugin host: themes may name an editor-scheme merged over the theme; comments allowed in theme files.
- Fixes: a plugin theme's kind now switches the light/dark base; plugin themes go in their own stylesheet so the Appearance accent and editor scheme still layer on top.
Verified: ide-plugin tests, vitest (44), in-app on macOS: installed the template from disk, applied Harbor Night (dark base + teal accent over Islands Light), back to default restored the light theme.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 10:39:08 +08:00

53 рядки
2.1 KiB
TypeScript
Неформатований Анотація Історія

Цей файл містить неоднозначні символи Юнікоду
Цей файл містить символи Юнікоду, які можна сплутати з іншими символами. Якщо ви вважаєте, що це зроблено навмисно, можете сміливо ігнорувати це попередження. Щоб показати їх, скористайтеся кнопкою Escape.
/**
* Converts an IntelliJ theme into an OpenIDEA theme plugin package.
*
* pnpm theme:import-intellij <file.theme.json> [file.icls] --out <dir> [--id <id>] [--author <name>]
*
* Writes <dir>/plugin.toml and <dir>/themes/<id>.theme.json (+ .scheme.json),
* ready for Settings › Plugins › Install Plugin from Disk…. Only port themes
* whose licence allows it, and credit the original author.
*/
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { basename, join } from "node:path";
import { parseArgs } from "node:util";
import { convertIntellijTheme, pluginManifest } from "./intellij.ts";
const { values, positionals } = parseArgs({
allowPositionals: true,
options: { out: { type: "string" }, id: { type: "string" }, author: { type: "string" } },
});
const [themePath, iclsPath] = positionals;
if (!themePath || !values.out) {
console.error(
"usage: pnpm theme:import-intellij <file.theme.json> [file.icls] --out <dir> [--id <id>] [--author <name>]",
);
process.exit(2);
}
const converted = convertIntellijTheme(
readFileSync(themePath, "utf8"),
iclsPath ? readFileSync(iclsPath, "utf8") : undefined,
values.id,
);
const { theme, scheme } = converted;
const source = [basename(themePath), iclsPath && basename(iclsPath)].filter(Boolean).join(" + ");
const header = (what: string) => `// ${theme.name}: ${what}, converted from ${source}.\n`;
mkdirSync(join(values.out, "themes"), { recursive: true });
writeFileSync(join(values.out, "plugin.toml"), pluginManifest(converted, values.author ?? "Unknown", source));
writeFileSync(
join(values.out, "themes", `${theme.id}.theme.json`),
header("UI theme") + JSON.stringify(theme, null, 2) + "\n",
);
if (scheme) {
writeFileSync(
join(values.out, "themes", `${theme.id}.scheme.json`),
header("editor colour scheme") + JSON.stringify(scheme, null, 2) + "\n",
);
}
console.log(
`${theme.name} (${theme.kind}): ${Object.keys(theme.tokens).length} UI tokens` +
(scheme ? `, ${Object.keys(scheme.tokens).length} editor tokens` : "") +
` → ${values.out}\nUnmapped tokens keep the built-in ${theme.kind} values; see docs/plugins/themes.md to fill them in.`,
);