bitburner-src/src/ScriptEditor/ui/themes.ts

628 lines
15 KiB
TypeScript
Raw Normal View History

import type { editor } from "monaco-editor";
import { getRecordKeys } from "../../Types/Record";
import { Settings } from "../../Settings/Settings";
type DefineThemeFn = typeof editor.defineTheme;
2022-07-20 02:10:30 +02:00
2022-01-30 02:27:49 +01:00
export interface IScriptEditorTheme {
2022-07-20 02:10:30 +02:00
base: "vs" | "vs-dark" | "hc-black";
2022-01-30 02:27:49 +01:00
inherit: boolean;
common: {
accent: string;
bg: string;
fg: string;
};
syntax: {
tag: string;
entity: string;
string: string;
regexp: string;
markup: string;
keyword: string;
comment: string;
constant: string;
error: string;
};
ui: {
line: string;
panel: {
bg: string;
2022-01-30 05:39:13 +01:00
selected: string;
2022-01-30 02:27:49 +01:00
border: string;
};
selection: {
bg: string;
};
};
}
export const defaultMonacoTheme: IScriptEditorTheme = {
base: "vs-dark",
inherit: true,
common: {
accent: "B5CEA8",
2022-01-30 02:27:49 +01:00
bg: "1E1E1E",
fg: "D4D4D4",
},
syntax: {
tag: "569CD6",
entity: "569CD6",
string: "CE9178",
2022-01-30 02:27:49 +01:00
regexp: "646695",
markup: "569CD6",
keyword: "569CD6",
2022-01-30 02:27:49 +01:00
comment: "6A9955",
constant: "569CD6",
2022-04-13 21:42:07 +02:00
error: "F44747",
2022-01-30 02:27:49 +01:00
},
ui: {
line: "1E1E1E",
panel: {
bg: "252526",
2022-01-30 05:39:13 +01:00
selected: "252526",
2022-04-13 21:42:07 +02:00
border: "1E1E1E",
2022-01-30 02:27:49 +01:00
},
selection: {
2022-04-13 21:42:07 +02:00
bg: "ADD6FF26",
},
},
};
2022-01-30 02:27:49 +01:00
// 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 => {
if (typeof theme !== "object") {
Settings.EditorTheme = defaultMonacoTheme;
return;
}
for (const themeKey of getRecordKeys(theme)) {
if (typeof theme[themeKey] !== "object") delete theme[themeKey];
switch (themeKey) {
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 block = theme[themeKey];
function repairBlock<T extends Record<string, unknown>>(block: T) {
for (const [blockKey, blockValue] of Object.entries(block) as [keyof T, unknown][]) {
if (!blockValue || (typeof blockValue !== "string" && typeof blockValue !== "object"))
(block[blockKey] as string) = "FF0000";
else if (typeof blockValue === "object") repairBlock(block);
else if (!blockValue.match(colorRegExp)) (block[blockKey] as string) = "FF0000";
}
}
// Type assertion is to something less specific.
repairBlock(block);
}
2022-04-13 21:42:07 +02:00
};
export function makeTheme(theme: IScriptEditorTheme): editor.IStandaloneThemeData {
2022-01-30 02:27:49 +01:00
const themeRules = [
{
token: "",
background: theme.ui.line,
2022-04-13 21:42:07 +02:00
foreground: theme.common.fg,
2022-01-30 02:27:49 +01:00
},
{
token: "identifier",
2022-04-13 21:42:07 +02:00
foreground: theme.common.accent,
2022-01-30 02:27:49 +01:00
},
{
token: "keyword",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.keyword,
2022-01-30 02:27:49 +01:00
},
{
token: "string",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.string,
2022-01-30 02:27:49 +01:00
},
{
token: "string.escape",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.regexp,
2022-01-30 02:27:49 +01:00
},
{
token: "comment",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.comment,
2022-01-30 02:27:49 +01:00
},
{
token: "constant",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.constant,
2022-01-30 02:27:49 +01:00
},
{
token: "entity",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.entity,
2022-01-30 02:27:49 +01:00
},
2022-01-30 06:11:21 +01:00
{
token: "type",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.tag,
2022-01-30 06:11:21 +01:00
},
2022-01-30 02:27:49 +01:00
{
token: "tag",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.tag,
2022-01-30 02:27:49 +01:00
},
{
token: "regexp",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.regexp,
2022-01-30 02:27:49 +01:00
},
{
token: "attribute",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.tag,
2022-01-30 02:27:49 +01:00
},
{
token: "constructor",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.markup,
2022-01-30 02:27:49 +01:00
},
{
token: "invalid",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.error,
2022-01-30 02:27:49 +01:00
},
{
token: "number",
2022-04-13 21:42:07 +02:00
foreground: theme.common.accent,
2022-01-30 02:27:49 +01:00
},
{
token: "delimiter",
2022-04-13 21:42:07 +02:00
foreground: theme.common.fg,
2022-01-30 02:27:49 +01:00
},
// Custom tokens
{
token: "ns",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.tag,
2022-01-30 02:27:49 +01:00
},
{
token: "netscriptfunction",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.markup,
2022-01-30 02:27:49 +01:00
},
{
token: "otherkeywords",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.keyword,
2022-01-30 02:27:49 +01:00
},
{
token: "otherkeyvars",
2022-04-13 21:42:07 +02:00
foreground: theme.common.accent,
2022-01-30 02:27:49 +01:00
},
{
token: "this",
2022-04-13 21:42:07 +02:00
foreground: theme.syntax.tag,
},
2022-01-30 02:27:49 +01:00
];
2022-04-13 21:42:07 +02:00
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],
2022-01-30 02:27:49 +01:00
2022-04-13 21:42:07 +02:00
["editorSuggestWidget.background", theme.ui.panel.bg],
["editorSuggestWidget.border", theme.ui.panel.border],
["editorSuggestWidget.selectedBackground", theme.ui.panel.selected],
2022-01-30 02:27:49 +01:00
2022-04-13 21:42:07 +02:00
["editorHoverWidget.background", theme.ui.panel.bg],
["editorHoverWidget.border", theme.ui.panel.border],
2022-01-30 02:27:49 +01:00
2022-04-13 21:42:07 +02:00
["editorWidget.background", theme.ui.panel.bg],
["editorWidget.border", theme.ui.panel.border],
2022-01-30 02:27:49 +01:00
2022-04-13 21:42:07 +02:00
["input.background", theme.ui.panel.bg],
["input.border", theme.ui.panel.border],
].map(([k, v]) => [k, "#" + v]),
);
2022-01-30 02:27:49 +01:00
2022-04-13 21:42:07 +02:00
return { base: theme.base, inherit: theme.inherit, rules: themeRules, colors: themeColors };
2022-01-30 02:27:49 +01:00
}
export async function loadThemes(defineTheme: DefineThemeFn): Promise<void> {
defineTheme("monokai", {
2021-10-10 01:00:27 +02:00
base: "vs-dark",
inherit: true,
rules: [
{
background: "272822",
token: "",
},
{
foreground: "75715e",
token: "comment",
},
{
foreground: "e6db74",
token: "string",
},
{
token: "number",
foreground: "ae81ff",
},
2021-10-16 00:58:10 +02:00
{
token: "otherkeyvars",
foreground: "ae81ff",
},
2021-10-10 01:00:27 +02:00
{
foreground: "ae81ff",
token: "function",
},
{
foreground: "f92672",
token: "keyword",
},
{
token: "storage.type.function.js",
foreground: "ae81ff",
},
{
token: "ns",
foreground: "97d92b",
},
{
token: "netscriptfunction",
foreground: "53d3e4",
},
2021-10-16 00:58:10 +02:00
{
token: "otherkeywords",
foreground: "53d3e4",
},
{
token: "this",
foreground: "fd971f",
},
2021-10-10 01:00:27 +02:00
],
colors: {
"editor.foreground": "#F8F8F2",
"editor.background": "#272822",
"editor.selectionBackground": "#49483E",
"editor.lineHighlightBackground": "#3E3D32",
"editorCursor.foreground": "#F8F8F0",
"editorWhitespace.foreground": "#3B3A32",
"editorIndentGuide.activeBackground": "#9D550FB0",
"editor.selectionHighlightBorder": "#222218",
},
});
defineTheme("solarized-dark", {
base: "vs-dark",
inherit: true,
rules: [
{
background: "002b36",
token: "",
},
{
foreground: "586e75",
token: "comment",
},
{
foreground: "00afaf",
token: "string",
},
{
token: "number",
foreground: "00afaf",
},
{
token: "otherkeyvars",
foreground: "268bd2",
},
{
foreground: "268bd2",
token: "function",
},
{
foreground: "859900",
token: "keyword",
},
{
token: "storage.type.function.js",
foreground: "cb4b16",
},
{
token: "ns",
foreground: "cb4b16",
},
{
token: "netscriptfunction",
foreground: "268bd2",
},
{
token: "otherkeywords",
foreground: "268bd2",
},
{
2021-11-11 01:28:20 +01:00
token: "type.identifier.js",
foreground: "b58900",
},
{
2021-11-11 01:28:20 +01:00
token: "delimiter.square.js",
foreground: "0087ff",
},
{
2021-11-11 01:28:20 +01:00
token: "delimiter.bracket.js",
foreground: "0087ff",
},
{
token: "this",
foreground: "cb4b16",
},
],
colors: {
"editor.foreground": "#839496",
"editor.background": "#002b36",
"editor.selectionBackground": "#073642",
"editor.lineHighlightBackground": "#073642",
"editorCursor.foreground": "#819090",
"editorWhitespace.foreground": "#073642",
"editorIndentGuide.activeBackground": "#9D550FB0",
"editor.selectionHighlightBorder": "#222218",
},
});
defineTheme("solarized-light", {
base: "vs",
inherit: true,
rules: [
{
foreground: "657b83",
2021-11-11 01:28:20 +01:00
background: "fdf6e3",
token: "",
},
{
foreground: "586e75",
token: "comment",
},
{
foreground: "2aa198",
token: "string",
},
{
token: "number",
foreground: "2aa198",
},
{
token: "otherkeyvars",
foreground: "268bd2",
},
{
foreground: "268bd2",
token: "function",
},
{
foreground: "859900",
token: "keyword",
},
{
token: "storage.type.function.js",
foreground: "bc4b16",
},
{
token: "ns",
foreground: "cb4b16",
},
{
token: "netscriptfunction",
foreground: "268bd2",
},
{
token: "otherkeywords",
foreground: "268bd2",
},
{
2021-11-11 01:28:20 +01:00
token: "type.identifier.js",
foreground: "b58900",
},
{
2021-11-11 01:28:20 +01:00
token: "delimiter.square.js",
foreground: "0087ff",
},
{
2021-11-11 01:28:20 +01:00
token: "delimiter.bracket.js",
foreground: "0087ff",
},
{
token: "this",
foreground: "cb4b16",
},
],
colors: {
"editor.foreground": "#657b83",
"editor.background": "#fdf6e3",
"editor.selectionBackground": "#eee8d5",
"editor.lineHighlightBackground": "#eee8d5",
"editorCursor.foreground": "#657b83",
"editorWhitespace.foreground": "#eee8d5",
"editorIndentGuide.activeBackground": "#eee8d5",
"editor.selectionHighlightBorder": "#073642",
},
});
defineTheme("dracula", {
base: "vs-dark",
inherit: true,
rules: [
{
background: "282A36",
foreground: "F8F8F2",
token: "",
},
{
foreground: "6272A4",
token: "comment",
},
{
foreground: "F1FA8C",
token: "string",
},
{
token: "number",
foreground: "BD93F9",
},
{
token: "otherkeyvars",
foreground: "BD93F9",
},
{
foreground: "FF79C6",
token: "function",
},
{
foreground: "FF79C6",
token: "keyword",
},
{
token: "storage.type.function.js",
foreground: "FF79C6",
},
{
token: "ns",
foreground: "FFB86C",
fontStyle: "italic",
},
2022-03-11 06:11:09 +01:00
{
token: "netscriptfunction",
foreground: "FF79C6",
},
{
token: "otherkeywords",
foreground: "FF68A7",
},
{
token: "type.identifier.js",
foreground: "7EE9FD",
2022-04-07 01:30:08 +02:00
fontStyle: "italic",
},
{
token: "delimiter.square.js",
foreground: "FFD709",
},
{
token: "delimiter.parenthesis.js",
2022-04-07 01:30:08 +02:00
foreground: "FFD709",
},
{
token: "delimiter.bracket.js",
foreground: "FFD709",
},
{
token: "this",
foreground: "BD93F9",
fontStyle: "italic",
},
],
2022-04-07 01:30:08 +02:00
colors: {
"editor.foreground": "#F8F8F2",
"editor.background": "#282A36",
"editorLineNumber.foreground": "#6272A4",
"editor.selectionBackground": "#44475A",
"editor.selectionHighlightBackground": "#424450",
"editor.foldBackground": "#21222C",
"editor.wordHighlightBackground": "#8BE9FD50",
"editor.wordHighlightStrongBackground": "#50FA7B50",
"editor.findMatchBackground": "#FFB86C80",
"editor.findMatchHighlightBackground": "#FFFFFF40",
"editor.findRangeHighlightBackground": "#44475A75",
"editor.hoverHighlightBackground": "#8BE9FD50",
"editor.lineHighlightBorder": "#44475A",
"editor.rangeHighlightBackground": "#BD93F915",
"editor.snippetTabstopHighlightBackground": "#282A36",
"editor.snippetTabstopHighlightBorder": "#6272A4",
"editor.snippetFinalTabstopHighlightBackground": "#282A36",
"editor.snippetFinalTabstopHighlightBorder": "#50FA7B",
},
});
defineTheme("one-dark", {
base: "vs-dark",
inherit: true,
rules: [
{
token: "",
background: "333842",
foreground: "ABB2BF",
},
{
token: "comment",
foreground: "5C6370",
},
{
token: "string",
foreground: "98C379",
},
{
token: "number",
foreground: "D19A66",
},
{
token: "function",
foreground: "C678DD",
},
{
token: "keyword",
foreground: "C678DD",
},
{
token: "otherkeyvars",
foreground: "D19A66",
},
{
token: "otherkeywords",
foreground: "C678DD",
},
{
token: "ns",
foreground: "E06C75",
},
{
token: "netscriptfunction",
foreground: "61AFEF",
},
{
token: "type.identifier",
foreground: "E5C07B",
},
{
token: "delimiter",
foreground: "ABB2BF",
},
{
token: "this",
foreground: "E06C75",
},
],
colors: {
"editor.background": "#282C34",
"editor.foreground": "#ABB2BF",
"editor.lineHighlightBackground": "#99BBFF0A",
"editor.selectionBackground": "#3E4451",
"editor.findMatchHighlightBackground": "#528BFF3D",
"editorCursor.foreground": "#528BFF",
"editorHoverWidget.background": "#21252B",
"editorHoverWidget.border": "#181A1F",
"editorIndentGuide.background": "#ABB2BF26",
"editorIndentGuide.activeBackground": "#626772",
"editorLineNumber.foreground": "#636D83",
"editorLineNumber.activeForeground": "#ABB2BF",
"editorSuggestWidget.background": "#21252B",
"editorSuggestWidget.border": "#181A1F",
"editorSuggestWidget.selectedBackground": "#2C313A",
"editorWhitespace.foreground": "#ABB2BF26",
"editorWidget.background": "#21252B",
"editorWidget.border": "#3A3F4B",
"input.background": "#1B1D23",
"input.border": "#181A1F",
"peekView.border": "#528BFF",
"peekViewResult.background": "#21252B",
"peekViewResult.selectionBackground": "#2C313A",
"peekViewTitle.background": "#1B1D23",
"peekViewEditor.background": "#1B1D23",
"scrollbarSlider.background": "#4E566680",
"scrollbarSlider.activeBackground": "#747D9180",
"scrollbarSlider.hoverBackground": "#5A637580",
2022-04-07 01:30:08 +02:00
},
});
2021-10-10 01:00:27 +02:00
}