mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-21 08:42:53 +02:00
Merge pull request #2876 from nickofolas/feature/monaco-theme-editor
[Feature] Script Editor Theme Customization
This commit is contained in:
@@ -1,3 +1,216 @@
|
||||
export interface IScriptEditorTheme {
|
||||
[key: string]: any;
|
||||
base: string;
|
||||
inherit: boolean;
|
||||
common: {
|
||||
[key: string]: string;
|
||||
accent: string;
|
||||
bg: string;
|
||||
fg: string;
|
||||
};
|
||||
syntax: {
|
||||
[key: string]: string;
|
||||
tag: string;
|
||||
entity: string;
|
||||
string: string;
|
||||
regexp: string;
|
||||
markup: string;
|
||||
keyword: string;
|
||||
comment: string;
|
||||
constant: string;
|
||||
error: string;
|
||||
};
|
||||
ui: {
|
||||
[key: string]: any;
|
||||
line: string;
|
||||
panel: {
|
||||
[key: string]: string;
|
||||
bg: string;
|
||||
selected: string;
|
||||
border: string;
|
||||
};
|
||||
selection: {
|
||||
[key: string]: string;
|
||||
bg: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const defaultMonacoTheme: IScriptEditorTheme = {
|
||||
base: "vs-dark",
|
||||
inherit: true,
|
||||
common: {
|
||||
accent: "B5CEA8",
|
||||
bg: "1E1E1E",
|
||||
fg: "D4D4D4",
|
||||
},
|
||||
syntax: {
|
||||
tag: "569CD6",
|
||||
entity: "569CD6",
|
||||
string: "CE9178",
|
||||
regexp: "646695",
|
||||
markup: "569CD6",
|
||||
keyword: "569CD6",
|
||||
comment: "6A9955",
|
||||
constant: "569CD6",
|
||||
error: "F44747"
|
||||
},
|
||||
ui: {
|
||||
line: "1E1E1E",
|
||||
panel: {
|
||||
bg: "252526",
|
||||
selected: "252526",
|
||||
border: "1E1E1E"
|
||||
},
|
||||
selection: {
|
||||
bg: "ADD6FF26"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Regex used for token color validation
|
||||
// https://github.com/microsoft/vscode/blob/973684056e67153952f495fce93bf50d0ec0b892/src/vs/editor/common/languages/supports/tokenization.ts#L153
|
||||
const colorRegExp = /^#?([0-9A-Fa-f]{6})([0-9A-Fa-f]{2})?$/;
|
||||
|
||||
// Recursively sanitize the theme data to prevent errors
|
||||
// Invalid data will be replaced with FF0000 (bright red)
|
||||
export const sanitizeTheme = (theme: IScriptEditorTheme): void => {
|
||||
for (const [k, v] of Object.entries(theme)) {
|
||||
switch (k) {
|
||||
case "base":
|
||||
if (!["vs-dark", "vs"].includes(theme.base)) theme.base = "vs-dark";
|
||||
continue;
|
||||
case "inherit":
|
||||
if (typeof theme.inherit !== "boolean") theme.inherit = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
const repairBlock = (block: { [key: string]: any }): void => {
|
||||
for (const [k, v] of Object.entries(block)) {
|
||||
if (typeof v === "object") {
|
||||
repairBlock(v as { [key: string]: string });
|
||||
} else {
|
||||
if (!v.match(colorRegExp)) block[k] = "FF0000";
|
||||
}
|
||||
}
|
||||
}
|
||||
repairBlock(v);
|
||||
}
|
||||
}
|
||||
|
||||
export function makeTheme(theme: IScriptEditorTheme): any {
|
||||
const themeRules = [
|
||||
{
|
||||
token: "",
|
||||
background: theme.ui.line,
|
||||
foreground: theme.common.fg
|
||||
},
|
||||
{
|
||||
token: "identifier",
|
||||
foreground: theme.common.accent
|
||||
},
|
||||
{
|
||||
token: "keyword",
|
||||
foreground: theme.syntax.keyword
|
||||
},
|
||||
{
|
||||
token: "string",
|
||||
foreground: theme.syntax.string
|
||||
},
|
||||
{
|
||||
token: "string.escape",
|
||||
foreground: theme.syntax.regexp
|
||||
},
|
||||
{
|
||||
token: "comment",
|
||||
foreground: theme.syntax.comment
|
||||
},
|
||||
{
|
||||
token: "constant",
|
||||
foreground: theme.syntax.constant
|
||||
},
|
||||
{
|
||||
token: "entity",
|
||||
foreground: theme.syntax.entity
|
||||
},
|
||||
{
|
||||
token: "type",
|
||||
foreground: theme.syntax.tag
|
||||
},
|
||||
{
|
||||
token: "tag",
|
||||
foreground: theme.syntax.tag
|
||||
},
|
||||
{
|
||||
token: "regexp",
|
||||
foreground: theme.syntax.regexp
|
||||
},
|
||||
{
|
||||
token: "attribute",
|
||||
foreground: theme.syntax.tag
|
||||
},
|
||||
{
|
||||
token: "constructor",
|
||||
foreground: theme.syntax.markup
|
||||
},
|
||||
{
|
||||
token: "invalid",
|
||||
foreground: theme.syntax.error
|
||||
},
|
||||
{
|
||||
token: "number",
|
||||
foreground: theme.common.accent
|
||||
},
|
||||
{
|
||||
token: "delimiter",
|
||||
foreground: theme.common.fg
|
||||
},
|
||||
// Custom tokens
|
||||
{
|
||||
token: "ns",
|
||||
foreground: theme.syntax.tag
|
||||
},
|
||||
{
|
||||
token: "netscriptfunction",
|
||||
foreground: theme.syntax.markup
|
||||
},
|
||||
{
|
||||
token: "otherkeywords",
|
||||
foreground: theme.syntax.keyword
|
||||
},
|
||||
{
|
||||
token: "otherkeyvars",
|
||||
foreground: theme.common.accent
|
||||
},
|
||||
{
|
||||
token: "this",
|
||||
foreground: theme.syntax.tag
|
||||
}
|
||||
];
|
||||
|
||||
const themeColors = Object.fromEntries([
|
||||
["editor.background", theme.common.bg],
|
||||
["editor.foreground", theme.common.fg],
|
||||
["editor.lineHighlightBackground", theme.ui.line],
|
||||
["editor.selectionBackground", theme.ui.selection.bg],
|
||||
|
||||
["editorSuggestWidget.background", theme.ui.panel.bg],
|
||||
["editorSuggestWidget.border", theme.ui.panel.border],
|
||||
["editorSuggestWidget.selectedBackground", theme.ui.panel.selected],
|
||||
|
||||
["editorHoverWidget.background", theme.ui.panel.bg],
|
||||
["editorHoverWidget.border", theme.ui.panel.border],
|
||||
|
||||
["editorWidget.background", theme.ui.panel.bg],
|
||||
["editorWidget.border", theme.ui.panel.border],
|
||||
|
||||
["input.background", theme.ui.panel.bg],
|
||||
["input.border", theme.ui.panel.border]
|
||||
].map(([k, v]) => [k, "#" + v]));
|
||||
|
||||
return { base: theme.base, inherit: theme.inherit, rules: themeRules, colors: themeColors }
|
||||
}
|
||||
|
||||
export async function loadThemes(monaco: { editor: any }): Promise<void> {
|
||||
monaco.editor.defineTheme("monokai", {
|
||||
base: "vs-dark",
|
||||
|
||||
Reference in New Issue
Block a user