Формат tmTheme по-прежнему поддерживается в расширениях тем и конвертируется при импорте (насколько я помню). Однако основное определение темы в расширении использует подход, подобный показанному в dark_plus.json.
Довольно легко преобразовать формат json в структуру, которую ожидает редактор monaco:
export interface Colors { [key: string]: string }
export interface ITokenEntry {
name?: string;
scope: string[] | string;
settings: {
foreground?: string;
background?: string;
fontStyle?: string;
};
}
// This is the structure of a vscode theme file.
export interface IThemeObject {
name: string;
type?: string;
include?: string;
colors?: Colors;
settings?: ITokenEntry[]; // Old style specification.
tokenColors?: ITokenEntry[]; // This is how it should be done now.
}
Эти интерфейсы описывают формат файла json. В более старых определениях темы для определения цветов темы используется член settings
. В таком случае просто установите член tokenColors
на член settings
и продолжайте.
После загрузки темы вы можете использовать этот статический метод, чтобы загрузить ее в редактор monaco:
/**
* Updates the theme used by all code editor instances.
*
* @param theme The theme name.
* @param type The base type of the theme.
* @param values The actual theme values.
*/
public static updateTheme(theme: string, type: "light" | "dark", values: IThemeObject): void {
// Convert all color values to CSS hex form.
const entries: { [key: string]: string } = {};
for (const [key, value] of Object.entries(values.colors || {})) {
entries[key] = colorToHex(value) || "";
}
const tokenRules: Monaco.ITokenThemeRule[] = [];
(values.tokenColors || []).forEach((value: ITokenEntry): void => {
const scopeValue = value.scope || [];
const scopes = Array.isArray(scopeValue) ? scopeValue : scopeValue.split(",");
scopes.forEach((scope: string): void => {
tokenRules.push({
token: scope,
foreground: colorToHex(value.settings.foreground),
background: colorToHex(value.settings.background),
fontStyle: value.settings.fontStyle,
});
});
});
CodeEditor.currentThemeId = theme.replace(/[^a-zA-Z]+/g, "-");
Monaco.defineTheme(CodeEditor.currentThemeId, {
base: type === "light" ? "vs" : "vs-dark",
inherit: true,
rules: tokenRules,
colors: entries,
});
Monaco.setTheme(CodeEditor.currentThemeId);
}
CodeEditor
- это мой класс TS, который является оболочкой для редактора monaco. Функция colorToHex
определяется как:
import Color from "color";
/**
* Converts a color string or a color to a hex string.
*
* @param color The value to convert.
*
* @returns A hex string of the given color, including the alpha value.
*/
export const colorToHex = (color: string | Color | undefined): string | undefined => {
if (!color) {
return;
}
if (typeof color === "string") {
color = new Color(color);
}
// Hex color values have no alpha component, so we have to add that explicitly.
if (color.alpha() < 1) {
let alpha = Math.round((color.alpha() * 255)).toString(16);
if (alpha.length < 2) {
alpha = "0" + alpha;
}
return color.hex() + alpha;
} else {
return color.hex();
}
};
person
Mike Lischke
schedule
30.01.2021