Просмотр исходного кода

Replace react-syntax-highlighter with rehype-highlight to reduce memory footprint when scrolling code blocks

Saoud Rizwan 1 год назад
Родитель
Сommit
ea14481771

+ 65 - 1
package-lock.json

@@ -23,6 +23,7 @@
         "execa": "^9.3.0",
         "globby": "^14.0.2",
         "mammoth": "^1.8.0",
+        "monaco-vscode-textmate-theme-converter": "^0.1.7",
         "openai": "^4.54.0",
         "os-name": "^6.0.0",
         "p-wait-for": "^5.0.2",
@@ -5449,6 +5450,15 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/commander": {
+      "version": "8.3.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+      "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 12"
+      }
+    },
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -6433,6 +6443,20 @@
         "node": ">= 14"
       }
     },
+    "node_modules/fs-extra": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+      "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+      "license": "MIT",
+      "dependencies": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=6 <7 || >=8"
+      }
+    },
     "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -6728,7 +6752,6 @@
       "version": "4.2.11",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
       "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
-      "dev": true,
       "license": "ISC"
     },
     "node_modules/graphemer": {
@@ -7503,6 +7526,15 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/jsonfile": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+      "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+      "license": "MIT",
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
     "node_modules/jszip": {
       "version": "3.10.1",
       "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
@@ -7981,6 +8013,29 @@
         "node": ">=10"
       }
     },
+    "node_modules/monaco-vscode-textmate-theme-converter": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/monaco-vscode-textmate-theme-converter/-/monaco-vscode-textmate-theme-converter-0.1.7.tgz",
+      "integrity": "sha512-ZMsq1RPWwOD3pvXD0n+9ddnhfzZoiUMwNIWPNUqYqEiQeH2HjyZ9KYOdt/pqe0kkN8WnYWLrxT9C/SrtIsAu2Q==",
+      "license": "MIT",
+      "dependencies": {
+        "commander": "^8.1.0",
+        "fs-extra": "^7.0.1",
+        "tslib": "^2.3.0"
+      },
+      "bin": {
+        "mvttc": "lib/cjs/npx-script.js"
+      },
+      "peerDependencies": {
+        "tslib": "^2.0.1"
+      }
+    },
+    "node_modules/monaco-vscode-textmate-theme-converter/node_modules/tslib": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
+      "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
+      "license": "0BSD"
+    },
     "node_modules/ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -9919,6 +9974,15 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/universalify": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
     "node_modules/uri-js": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",

+ 1 - 0
package.json

@@ -147,6 +147,7 @@
     "execa": "^9.3.0",
     "globby": "^14.0.2",
     "mammoth": "^1.8.0",
+    "monaco-vscode-textmate-theme-converter": "^0.1.7",
     "openai": "^4.54.0",
     "os-name": "^6.0.0",
     "p-wait-for": "^5.0.2",

+ 5 - 3
src/providers/ClaudeDevProvider.ts

@@ -9,6 +9,7 @@ import * as path from "path"
 import fs from "fs/promises"
 import { HistoryItem } from "../shared/HistoryItem"
 import axios from "axios"
+import { getTheme } from "../utils/getTheme"
 
 /*
 https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts
@@ -156,10 +157,10 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
 
 		// Listen for when color changes
 		vscode.workspace.onDidChangeConfiguration(
-			(e) => {
+			async (e) => {
 				if (e && e.affectsConfiguration("workbench.colorTheme")) {
 					// Sends latest theme name to webview
-					this.postStateToWebview()
+					await this.postMessageToWebview({ type: "theme", text: JSON.stringify(await getTheme()) })
 				}
 			},
 			null,
@@ -293,6 +294,8 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
 				switch (message.type) {
 					case "webviewDidLaunch":
 						await this.postStateToWebview()
+						const theme = await getTheme()
+						await this.postMessageToWebview({ type: "theme", text: JSON.stringify(theme) })
 						break
 					case "newTask":
 						// Code that should run in response to the hello message command
@@ -543,7 +546,6 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
 			apiConfiguration,
 			customInstructions,
 			alwaysAllowReadOnly,
-			themeName: vscode.workspace.getConfiguration("workbench").get<string>("colorTheme"),
 			uriScheme: vscode.env.uriScheme,
 			claudeMessages: this.claudeDev?.claudeMessages || [],
 			taskHistory: (taskHistory || []).filter((item) => item.ts && item.task).sort((a, b) => b.ts - a.ts),

+ 1 - 2
src/shared/ExtensionMessage.ts

@@ -5,7 +5,7 @@ import { HistoryItem } from "./HistoryItem"
 
 // webview will hold state
 export interface ExtensionMessage {
-	type: "action" | "state" | "selectedImages" | "ollamaModels"
+	type: "action" | "state" | "selectedImages" | "ollamaModels" | "theme"
 	text?: string
 	action?: "chatButtonTapped" | "settingsButtonTapped" | "historyButtonTapped" | "didBecomeVisible"
 	state?: ExtensionState
@@ -18,7 +18,6 @@ export interface ExtensionState {
 	apiConfiguration?: ApiConfiguration
 	customInstructions?: string
 	alwaysAllowReadOnly?: boolean
-	themeName?: string
 	uriScheme?: string
 	claudeMessages: ClaudeMessage[]
 	taskHistory: HistoryItem[]

+ 128 - 0
src/utils/default-themes/dark_modern.json

@@ -0,0 +1,128 @@
+{
+  "$schema": "vscode://schemas/color-theme",
+  "name": "Default Dark Modern",
+  "include": "./dark_plus.json",
+  "colors": {
+    "activityBar.activeBorder": "#0078D4",
+    "activityBar.background": "#181818",
+    "activityBar.border": "#2B2B2B",
+    "activityBar.foreground": "#D7D7D7",
+    "activityBar.inactiveForeground": "#868686",
+    "activityBarBadge.background": "#0078D4",
+    "activityBarBadge.foreground": "#FFFFFF",
+    "badge.background": "#616161",
+    "badge.foreground": "#F8F8F8",
+    "button.background": "#0078D4",
+    "button.border": "#FFFFFF12",
+    "button.foreground": "#FFFFFF",
+    "button.hoverBackground": "#026EC1",
+    "button.secondaryBackground": "#313131",
+    "button.secondaryForeground": "#CCCCCC",
+    "button.secondaryHoverBackground": "#3C3C3C",
+    "chat.slashCommandBackground": "#34414B",
+    "chat.slashCommandForeground": "#40A6FF",
+    "checkbox.background": "#313131",
+    "checkbox.border": "#3C3C3C",
+    "debugToolBar.background": "#181818",
+    "descriptionForeground": "#9D9D9D",
+    "dropdown.background": "#313131",
+    "dropdown.border": "#3C3C3C",
+    "dropdown.foreground": "#CCCCCC",
+    "dropdown.listBackground": "#1F1F1F",
+    "editor.background": "#1F1F1F",
+    "editor.findMatchBackground": "#9E6A03",
+    "editor.foreground": "#CCCCCC",
+    "editorGroup.border": "#FFFFFF17",
+    "editorGroupHeader.tabsBackground": "#181818",
+    "editorGroupHeader.tabsBorder": "#2B2B2B",
+    "editorGutter.addedBackground": "#2EA043",
+    "editorGutter.deletedBackground": "#F85149",
+    "editorGutter.modifiedBackground": "#0078D4",
+    "editorLineNumber.activeForeground": "#CCCCCC",
+    "editorLineNumber.foreground": "#6E7681",
+    "editorOverviewRuler.border": "#010409",
+    "editorWidget.background": "#202020",
+    "errorForeground": "#F85149",
+    "focusBorder": "#0078D4",
+    "foreground": "#CCCCCC",
+    "icon.foreground": "#CCCCCC",
+    "input.background": "#313131",
+    "input.border": "#3C3C3C",
+    "input.foreground": "#CCCCCC",
+    "input.placeholderForeground": "#989898",
+    "inputOption.activeBackground": "#2489DB82",
+    "inputOption.activeBorder": "#2488DB",
+    "keybindingLabel.foreground": "#CCCCCC",
+    "menu.background": "#1F1F1F",
+    "notificationCenterHeader.background": "#1F1F1F",
+    "notificationCenterHeader.foreground": "#CCCCCC",
+    "notifications.background": "#1F1F1F",
+    "notifications.border": "#2B2B2B",
+    "notifications.foreground": "#CCCCCC",
+    "panel.background": "#181818",
+    "panel.border": "#2B2B2B",
+    "panelInput.border": "#2B2B2B",
+    "panelTitle.activeBorder": "#0078D4",
+    "panelTitle.activeForeground": "#CCCCCC",
+    "panelTitle.inactiveForeground": "#9D9D9D",
+    "peekViewEditor.background": "#1F1F1F",
+    "peekViewEditor.matchHighlightBackground": "#BB800966",
+    "peekViewResult.background": "#1F1F1F",
+    "peekViewResult.matchHighlightBackground": "#BB800966",
+    "pickerGroup.border": "#3C3C3C",
+    "progressBar.background": "#0078D4",
+    "quickInput.background": "#222222",
+    "quickInput.foreground": "#CCCCCC",
+    "settings.dropdownBackground": "#313131",
+    "settings.dropdownBorder": "#3C3C3C",
+    "settings.headerForeground": "#FFFFFF",
+    "settings.modifiedItemIndicator": "#BB800966",
+    "sideBar.background": "#181818",
+    "sideBar.border": "#2B2B2B",
+    "sideBar.foreground": "#CCCCCC",
+    "sideBarSectionHeader.background": "#181818",
+    "sideBarSectionHeader.border": "#2B2B2B",
+    "sideBarSectionHeader.foreground": "#CCCCCC",
+    "sideBarTitle.foreground": "#CCCCCC",
+    "statusBar.background": "#181818",
+    "statusBar.border": "#2B2B2B",
+    "statusBar.debuggingBackground": "#0078D4",
+    "statusBar.debuggingForeground": "#FFFFFF",
+    "statusBar.focusBorder": "#0078D4",
+    "statusBar.foreground": "#CCCCCC",
+    "statusBar.noFolderBackground": "#1F1F1F",
+    "statusBarItem.focusBorder": "#0078D4",
+    "statusBarItem.prominentBackground": "#6E768166",
+    "statusBarItem.remoteBackground": "#0078D4",
+    "statusBarItem.remoteForeground": "#FFFFFF",
+    "tab.activeBackground": "#1F1F1F",
+    "tab.activeBorder": "#1F1F1F",
+    "tab.activeBorderTop": "#0078D4",
+    "tab.activeForeground": "#FFFFFF",
+    "tab.border": "#2B2B2B",
+    "tab.hoverBackground": "#1F1F1F",
+    "tab.inactiveBackground": "#181818",
+    "tab.inactiveForeground": "#9D9D9D",
+    "tab.unfocusedActiveBorder": "#1F1F1F",
+    "tab.unfocusedActiveBorderTop": "#2B2B2B",
+    "tab.unfocusedHoverBackground": "#1F1F1F",
+    "terminal.foreground": "#CCCCCC",
+    "terminal.tab.activeBorder": "#0078D4",
+    "textBlockQuote.background": "#2B2B2B",
+    "textBlockQuote.border": "#616161",
+    "textCodeBlock.background": "#2B2B2B",
+    "textLink.activeForeground": "#4daafc",
+    "textLink.foreground": "#4daafc",
+    "textPreformat.foreground": "#D0D0D0",
+    "textPreformat.background": "#3C3C3C",
+    "textSeparator.foreground": "#21262D",
+    "titleBar.activeBackground": "#181818",
+    "titleBar.activeForeground": "#CCCCCC",
+    "titleBar.border": "#2B2B2B",
+    "titleBar.inactiveBackground": "#1F1F1F",
+    "titleBar.inactiveForeground": "#9D9D9D",
+    "welcomePage.tileBackground": "#2B2B2B",
+    "welcomePage.progress.foreground": "#0078D4",
+    "widget.border": "#313131"
+  }
+}

+ 193 - 0
src/utils/default-themes/dark_plus.json

@@ -0,0 +1,193 @@
+{
+  "$schema": "vscode://schemas/color-theme",
+  "name": "Dark+",
+  "include": "./dark_vs.json",
+  "tokenColors": [
+    {
+      "name": "Function declarations",
+      "scope": [
+        "entity.name.function",
+        "support.function",
+        "support.constant.handlebars",
+        "source.powershell variable.other.member",
+        "entity.name.operator.custom-literal"
+      ],
+      "settings": {
+        "foreground": "#DCDCAA"
+      }
+    },
+    {
+      "name": "Types declaration and references",
+      "scope": [
+        "support.class",
+        "support.type",
+        "entity.name.type",
+        "entity.name.namespace",
+        "entity.other.attribute",
+        "entity.name.scope-resolution",
+        "entity.name.class",
+        "storage.type.numeric.go",
+        "storage.type.byte.go",
+        "storage.type.boolean.go",
+        "storage.type.string.go",
+        "storage.type.uintptr.go",
+        "storage.type.error.go",
+        "storage.type.rune.go",
+        "storage.type.cs",
+        "storage.type.generic.cs",
+        "storage.type.modifier.cs",
+        "storage.type.variable.cs",
+        "storage.type.annotation.java",
+        "storage.type.generic.java",
+        "storage.type.java",
+        "storage.type.object.array.java",
+        "storage.type.primitive.array.java",
+        "storage.type.primitive.java",
+        "storage.type.token.java",
+        "storage.type.groovy",
+        "storage.type.annotation.groovy",
+        "storage.type.parameters.groovy",
+        "storage.type.generic.groovy",
+        "storage.type.object.array.groovy",
+        "storage.type.primitive.array.groovy",
+        "storage.type.primitive.groovy"
+      ],
+      "settings": {
+        "foreground": "#4EC9B0"
+      }
+    },
+    {
+      "name": "Types declaration and references, TS grammar specific",
+      "scope": [
+        "meta.type.cast.expr",
+        "meta.type.new.expr",
+        "support.constant.math",
+        "support.constant.dom",
+        "support.constant.json",
+        "entity.other.inherited-class"
+      ],
+      "settings": {
+        "foreground": "#4EC9B0"
+      }
+    },
+    {
+      "name": "Control flow / Special keywords",
+      "scope": [
+        "keyword.control",
+        "source.cpp keyword.operator.new",
+        "keyword.operator.delete",
+        "keyword.other.using",
+        "keyword.other.directive.using",
+        "keyword.other.operator",
+        "entity.name.operator"
+      ],
+      "settings": {
+        "foreground": "#C586C0"
+      }
+    },
+    {
+      "name": "Variable and parameter name",
+      "scope": [
+        "variable",
+        "meta.definition.variable.name",
+        "support.variable",
+        "entity.name.variable",
+        "constant.other.placeholder"
+      ],
+      "settings": {
+        "foreground": "#9CDCFE"
+      }
+    },
+    {
+      "name": "Constants and enums",
+      "scope": ["variable.other.constant", "variable.other.enummember"],
+      "settings": {
+        "foreground": "#4FC1FF"
+      }
+    },
+    {
+      "name": "Object keys, TS grammar specific",
+      "scope": ["meta.object-literal.key"],
+      "settings": {
+        "foreground": "#9CDCFE"
+      }
+    },
+    {
+      "name": "CSS property value",
+      "scope": [
+        "support.constant.property-value",
+        "support.constant.font-name",
+        "support.constant.media-type",
+        "support.constant.media",
+        "constant.other.color.rgb-value",
+        "constant.other.rgb-value",
+        "support.constant.color"
+      ],
+      "settings": {
+        "foreground": "#CE9178"
+      }
+    },
+    {
+      "name": "Regular expression groups",
+      "scope": [
+        "punctuation.definition.group.regexp",
+        "punctuation.definition.group.assertion.regexp",
+        "punctuation.definition.character-class.regexp",
+        "punctuation.character.set.begin.regexp",
+        "punctuation.character.set.end.regexp",
+        "keyword.operator.negation.regexp",
+        "support.other.parenthesis.regexp"
+      ],
+      "settings": {
+        "foreground": "#CE9178"
+      }
+    },
+    {
+      "scope": [
+        "constant.character.character-class.regexp",
+        "constant.other.character-class.set.regexp",
+        "constant.other.character-class.regexp",
+        "constant.character.set.regexp"
+      ],
+      "settings": {
+        "foreground": "#d16969"
+      }
+    },
+    {
+      "scope": ["keyword.operator.or.regexp", "keyword.control.anchor.regexp"],
+      "settings": {
+        "foreground": "#DCDCAA"
+      }
+    },
+    {
+      "scope": "keyword.operator.quantifier.regexp",
+      "settings": {
+        "foreground": "#d7ba7d"
+      }
+    },
+    {
+      "scope": ["constant.character", "constant.other.option"],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "constant.character.escape",
+      "settings": {
+        "foreground": "#d7ba7d"
+      }
+    },
+    {
+      "scope": "entity.name.label",
+      "settings": {
+        "foreground": "#C8C8C8"
+      }
+    }
+  ],
+  "semanticTokenColors": {
+    "newOperator": "#C586C0",
+    "stringLiteral": "#ce9178",
+    "customLiteral": "#DCDCAA",
+    "numberLiteral": "#b5cea8"
+  }
+}

+ 394 - 0
src/utils/default-themes/dark_vs.json

@@ -0,0 +1,394 @@
+{
+  "$schema": "vscode://schemas/color-theme",
+  "name": "Dark (Visual Studio)",
+  "colors": {
+    "checkbox.border": "#6B6B6B",
+    "editor.background": "#1E1E1E",
+    "editor.foreground": "#D4D4D4",
+    "editor.inactiveSelectionBackground": "#3A3D41",
+    "editorIndentGuide.background1": "#404040",
+    "editorIndentGuide.activeBackground1": "#707070",
+    "editor.selectionHighlightBackground": "#ADD6FF26",
+    "list.dropBackground": "#383B3D",
+    "activityBarBadge.background": "#007ACC",
+    "sideBarTitle.foreground": "#BBBBBB",
+    "input.placeholderForeground": "#A6A6A6",
+    "menu.background": "#252526",
+    "menu.foreground": "#CCCCCC",
+    "menu.separatorBackground": "#454545",
+    "menu.border": "#454545",
+    "statusBarItem.remoteForeground": "#FFF",
+    "statusBarItem.remoteBackground": "#16825D",
+    "ports.iconRunningProcessForeground": "#369432",
+    "sideBarSectionHeader.background": "#0000",
+    "sideBarSectionHeader.border": "#ccc3",
+    "tab.lastPinnedBorder": "#ccc3",
+    "list.activeSelectionIconForeground": "#FFF",
+    "terminal.inactiveSelectionBackground": "#3A3D41",
+    "widget.border": "#303031",
+    "actionBar.toggledBackground": "#383a49"
+  },
+  "tokenColors": [
+    {
+      "scope": [
+        "meta.embedded",
+        "source.groovy.embedded",
+        "string meta.image.inline.markdown",
+        "variable.legacy.builtin.python"
+      ],
+      "settings": {
+        "foreground": "#D4D4D4"
+      }
+    },
+    {
+      "scope": "emphasis",
+      "settings": {
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": "strong",
+      "settings": {
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "scope": "header",
+      "settings": {
+        "foreground": "#000080"
+      }
+    },
+    {
+      "scope": "comment",
+      "settings": {
+        "foreground": "#6A9955"
+      }
+    },
+    {
+      "scope": "constant.language",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": [
+        "constant.numeric",
+        "variable.other.enummember",
+        "keyword.operator.plus.exponent",
+        "keyword.operator.minus.exponent"
+      ],
+      "settings": {
+        "foreground": "#b5cea8"
+      }
+    },
+    {
+      "scope": "constant.regexp",
+      "settings": {
+        "foreground": "#646695"
+      }
+    },
+    {
+      "scope": "entity.name.tag",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": ["entity.name.tag.css", "entity.name.tag.less"],
+      "settings": {
+        "foreground": "#d7ba7d"
+      }
+    },
+    {
+      "scope": "entity.other.attribute-name",
+      "settings": {
+        "foreground": "#9cdcfe"
+      }
+    },
+    {
+      "scope": [
+        "entity.other.attribute-name.class.css",
+        "source.css entity.other.attribute-name.class",
+        "entity.other.attribute-name.id.css",
+        "entity.other.attribute-name.parent-selector.css",
+        "entity.other.attribute-name.parent.less",
+        "source.css entity.other.attribute-name.pseudo-class",
+        "entity.other.attribute-name.pseudo-element.css",
+        "source.css.less entity.other.attribute-name.id",
+        "entity.other.attribute-name.scss"
+      ],
+      "settings": {
+        "foreground": "#d7ba7d"
+      }
+    },
+    {
+      "scope": "invalid",
+      "settings": {
+        "foreground": "#f44747"
+      }
+    },
+    {
+      "scope": "markup.underline",
+      "settings": {
+        "fontStyle": "underline"
+      }
+    },
+    {
+      "scope": "markup.bold",
+      "settings": {
+        "fontStyle": "bold",
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "markup.heading",
+      "settings": {
+        "fontStyle": "bold",
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "markup.italic",
+      "settings": {
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": "markup.strikethrough",
+      "settings": {
+        "fontStyle": "strikethrough"
+      }
+    },
+    {
+      "scope": "markup.inserted",
+      "settings": {
+        "foreground": "#b5cea8"
+      }
+    },
+    {
+      "scope": "markup.deleted",
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "scope": "markup.changed",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "punctuation.definition.quote.begin.markdown",
+      "settings": {
+        "foreground": "#6A9955"
+      }
+    },
+    {
+      "scope": "punctuation.definition.list.begin.markdown",
+      "settings": {
+        "foreground": "#6796e6"
+      }
+    },
+    {
+      "scope": "markup.inline.raw",
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "name": "brackets of XML/HTML tags",
+      "scope": "punctuation.definition.tag",
+      "settings": {
+        "foreground": "#808080"
+      }
+    },
+    {
+      "scope": ["meta.preprocessor", "entity.name.function.preprocessor"],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "meta.preprocessor.string",
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "scope": "meta.preprocessor.numeric",
+      "settings": {
+        "foreground": "#b5cea8"
+      }
+    },
+    {
+      "scope": "meta.structure.dictionary.key.python",
+      "settings": {
+        "foreground": "#9cdcfe"
+      }
+    },
+    {
+      "scope": "meta.diff.header",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "storage",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "storage.type",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": ["storage.modifier", "keyword.operator.noexcept"],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": ["string", "meta.embedded.assembly"],
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "scope": "string.tag",
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "scope": "string.value",
+      "settings": {
+        "foreground": "#ce9178"
+      }
+    },
+    {
+      "scope": "string.regexp",
+      "settings": {
+        "foreground": "#d16969"
+      }
+    },
+    {
+      "name": "String interpolation",
+      "scope": [
+        "punctuation.definition.template-expression.begin",
+        "punctuation.definition.template-expression.end",
+        "punctuation.section.embedded"
+      ],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "name": "Reset JavaScript string interpolation expression",
+      "scope": ["meta.template.expression"],
+      "settings": {
+        "foreground": "#d4d4d4"
+      }
+    },
+    {
+      "scope": [
+        "support.type.vendored.property-name",
+        "support.type.property-name",
+        "source.css variable",
+        "source.coffee.embedded"
+      ],
+      "settings": {
+        "foreground": "#9cdcfe"
+      }
+    },
+    {
+      "scope": "keyword",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "keyword.control",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "keyword.operator",
+      "settings": {
+        "foreground": "#d4d4d4"
+      }
+    },
+    {
+      "scope": [
+        "keyword.operator.new",
+        "keyword.operator.expression",
+        "keyword.operator.cast",
+        "keyword.operator.sizeof",
+        "keyword.operator.alignof",
+        "keyword.operator.typeid",
+        "keyword.operator.alignas",
+        "keyword.operator.instanceof",
+        "keyword.operator.logical.python",
+        "keyword.operator.wordlike"
+      ],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "keyword.other.unit",
+      "settings": {
+        "foreground": "#b5cea8"
+      }
+    },
+    {
+      "scope": [
+        "punctuation.section.embedded.begin.php",
+        "punctuation.section.embedded.end.php"
+      ],
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    },
+    {
+      "scope": "support.function.git-rebase",
+      "settings": {
+        "foreground": "#9cdcfe"
+      }
+    },
+    {
+      "scope": "constant.sha.git-rebase",
+      "settings": {
+        "foreground": "#b5cea8"
+      }
+    },
+    {
+      "name": "coloring of the Java import and package identifiers",
+      "scope": [
+        "storage.modifier.import.java",
+        "variable.language.wildcard.java",
+        "storage.modifier.package.java"
+      ],
+      "settings": {
+        "foreground": "#d4d4d4"
+      }
+    },
+    {
+      "name": "this.self",
+      "scope": "variable.language",
+      "settings": {
+        "foreground": "#569cd6"
+      }
+    }
+  ],
+  "semanticHighlighting": true,
+  "semanticTokenColors": {
+    "newOperator": "#d4d4d4",
+    "stringLiteral": "#ce9178",
+    "customLiteral": "#D4D4D4",
+    "numberLiteral": "#b5cea8"
+  }
+}

+ 468 - 0
src/utils/default-themes/hc_black.json

@@ -0,0 +1,468 @@
+{
+	"$schema": "vscode://schemas/color-theme",
+	"name": "Dark High Contrast",
+	"colors": {
+		"editor.background": "#000000",
+		"editor.foreground": "#FFFFFF",
+		"editorIndentGuide.background1": "#FFFFFF",
+		"editorIndentGuide.activeBackground1": "#FFFFFF",
+		"sideBarTitle.foreground": "#FFFFFF",
+		"selection.background": "#008000",
+		"editor.selectionBackground": "#FFFFFF",
+		"statusBarItem.remoteBackground": "#00000000",
+		"ports.iconRunningProcessForeground": "#FFFFFF",
+		"editorWhitespace.foreground": "#7c7c7c",
+		"actionBar.toggledBackground": "#383a49"
+	},
+	"tokenColors": [
+		{
+			"scope": [
+				"meta.embedded",
+				"source.groovy.embedded",
+				"string meta.image.inline.markdown",
+				"variable.legacy.builtin.python"
+			],
+			"settings": {
+				"foreground": "#FFFFFF"
+			}
+		},
+		{
+			"scope": "emphasis",
+			"settings": {
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": "strong",
+			"settings": {
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"scope": "meta.diff.header",
+			"settings": {
+				"foreground": "#000080"
+			}
+		},
+		{
+			"scope": "comment",
+			"settings": {
+				"foreground": "#7ca668"
+			}
+		},
+		{
+			"scope": "constant.language",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"scope": [
+				"constant.numeric",
+				"constant.other.color.rgb-value",
+				"constant.other.rgb-value",
+				"support.constant.color"
+			],
+			"settings": {
+				"foreground": "#b5cea8"
+			}
+		},
+		{
+			"scope": "constant.regexp",
+			"settings": {
+				"foreground": "#b46695"
+			}
+		},
+		{
+			"scope": "constant.character",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"scope": "entity.name.tag",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"scope": [
+				"entity.name.tag.css",
+				"entity.name.tag.less"
+			],
+			"settings": {
+				"foreground": "#d7ba7d"
+			}
+		},
+		{
+			"scope": "entity.other.attribute-name",
+			"settings": {
+				"foreground": "#9cdcfe"
+			}
+		},
+		{
+			"scope": [
+				"entity.other.attribute-name.class.css",
+				"source.css entity.other.attribute-name.class",
+				"entity.other.attribute-name.id.css",
+				"entity.other.attribute-name.parent-selector.css",
+				"entity.other.attribute-name.parent.less",
+				"source.css entity.other.attribute-name.pseudo-class",
+				"entity.other.attribute-name.pseudo-element.css",
+				"source.css.less entity.other.attribute-name.id",
+				"entity.other.attribute-name.scss"
+			],
+			"settings": {
+				"foreground": "#d7ba7d"
+			}
+		},
+		{
+			"scope": "invalid",
+			"settings": {
+				"foreground": "#f44747"
+			}
+		},
+		{
+			"scope": "markup.underline",
+			"settings": {
+				"fontStyle": "underline"
+			}
+		},
+		{
+			"scope": "markup.bold",
+			"settings": {
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"scope": "markup.heading",
+			"settings": {
+				"fontStyle": "bold",
+				"foreground": "#6796e6"
+			}
+		},
+		{
+			"scope": "markup.italic",
+			"settings": {
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": "markup.strikethrough",
+			"settings": {
+				"fontStyle": "strikethrough"
+			}
+		},
+		{
+			"scope": "markup.inserted",
+			"settings": {
+				"foreground": "#b5cea8"
+			}
+		},
+		{
+			"scope": "markup.deleted",
+			"settings": {
+				"foreground": "#ce9178"
+			}
+		},
+		{
+			"scope": "markup.changed",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"name": "brackets of XML/HTML tags",
+			"scope": [
+				"punctuation.definition.tag"
+			],
+			"settings": {
+				"foreground": "#808080"
+			}
+		},
+		{
+			"scope": "meta.preprocessor",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"scope": "meta.preprocessor.string",
+			"settings": {
+				"foreground": "#ce9178"
+			}
+		},
+		{
+			"scope": "meta.preprocessor.numeric",
+			"settings": {
+				"foreground": "#b5cea8"
+			}
+		},
+		{
+			"scope": "meta.structure.dictionary.key.python",
+			"settings": {
+				"foreground": "#9cdcfe"
+			}
+		},
+		{
+			"scope": "storage",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"scope": "storage.type",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"scope": "storage.modifier",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"scope": "string",
+			"settings": {
+				"foreground": "#ce9178"
+			}
+		},
+		{
+			"scope": "string.tag",
+			"settings": {
+				"foreground": "#ce9178"
+			}
+		},
+		{
+			"scope": "string.value",
+			"settings": {
+				"foreground": "#ce9178"
+			}
+		},
+		{
+			"scope": "string.regexp",
+			"settings": {
+				"foreground": "#d16969"
+			}
+		},
+		{
+			"name": "String interpolation",
+			"scope": [
+				"punctuation.definition.template-expression.begin",
+				"punctuation.definition.template-expression.end",
+				"punctuation.section.embedded"
+			],
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"name": "Reset JavaScript string interpolation expression",
+			"scope": [
+				"meta.template.expression"
+			],
+			"settings": {
+				"foreground": "#ffffff"
+			}
+		},
+		{
+			"scope": [
+				"support.type.vendored.property-name",
+				"support.type.property-name",
+				"source.css variable",
+				"source.coffee.embedded"
+			],
+			"settings": {
+				"foreground": "#d4d4d4"
+			}
+		},
+		{
+			"scope": "keyword",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"scope": "keyword.control",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"scope": "keyword.operator",
+			"settings": {
+				"foreground": "#d4d4d4"
+			}
+		},
+		{
+			"scope": [
+				"keyword.operator.new",
+				"keyword.operator.expression",
+				"keyword.operator.cast",
+				"keyword.operator.sizeof",
+				"keyword.operator.logical.python"
+			],
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"scope": "keyword.other.unit",
+			"settings": {
+				"foreground": "#b5cea8"
+			}
+		},
+		{
+			"scope": "support.function.git-rebase",
+			"settings": {
+				"foreground": "#d4d4d4"
+			}
+		},
+		{
+			"scope": "constant.sha.git-rebase",
+			"settings": {
+				"foreground": "#b5cea8"
+			}
+		},
+		{
+			"name": "coloring of the Java import and package identifiers",
+			"scope": [
+				"storage.modifier.import.java",
+				"variable.language.wildcard.java",
+				"storage.modifier.package.java"
+			],
+			"settings": {
+				"foreground": "#d4d4d4"
+			}
+		},
+		{
+			"name": "coloring of the TS this",
+			"scope": "variable.language.this",
+			"settings": {
+				"foreground": "#569cd6"
+			}
+		},
+		{
+			"name": "Function declarations",
+			"scope": [
+				"entity.name.function",
+				"support.function",
+				"support.constant.handlebars",
+				"source.powershell variable.other.member"
+			],
+			"settings": {
+				"foreground": "#DCDCAA"
+			}
+		},
+		{
+			"name": "Types declaration and references",
+			"scope": [
+				"support.class",
+				"support.type",
+				"entity.name.type",
+				"entity.name.namespace",
+				"entity.name.scope-resolution",
+				"entity.name.class",
+				"storage.type.cs",
+				"storage.type.generic.cs",
+				"storage.type.modifier.cs",
+				"storage.type.variable.cs",
+				"storage.type.annotation.java",
+				"storage.type.generic.java",
+				"storage.type.java",
+				"storage.type.object.array.java",
+				"storage.type.primitive.array.java",
+				"storage.type.primitive.java",
+				"storage.type.token.java",
+				"storage.type.groovy",
+				"storage.type.annotation.groovy",
+				"storage.type.parameters.groovy",
+				"storage.type.generic.groovy",
+				"storage.type.object.array.groovy",
+				"storage.type.primitive.array.groovy",
+				"storage.type.primitive.groovy"
+			],
+			"settings": {
+				"foreground": "#4EC9B0"
+			}
+		},
+		{
+			"name": "Types declaration and references, TS grammar specific",
+			"scope": [
+				"meta.type.cast.expr",
+				"meta.type.new.expr",
+				"support.constant.math",
+				"support.constant.dom",
+				"support.constant.json",
+				"entity.other.inherited-class"
+			],
+			"settings": {
+				"foreground": "#4EC9B0"
+			}
+		},
+		{
+			"name": "Control flow / Special keywords",
+			"scope": [
+				"keyword.control",
+				"source.cpp keyword.operator.new",
+				"source.cpp keyword.operator.delete",
+				"keyword.other.using",
+				"keyword.other.directive.using",
+				"keyword.other.operator"
+			],
+			"settings": {
+				"foreground": "#C586C0"
+			}
+		},
+		{
+			"name": "Variable and parameter name",
+			"scope": [
+				"variable",
+				"meta.definition.variable.name",
+				"support.variable"
+			],
+			"settings": {
+				"foreground": "#9CDCFE"
+			}
+		},
+		{
+			"name": "Object keys, TS grammar specific",
+			"scope": [
+				"meta.object-literal.key"
+			],
+			"settings": {
+				"foreground": "#9CDCFE"
+			}
+		},
+		{
+			"name": "CSS property value",
+			"scope": [
+				"support.constant.property-value",
+				"support.constant.font-name",
+				"support.constant.media-type",
+				"support.constant.media",
+				"constant.other.color.rgb-value",
+				"constant.other.rgb-value",
+				"support.constant.color"
+			],
+			"settings": {
+				"foreground": "#CE9178"
+			}
+		},
+		{
+			"name": "HC Search Editor context line override",
+			"scope": "meta.resultLinePrefix.contextLinePrefix.search",
+			"settings": {
+				"foreground": "#CBEDCB"
+			}
+		}
+	],
+	"semanticHighlighting": true,
+	"semanticTokenColors": {
+		"newOperator": "#FFFFFF",
+		"stringLiteral": "#ce9178",
+		"customLiteral": "#DCDCAA",
+		"numberLiteral": "#b5cea8"
+	}
+}

+ 573 - 0
src/utils/default-themes/hc_light.json

@@ -0,0 +1,573 @@
+{
+	"$schema": "vscode://schemas/color-theme",
+	"name": "Light High Contrast",
+	"tokenColors": [
+		{
+			"scope": [
+				"meta.embedded",
+				"source.groovy.embedded",
+				"variable.legacy.builtin.python"
+			],
+			"settings": {
+				"foreground": "#292929"
+			}
+		},
+		{
+			"scope": "emphasis",
+			"settings": {
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": "strong",
+			"settings": {
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"scope": "meta.diff.header",
+			"settings": {
+				"foreground": "#062F4A"
+			}
+		},
+		{
+			"scope": "comment",
+			"settings": {
+				"foreground": "#515151"
+			}
+		},
+		{
+			"scope": "constant.language",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": [
+				"constant.numeric",
+				"variable.other.enummember",
+				"keyword.operator.plus.exponent",
+				"keyword.operator.minus.exponent"
+			],
+			"settings": {
+				"foreground": "#096d48"
+			}
+		},
+		{
+			"scope": "constant.regexp",
+			"settings": {
+				"foreground": "#811F3F"
+			}
+		},
+		{
+			"scope": "entity.name.tag",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "entity.name.selector",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "entity.other.attribute-name",
+			"settings": {
+				"foreground": "#264F78"
+			}
+		},
+		{
+			"scope": [
+				"entity.other.attribute-name.class.css",
+				"source.css entity.other.attribute-name.class",
+				"entity.other.attribute-name.id.css",
+				"entity.other.attribute-name.parent-selector.css",
+				"entity.other.attribute-name.parent.less",
+				"source.css entity.other.attribute-name.pseudo-class",
+				"entity.other.attribute-name.pseudo-element.css",
+				"source.css.less entity.other.attribute-name.id",
+				"entity.other.attribute-name.scss"
+			],
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "invalid",
+			"settings": {
+				"foreground": "#B5200D"
+			}
+		},
+		{
+			"scope": "markup.underline",
+			"settings": {
+				"fontStyle": "underline"
+			}
+		},
+		{
+			"scope": "markup.bold",
+			"settings": {
+				"foreground": "#000080",
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"scope": "markup.heading",
+			"settings": {
+				"foreground": "#0F4A85",
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"scope": "markup.italic",
+			"settings": {
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": "markup.strikethrough",
+			"settings": {
+				"fontStyle": "strikethrough"
+			}
+		},
+		{
+			"scope": "markup.inserted",
+			"settings": {
+				"foreground": "#096d48"
+			}
+		},
+		{
+			"scope": "markup.deleted",
+			"settings": {
+				"foreground": "#5A5A5A"
+			}
+		},
+		{
+			"scope": "markup.changed",
+			"settings": {
+				"foreground": "#0451A5"
+			}
+		},
+		{
+			"scope": [
+				"punctuation.definition.quote.begin.markdown",
+				"punctuation.definition.list.begin.markdown"
+			],
+			"settings": {
+				"foreground": "#0451A5"
+			}
+		},
+		{
+			"scope": "markup.inline.raw",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "punctuation.definition.tag",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": ["meta.preprocessor", "entity.name.function.preprocessor"],
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "meta.preprocessor.string",
+			"settings": {
+				"foreground": "#b5200d"
+			}
+		},
+		{
+			"scope": "meta.preprocessor.numeric",
+			"settings": {
+				"foreground": "#096d48"
+			}
+		},
+		{
+			"scope": "meta.structure.dictionary.key.python",
+			"settings": {
+				"foreground": "#0451A5"
+			}
+		},
+		{
+			"scope": "storage",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "storage.type",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": ["storage.modifier", "keyword.operator.noexcept"],
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": ["string", "meta.embedded.assembly"],
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": [
+				"string.comment.buffered.block.pug",
+				"string.quoted.pug",
+				"string.interpolated.pug",
+				"string.unquoted.plain.in.yaml",
+				"string.unquoted.plain.out.yaml",
+				"string.unquoted.block.yaml",
+				"string.quoted.single.yaml",
+				"string.quoted.double.xml",
+				"string.quoted.single.xml",
+				"string.unquoted.cdata.xml",
+				"string.quoted.double.html",
+				"string.quoted.single.html",
+				"string.unquoted.html",
+				"string.quoted.single.handlebars",
+				"string.quoted.double.handlebars"
+			],
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "string.regexp",
+			"settings": {
+				"foreground": "#811F3F"
+			}
+		},
+		{
+			"scope": [
+				"punctuation.definition.template-expression.begin",
+				"punctuation.definition.template-expression.end",
+				"punctuation.section.embedded"
+			],
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": ["meta.template.expression"],
+			"settings": {
+				"foreground": "#000000"
+			}
+		},
+		{
+			"scope": [
+				"support.constant.property-value",
+				"support.constant.font-name",
+				"support.constant.media-type",
+				"support.constant.media",
+				"constant.other.color.rgb-value",
+				"constant.other.rgb-value",
+				"support.constant.color"
+			],
+			"settings": {
+				"foreground": "#0451A5"
+			}
+		},
+		{
+			"scope": [
+				"support.type.vendored.property-name",
+				"support.type.property-name",
+				"source.css variable",
+				"source.coffee.embedded"
+			],
+			"settings": {
+				"foreground": "#264F78"
+			}
+		},
+		{
+			"scope": ["support.type.property-name.json"],
+			"settings": {
+				"foreground": "#0451A5"
+			}
+		},
+		{
+			"scope": "keyword",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "keyword.control",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "keyword.operator",
+			"settings": {
+				"foreground": "#000000"
+			}
+		},
+		{
+			"scope": [
+				"keyword.operator.new",
+				"keyword.operator.expression",
+				"keyword.operator.cast",
+				"keyword.operator.sizeof",
+				"keyword.operator.alignof",
+				"keyword.operator.typeid",
+				"keyword.operator.alignas",
+				"keyword.operator.instanceof",
+				"keyword.operator.logical.python",
+				"keyword.operator.wordlike"
+			],
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "keyword.other.unit",
+			"settings": {
+				"foreground": "#096d48"
+			}
+		},
+		{
+			"scope": [
+				"punctuation.section.embedded.begin.php",
+				"punctuation.section.embedded.end.php"
+			],
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "support.function.git-rebase",
+			"settings": {
+				"foreground": "#0451A5"
+			}
+		},
+		{
+			"scope": "constant.sha.git-rebase",
+			"settings": {
+				"foreground": "#096d48"
+			}
+		},
+		{
+			"scope": [
+				"storage.modifier.import.java",
+				"variable.language.wildcard.java",
+				"storage.modifier.package.java"
+			],
+			"settings": {
+				"foreground": "#000000"
+			}
+		},
+		{
+			"scope": "variable.language",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": [
+				"entity.name.function",
+				"support.function",
+				"support.constant.handlebars",
+				"source.powershell variable.other.member",
+				"entity.name.operator.custom-literal"
+			],
+			"settings": {
+				"foreground": "#5e2cbc"
+			}
+		},
+		{
+			"scope": [
+				"support.class",
+				"support.type",
+				"entity.name.type",
+				"entity.name.namespace",
+				"entity.other.attribute",
+				"entity.name.scope-resolution",
+				"entity.name.class",
+				"storage.type.numeric.go",
+				"storage.type.byte.go",
+				"storage.type.boolean.go",
+				"storage.type.string.go",
+				"storage.type.uintptr.go",
+				"storage.type.error.go",
+				"storage.type.rune.go",
+				"storage.type.cs",
+				"storage.type.generic.cs",
+				"storage.type.modifier.cs",
+				"storage.type.variable.cs",
+				"storage.type.annotation.java",
+				"storage.type.generic.java",
+				"storage.type.java",
+				"storage.type.object.array.java",
+				"storage.type.primitive.array.java",
+				"storage.type.primitive.java",
+				"storage.type.token.java",
+				"storage.type.groovy",
+				"storage.type.annotation.groovy",
+				"storage.type.parameters.groovy",
+				"storage.type.generic.groovy",
+				"storage.type.object.array.groovy",
+				"storage.type.primitive.array.groovy",
+				"storage.type.primitive.groovy"
+			],
+			"settings": {
+				"foreground": "#185E73"
+			}
+		},
+		{
+			"scope": [
+				"meta.type.cast.expr",
+				"meta.type.new.expr",
+				"support.constant.math",
+				"support.constant.dom",
+				"support.constant.json",
+				"entity.other.inherited-class"
+			],
+			"settings": {
+				"foreground": "#185E73"
+			}
+		},
+		{
+			"scope": [
+				"keyword.control",
+				"source.cpp keyword.operator.new",
+				"source.cpp keyword.operator.delete",
+				"keyword.other.using",
+				"keyword.other.directive.using",
+				"keyword.other.operator",
+				"entity.name.operator"
+			],
+			"settings": {
+				"foreground": "#b5200d"
+			}
+		},
+		{
+			"scope": [
+				"variable",
+				"meta.definition.variable.name",
+				"support.variable",
+				"entity.name.variable",
+				"constant.other.placeholder"
+			],
+			"settings": {
+				"foreground": "#001080"
+			}
+		},
+		{
+			"scope": ["variable.other.constant", "variable.other.enummember"],
+			"settings": {
+				"foreground": "#02715D"
+			}
+		},
+		{
+			"scope": ["meta.object-literal.key"],
+			"settings": {
+				"foreground": "#001080"
+			}
+		},
+		{
+			"scope": [
+				"support.constant.property-value",
+				"support.constant.font-name",
+				"support.constant.media-type",
+				"support.constant.media",
+				"constant.other.color.rgb-value",
+				"constant.other.rgb-value",
+				"support.constant.color"
+			],
+			"settings": {
+				"foreground": "#0451A5"
+			}
+		},
+		{
+			"scope": [
+				"punctuation.definition.group.regexp",
+				"punctuation.definition.group.assertion.regexp",
+				"punctuation.definition.character-class.regexp",
+				"punctuation.character.set.begin.regexp",
+				"punctuation.character.set.end.regexp",
+				"keyword.operator.negation.regexp",
+				"support.other.parenthesis.regexp"
+			],
+			"settings": {
+				"foreground": "#D16969"
+			}
+		},
+		{
+			"scope": [
+				"constant.character.character-class.regexp",
+				"constant.other.character-class.set.regexp",
+				"constant.other.character-class.regexp",
+				"constant.character.set.regexp"
+			],
+			"settings": {
+				"foreground": "#811F3F"
+			}
+		},
+		{
+			"scope": "keyword.operator.quantifier.regexp",
+			"settings": {
+				"foreground": "#000000"
+			}
+		},
+		{
+			"scope": ["keyword.operator.or.regexp", "keyword.control.anchor.regexp"],
+			"settings": {
+				"foreground": "#EE0000"
+			}
+		},
+		{
+			"scope": "constant.character",
+			"settings": {
+				"foreground": "#0F4A85"
+			}
+		},
+		{
+			"scope": "constant.character.escape",
+			"settings": {
+				"foreground": "#EE0000"
+			}
+		},
+		{
+			"scope": "entity.name.label",
+			"settings": {
+				"foreground": "#000000"
+			}
+		},
+		{
+			"scope": "token.info-token",
+			"settings": {
+				"foreground": "#316BCD"
+			}
+		},
+		{
+			"scope": "token.warn-token",
+			"settings": {
+				"foreground": "#CD9731"
+			}
+		},
+		{
+			"scope": "token.error-token",
+			"settings": {
+				"foreground": "#CD3131"
+			}
+		},
+		{
+			"scope": "token.debug-token",
+			"settings": {
+				"foreground": "#800080"
+			}
+		}
+	],
+	"colors": {
+		"actionBar.toggledBackground": "#dddddd"
+	}
+}

+ 145 - 0
src/utils/default-themes/light_modern.json

@@ -0,0 +1,145 @@
+{
+  "$schema": "vscode://schemas/color-theme",
+  "name": "Default Light Modern",
+  "include": "./light_plus.json",
+  "colors": {
+    "activityBar.activeBorder": "#005FB8",
+    "activityBar.background": "#F8F8F8",
+    "activityBar.border": "#E5E5E5",
+    "activityBar.foreground": "#1F1F1F",
+    "activityBar.inactiveForeground": "#616161",
+    "activityBarBadge.background": "#005FB8",
+    "activityBarBadge.foreground": "#FFFFFF",
+    "badge.background": "#CCCCCC",
+    "badge.foreground": "#3B3B3B",
+    "button.background": "#005FB8",
+    "button.border": "#0000001a",
+    "button.foreground": "#FFFFFF",
+    "button.hoverBackground": "#0258A8",
+    "button.secondaryBackground": "#E5E5E5",
+    "button.secondaryForeground": "#3B3B3B",
+    "button.secondaryHoverBackground": "#CCCCCC",
+    "chat.slashCommandBackground": "#D2ECFF",
+    "chat.slashCommandForeground": "#306CA2",
+    "checkbox.background": "#F8F8F8",
+    "checkbox.border": "#CECECE",
+    "descriptionForeground": "#3B3B3B",
+    "dropdown.background": "#FFFFFF",
+    "dropdown.border": "#CECECE",
+    "dropdown.foreground": "#3B3B3B",
+    "dropdown.listBackground": "#FFFFFF",
+    "editor.background": "#FFFFFF",
+    "editor.foreground": "#3B3B3B",
+    "editor.inactiveSelectionBackground": "#E5EBF1",
+    "editor.selectionHighlightBackground": "#ADD6FF80",
+    "editorGroup.border": "#E5E5E5",
+    "editorGroupHeader.tabsBackground": "#F8F8F8",
+    "editorGroupHeader.tabsBorder": "#E5E5E5",
+    "editorGutter.addedBackground": "#2EA043",
+    "editorGutter.deletedBackground": "#F85149",
+    "editorGutter.modifiedBackground": "#005FB8",
+    "editorIndentGuide.background1": "#D3D3D3",
+    "editorLineNumber.activeForeground": "#171184",
+    "editorLineNumber.foreground": "#6E7681",
+    "editorOverviewRuler.border": "#E5E5E5",
+    "editorSuggestWidget.background": "#F8F8F8",
+    "editorWidget.background": "#F8F8F8",
+    "errorForeground": "#F85149",
+    "focusBorder": "#005FB8",
+    "foreground": "#3B3B3B",
+    "icon.foreground": "#3B3B3B",
+    "input.background": "#FFFFFF",
+    "input.border": "#CECECE",
+    "input.foreground": "#3B3B3B",
+    "input.placeholderForeground": "#767676",
+    "inputOption.activeBackground": "#BED6ED",
+    "inputOption.activeBorder": "#005FB8",
+    "inputOption.activeForeground": "#000000",
+    "keybindingLabel.foreground": "#3B3B3B",
+    "list.activeSelectionBackground": "#E8E8E8",
+    "list.activeSelectionForeground": "#000000",
+    "list.activeSelectionIconForeground": "#000000",
+    "list.hoverBackground": "#F2F2F2",
+    "list.focusAndSelectionOutline": "#005FB8",
+    "menu.border": "#CECECE",
+    "notebook.cellBorderColor": "#E5E5E5",
+    "notebook.selectedCellBackground": "#C8DDF150",
+    "notificationCenterHeader.background": "#FFFFFF",
+    "notificationCenterHeader.foreground": "#3B3B3B",
+    "notifications.background": "#FFFFFF",
+    "notifications.border": "#E5E5E5",
+    "notifications.foreground": "#3B3B3B",
+    "panel.background": "#F8F8F8",
+    "panel.border": "#E5E5E5",
+    "panelInput.border": "#E5E5E5",
+    "panelTitle.activeBorder": "#005FB8",
+    "panelTitle.activeForeground": "#3B3B3B",
+    "panelTitle.inactiveForeground": "#3B3B3B",
+    "peekViewEditor.matchHighlightBackground": "#BB800966",
+    "peekViewResult.background": "#FFFFFF",
+    "peekViewResult.matchHighlightBackground": "#BB800966",
+    "pickerGroup.border": "#E5E5E5",
+    "pickerGroup.foreground": "#8B949E",
+    "ports.iconRunningProcessForeground": "#369432",
+    "progressBar.background": "#005FB8",
+    "quickInput.background": "#F8F8F8",
+    "quickInput.foreground": "#3B3B3B",
+    "searchEditor.textInputBorder": "#CECECE",
+    "settings.dropdownBackground": "#FFFFFF",
+    "settings.dropdownBorder": "#CECECE",
+    "settings.headerForeground": "#1F1F1F",
+    "settings.modifiedItemIndicator": "#BB800966",
+    "settings.numberInputBorder": "#CECECE",
+    "settings.textInputBorder": "#CECECE",
+    "sideBar.background": "#F8F8F8",
+    "sideBar.border": "#E5E5E5",
+    "sideBar.foreground": "#3B3B3B",
+    "sideBarSectionHeader.background": "#F8F8F8",
+    "sideBarSectionHeader.border": "#E5E5E5",
+    "sideBarSectionHeader.foreground": "#3B3B3B",
+    "sideBarTitle.foreground": "#3B3B3B",
+    "statusBar.background": "#F8F8F8",
+    "statusBar.foreground": "#3B3B3B",
+    "statusBar.border": "#E5E5E5",
+    "statusBar.debuggingBackground": "#FD716C",
+    "statusBar.debuggingForeground": "#000000",
+    "statusBar.focusBorder": "#005FB8",
+    "statusBar.noFolderBackground": "#F8F8F8",
+    "statusBarItem.errorBackground": "#C72E0F",
+    "statusBarItem.focusBorder": "#005FB8",
+    "statusBarItem.prominentBackground": "#6E768166",
+    "statusBarItem.remoteBackground": "#005FB8",
+    "statusBarItem.remoteForeground": "#FFFFFF",
+    "tab.activeBackground": "#FFFFFF",
+    "tab.activeBorder": "#F8F8F8",
+    "tab.activeBorderTop": "#005FB8",
+    "tab.activeForeground": "#3B3B3B",
+    "tab.border": "#E5E5E5",
+    "tab.hoverBackground": "#FFFFFF",
+    "tab.inactiveBackground": "#F8F8F8",
+    "tab.inactiveForeground": "#868686",
+    "tab.lastPinnedBorder": "#D4D4D4",
+    "tab.unfocusedActiveBorder": "#F8F8F8",
+    "tab.unfocusedActiveBorderTop": "#E5E5E5",
+    "tab.unfocusedHoverBackground": "#F8F8F8",
+    "terminalCursor.foreground": "#005FB8",
+    "terminal.foreground": "#3B3B3B",
+    "terminal.inactiveSelectionBackground": "#E5EBF1",
+    "terminal.tab.activeBorder": "#005FB8",
+    "textBlockQuote.background": "#F8F8F8",
+    "textBlockQuote.border": "#E5E5E5",
+    "textCodeBlock.background": "#F8F8F8",
+    "textLink.activeForeground": "#005FB8",
+    "textLink.foreground": "#005FB8",
+    "textPreformat.foreground": "#3B3B3B",
+    "textPreformat.background": "#0000001F",
+    "textSeparator.foreground": "#21262D",
+    "titleBar.activeBackground": "#F8F8F8",
+    "titleBar.activeForeground": "#1E1E1E",
+    "titleBar.border": "#E5E5E5",
+    "titleBar.inactiveBackground": "#F8F8F8",
+    "titleBar.inactiveForeground": "#8B949E",
+    "welcomePage.tileBackground": "#F3F3F3",
+    "widget.border": "#E5E5E5"
+  }
+}

+ 194 - 0
src/utils/default-themes/light_plus.json

@@ -0,0 +1,194 @@
+{
+  "$schema": "vscode://schemas/color-theme",
+  "name": "Light+",
+  "include": "./light_vs.json",
+  "tokenColors": [
+    {
+      "name": "Function declarations",
+      "scope": [
+        "entity.name.function",
+        "support.function",
+        "support.constant.handlebars",
+        "source.powershell variable.other.member",
+        "entity.name.operator.custom-literal"
+      ],
+      "settings": {
+        "foreground": "#795E26"
+      }
+    },
+    {
+      "name": "Types declaration and references",
+      "scope": [
+        "support.class",
+        "support.type",
+        "entity.name.type",
+        "entity.name.namespace",
+        "entity.other.attribute",
+        "entity.name.scope-resolution",
+        "entity.name.class",
+        "storage.type.numeric.go",
+        "storage.type.byte.go",
+        "storage.type.boolean.go",
+        "storage.type.string.go",
+        "storage.type.uintptr.go",
+        "storage.type.error.go",
+        "storage.type.rune.go",
+        "storage.type.cs",
+        "storage.type.generic.cs",
+        "storage.type.modifier.cs",
+        "storage.type.variable.cs",
+        "storage.type.annotation.java",
+        "storage.type.generic.java",
+        "storage.type.java",
+        "storage.type.object.array.java",
+        "storage.type.primitive.array.java",
+        "storage.type.primitive.java",
+        "storage.type.token.java",
+        "storage.type.groovy",
+        "storage.type.annotation.groovy",
+        "storage.type.parameters.groovy",
+        "storage.type.generic.groovy",
+        "storage.type.object.array.groovy",
+        "storage.type.primitive.array.groovy",
+        "storage.type.primitive.groovy"
+      ],
+      "settings": {
+        "foreground": "#267f99"
+      }
+    },
+    {
+      "name": "Types declaration and references, TS grammar specific",
+      "scope": [
+        "meta.type.cast.expr",
+        "meta.type.new.expr",
+        "support.constant.math",
+        "support.constant.dom",
+        "support.constant.json",
+        "entity.other.inherited-class"
+      ],
+      "settings": {
+        "foreground": "#267f99"
+      }
+    },
+    {
+      "name": "Control flow / Special keywords",
+      "scope": [
+        "keyword.control",
+        "source.cpp keyword.operator.new",
+        "source.cpp keyword.operator.delete",
+        "keyword.other.using",
+        "keyword.other.directive.using",
+        "keyword.other.operator",
+        "entity.name.operator"
+      ],
+      "settings": {
+        "foreground": "#AF00DB"
+      }
+    },
+    {
+      "name": "Variable and parameter name",
+      "scope": [
+        "variable",
+        "meta.definition.variable.name",
+        "support.variable",
+        "entity.name.variable",
+        "constant.other.placeholder"
+      ],
+      "settings": {
+        "foreground": "#001080"
+      }
+    },
+    {
+      "name": "Constants and enums",
+      "scope": ["variable.other.constant", "variable.other.enummember"],
+      "settings": {
+        "foreground": "#0070C1"
+      }
+    },
+    {
+      "name": "Object keys, TS grammar specific",
+      "scope": ["meta.object-literal.key"],
+      "settings": {
+        "foreground": "#001080"
+      }
+    },
+    {
+      "name": "CSS property value",
+      "scope": [
+        "support.constant.property-value",
+        "support.constant.font-name",
+        "support.constant.media-type",
+        "support.constant.media",
+        "constant.other.color.rgb-value",
+        "constant.other.rgb-value",
+        "support.constant.color"
+      ],
+      "settings": {
+        "foreground": "#0451a5"
+      }
+    },
+    {
+      "name": "Regular expression groups",
+      "scope": [
+        "punctuation.definition.group.regexp",
+        "punctuation.definition.group.assertion.regexp",
+        "punctuation.definition.character-class.regexp",
+        "punctuation.character.set.begin.regexp",
+        "punctuation.character.set.end.regexp",
+        "keyword.operator.negation.regexp",
+        "support.other.parenthesis.regexp"
+      ],
+      "settings": {
+        "foreground": "#d16969"
+      }
+    },
+    {
+      "scope": [
+        "constant.character.character-class.regexp",
+        "constant.other.character-class.set.regexp",
+        "constant.other.character-class.regexp",
+        "constant.character.set.regexp"
+      ],
+      "settings": {
+        "foreground": "#811f3f"
+      }
+    },
+    {
+      "scope": "keyword.operator.quantifier.regexp",
+      "settings": {
+        "foreground": "#000000"
+      }
+    },
+    {
+      "scope": ["keyword.operator.or.regexp", "keyword.control.anchor.regexp"],
+      "settings": {
+        "foreground": "#EE0000"
+      }
+    },
+    {
+      "scope": ["constant.character", "constant.other.option"],
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "scope": "constant.character.escape",
+      "settings": {
+        "foreground": "#EE0000"
+      }
+    },
+    {
+      "scope": "entity.name.label",
+      "settings": {
+        "foreground": "#000000"
+      }
+    }
+  ],
+  "semanticHighlighting": true,
+  "semanticTokenColors": {
+    "newOperator": "#AF00DB",
+    "stringLiteral": "#a31515",
+    "customLiteral": "#795E26",
+    "numberLiteral": "#098658"
+  }
+}

+ 422 - 0
src/utils/default-themes/light_vs.json

@@ -0,0 +1,422 @@
+{
+  "$schema": "vscode://schemas/color-theme",
+  "name": "Light (Visual Studio)",
+  "colors": {
+    "checkbox.border": "#919191",
+    "editor.background": "#FFFFFF",
+    "editor.foreground": "#000000",
+    "editor.inactiveSelectionBackground": "#E5EBF1",
+    "editorIndentGuide.background1": "#D3D3D3",
+    "editorIndentGuide.activeBackground1": "#939393",
+    "editor.selectionHighlightBackground": "#ADD6FF80",
+    "editorSuggestWidget.background": "#F3F3F3",
+    "activityBarBadge.background": "#007ACC",
+    "sideBarTitle.foreground": "#6F6F6F",
+    "list.hoverBackground": "#E8E8E8",
+    "menu.border": "#D4D4D4",
+    "input.placeholderForeground": "#767676",
+    "searchEditor.textInputBorder": "#CECECE",
+    "settings.textInputBorder": "#CECECE",
+    "settings.numberInputBorder": "#CECECE",
+    "statusBarItem.remoteForeground": "#FFF",
+    "statusBarItem.remoteBackground": "#16825D",
+    "ports.iconRunningProcessForeground": "#369432",
+    "sideBarSectionHeader.background": "#0000",
+    "sideBarSectionHeader.border": "#61616130",
+    "tab.lastPinnedBorder": "#61616130",
+    "notebook.cellBorderColor": "#E8E8E8",
+    "notebook.selectedCellBackground": "#c8ddf150",
+    "statusBarItem.errorBackground": "#c72e0f",
+    "list.activeSelectionIconForeground": "#FFF",
+    "list.focusAndSelectionOutline": "#90C2F9",
+    "terminal.inactiveSelectionBackground": "#E5EBF1",
+    "widget.border": "#d4d4d4",
+    "actionBar.toggledBackground": "#dddddd",
+    "diffEditor.unchangedRegionBackground": "#f8f8f8"
+  },
+  "tokenColors": [
+    {
+      "scope": [
+        "meta.embedded",
+        "source.groovy.embedded",
+        "string meta.image.inline.markdown",
+        "variable.legacy.builtin.python"
+      ],
+      "settings": {
+        "foreground": "#000000ff"
+      }
+    },
+    {
+      "scope": "emphasis",
+      "settings": {
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": "strong",
+      "settings": {
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "scope": "meta.diff.header",
+      "settings": {
+        "foreground": "#000080"
+      }
+    },
+    {
+      "scope": "comment",
+      "settings": {
+        "foreground": "#008000"
+      }
+    },
+    {
+      "scope": "constant.language",
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "scope": [
+        "constant.numeric",
+        "variable.other.enummember",
+        "keyword.operator.plus.exponent",
+        "keyword.operator.minus.exponent"
+      ],
+      "settings": {
+        "foreground": "#098658"
+      }
+    },
+    {
+      "scope": "constant.regexp",
+      "settings": {
+        "foreground": "#811f3f"
+      }
+    },
+    {
+      "name": "css tags in selectors, xml tags",
+      "scope": "entity.name.tag",
+      "settings": {
+        "foreground": "#800000"
+      }
+    },
+    {
+      "scope": "entity.name.selector",
+      "settings": {
+        "foreground": "#800000"
+      }
+    },
+    {
+      "scope": "entity.other.attribute-name",
+      "settings": {
+        "foreground": "#e50000"
+      }
+    },
+    {
+      "scope": [
+        "entity.other.attribute-name.class.css",
+        "source.css entity.other.attribute-name.class",
+        "entity.other.attribute-name.id.css",
+        "entity.other.attribute-name.parent-selector.css",
+        "entity.other.attribute-name.parent.less",
+        "source.css entity.other.attribute-name.pseudo-class",
+        "entity.other.attribute-name.pseudo-element.css",
+        "source.css.less entity.other.attribute-name.id",
+        "entity.other.attribute-name.scss"
+      ],
+      "settings": {
+        "foreground": "#800000"
+      }
+    },
+    {
+      "scope": "invalid",
+      "settings": {
+        "foreground": "#cd3131"
+      }
+    },
+    {
+      "scope": "markup.underline",
+      "settings": {
+        "fontStyle": "underline"
+      }
+    },
+    {
+      "scope": "markup.bold",
+      "settings": {
+        "fontStyle": "bold",
+        "foreground": "#000080"
+      }
+    },
+    {
+      "scope": "markup.heading",
+      "settings": {
+        "fontStyle": "bold",
+        "foreground": "#800000"
+      }
+    },
+    {
+      "scope": "markup.italic",
+      "settings": {
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": "markup.strikethrough",
+      "settings": {
+        "fontStyle": "strikethrough"
+      }
+    },
+    {
+      "scope": "markup.inserted",
+      "settings": {
+        "foreground": "#098658"
+      }
+    },
+    {
+      "scope": "markup.deleted",
+      "settings": {
+        "foreground": "#a31515"
+      }
+    },
+    {
+      "scope": "markup.changed",
+      "settings": {
+        "foreground": "#0451a5"
+      }
+    },
+    {
+      "scope": [
+        "punctuation.definition.quote.begin.markdown",
+        "punctuation.definition.list.begin.markdown"
+      ],
+      "settings": {
+        "foreground": "#0451a5"
+      }
+    },
+    {
+      "scope": "markup.inline.raw",
+      "settings": {
+        "foreground": "#800000"
+      }
+    },
+    {
+      "name": "brackets of XML/HTML tags",
+      "scope": "punctuation.definition.tag",
+      "settings": {
+        "foreground": "#800000"
+      }
+    },
+    {
+      "scope": ["meta.preprocessor", "entity.name.function.preprocessor"],
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "scope": "meta.preprocessor.string",
+      "settings": {
+        "foreground": "#a31515"
+      }
+    },
+    {
+      "scope": "meta.preprocessor.numeric",
+      "settings": {
+        "foreground": "#098658"
+      }
+    },
+    {
+      "scope": "meta.structure.dictionary.key.python",
+      "settings": {
+        "foreground": "#0451a5"
+      }
+    },
+    {
+      "scope": "storage",
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "scope": "storage.type",
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "scope": ["storage.modifier", "keyword.operator.noexcept"],
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "scope": ["string", "meta.embedded.assembly"],
+      "settings": {
+        "foreground": "#a31515"
+      }
+    },
+    {
+      "scope": [
+        "string.comment.buffered.block.pug",
+        "string.quoted.pug",
+        "string.interpolated.pug",
+        "string.unquoted.plain.in.yaml",
+        "string.unquoted.plain.out.yaml",
+        "string.unquoted.block.yaml",
+        "string.quoted.single.yaml",
+        "string.quoted.double.xml",
+        "string.quoted.single.xml",
+        "string.unquoted.cdata.xml",
+        "string.quoted.double.html",
+        "string.quoted.single.html",
+        "string.unquoted.html",
+        "string.quoted.single.handlebars",
+        "string.quoted.double.handlebars"
+      ],
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "scope": "string.regexp",
+      "settings": {
+        "foreground": "#811f3f"
+      }
+    },
+    {
+      "name": "String interpolation",
+      "scope": [
+        "punctuation.definition.template-expression.begin",
+        "punctuation.definition.template-expression.end",
+        "punctuation.section.embedded"
+      ],
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "name": "Reset JavaScript string interpolation expression",
+      "scope": ["meta.template.expression"],
+      "settings": {
+        "foreground": "#000000"
+      }
+    },
+    {
+      "scope": [
+        "support.constant.property-value",
+        "support.constant.font-name",
+        "support.constant.media-type",
+        "support.constant.media",
+        "constant.other.color.rgb-value",
+        "constant.other.rgb-value",
+        "support.constant.color"
+      ],
+      "settings": {
+        "foreground": "#0451a5"
+      }
+    },
+    {
+      "scope": [
+        "support.type.vendored.property-name",
+        "support.type.property-name",
+        "source.css variable",
+        "source.coffee.embedded"
+      ],
+      "settings": {
+        "foreground": "#e50000"
+      }
+    },
+    {
+      "scope": ["support.type.property-name.json"],
+      "settings": {
+        "foreground": "#0451a5"
+      }
+    },
+    {
+      "scope": "keyword",
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "scope": "keyword.control",
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "scope": "keyword.operator",
+      "settings": {
+        "foreground": "#000000"
+      }
+    },
+    {
+      "scope": [
+        "keyword.operator.new",
+        "keyword.operator.expression",
+        "keyword.operator.cast",
+        "keyword.operator.sizeof",
+        "keyword.operator.alignof",
+        "keyword.operator.typeid",
+        "keyword.operator.alignas",
+        "keyword.operator.instanceof",
+        "keyword.operator.logical.python",
+        "keyword.operator.wordlike"
+      ],
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    },
+    {
+      "scope": "keyword.other.unit",
+      "settings": {
+        "foreground": "#098658"
+      }
+    },
+    {
+      "scope": [
+        "punctuation.section.embedded.begin.php",
+        "punctuation.section.embedded.end.php"
+      ],
+      "settings": {
+        "foreground": "#800000"
+      }
+    },
+    {
+      "scope": "support.function.git-rebase",
+      "settings": {
+        "foreground": "#0451a5"
+      }
+    },
+    {
+      "scope": "constant.sha.git-rebase",
+      "settings": {
+        "foreground": "#098658"
+      }
+    },
+    {
+      "name": "coloring of the Java import and package identifiers",
+      "scope": [
+        "storage.modifier.import.java",
+        "variable.language.wildcard.java",
+        "storage.modifier.package.java"
+      ],
+      "settings": {
+        "foreground": "#000000"
+      }
+    },
+    {
+      "name": "this.self",
+      "scope": "variable.language",
+      "settings": {
+        "foreground": "#0000ff"
+      }
+    }
+  ],
+  "semanticHighlighting": true,
+  "semanticTokenColors": {
+    "newOperator": "#0000ff",
+    "stringLiteral": "#a31515",
+    "customLiteral": "#000000",
+    "numberLiteral": "#098658"
+  }
+}

+ 145 - 0
src/utils/getTheme.ts

@@ -0,0 +1,145 @@
+import * as vscode from "vscode"
+import * as path from "path"
+import * as fs from "fs/promises"
+import { convertTheme } from "monaco-vscode-textmate-theme-converter/lib/cjs"
+
+const defaultThemes: Record<string, string> = {
+	"Default Dark Modern": "dark_modern",
+	"Dark+": "dark_plus",
+	"Default Dark+": "dark_plus",
+	"Dark (Visual Studio)": "dark_vs",
+	"Visual Studio Dark": "dark_vs",
+	"Dark High Contrast": "hc_black",
+	"Default High Contrast": "hc_black",
+	"Light High Contrast": "hc_light",
+	"Default High Contrast Light": "hc_light",
+	"Default Light Modern": "light_modern",
+	"Light+": "light_plus",
+	"Default Light+": "light_plus",
+	"Light (Visual Studio)": "light_vs",
+	"Visual Studio Light": "light_vs",
+}
+
+function parseThemeString(themeString: string | undefined): any {
+	themeString = themeString
+		?.split("\n")
+		.filter((line) => {
+			return !line.trim().startsWith("//")
+		})
+		.join("\n")
+	return JSON.parse(themeString ?? "{}")
+}
+
+export async function getTheme() {
+	let currentTheme = undefined
+	const colorTheme = vscode.workspace.getConfiguration("workbench").get<string>("colorTheme") || "Default Dark Modern"
+
+	try {
+		for (let i = vscode.extensions.all.length - 1; i >= 0; i--) {
+			if (currentTheme) {
+				break
+			}
+			const extension = vscode.extensions.all[i]
+			if (extension.packageJSON?.contributes?.themes?.length > 0) {
+				for (const theme of extension.packageJSON.contributes.themes) {
+					if (theme.label === colorTheme) {
+						const themePath = path.join(extension.extensionPath, theme.path)
+						currentTheme = await fs.readFile(themePath, "utf-8")
+						break
+					}
+				}
+			}
+		}
+
+		if (currentTheme === undefined && defaultThemes[colorTheme]) {
+			const filename = `${defaultThemes[colorTheme]}.json`
+			currentTheme = await fs.readFile(
+				path.join(getExtensionUri().fsPath, "src", "utils", "default-themes", filename),
+				"utf-8"
+			)
+		}
+
+		// Strip comments from theme
+		let parsed = parseThemeString(currentTheme)
+
+		if (parsed.include) {
+			const includeThemeString = await fs.readFile(
+				path.join(getExtensionUri().fsPath, "src", "utils", "default-themes", parsed.include),
+				"utf-8"
+			)
+			const includeTheme = parseThemeString(includeThemeString)
+			parsed = mergeJson(parsed, includeTheme)
+		}
+
+		const converted = convertTheme(parsed)
+
+		converted.base = (
+			["vs", "hc-black"].includes(converted.base)
+				? converted.base
+				: colorTheme.includes("Light")
+				? "vs"
+				: "vs-dark"
+		) as any
+
+		return converted
+	} catch (e) {
+		console.log("Error loading color theme: ", e)
+	}
+	return undefined
+}
+
+type JsonObject = { [key: string]: any }
+export function mergeJson(
+	first: JsonObject,
+	second: JsonObject,
+	mergeBehavior?: "merge" | "overwrite",
+	mergeKeys?: { [key: string]: (a: any, b: any) => boolean }
+): any {
+	const copyOfFirst = JSON.parse(JSON.stringify(first))
+
+	try {
+		for (const key in second) {
+			const secondValue = second[key]
+
+			if (!(key in copyOfFirst) || mergeBehavior === "overwrite") {
+				// New value
+				copyOfFirst[key] = secondValue
+				continue
+			}
+
+			const firstValue = copyOfFirst[key]
+			if (Array.isArray(secondValue) && Array.isArray(firstValue)) {
+				// Array
+				if (mergeKeys?.[key]) {
+					// Merge keys are used to determine whether an item form the second object should override one from the first
+					const keptFromFirst: any[] = []
+					firstValue.forEach((item: any) => {
+						if (!secondValue.some((item2: any) => mergeKeys[key](item, item2))) {
+							keptFromFirst.push(item)
+						}
+					})
+					copyOfFirst[key] = [...keptFromFirst, ...secondValue]
+				} else {
+					copyOfFirst[key] = [...firstValue, ...secondValue]
+				}
+			} else if (typeof secondValue === "object" && typeof firstValue === "object") {
+				// Object
+				copyOfFirst[key] = mergeJson(firstValue, secondValue, mergeBehavior)
+			} else {
+				// Other (boolean, number, string)
+				copyOfFirst[key] = secondValue
+			}
+		}
+		return copyOfFirst
+	} catch (e) {
+		console.error("Error merging JSON", e, copyOfFirst, second)
+		return {
+			...copyOfFirst,
+			...second,
+		}
+	}
+}
+
+function getExtensionUri(): vscode.Uri {
+	return vscode.extensions.getExtension("saoudrizwan.claude-dev")!.extensionUri
+}

Разница между файлами не показана из-за своего большого размера
+ 641 - 165
webview-ui/package-lock.json


+ 3 - 1
webview-ui/package.json

@@ -14,13 +14,15 @@
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
     "react-markdown": "^9.0.1",
+    "react-remark": "^2.1.0",
     "react-scripts": "5.0.1",
-    "react-syntax-highlighter": "^15.5.0",
     "react-textarea-autosize": "^8.5.3",
     "react-use": "^17.5.1",
     "react-virtuoso": "^4.7.13",
+    "rehype-highlight": "^7.0.0",
     "rewire": "^7.0.0",
     "strip-ansi": "^7.1.0",
+    "styled-components": "^6.1.13",
     "typescript": "^4.9.5",
     "web-vitals": "^2.1.4"
   },

+ 105 - 137
webview-ui/src/components/ChatRow.tsx

@@ -1,17 +1,15 @@
 import { VSCodeBadge, VSCodeButton, VSCodeProgressRing } from "@vscode/webview-ui-toolkit/react"
 import React, { memo, useMemo } from "react"
 import ReactMarkdown from "react-markdown"
-import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
 import { ClaudeMessage, ClaudeSayTool } from "../../../src/shared/ExtensionMessage"
 import { COMMAND_OUTPUT_STRING } from "../../../src/shared/combineCommandSequences"
-import { SyntaxHighlighterStyle } from "../utils/getSyntaxHighlighterStyleFromTheme"
+import CodeAccordian from "./CodeAccordian"
 import CodeBlock from "./CodeBlock"
 import Terminal from "./Terminal"
 import Thumbnails from "./Thumbnails"
 
 interface ChatRowProps {
 	message: ClaudeMessage
-	syntaxHighlighterStyle: SyntaxHighlighterStyle
 	isExpanded: boolean
 	onToggleExpand: () => void
 	lastModifiedMessage?: ClaudeMessage
@@ -35,7 +33,6 @@ export default ChatRow
 
 const ChatRowContent = ({
 	message,
-	syntaxHighlighterStyle,
 	isExpanded,
 	onToggleExpand,
 	lastModifiedMessage,
@@ -165,10 +162,9 @@ const ChatRowContent = ({
 							{toolIcon("edit")}
 							<span style={{ fontWeight: "bold" }}>Claude wants to edit this file:</span>
 						</div>
-						<CodeBlock
+						<CodeAccordian
 							diff={tool.diff!}
 							path={tool.path!}
-							syntaxHighlighterStyle={syntaxHighlighterStyle}
 							isExpanded={isExpanded}
 							onToggleExpand={onToggleExpand}
 						/>
@@ -181,10 +177,9 @@ const ChatRowContent = ({
 							{toolIcon("new-file")}
 							<span style={{ fontWeight: "bold" }}>Claude wants to create a new file:</span>
 						</div>
-						<CodeBlock
+						<CodeAccordian
 							code={tool.content!}
 							path={tool.path!}
-							syntaxHighlighterStyle={syntaxHighlighterStyle}
 							isExpanded={isExpanded}
 							onToggleExpand={onToggleExpand}
 						/>
@@ -199,10 +194,9 @@ const ChatRowContent = ({
 								{message.type === "ask" ? "Claude wants to read this file:" : "Claude read this file:"}
 							</span>
 						</div>
-						<CodeBlock
+						<CodeAccordian
 							code={tool.content!}
 							path={tool.path!}
-							syntaxHighlighterStyle={syntaxHighlighterStyle}
 							isExpanded={isExpanded}
 							onToggleExpand={onToggleExpand}
 						/>
@@ -219,11 +213,10 @@ const ChatRowContent = ({
 									: "Claude viewed the top level files in this directory:"}
 							</span>
 						</div>
-						<CodeBlock
+						<CodeAccordian
 							code={tool.content!}
 							path={tool.path!}
 							language="shell-session"
-							syntaxHighlighterStyle={syntaxHighlighterStyle}
 							isExpanded={isExpanded}
 							onToggleExpand={onToggleExpand}
 						/>
@@ -240,11 +233,10 @@ const ChatRowContent = ({
 									: "Claude recursively viewed all files in this directory:"}
 							</span>
 						</div>
-						<CodeBlock
+						<CodeAccordian
 							code={tool.content!}
 							path={tool.path!}
 							language="shell-session"
-							syntaxHighlighterStyle={syntaxHighlighterStyle}
 							isExpanded={isExpanded}
 							onToggleExpand={onToggleExpand}
 						/>
@@ -261,10 +253,9 @@ const ChatRowContent = ({
 									: "Claude viewed source code definition names used in this directory:"}
 							</span>
 						</div>
-						<CodeBlock
+						<CodeAccordian
 							code={tool.content!}
 							path={tool.path!}
-							syntaxHighlighterStyle={syntaxHighlighterStyle}
 							isExpanded={isExpanded}
 							onToggleExpand={onToggleExpand}
 						/>
@@ -287,11 +278,10 @@ const ChatRowContent = ({
 								)}
 							</span>
 						</div>
-						<CodeBlock
+						<CodeAccordian
 							code={tool.content!}
 							path={tool.path! + (tool.filePattern ? `/(${tool.filePattern})` : "")}
 							language="plaintext"
-							syntaxHighlighterStyle={syntaxHighlighterStyle}
 							isExpanded={isExpanded}
 							onToggleExpand={onToggleExpand}
 						/>
@@ -365,10 +355,9 @@ const ChatRowContent = ({
 
 							{isExpanded && (
 								<div style={{ marginTop: "10px" }}>
-									<CodeBlock
+									<CodeAccordian
 										code={JSON.stringify(JSON.parse(message.text || "{}").request, null, 2)}
 										language="json"
-										syntaxHighlighterStyle={syntaxHighlighterStyle}
 										isExpanded={true}
 										onToggleExpand={onToggleExpand}
 									/>
@@ -381,7 +370,7 @@ const ChatRowContent = ({
 				case "text":
 					return (
 						<div>
-							<Markdown syntaxHighlighterStyle={syntaxHighlighterStyle} markdown={message.text} />
+							<Markdown markdown={message.text} />
 						</div>
 					)
 				case "user_feedback":
@@ -421,10 +410,9 @@ const ChatRowContent = ({
 								}}>
 								The user made the following changes:
 							</span>
-							<CodeBlock
+							<CodeAccordian
 								diff={tool.diff!}
 								path={tool.path!}
-								syntaxHighlighterStyle={syntaxHighlighterStyle}
 								isExpanded={isExpanded}
 								onToggleExpand={onToggleExpand}
 							/>
@@ -450,7 +438,7 @@ const ChatRowContent = ({
 								{title}
 							</div>
 							<div style={{ color: "var(--vscode-charts-green)" }}>
-								<Markdown syntaxHighlighterStyle={syntaxHighlighterStyle} markdown={message.text} />
+								<Markdown markdown={message.text} />
 							</div>
 						</>
 					)
@@ -465,7 +453,7 @@ const ChatRowContent = ({
 								</div>
 							)}
 							<div>
-								<Markdown syntaxHighlighterStyle={syntaxHighlighterStyle} markdown={message.text} />
+								<Markdown markdown={message.text} />
 							</div>
 						</>
 					)
@@ -517,7 +505,7 @@ const ChatRowContent = ({
 									{title}
 								</div>
 								<div style={{ color: "var(--vscode-charts-green)" }}>
-									<Markdown syntaxHighlighterStyle={syntaxHighlighterStyle} markdown={message.text} />
+									<Markdown markdown={message.text} />
 								</div>
 							</div>
 						)
@@ -534,7 +522,7 @@ const ChatRowContent = ({
 								</div>
 							)}
 							<div>
-								<Markdown syntaxHighlighterStyle={syntaxHighlighterStyle} markdown={message.text} />
+								<Markdown markdown={message.text} />
 							</div>
 						</>
 					)
@@ -559,114 +547,94 @@ const ProgressIndicator = () => (
 	</div>
 )
 
-const Markdown = memo(
-	({ syntaxHighlighterStyle, markdown }: { syntaxHighlighterStyle: SyntaxHighlighterStyle; markdown?: string }) => {
-		// react-markdown lets us customize elements, so here we're using their example of replacing code blocks with SyntaxHighlighter. However when there are no language matches (` or ``` without a language specifier) then we default to a normal code element for inline code. Code blocks without a language specifier shouldn't be a common occurrence as we prompt Claude to always use a language specifier.
-		// when claude wraps text in thinking tags, he doesnt use line breaks so we need to insert those ourselves to render markdown correctly
-		const parsed = markdown?.replace(/<thinking>([\s\S]*?)<\/thinking>/g, (match, content) => {
-			return `_<thinking>_\n\n${content}\n\n_</thinking>_`
-		})
-		return (
-			<div style={{ wordBreak: "break-word", overflowWrap: "anywhere" }}>
-				<ReactMarkdown
-					children={parsed}
-					components={{
-						p(props) {
-							const { style, ...rest } = props
-							return (
-								<p
-									style={{
-										...style,
-										margin: 0,
-										marginTop: 0,
-										marginBottom: 0,
-										whiteSpace: "pre-wrap",
-										wordBreak: "break-word",
-										overflowWrap: "anywhere",
-									}}
-									{...rest}
-								/>
-							)
-						},
-						ol(props) {
-							const { style, ...rest } = props
-							return (
-								<ol
-									style={{
-										...style,
-										padding: "0 0 0 20px",
-										margin: "10px 0",
-										wordBreak: "break-word",
-										overflowWrap: "anywhere",
-									}}
-									{...rest}
-								/>
-							)
-						},
-						ul(props) {
-							const { style, ...rest } = props
-							return (
-								<ul
-									style={{
-										...style,
-										padding: "0 0 0 20px",
-										margin: "10px 0",
-										wordBreak: "break-word",
-										overflowWrap: "anywhere",
-									}}
-									{...rest}
-								/>
-							)
-						},
-						// https://github.com/remarkjs/react-markdown?tab=readme-ov-file#use-custom-components-syntax-highlight
-						code(props) {
-							const { children, className, node, ...rest } = props
-							const match = /language-(\w+)/.exec(className || "")
-							return match ? (
-								<SyntaxHighlighter
-									{...(rest as any)} // will be passed down to pre
-									PreTag="div"
-									children={String(children).replace(/\n$/, "")}
-									language={match[1]}
-									style={{
-										...syntaxHighlighterStyle,
-										'code[class*="language-"]': {
-											background: "var(--vscode-editor-background)",
-										},
-										'pre[class*="language-"]': {
-											background: "var(--vscode-editor-background)",
-										},
-									}}
-									customStyle={{
-										overflowX: "auto",
-										overflowY: "hidden",
-										maxWidth: "100%",
-										margin: 0,
-										padding: "10px",
-										// important to note that min-width: max-content is not required here how it is in CodeBlock.tsx
-										borderRadius: 3,
-										border: "1px solid var(--vscode-sideBar-border)",
-										fontSize: "var(--vscode-editor-font-size)",
-										lineHeight: "var(--vscode-editor-line-height)",
-										fontFamily: "var(--vscode-editor-font-family)",
-									}}
+const Markdown = memo(({ markdown }: { markdown?: string }) => {
+	// react-markdown lets us customize elements, so here we're using their example of replacing code blocks with SyntaxHighlighter. However when there are no language matches (` or ``` without a language specifier) then we default to a normal code element for inline code. Code blocks without a language specifier shouldn't be a common occurrence as we prompt Claude to always use a language specifier.
+	// when claude wraps text in thinking tags, he doesnt use line breaks so we need to insert those ourselves to render markdown correctly
+	const parsed = markdown?.replace(/<thinking>([\s\S]*?)<\/thinking>/g, (match, content) => {
+		return `_<thinking>_\n\n${content}\n\n_</thinking>_`
+	})
+	return (
+		<div style={{ wordBreak: "break-word", overflowWrap: "anywhere" }}>
+			<ReactMarkdown
+				children={parsed}
+				components={{
+					p(props) {
+						const { style, ...rest } = props
+						return (
+							<p
+								style={{
+									...style,
+									margin: 0,
+									marginTop: 0,
+									marginBottom: 0,
+									whiteSpace: "pre-wrap",
+									wordBreak: "break-word",
+									overflowWrap: "anywhere",
+								}}
+								{...rest}
+							/>
+						)
+					},
+					ol(props) {
+						const { style, ...rest } = props
+						return (
+							<ol
+								style={{
+									...style,
+									padding: "0 0 0 20px",
+									margin: "10px 0",
+									wordBreak: "break-word",
+									overflowWrap: "anywhere",
+								}}
+								{...rest}
+							/>
+						)
+					},
+					ul(props) {
+						const { style, ...rest } = props
+						return (
+							<ul
+								style={{
+									...style,
+									padding: "0 0 0 20px",
+									margin: "10px 0",
+									wordBreak: "break-word",
+									overflowWrap: "anywhere",
+								}}
+								{...rest}
+							/>
+						)
+					},
+					// https://github.com/remarkjs/react-markdown?tab=readme-ov-file#use-custom-components-syntax-highlight
+					code(props) {
+						const { children, className, node, ...rest } = props
+						const match = /language-(\w+)/.exec(className || "")
+						return match ? (
+							<div
+								style={{
+									borderRadius: 3,
+									border: "1px solid var(--vscode-sideBar-border)",
+									overflow: "hidden",
+								}}>
+								<CodeBlock
+									source={`${"```"}${match[1]}\n${String(children).replace(/\n$/, "")}\n${"```"}`}
 								/>
-							) : (
-								<code
-									{...rest}
-									className={className}
-									style={{
-										whiteSpace: "pre-line",
-										wordBreak: "break-word",
-										overflowWrap: "anywhere",
-									}}>
-									{children}
-								</code>
-							)
-						},
-					}}
-				/>
-			</div>
-		)
-	}
-)
+							</div>
+						) : (
+							<code
+								{...rest}
+								className={className}
+								style={{
+									whiteSpace: "pre-line",
+									wordBreak: "break-word",
+									overflowWrap: "anywhere",
+								}}>
+								{children}
+							</code>
+						)
+					},
+				}}
+			/>
+		</div>
+	)
+})

+ 2 - 21
webview-ui/src/components/ChatView.tsx

@@ -1,6 +1,5 @@
 import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react"
 import { KeyboardEvent, useCallback, useEffect, useMemo, useRef, useState } from "react"
-import vsDarkPlus from "react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus"
 import DynamicTextArea from "react-textarea-autosize"
 import { useEvent, useMount } from "react-use"
 import { Virtuoso, type VirtuosoHandle } from "react-virtuoso"
@@ -9,7 +8,6 @@ import { combineApiRequests } from "../../../src/shared/combineApiRequests"
 import { combineCommandSequences, COMMAND_STDIN_STRING } from "../../../src/shared/combineCommandSequences"
 import { getApiMetrics } from "../../../src/shared/getApiMetrics"
 import { useExtensionState } from "../context/ExtensionStateContext"
-import { getSyntaxHighlighterStyleFromTheme } from "../utils/getSyntaxHighlighterStyleFromTheme"
 import { vscode } from "../utils/vscode"
 import Announcement from "./Announcement"
 import ChatRow from "./ChatRow"
@@ -36,14 +34,7 @@ const ChatView = ({
 	hideAnnouncement,
 	showHistoryView,
 }: ChatViewProps) => {
-	const {
-		version,
-		claudeMessages: messages,
-		taskHistory,
-		themeName: vscodeThemeName,
-		apiConfiguration,
-		uriScheme,
-	} = useExtensionState()
+	const { version, claudeMessages: messages, taskHistory, apiConfiguration, uriScheme } = useExtensionState()
 
 	//const task = messages.length > 0 ? (messages[0].say === "task" ? messages[0] : undefined) : undefined) : undefined
 	const task = messages.length > 0 ? messages[0] : undefined // leaving this less safe version here since if the first message is not a task, then the extension is in a bad state and needs to be debugged (see ClaudeDev.abort)
@@ -65,7 +56,6 @@ const ChatView = ({
 	const [enableButtons, setEnableButtons] = useState<boolean>(false)
 	const [primaryButtonText, setPrimaryButtonText] = useState<string | undefined>(undefined)
 	const [secondaryButtonText, setSecondaryButtonText] = useState<string | undefined>(undefined)
-	const [syntaxHighlighterStyle, setSyntaxHighlighterStyle] = useState(vsDarkPlus)
 	const virtuosoRef = useRef<VirtuosoHandle>(null)
 	const [expandedRows, setExpandedRows] = useState<Record<number, boolean>>({})
 
@@ -76,14 +66,6 @@ const ChatView = ({
 		}))
 	}
 
-	useEffect(() => {
-		if (!vscodeThemeName) return
-		const theme = getSyntaxHighlighterStyleFromTheme(vscodeThemeName)
-		if (theme) {
-			setSyntaxHighlighterStyle(theme)
-		}
-	}, [vscodeThemeName])
-
 	useEffect(() => {
 		// if last message is an ask, show user ask UI
 
@@ -486,7 +468,6 @@ const ChatView = ({
 			<ChatRow
 				key={message.ts}
 				message={message}
-				syntaxHighlighterStyle={syntaxHighlighterStyle}
 				isExpanded={expandedRows[message.ts] || false}
 				onToggleExpand={() => toggleRowExpansion(message.ts)}
 				lastModifiedMessage={modifiedMessages.at(-1)}
@@ -494,7 +475,7 @@ const ChatView = ({
 				handleSendStdin={handleSendStdin}
 			/>
 		),
-		[expandedRows, syntaxHighlighterStyle, modifiedMessages, visibleMessages.length, handleSendStdin]
+		[expandedRows, modifiedMessages, visibleMessages.length, handleSendStdin]
 	)
 
 	return (

+ 85 - 0
webview-ui/src/components/CodeAccordian.tsx

@@ -0,0 +1,85 @@
+import { memo, useMemo } from "react"
+import { getLanguageFromPath } from "../utils/getLanguageFromPath"
+import CodeBlock from "./CodeBlock"
+
+interface CodeAccordianProps {
+	code?: string
+	diff?: string
+	language?: string | undefined
+	path?: string
+	isExpanded: boolean
+	onToggleExpand: () => void
+}
+
+/*
+We need to remove leading non-alphanumeric characters from the path in order for our leading ellipses trick to work.
+^: Anchors the match to the start of the string.
+[^a-zA-Z0-9]+: Matches one or more characters that are not alphanumeric.
+The replace method removes these matched characters, effectively trimming the string up to the first alphanumeric character.
+*/
+const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "")
+
+const CodeAccordian = ({ code, diff, language, path, isExpanded, onToggleExpand }: CodeAccordianProps) => {
+	const inferredLanguage = useMemo(
+		() => code && (language ?? (path ? getLanguageFromPath(path) : undefined)),
+		[path, language, code]
+	)
+
+	return (
+		<div
+			style={{
+				borderRadius: 3,
+				backgroundColor: "var(--vscode-editor-background)",
+				overflow: "hidden", // This ensures the inner scrollable area doesn't overflow the rounded corners
+				border: "1px solid var(--vscode-editorGroup-border)",
+			}}>
+			{path && (
+				<div
+					style={{
+						color: "var(--vscode-descriptionForeground)",
+						display: "flex",
+						justifyContent: "space-between",
+						alignItems: "center",
+						padding: "6px 10px",
+						cursor: "pointer",
+					}}
+					onClick={onToggleExpand}>
+					<span
+						style={{
+							whiteSpace: "nowrap",
+							overflow: "hidden",
+							textOverflow: "ellipsis",
+							marginRight: "8px",
+							fontSize: "11px",
+							// trick to get ellipsis at beginning of string
+							direction: "rtl",
+							textAlign: "left",
+						}}>
+						{removeLeadingNonAlphanumeric(path) + "\u200E"}
+					</span>
+					<span className={`codicon codicon-chevron-${isExpanded ? "up" : "down"}`}></span>
+				</div>
+			)}
+			{(!path || isExpanded) && (
+				<div
+					//className="code-block-scrollable" this doesn't seem to be necessary anymore, on silicon macs it shows the native mac scrollbar instead of the vscode styled one
+					style={{
+						overflowX: "auto",
+						overflowY: "hidden",
+						maxWidth: "100%",
+					}}>
+					<CodeBlock
+						source={`${"```"}${diff !== undefined ? "diff" : inferredLanguage}\n${(
+							code ??
+							diff ??
+							""
+						).trim()}\n${"```"}`}
+					/>
+				</div>
+			)}
+		</div>
+	)
+}
+
+// memo does shallow comparison of props, so if you need it to re-render when a nested object changes, you need to pass a custom comparison function
+export default memo(CodeAccordian)

+ 116 - 158
webview-ui/src/components/CodeBlock.tsx

@@ -1,171 +1,129 @@
-import { memo, useMemo } from "react"
-import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
-import { getLanguageFromPath } from "../utils/getLanguageFromPath"
-import { SyntaxHighlighterStyle } from "../utils/getSyntaxHighlighterStyleFromTheme"
+import { memo, useEffect } from "react"
+import { useRemark } from "react-remark"
+import rehypeHighlight, { Options } from "rehype-highlight"
+import styled from "styled-components"
+import { visit } from "unist-util-visit"
+import { useExtensionState } from "../context/ExtensionStateContext"
 
-/*
-const vscodeSyntaxStyle: React.CSSProperties = {
-	backgroundColor: "var(--vscode-editor-background)",
-	color: "var(--vscode-editor-foreground)",
-	fontFamily: "var(--vscode-editor-font-family)",
-	fontSize: "var(--vscode-editor-font-size)",
-	lineHeight: "var(--vscode-editor-line-height)",
-	textAlign: "left",
-	whiteSpace: "pre",
-	wordSpacing: "normal",
-	wordBreak: "normal",
-	wordWrap: "normal",
-	tabSize: 4,
-	hyphens: "none",
-	padding: "1em",
-	margin: "0.5em 0",
-	overflow: "auto",
-	borderRadius: "6px",
-}
+const BG_COLOR = "var(--vscode-editor-background, --vscode-sideBar-background, rgb(30 30 30))"
 
-const tokenStyles = {
-	comment: { color: "var(--vscode-editor-foreground)" },
-	prolog: { color: "var(--vscode-editor-foreground)" },
-	doctype: { color: "var(--vscode-editor-foreground)" },
-	cdata: { color: "var(--vscode-editor-foreground)" },
-	punctuation: { color: "var(--vscode-editor-foreground)" },
-	property: { color: "var(--vscode-symbolIcon-propertyForeground)" },
-	tag: { color: "var(--vscode-symbolIcon-colorForeground)" },
-	boolean: { color: "var(--vscode-symbolIcon-booleanForeground)" },
-	number: { color: "var(--vscode-symbolIcon-numberForeground)" },
-	constant: { color: "var(--vscode-symbolIcon-constantForeground)" },
-	symbol: { color: "var(--vscode-symbolIcon-colorForeground)" },
-	selector: { color: "var(--vscode-symbolIcon-colorForeground)" },
-	"attr-name": { color: "var(--vscode-symbolIcon-propertyForeground)" },
-	string: { color: "var(--vscode-symbolIcon-stringForeground)" },
-	char: { color: "var(--vscode-symbolIcon-stringForeground)" },
-	builtin: { color: "var(--vscode-symbolIcon-keywordForeground)" },
-	inserted: { color: "var(--vscode-gitDecoration-addedResourceForeground)" },
-	operator: { color: "var(--vscode-symbolIcon-operatorForeground)" },
-	entity: { color: "var(--vscode-symbolIcon-snippetForeground)", cursor: "help" },
-	url: { color: "var(--vscode-textLink-foreground)" },
-	variable: { color: "var(--vscode-symbolIcon-variableForeground)" },
-	atrule: { color: "var(--vscode-symbolIcon-keywordForeground)" },
-	"attr-value": { color: "var(--vscode-symbolIcon-stringForeground)" },
-	keyword: { color: "var(--vscode-symbolIcon-keywordForeground)" },
-	function: { color: "var(--vscode-symbolIcon-functionForeground)" },
-	regex: { color: "var(--vscode-symbolIcon-regexForeground)" },
-	important: { color: "var(--vscode-editorWarning-foreground)", fontWeight: "bold" },
-	bold: { fontWeight: "bold" },
-	italic: { fontStyle: "italic" },
-	deleted: { color: "var(--vscode-gitDecoration-deletedResourceForeground)" },
-}
+/*
+overflowX: auto + inner div with padding results in an issue where the top/left/bottom padding renders but the right padding inside does not count as overflow as the width of the element is not exceeded. Once the inner div is outside the boundaries of the parent it counts as overflow.
+https://stackoverflow.com/questions/60778406/why-is-padding-right-clipped-with-overflowscroll/77292459#77292459
+this fixes the issue of right padding clipped off 
+“ideal” size in a given axis when given infinite available space--allows the syntax highlighter to grow to largest possible width including its padding
+minWidth: "max-content",
 */
 
-interface CodeBlockProps {
-	code?: string
-	diff?: string
-	language?: string | undefined
-	path?: string
-	syntaxHighlighterStyle: SyntaxHighlighterStyle
-	isExpanded: boolean
-	onToggleExpand: () => void
-}
+const StyledMarkdown = styled.div`
+	pre {
+		background-color: ${BG_COLOR};
+		border-radius: 5px;
+		margin: 0;
+		min-width: max-content;
+		padding: 10px 10px;
+	}
 
-/*
-We need to remove leading non-alphanumeric characters from the path in order for our leading ellipses trick to work.
-^: Anchors the match to the start of the string.
-[^a-zA-Z0-9]+: Matches one or more characters that are not alphanumeric.
-The replace method removes these matched characters, effectively trimming the string up to the first alphanumeric character.
-*/
-const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "")
+	pre > code {
+		.hljs-deletion {
+			background-color: var(--vscode-diffEditor-removedTextBackground);
+		}
+		.hljs-addition {
+			background-color: var(--vscode-diffEditor-insertedTextBackground);
+		}
+	}
 
-const CodeBlock = ({
-	code,
-	diff,
-	language,
-	path,
-	syntaxHighlighterStyle,
-	isExpanded,
-	onToggleExpand,
-}: CodeBlockProps) => {
-	const inferredLanguage = useMemo(
-		() => code && (language ?? (path ? getLanguageFromPath(path) : undefined)),
-		[path, language, code]
-	)
+	code {
+		span.line:empty {
+			display: none;
+		}
+		word-wrap: break-word;
+		border-radius: 5px;
+		background-color: ${BG_COLOR};
+		font-size: var(--vscode-editor-font-size, var(--vscode-font-size, 12px));
+		font-family: var(--vscode-editor-font-family);
+	}
+
+	code:not(pre > code) {
+		font-family: var(--vscode-editor-font-family);
+		color: #f78383;
+	}
+
+	background-color: ${BG_COLOR};
+	font-family: var(--vscode-font-family), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
+		Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
+	font-size: var(--vscode-editor-font-size, var(--vscode-font-size, 12px));
+	color: var(--vscode-editor-foreground, #fff);
+
+	p,
+	li,
+	ol,
+	ul {
+		line-height: 1.5;
+	}
+`
+
+const StyledPre = styled.pre<{ theme: any }>`
+	& .hljs {
+		color: var(--vscode-editor-foreground, #fff);
+	}
+
+	${(props) =>
+		Object.keys(props.theme)
+			.map((key, index) => {
+				return `
+      & ${key} {
+        color: ${props.theme[key]};
+      }
+    `
+			})
+			.join("")}
+`
+
+const CodeBlock = memo(function CodeBlock({ source }: { source?: string }) {
+	const { theme } = useExtensionState()
+	const [reactContent, setMarkdownSource] = useRemark({
+		remarkPlugins: [
+			() => {
+				return (tree) => {
+					visit(tree, "code", (node: any) => {
+						if (!node.lang) {
+							node.lang = "javascript"
+						} else if (node.lang.includes(".")) {
+							// if the langauge is a file, get the extension
+							node.lang = node.lang.split(".").slice(-1)[0]
+						}
+					})
+				}
+			},
+		],
+		rehypePlugins: [
+			rehypeHighlight as any,
+			{
+				// languages: {},
+			} as Options,
+		],
+		rehypeReactOptions: {
+			components: {
+				pre: ({ node, ...preProps }: any) => <StyledPre {...preProps} theme={theme} />,
+			},
+		},
+	})
+
+	useEffect(() => {
+		setMarkdownSource(source || "")
+	}, [source, setMarkdownSource, theme])
 
 	return (
 		<div
 			style={{
-				borderRadius: "3px",
-				backgroundColor: "var(--vscode-editor-background)",
-				overflow: "hidden", // This ensures the inner scrollable area doesn't overflow the rounded corners
-				border: "1px solid var(--vscode-editorGroup-border)",
+				overflowY: "auto",
+				maxHeight: "100%",
+				backgroundColor: BG_COLOR,
 			}}>
-			{path && (
-				<div
-					style={{
-						color: "var(--vscode-descriptionForeground)",
-						display: "flex",
-						justifyContent: "space-between",
-						alignItems: "center",
-						padding: "6px 10px",
-						cursor: "pointer",
-					}}
-					onClick={onToggleExpand}>
-					<span
-						style={{
-							whiteSpace: "nowrap",
-							overflow: "hidden",
-							textOverflow: "ellipsis",
-							marginRight: "8px",
-							fontSize: "11px",
-							// trick to get ellipsis at beginning of string
-							direction: "rtl",
-							textAlign: "left",
-						}}>
-						{removeLeadingNonAlphanumeric(path) + "\u200E"}
-					</span>
-					<span className={`codicon codicon-chevron-${isExpanded ? "up" : "down"}`}></span>
-				</div>
-			)}
-			{(!path || isExpanded) && (
-				<div
-					//className="code-block-scrollable" this doesn't seem to be necessary anymore, on silicon macs it shows the native mac scrollbar instead of the vscode styled one
-					style={{
-						overflowX: "auto",
-						overflowY: "hidden",
-						maxWidth: "100%",
-					}}>
-					<SyntaxHighlighter
-						wrapLines={false}
-						language={diff ? "diff" : inferredLanguage} // "diff" automatically colors changed lines in green/red
-						style={{
-							...syntaxHighlighterStyle,
-							// Our syntax highlighter style doesn't always match the vscode theme 1:1, so we'll apply sensible styles here that vscode exposes to us
-							'code[class*="language-"]': {
-								background: "var(--vscode-editor-background)",
-							},
-							'pre[class*="language-"]': {
-								background: "var(--vscode-editor-background)",
-							},
-						}}
-						customStyle={{
-							margin: 0,
-							padding: "6px 10px",
-							/*
-							overflowX: auto + inner div with padding results in an issue where the top/left/bottom padding renders but the right padding inside does not count as overflow as the width of the element is not exceeded. Once the inner div is outside the boundaries of the parent it counts as overflow.
-							https://stackoverflow.com/questions/60778406/why-is-padding-right-clipped-with-overflowscroll/77292459#77292459
-							this fixes the issue of right padding clipped off 
-							“ideal” size in a given axis when given infinite available space--allows the syntax highlighter to grow to largest possible width including its padding
-							*/
-							minWidth: "max-content",
-							borderRadius: 0,
-							fontSize: "var(--vscode-editor-font-size)",
-							lineHeight: "var(--vscode-editor-line-height)",
-							fontFamily: "var(--vscode-editor-font-family)",
-						}}>
-						{code ?? diff ?? ""}
-					</SyntaxHighlighter>
-				</div>
-			)}
+			<StyledMarkdown>{reactContent}</StyledMarkdown>
 		</div>
 	)
-}
-// memo does shallow comparison of props, so if you need it to re-render when a nested object changes, you need to pass a custom comparison function
-export default memo(CodeBlock)
+})
+
+export default CodeBlock

+ 7 - 1
webview-ui/src/context/ExtensionStateContext.tsx

@@ -3,10 +3,12 @@ import { useEvent } from "react-use"
 import { ExtensionMessage, ExtensionState } from "../../../src/shared/ExtensionMessage"
 import { ApiConfiguration } from "../../../src/shared/api"
 import { vscode } from "../utils/vscode"
+import { convertTextMateToHljs } from "../utils/textMateToHljs"
 
 interface ExtensionStateContextType extends ExtensionState {
 	didHydrateState: boolean
 	showWelcome: boolean
+	theme: any
 	setApiConfiguration: (config: ApiConfiguration) => void
 	setCustomInstructions: (value?: string) => void
 	setAlwaysAllowReadOnly: (value: boolean) => void
@@ -24,7 +26,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
 	})
 	const [didHydrateState, setDidHydrateState] = useState(false)
 	const [showWelcome, setShowWelcome] = useState(false)
-
+	const [theme, setTheme] = useState<any>(undefined)
 	const handleMessage = useCallback((event: MessageEvent) => {
 		const message: ExtensionMessage = event.data
 		if (message.type === "state" && message.state) {
@@ -43,6 +45,9 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
 			setShowWelcome(!hasKey)
 			setDidHydrateState(true)
 		}
+		if (message.type === "theme" && message.text) {
+			setTheme(convertTextMateToHljs(JSON.parse(message.text)))
+		}
 	}, [])
 
 	useEvent("message", handleMessage)
@@ -55,6 +60,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
 		...state,
 		didHydrateState,
 		showWelcome,
+		theme,
 		setApiConfiguration: (value) => setState((prevState) => ({ ...prevState, apiConfiguration: value })),
 		setCustomInstructions: (value) => setState((prevState) => ({ ...prevState, customInstructions: value })),
 		setAlwaysAllowReadOnly: (value) => setState((prevState) => ({ ...prevState, alwaysAllowReadOnly: value })),

+ 0 - 89
webview-ui/src/utils/getSyntaxHighlighterStyleFromTheme.ts

@@ -1,89 +0,0 @@
-import * as defaultThemes from "react-syntax-highlighter/dist/esm/styles/prism"
-import * as generatedThemes from "./vscode-themes"
-
-/*
-VSCode extension webviews have a notoriously difficult time syntax highlighting with styles from the user's theme. We don’t have access to css variables like --vscode-function-color that map to all the token styles react-syntax-highlighter expects. Fortunately, react-syntax-highlighter comes with many built-in themes that we can map to popular VSCode themes. We can also use the few editor css variables exposed to use like --vscode-editor-background (see CodeBlock.tsx), which 99% of the time results in syntax highlighting identical to how the user's editor looks. This approach avoids the overhead of using VSCode's Monaco editor and the monaco-vscode-textmate-theme-converter as some other extensions do, and allows us to take advantage of all the benefits of react-syntax-highlighter.
-For themes that don't have a 1:1 match with react-syntax-highlighter built-in themes, we can use Claude to generate style objects based on the results from the "Developer: Generate Color Theme From Current Settings" command.
-
-https://github.com/microsoft/vscode/issues/56356
-*/
-
-// See https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/AVAILABLE_STYLES_PRISM.MD for available styles react-syntax-highlighter provides
-const defaultSyntaxHighlighterThemes: { [key: string]: string } = {
-	// Vscode built-in
-	"Default Dark Modern": "vscDarkPlus",
-	"Dark+": "vscDarkPlus",
-	"Default Dark+": "vscDarkPlus",
-	"Dark (Visual Studio)": "vscDarkPlus",
-	"Visual Studio Dark": "vscDarkPlus",
-	"Dark High Contrast": "vscDarkPlus",
-	"Default High Contrast": "vscDarkPlus",
-	"Light High Contrast": "vs",
-	"Default High Contrast Light": "vs", // FIXME: some text renders white
-	"Default Light Modern": "vs",
-	"Light+": "vs",
-	"Default Light+": "vs",
-	"Light (Visual Studio)": "vs",
-	"Visual Studio Light": "vs",
-
-	// Third party
-	Anysphere: "nightOwl",
-	Abyss: "materialOceanic",
-	"Kimbie Dark": "cb",
-	Monokai: "darcula",
-	"Monokai Dimmed": "darcula",
-	"Solarized Dark": "solarizedDarkAtom",
-	"Solarized Light": "solarizedlight",
-	"Quiet Light": "solarizedlight",
-	"Tomorrow Night Blue": "lucario",
-	Dracula: "dracula",
-	"Dracula Theme": "dracula",
-	"Dracula Theme Soft": "dracula",
-	"Night Owl": "nightOwl",
-	"Material Theme": "materialDark",
-	"Material Theme Lighter": "materialLight",
-	"Material Theme Lighter High Contrast": "materialLight",
-	"One Dark Pro": "oneDark",
-	"One Dark Pro Darker": "oneDark",
-	"One Dark Pro Flat": "oneDark",
-	"One Dark Pro Mix": "oneDark",
-	"One Light": "oneLight",
-	"Winter is Coming": "nord",
-	"Atom One Dark": "oneDark",
-	"SynthWave '84": "synthwave84",
-}
-
-// Themes that don't have an already provided 1:1 syntax highlighter style
-// These style objects are built with Claude using the results from "Developer: Generate Color Theme From Current Settings" command
-const generatedSyntaxHighlighterThemes: { [key: string]: string } = {
-	"Github Dark": "githubDark",
-	"GitHub Dark Colorblind (Beta)": "githubDark",
-	"GitHub Dark Colorblind": "githubDark",
-	"GitHub Dark Default": "githubDark",
-	"GitHub Dark Dimmed": "githubDark",
-	"GitHub Dark High Contrast": "githubDark",
-
-	"Github Light": "githubLight",
-	"GitHub Light Colorblind (Beta)": "githubLight",
-	"GitHub Light Colorblind": "githubLight",
-	"GitHub Light Default": "githubLight",
-	"GitHub Light High Contrast": "githubLight",
-}
-
-export type SyntaxHighlighterStyle = { [key: string]: React.CSSProperties }
-
-export function getSyntaxHighlighterStyleFromTheme(themeName: string): SyntaxHighlighterStyle | undefined {
-	const defaultSyntaxHighlighterTheme = Object.entries(defaultSyntaxHighlighterThemes).find(([key]) =>
-		key.toLowerCase().startsWith(themeName.toLowerCase())
-	)?.[1]
-	if (defaultSyntaxHighlighterTheme && defaultSyntaxHighlighterTheme in defaultThemes) {
-		return defaultThemes[defaultSyntaxHighlighterTheme as keyof typeof defaultThemes]
-	} else {
-		const generatedSyntaxHighlighterTheme = Object.entries(generatedSyntaxHighlighterThemes).find(([key]) =>
-			key.toLowerCase().startsWith(themeName.toLowerCase())
-		)?.[1]
-		if (generatedSyntaxHighlighterTheme && generatedSyntaxHighlighterTheme in generatedThemes) {
-			return generatedThemes[generatedSyntaxHighlighterTheme as keyof typeof generatedThemes]
-		}
-	}
-}

+ 156 - 0
webview-ui/src/utils/textMateToHljs.ts

@@ -0,0 +1,156 @@
+const hljsToTextMate: Record<string, string[]> = {
+	".hljs-comment": ["comment"],
+	".hljs-tag": ["tag"],
+	".hljs-doctag": ["keyword"],
+	".hljs-keyword": ["keyword"],
+	".hljs-meta .hljs-keyword": ["keyword"],
+	".hljs-template-tag": ["keyword"],
+	".hljs-template-variable": ["keyword"],
+	".hljs-type": ["keyword"],
+	".hljs-variable.language_": ["keyword"],
+	".hljs-title": ["title", "function", "class"],
+	".hljs-title.class_": ["title", "function", "class", "variable"],
+	".hljs-title.class_.inherited__": ["title", "function", "class", "variable"],
+	".hljs-title.function_": ["support.function", "entity.name.function", "title", "function", "class"],
+	".hljs-built_in": ["support.function", "entity.name.function", "title", "function", "class"],
+	".hljs-name": ["constant"],
+	".hljs-attr": ["variable", "operator", "number"],
+	".hljs-attribute": ["attribute", "variable", "operator", "number"],
+	".hljs-literal": ["variable", "operator", "number"],
+	".hljs-meta": ["variable", "operator", "number"],
+	".hljs-number": ["constant.numeric", "number", "variable", "operator"],
+	".hljs-operator": ["variable", "operator", "number"],
+	".hljs-variable": ["variable", "operator", "number"],
+	".hljs-selector-attr": ["variable", "operator", "number"],
+	".hljs-selector-class": ["variable", "operator", "number"],
+	".hljs-selector-id": ["variable", "operator", "number"],
+	".hljs-regexp": ["string"],
+	".hljs-string": ["string"],
+	".hljs-meta .hljs-string": ["string"],
+	".hljs-params": ["variable", "operator", "number"],
+}
+
+type FullColorTheme = {
+	rules?: {
+		token?: string
+		foreground?: string
+	}[]
+}
+
+function constructTheme(tmTheme: FullColorTheme): Record<string, string> {
+	const rules = tmTheme["rules"] || []
+
+	const tokenToForeground: Record<string, string> = {}
+	rules.forEach(({ token, foreground }) => {
+		if (!foreground || !token) {
+			return
+		}
+		tokenToForeground[token] = foreground
+	})
+
+	const theme: Record<string, string> = {}
+	Object.keys(hljsToTextMate).forEach((className) => {
+		const tokens = hljsToTextMate[className]
+		for (const scope of tokens) {
+			if (tokenToForeground[scope]) {
+				theme[className] = tokenToForeground[scope]
+				break
+			}
+		}
+	})
+
+	if (Object.keys(theme).length === 0) {
+		return fallbackTheme()
+	}
+
+	return theme
+}
+
+function fallbackTheme() {
+	const styles = getComputedStyle(document.body)
+	const backgroundColor = styles.getPropertyValue("--vscode-editor-background")
+	const { r, g, b } = parseHexColor(backgroundColor)
+	const avg = (r + g + b) / 3
+
+	return avg >= 128
+		? {
+				".hljs-comment": "#008000",
+				".hljs-doctag": "#0000ff",
+				".hljs-keyword": "#0000ff",
+				".hljs-meta .hljs-keyword": "#0000ff",
+				".hljs-template-tag": "#0000ff",
+				".hljs-template-variable": "#0000ff",
+				".hljs-type": "#0000ff",
+				".hljs-variable.language_": "#0000ff",
+				".hljs-title.class_": "#001080",
+				".hljs-title.class_.inherited__": "#001080",
+				".hljs-title.function_": "#795E26",
+				".hljs-built_in": "#795E26",
+				".hljs-attr": "#001080",
+				".hljs-attribute": "#001080",
+				".hljs-literal": "#001080",
+				".hljs-meta": "#001080",
+				".hljs-number": "#098658",
+				".hljs-operator": "#001080",
+				".hljs-variable": "#001080",
+				".hljs-selector-attr": "#001080",
+				".hljs-selector-class": "#001080",
+				".hljs-selector-id": "#001080",
+				".hljs-regexp": "#a31515",
+				".hljs-string": "#a31515",
+				".hljs-meta .hljs-string": "#a31515",
+				".hljs-params": "#001080",
+		  }
+		: {
+				".hljs-comment": "#6A9955",
+				".hljs-doctag": "#569cd6",
+				".hljs-keyword": "#569cd6",
+				".hljs-meta .hljs-keyword": "#569cd6",
+				".hljs-template-tag": "#569cd6",
+				".hljs-template-variable": "#569cd6",
+				".hljs-type": "#569cd6",
+				".hljs-variable.language_": "#569cd6",
+				".hljs-title.class_": "#9CDCFE",
+				".hljs-title.class_.inherited__": "#9CDCFE",
+				".hljs-title.function_": "#DCDCAA",
+				".hljs-built_in": "#DCDCAA",
+				".hljs-attr": "#9CDCFE",
+				".hljs-attribute": "#9CDCFE",
+				".hljs-literal": "#9CDCFE",
+				".hljs-meta": "#9CDCFE",
+				".hljs-number": "#b5cea8",
+				".hljs-operator": "#9CDCFE",
+				".hljs-variable": "#9CDCFE",
+				".hljs-selector-attr": "#9CDCFE",
+				".hljs-selector-class": "#9CDCFE",
+				".hljs-selector-id": "#9CDCFE",
+				".hljs-regexp": "#ce9178",
+				".hljs-string": "#ce9178",
+				".hljs-meta .hljs-string": "#ce9178",
+				".hljs-params": "#9CDCFE",
+		  }
+}
+
+export function convertTextMateToHljs(fullColorTheme: any) {
+	return constructTheme(fullColorTheme || {})
+}
+
+function parseHexColor(hexColor: string): {
+	r: number
+	g: number
+	b: number
+} {
+	if (hexColor.startsWith("#")) {
+		hexColor = hexColor.slice(1)
+	}
+
+	if (hexColor.length > 6) {
+		hexColor = hexColor.slice(0, 6)
+	}
+
+	const r = parseInt(hexColor.substring(0, 2), 16)
+	const g = parseInt(hexColor.substring(2, 4), 16)
+	const b = parseInt(hexColor.substring(4, 6), 16)
+
+	return { r, g, b }
+}

+ 0 - 503
webview-ui/src/utils/vscode-themes/github-dark.ts

@@ -1,503 +0,0 @@
-const theme: { [key: string]: React.CSSProperties } = {
-	'code[class*="language-"]': {
-		color: "#e1e4e8",
-		background: "#24292e",
-		textShadow: "0 1px rgba(0, 0, 0, 0.3)",
-		fontFamily: '"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',
-		direction: "ltr",
-		textAlign: "left",
-		whiteSpace: "pre",
-		wordSpacing: "normal",
-		wordBreak: "normal",
-		lineHeight: "1.5",
-		MozTabSize: "2",
-		OTabSize: "2",
-		tabSize: "2",
-		WebkitHyphens: "none",
-		MozHyphens: "none",
-		msHyphens: "none",
-		hyphens: "none",
-	},
-	'pre[class*="language-"]': {
-		color: "#e1e4e8",
-		background: "#24292e",
-		textShadow: "0 1px rgba(0, 0, 0, 0.3)",
-		fontFamily: '"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',
-		direction: "ltr",
-		textAlign: "left",
-		whiteSpace: "pre",
-		wordSpacing: "normal",
-		wordBreak: "normal",
-		lineHeight: "1.5",
-		MozTabSize: "2",
-		OTabSize: "2",
-		tabSize: "2",
-		WebkitHyphens: "none",
-		MozHyphens: "none",
-		msHyphens: "none",
-		hyphens: "none",
-		padding: "1em",
-		margin: "0.5em 0",
-		overflow: "auto",
-		borderRadius: "0.3em",
-	},
-	'code[class*="language-"]::-moz-selection': {
-		background: "#3392ff44",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'code[class*="language-"] *::-moz-selection': {
-		background: "#3392ff44",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'pre[class*="language-"] *::-moz-selection': {
-		background: "#3392ff44",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'code[class*="language-"]::selection': {
-		background: "#3392ff44",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'code[class*="language-"] *::selection': {
-		background: "#3392ff44",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'pre[class*="language-"] *::selection': {
-		background: "#3392ff44",
-		color: "inherit",
-		textShadow: "none",
-	},
-	':not(pre) > code[class*="language-"]': {
-		background: "#24292e",
-		padding: "0.1em",
-		borderRadius: "0.3em",
-		whiteSpace: "normal",
-	},
-	comment: {
-		color: "#6A737D",
-		fontStyle: "italic",
-	},
-	prolog: {
-		color: "#6A737D",
-	},
-	cdata: {
-		color: "#6A737D",
-	},
-	doctype: {
-		color: "#e1e4e8",
-	},
-	punctuation: {
-		color: "#e1e4e8",
-	},
-	entity: {
-		color: "#e1e4e8",
-		cursor: "help",
-	},
-	"attr-name": {
-		color: "#79B8FF",
-	},
-	"class-name": {
-		color: "#B392F0",
-	},
-	boolean: {
-		color: "#79B8FF",
-	},
-	constant: {
-		color: "#79B8FF",
-	},
-	number: {
-		color: "#79B8FF",
-	},
-	atrule: {
-		color: "#79B8FF",
-	},
-	keyword: {
-		color: "#F97583",
-	},
-	property: {
-		color: "#79B8FF",
-	},
-	tag: {
-		color: "#85E89D",
-	},
-	symbol: {
-		color: "#79B8FF",
-	},
-	deleted: {
-		color: "#FDAEB7",
-		background: "#86181D",
-	},
-	important: {
-		color: "#F97583",
-	},
-	selector: {
-		color: "#85E89D",
-	},
-	string: {
-		color: "#9ECBFF",
-	},
-	char: {
-		color: "#9ECBFF",
-	},
-	builtin: {
-		color: "#79B8FF",
-	},
-	inserted: {
-		color: "#85E89D",
-		background: "#144620",
-	},
-	regex: {
-		color: "#DBEDFF",
-	},
-	"attr-value": {
-		color: "#9ECBFF",
-	},
-	"attr-value > .token.punctuation": {
-		color: "#9ECBFF",
-	},
-	variable: {
-		color: "#FFAB70",
-	},
-	operator: {
-		color: "#F97583",
-	},
-	function: {
-		color: "#B392F0",
-	},
-	url: {
-		color: "#79B8FF",
-	},
-	"attr-value > .token.punctuation.attr-equals": {
-		color: "#e1e4e8",
-	},
-	"special-attr > .token.attr-value > .token.value.css": {
-		color: "#e1e4e8",
-	},
-	".language-css .token.selector": {
-		color: "#85E89D",
-	},
-	".language-css .token.property": {
-		color: "#79B8FF",
-	},
-	".language-css .token.function": {
-		color: "#79B8FF",
-	},
-	".language-css .token.url > .token.function": {
-		color: "#79B8FF",
-	},
-	".language-css .token.url > .token.string.url": {
-		color: "#9ECBFF",
-	},
-	".language-css .token.important": {
-		color: "#F97583",
-	},
-	".language-css .token.atrule .token.rule": {
-		color: "#F97583",
-	},
-	".language-javascript .token.operator": {
-		color: "#F97583",
-	},
-	".language-javascript .token.template-string > .token.interpolation > .token.interpolation-punctuation.punctuation":
-		{
-			color: "#FDAEB7",
-		},
-	".language-json .token.operator": {
-		color: "#e1e4e8",
-	},
-	".language-json .token.null.keyword": {
-		color: "#79B8FF",
-	},
-	".language-markdown .token.url": {
-		color: "#e1e4e8",
-	},
-	".language-markdown .token.url > .token.operator": {
-		color: "#e1e4e8",
-	},
-	".language-markdown .token.url-reference.url > .token.string": {
-		color: "#e1e4e8",
-	},
-	".language-markdown .token.url > .token.content": {
-		color: "#79B8FF",
-	},
-	".language-markdown .token.url > .token.url": {
-		color: "#79B8FF",
-	},
-	".language-markdown .token.url-reference.url": {
-		color: "#79B8FF",
-	},
-	".language-markdown .token.blockquote.punctuation": {
-		color: "#6A737D",
-		fontStyle: "italic",
-	},
-	".language-markdown .token.hr.punctuation": {
-		color: "#6A737D",
-		fontStyle: "italic",
-	},
-	".language-markdown .token.code-snippet": {
-		color: "#9ECBFF",
-	},
-	".language-markdown .token.bold .token.content": {
-		color: "#79B8FF",
-	},
-	".language-markdown .token.italic .token.content": {
-		color: "#B392F0",
-	},
-	".language-markdown .token.strike .token.content": {
-		color: "#FDAEB7",
-	},
-	".language-markdown .token.strike .token.punctuation": {
-		color: "#FDAEB7",
-	},
-	".language-markdown .token.list.punctuation": {
-		color: "#FDAEB7",
-	},
-	".language-markdown .token.title.important > .token.punctuation": {
-		color: "#FDAEB7",
-	},
-	bold: {
-		fontWeight: "bold",
-	},
-	italic: {
-		fontStyle: "italic",
-	},
-	namespace: {
-		opacity: "0.8",
-	},
-	"token.tab:not(:empty):before": {
-		color: "#6A737D",
-	},
-	"token.cr:before": {
-		color: "#6A737D",
-	},
-	"token.lf:before": {
-		color: "#6A737D",
-	},
-	"token.space:before": {
-		color: "#6A737D",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item": {
-		marginRight: "0.4em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button": {
-		background: "#2f363d",
-		color: "#959da5",
-		padding: "0.1em 0.4em",
-		borderRadius: "0.3em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a": {
-		background: "#2f363d",
-		color: "#959da5",
-		padding: "0.1em 0.4em",
-		borderRadius: "0.3em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span": {
-		background: "#2f363d",
-		color: "#959da5",
-		padding: "0.1em 0.4em",
-		borderRadius: "0.3em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover": {
-		background: "#444d56",
-		color: "#e1e4e8",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus": {
-		background: "#444d56",
-		color: "#e1e4e8",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover": {
-		background: "#444d56",
-		color: "#e1e4e8",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus": {
-		background: "#444d56",
-		color: "#e1e4e8",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover": {
-		background: "#444d56",
-		color: "#e1e4e8",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus": {
-		background: "#444d56",
-		color: "#e1e4e8",
-	},
-	".line-highlight.line-highlight": {
-		background: "#2b3036",
-	},
-	".line-highlight.line-highlight:before": {
-		background: "#2f363d",
-		color: "#e1e4e8",
-		padding: "0.1em 0.6em",
-		borderRadius: "0.3em",
-		boxShadow: "0 2px 0 0 rgba(0, 0, 0, 0.2)",
-	},
-	".line-highlight.line-highlight[data-end]:after": {
-		background: "#2f363d",
-		color: "#e1e4e8",
-		padding: "0.1em 0.6em",
-		borderRadius: "0.3em",
-		boxShadow: "0 2px 0 0 rgba(0, 0, 0, 0.2)",
-	},
-	"pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before": {
-		backgroundColor: "#2b3036",
-	},
-	".line-numbers.line-numbers .line-numbers-rows": {
-		borderRightColor: "#444d56",
-	},
-	".command-line .command-line-prompt": {
-		borderRightColor: "#444d56",
-	},
-	".line-numbers .line-numbers-rows > span:before": {
-		color: "#444d56",
-	},
-	".command-line .command-line-prompt > span:before": {
-		color: "#444d56",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-1": {
-		color: "#FDAEB7",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-5": {
-		color: "#FDAEB7",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-9": {
-		color: "#FDAEB7",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-2": {
-		color: "#9ECBFF",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-6": {
-		color: "#9ECBFF",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-10": {
-		color: "#9ECBFF",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-3": {
-		color: "#79B8FF",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-7": {
-		color: "#79B8FF",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-11": {
-		color: "#79B8FF",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-4": {
-		color: "#B392F0",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-8": {
-		color: "#B392F0",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-12": {
-		color: "#B392F0",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix)": {
-		backgroundColor: "#86181D",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix)": {
-		backgroundColor: "#86181D",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection": {
-		backgroundColor: "#86181D",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "#86181D",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection": {
-		backgroundColor: "#86181D",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "#86181D",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection": {
-		backgroundColor: "#86181D",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection": {
-		backgroundColor: "#86181D",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection": {
-		backgroundColor: "#86181D",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection": {
-		backgroundColor: "#86181D",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix)": {
-		backgroundColor: "#144620",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix)": {
-		backgroundColor: "#144620",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection": {
-		backgroundColor: "#144620",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "#144620",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection": {
-		backgroundColor: "#144620",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "#144620",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection": {
-		backgroundColor: "#144620",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection": {
-		backgroundColor: "#144620",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection": {
-		backgroundColor: "#144620",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection": {
-		backgroundColor: "#144620",
-	},
-	".prism-previewer.prism-previewer:before": {
-		borderColor: "#1b1f23",
-	},
-	".prism-previewer-gradient.prism-previewer-gradient div": {
-		borderColor: "#1b1f23",
-		borderRadius: "0.3em",
-	},
-	".prism-previewer-color.prism-previewer-color:before": {
-		borderRadius: "0.3em",
-	},
-	".prism-previewer-easing.prism-previewer-easing:before": {
-		borderRadius: "0.3em",
-	},
-	".prism-previewer.prism-previewer:after": {
-		borderTopColor: "#1b1f23",
-	},
-	".prism-previewer-flipped.prism-previewer-flipped.after": {
-		borderBottomColor: "#1b1f23",
-	},
-	".prism-previewer-angle.prism-previewer-angle:before": {
-		background: "#1f2428",
-	},
-	".prism-previewer-time.prism-previewer-time:before": {
-		background: "#1f2428",
-	},
-	".prism-previewer-easing.prism-previewer-easing": {
-		background: "#1f2428",
-	},
-	".prism-previewer-angle.prism-previewer-angle circle": {
-		stroke: "#e1e4e8",
-		strokeOpacity: "1",
-	},
-	".prism-previewer-time.prism-previewer-time circle": {
-		stroke: "#e1e4e8",
-		strokeOpacity: "1",
-	},
-	".prism-previewer-easing.prism-previewer-easing circle": {
-		stroke: "#e1e4e8",
-		fill: "transparent",
-	},
-	".prism-previewer-easing.prism-previewer-easing path": {
-		stroke: "#e1e4e8",
-	},
-	".prism-previewer-easing.prism-previewer-easing line": {
-		stroke: "#e1e4e8",
-	},
-}
-
-export default theme

+ 0 - 506
webview-ui/src/utils/vscode-themes/github-light.ts

@@ -1,506 +0,0 @@
-const theme: { [key: string]: React.CSSProperties } = {
-	'code[class*="language-"]': {
-		background: "#ffffff",
-		color: "#24292e",
-		textShadow: "0 1px rgba(0, 0, 0, 0.3)",
-		fontFamily: '"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',
-		direction: "ltr",
-		textAlign: "left",
-		whiteSpace: "pre",
-		wordSpacing: "normal",
-		wordBreak: "normal",
-		lineHeight: "1.5",
-		MozTabSize: "2",
-		OTabSize: "2",
-		tabSize: "2",
-		WebkitHyphens: "none",
-		MozHyphens: "none",
-		msHyphens: "none",
-		hyphens: "none",
-	},
-	'pre[class*="language-"]': {
-		background: "#ffffff",
-		color: "#24292e",
-		textShadow: "0 1px rgba(0, 0, 0, 0.3)",
-		fontFamily: '"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',
-		direction: "ltr",
-		textAlign: "left",
-		whiteSpace: "pre",
-		wordSpacing: "normal",
-		wordBreak: "normal",
-		lineHeight: "1.5",
-		MozTabSize: "2",
-		OTabSize: "2",
-		tabSize: "2",
-		WebkitHyphens: "none",
-		MozHyphens: "none",
-		msHyphens: "none",
-		hyphens: "none",
-		padding: "1em",
-		margin: "0.5em 0",
-		overflow: "auto",
-		borderRadius: "0.3em",
-	},
-	'code[class*="language-"]::-moz-selection': {
-		background: "#0366d625",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'code[class*="language-"] *::-moz-selection': {
-		background: "#0366d625",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'pre[class*="language-"] *::-moz-selection': {
-		background: "#0366d625",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'code[class*="language-"]::selection': {
-		background: "#0366d625",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'code[class*="language-"] *::selection': {
-		background: "#0366d625",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'pre[class*="language-"] *::selection': {
-		background: "#0366d625",
-		color: "inherit",
-		textShadow: "none",
-	},
-	':not(pre) > code[class*="language-"]': {
-		padding: "0.2em 0.3em",
-		borderRadius: "0.3em",
-		whiteSpace: "normal",
-	},
-	comment: {
-		color: "#6A737D",
-		fontStyle: "italic",
-	},
-	prolog: {
-		color: "#6A737D",
-	},
-	cdata: {
-		color: "#6A737D",
-	},
-	doctype: {
-		color: "#24292e",
-	},
-	punctuation: {
-		color: "#24292e",
-	},
-	entity: {
-		color: "#24292e",
-		cursor: "help",
-	},
-	"attr-name": {
-		color: "#6F42C1",
-	},
-	"class-name": {
-		color: "#6F42C1",
-	},
-	boolean: {
-		color: "#005CC5",
-	},
-	constant: {
-		color: "#005CC5",
-	},
-	number: {
-		color: "#005CC5",
-	},
-	atrule: {
-		color: "#005CC5",
-	},
-	keyword: {
-		color: "#D73A49",
-	},
-	property: {
-		color: "#005CC5",
-	},
-	tag: {
-		color: "#22863A",
-	},
-	symbol: {
-		color: "#005CC5",
-	},
-	deleted: {
-		color: "#B31D28",
-		background: "#FFEEF0",
-	},
-	important: {
-		color: "#D73A49",
-	},
-	selector: {
-		color: "#22863A",
-	},
-	string: {
-		color: "#032F62",
-	},
-	char: {
-		color: "#032F62",
-	},
-	builtin: {
-		color: "#005CC5",
-	},
-	inserted: {
-		color: "#22863A",
-		background: "#F0FFF4",
-	},
-	regex: {
-		color: "#032F62",
-	},
-	"attr-value": {
-		color: "#032F62",
-	},
-	"attr-value > .token.punctuation": {
-		color: "#032F62",
-	},
-	variable: {
-		color: "#E36209",
-	},
-	operator: {
-		color: "#D73A49",
-	},
-	function: {
-		color: "#6F42C1",
-	},
-	url: {
-		color: "#005CC5",
-	},
-	"attr-value > .token.punctuation.attr-equals": {
-		color: "#24292e",
-	},
-	"special-attr > .token.attr-value > .token.value.css": {
-		color: "#24292e",
-	},
-	".language-css .token.selector": {
-		color: "#22863A",
-	},
-	".language-css .token.property": {
-		color: "#005CC5",
-	},
-	".language-css .token.function": {
-		color: "#005CC5",
-	},
-	".language-css .token.url > .token.function": {
-		color: "#005CC5",
-	},
-	".language-css .token.url > .token.string.url": {
-		color: "#032F62",
-	},
-	".language-css .token.important": {
-		color: "#D73A49",
-	},
-	".language-css .token.atrule .token.rule": {
-		color: "#D73A49",
-	},
-	".language-javascript .token.operator": {
-		color: "#D73A49",
-	},
-	".language-javascript .token.template-string > .token.interpolation > .token.interpolation-punctuation.punctuation":
-		{
-			color: "#B31D28",
-		},
-	".language-json .token.operator": {
-		color: "#24292e",
-	},
-	".language-json .token.null.keyword": {
-		color: "#005CC5",
-	},
-	".language-markdown .token.url": {
-		color: "#24292e",
-	},
-	".language-markdown .token.url > .token.operator": {
-		color: "#24292e",
-	},
-	".language-markdown .token.url-reference.url > .token.string": {
-		color: "#24292e",
-	},
-	".language-markdown .token.url > .token.content": {
-		color: "#005CC5",
-	},
-	".language-markdown .token.url > .token.url": {
-		color: "#005CC5",
-	},
-	".language-markdown .token.url-reference.url": {
-		color: "#005CC5",
-	},
-	".language-markdown .token.blockquote.punctuation": {
-		color: "#6A737D",
-		fontStyle: "italic",
-	},
-	".language-markdown .token.hr.punctuation": {
-		color: "#6A737D",
-		fontStyle: "italic",
-	},
-	".language-markdown .token.code-snippet": {
-		color: "#032F62",
-	},
-	".language-markdown .token.bold .token.content": {
-		color: "#005CC5",
-	},
-	".language-markdown .token.italic .token.content": {
-		color: "#6F42C1",
-	},
-	".language-markdown .token.strike .token.content": {
-		color: "#B31D28",
-	},
-	".language-markdown .token.strike .token.punctuation": {
-		color: "#B31D28",
-	},
-	".language-markdown .token.list.punctuation": {
-		color: "#B31D28",
-	},
-	".language-markdown .token.title.important > .token.punctuation": {
-		color: "#B31D28",
-	},
-	bold: {
-		fontWeight: "bold",
-	},
-	italic: {
-		fontStyle: "italic",
-	},
-	namespace: {
-		opacity: "0.8",
-	},
-	"token.tab:not(:empty):before": {
-		color: "#24292e33",
-		textShadow: "none",
-	},
-	"token.cr:before": {
-		color: "#24292e33",
-		textShadow: "none",
-	},
-	"token.lf:before": {
-		color: "#24292e33",
-		textShadow: "none",
-	},
-	"token.space:before": {
-		color: "#24292e33",
-		textShadow: "none",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item": {
-		marginRight: "0.4em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button": {
-		background: "#f6f8fa",
-		color: "#24292e",
-		padding: "0.1em 0.4em",
-		borderRadius: "0.3em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a": {
-		background: "#f6f8fa",
-		color: "#24292e",
-		padding: "0.1em 0.4em",
-		borderRadius: "0.3em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span": {
-		background: "#f6f8fa",
-		color: "#24292e",
-		padding: "0.1em 0.4em",
-		borderRadius: "0.3em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover": {
-		background: "#e1e4e8",
-		color: "#2f363d",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus": {
-		background: "#e1e4e8",
-		color: "#2f363d",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover": {
-		background: "#e1e4e8",
-		color: "#2f363d",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus": {
-		background: "#e1e4e8",
-		color: "#2f363d",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover": {
-		background: "#e1e4e8",
-		color: "#2f363d",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus": {
-		background: "#e1e4e8",
-		color: "#2f363d",
-	},
-	".line-highlight.line-highlight": {
-		background: "#f6f8fa",
-	},
-	".line-highlight.line-highlight:before": {
-		background: "#f6f8fa",
-		color: "#24292e",
-		padding: "0.1em 0.6em",
-		borderRadius: "0.3em",
-		boxShadow: "0 2px 0 0 rgba(0, 0, 0, 0.2)",
-	},
-	".line-highlight.line-highlight[data-end]:after": {
-		background: "#f6f8fa",
-		color: "#24292e",
-		padding: "0.1em 0.6em",
-		borderRadius: "0.3em",
-		boxShadow: "0 2px 0 0 rgba(0, 0, 0, 0.2)",
-	},
-	"pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before": {
-		backgroundColor: "#f6f8fa",
-	},
-	".line-numbers.line-numbers .line-numbers-rows": {
-		borderRightColor: "#e1e4e8",
-	},
-	".command-line .command-line-prompt": {
-		borderRightColor: "#e1e4e8",
-	},
-	".line-numbers .line-numbers-rows > span:before": {
-		color: "#1b1f234d",
-	},
-	".command-line .command-line-prompt > span:before": {
-		color: "#1b1f234d",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-1": {
-		color: "#B31D28",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-5": {
-		color: "#B31D28",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-9": {
-		color: "#B31D28",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-2": {
-		color: "#22863A",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-6": {
-		color: "#22863A",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-10": {
-		color: "#22863A",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-3": {
-		color: "#005CC5",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-7": {
-		color: "#005CC5",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-11": {
-		color: "#005CC5",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-4": {
-		color: "#6F42C1",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-8": {
-		color: "#6F42C1",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-12": {
-		color: "#6F42C1",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix)": {
-		backgroundColor: "#FFEEF0",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix)": {
-		backgroundColor: "#FFEEF0",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection": {
-		backgroundColor: "#FFEEF0",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "#FFEEF0",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection": {
-		backgroundColor: "#FFEEF0",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "#FFEEF0",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection": {
-		backgroundColor: "#FFEEF0",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection": {
-		backgroundColor: "#FFEEF0",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection": {
-		backgroundColor: "#FFEEF0",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection": {
-		backgroundColor: "#FFEEF0",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix)": {
-		backgroundColor: "#F0FFF4",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix)": {
-		backgroundColor: "#F0FFF4",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection": {
-		backgroundColor: "#F0FFF4",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "#F0FFF4",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection": {
-		backgroundColor: "#F0FFF4",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "#F0FFF4",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection": {
-		backgroundColor: "#F0FFF4",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection": {
-		backgroundColor: "#F0FFF4",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection": {
-		backgroundColor: "#F0FFF4",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection": {
-		backgroundColor: "#F0FFF4",
-	},
-	".prism-previewer.prism-previewer:before": {
-		borderColor: "#ffffff",
-	},
-	".prism-previewer-gradient.prism-previewer-gradient div": {
-		borderColor: "#ffffff",
-		borderRadius: "0.3em",
-	},
-	".prism-previewer-color.prism-previewer-color:before": {
-		borderRadius: "0.3em",
-	},
-	".prism-previewer-easing.prism-previewer-easing:before": {
-		borderRadius: "0.3em",
-	},
-	".prism-previewer.prism-previewer:after": {
-		borderTopColor: "#ffffff",
-	},
-	".prism-previewer-flipped.prism-previewer-flipped.after": {
-		borderBottomColor: "#ffffff",
-	},
-	".prism-previewer-angle.prism-previewer-angle:before": {
-		background: "#f6f8fa",
-	},
-	".prism-previewer-time.prism-previewer-time:before": {
-		background: "#f6f8fa",
-	},
-	".prism-previewer-easing.prism-previewer-easing": {
-		background: "#f6f8fa",
-	},
-	".prism-previewer-angle.prism-previewer-angle circle": {
-		stroke: "#24292e",
-		strokeOpacity: "1",
-	},
-	".prism-previewer-time.prism-previewer-time circle": {
-		stroke: "#24292e",
-		strokeOpacity: "1",
-	},
-	".prism-previewer-easing.prism-previewer-easing circle": {
-		stroke: "#24292e",
-		fill: "transparent",
-	},
-	".prism-previewer-easing.prism-previewer-easing path": {
-		stroke: "#24292e",
-	},
-	".prism-previewer-easing.prism-previewer-easing line": {
-		stroke: "#24292e",
-	},
-}
-
-export default theme

+ 0 - 2
webview-ui/src/utils/vscode-themes/index.ts

@@ -1,2 +0,0 @@
-export { default as githubLight } from "./github-light"
-export { default as githubDark } from "./github-dark"

+ 0 - 503
webview-ui/src/utils/vscode-themes/one-dark-example.ts

@@ -1,503 +0,0 @@
-const theme: { [key: string]: React.CSSProperties } = {
-	'code[class*="language-"]': {
-		background: "hsl(220, 13%, 18%)",
-		color: "hsl(220, 14%, 71%)",
-		textShadow: "0 1px rgba(0, 0, 0, 0.3)",
-		fontFamily: '"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',
-		direction: "ltr",
-		textAlign: "left",
-		whiteSpace: "pre",
-		wordSpacing: "normal",
-		wordBreak: "normal",
-		lineHeight: "1.5",
-		MozTabSize: "2",
-		OTabSize: "2",
-		tabSize: "2",
-		WebkitHyphens: "none",
-		MozHyphens: "none",
-		msHyphens: "none",
-		hyphens: "none",
-	},
-	'pre[class*="language-"]': {
-		background: "hsl(220, 13%, 18%)",
-		color: "hsl(220, 14%, 71%)",
-		textShadow: "0 1px rgba(0, 0, 0, 0.3)",
-		fontFamily: '"Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace',
-		direction: "ltr",
-		textAlign: "left",
-		whiteSpace: "pre",
-		wordSpacing: "normal",
-		wordBreak: "normal",
-		lineHeight: "1.5",
-		MozTabSize: "2",
-		OTabSize: "2",
-		tabSize: "2",
-		WebkitHyphens: "none",
-		MozHyphens: "none",
-		msHyphens: "none",
-		hyphens: "none",
-		padding: "1em",
-		margin: "0.5em 0",
-		overflow: "auto",
-		borderRadius: "0.3em",
-	},
-	'code[class*="language-"]::-moz-selection': {
-		background: "hsl(220, 13%, 28%)",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'code[class*="language-"] *::-moz-selection': {
-		background: "hsl(220, 13%, 28%)",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'pre[class*="language-"] *::-moz-selection': {
-		background: "hsl(220, 13%, 28%)",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'code[class*="language-"]::selection': {
-		background: "hsl(220, 13%, 28%)",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'code[class*="language-"] *::selection': {
-		background: "hsl(220, 13%, 28%)",
-		color: "inherit",
-		textShadow: "none",
-	},
-	'pre[class*="language-"] *::selection': {
-		background: "hsl(220, 13%, 28%)",
-		color: "inherit",
-		textShadow: "none",
-	},
-	':not(pre) > code[class*="language-"]': {
-		padding: "0.2em 0.3em",
-		borderRadius: "0.3em",
-		whiteSpace: "normal",
-	},
-	comment: {
-		color: "hsl(220, 10%, 40%)",
-		fontStyle: "italic",
-	},
-	prolog: {
-		color: "hsl(220, 10%, 40%)",
-	},
-	cdata: {
-		color: "hsl(220, 10%, 40%)",
-	},
-	doctype: {
-		color: "hsl(220, 14%, 71%)",
-	},
-	punctuation: {
-		color: "hsl(220, 14%, 71%)",
-	},
-	entity: {
-		color: "hsl(220, 14%, 71%)",
-		cursor: "help",
-	},
-	"attr-name": {
-		color: "hsl(29, 54%, 61%)",
-	},
-	"class-name": {
-		color: "hsl(29, 54%, 61%)",
-	},
-	boolean: {
-		color: "hsl(29, 54%, 61%)",
-	},
-	constant: {
-		color: "hsl(29, 54%, 61%)",
-	},
-	number: {
-		color: "hsl(29, 54%, 61%)",
-	},
-	atrule: {
-		color: "hsl(29, 54%, 61%)",
-	},
-	keyword: {
-		color: "hsl(286, 60%, 67%)",
-	},
-	property: {
-		color: "hsl(355, 65%, 65%)",
-	},
-	tag: {
-		color: "hsl(355, 65%, 65%)",
-	},
-	symbol: {
-		color: "hsl(355, 65%, 65%)",
-	},
-	deleted: {
-		color: "hsl(355, 65%, 65%)",
-	},
-	important: {
-		color: "hsl(355, 65%, 65%)",
-	},
-	selector: {
-		color: "hsl(95, 38%, 62%)",
-	},
-	string: {
-		color: "hsl(95, 38%, 62%)",
-	},
-	char: {
-		color: "hsl(95, 38%, 62%)",
-	},
-	builtin: {
-		color: "hsl(95, 38%, 62%)",
-	},
-	inserted: {
-		color: "hsl(95, 38%, 62%)",
-	},
-	regex: {
-		color: "hsl(95, 38%, 62%)",
-	},
-	"attr-value": {
-		color: "hsl(95, 38%, 62%)",
-	},
-	"attr-value > .token.punctuation": {
-		color: "hsl(95, 38%, 62%)",
-	},
-	variable: {
-		color: "hsl(207, 82%, 66%)",
-	},
-	operator: {
-		color: "hsl(207, 82%, 66%)",
-	},
-	function: {
-		color: "hsl(207, 82%, 66%)",
-	},
-	url: {
-		color: "hsl(187, 47%, 55%)",
-	},
-	"attr-value > .token.punctuation.attr-equals": {
-		color: "hsl(220, 14%, 71%)",
-	},
-	"special-attr > .token.attr-value > .token.value.css": {
-		color: "hsl(220, 14%, 71%)",
-	},
-	".language-css .token.selector": {
-		color: "hsl(355, 65%, 65%)",
-	},
-	".language-css .token.property": {
-		color: "hsl(220, 14%, 71%)",
-	},
-	".language-css .token.function": {
-		color: "hsl(187, 47%, 55%)",
-	},
-	".language-css .token.url > .token.function": {
-		color: "hsl(187, 47%, 55%)",
-	},
-	".language-css .token.url > .token.string.url": {
-		color: "hsl(95, 38%, 62%)",
-	},
-	".language-css .token.important": {
-		color: "hsl(286, 60%, 67%)",
-	},
-	".language-css .token.atrule .token.rule": {
-		color: "hsl(286, 60%, 67%)",
-	},
-	".language-javascript .token.operator": {
-		color: "hsl(286, 60%, 67%)",
-	},
-	".language-javascript .token.template-string > .token.interpolation > .token.interpolation-punctuation.punctuation":
-		{
-			color: "hsl(5, 48%, 51%)",
-		},
-	".language-json .token.operator": {
-		color: "hsl(220, 14%, 71%)",
-	},
-	".language-json .token.null.keyword": {
-		color: "hsl(29, 54%, 61%)",
-	},
-	".language-markdown .token.url": {
-		color: "hsl(220, 14%, 71%)",
-	},
-	".language-markdown .token.url > .token.operator": {
-		color: "hsl(220, 14%, 71%)",
-	},
-	".language-markdown .token.url-reference.url > .token.string": {
-		color: "hsl(220, 14%, 71%)",
-	},
-	".language-markdown .token.url > .token.content": {
-		color: "hsl(207, 82%, 66%)",
-	},
-	".language-markdown .token.url > .token.url": {
-		color: "hsl(187, 47%, 55%)",
-	},
-	".language-markdown .token.url-reference.url": {
-		color: "hsl(187, 47%, 55%)",
-	},
-	".language-markdown .token.blockquote.punctuation": {
-		color: "hsl(220, 10%, 40%)",
-		fontStyle: "italic",
-	},
-	".language-markdown .token.hr.punctuation": {
-		color: "hsl(220, 10%, 40%)",
-		fontStyle: "italic",
-	},
-	".language-markdown .token.code-snippet": {
-		color: "hsl(95, 38%, 62%)",
-	},
-	".language-markdown .token.bold .token.content": {
-		color: "hsl(29, 54%, 61%)",
-	},
-	".language-markdown .token.italic .token.content": {
-		color: "hsl(286, 60%, 67%)",
-	},
-	".language-markdown .token.strike .token.content": {
-		color: "hsl(355, 65%, 65%)",
-	},
-	".language-markdown .token.strike .token.punctuation": {
-		color: "hsl(355, 65%, 65%)",
-	},
-	".language-markdown .token.list.punctuation": {
-		color: "hsl(355, 65%, 65%)",
-	},
-	".language-markdown .token.title.important > .token.punctuation": {
-		color: "hsl(355, 65%, 65%)",
-	},
-	bold: {
-		fontWeight: "bold",
-	},
-	italic: {
-		fontStyle: "italic",
-	},
-	namespace: {
-		opacity: "0.8",
-	},
-	"token.tab:not(:empty):before": {
-		color: "hsla(220, 14%, 71%, 0.15)",
-		textShadow: "none",
-	},
-	"token.cr:before": {
-		color: "hsla(220, 14%, 71%, 0.15)",
-		textShadow: "none",
-	},
-	"token.lf:before": {
-		color: "hsla(220, 14%, 71%, 0.15)",
-		textShadow: "none",
-	},
-	"token.space:before": {
-		color: "hsla(220, 14%, 71%, 0.15)",
-		textShadow: "none",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item": {
-		marginRight: "0.4em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button": {
-		background: "hsl(220, 13%, 26%)",
-		color: "hsl(220, 9%, 55%)",
-		padding: "0.1em 0.4em",
-		borderRadius: "0.3em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a": {
-		background: "hsl(220, 13%, 26%)",
-		color: "hsl(220, 9%, 55%)",
-		padding: "0.1em 0.4em",
-		borderRadius: "0.3em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span": {
-		background: "hsl(220, 13%, 26%)",
-		color: "hsl(220, 9%, 55%)",
-		padding: "0.1em 0.4em",
-		borderRadius: "0.3em",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover": {
-		background: "hsl(220, 13%, 28%)",
-		color: "hsl(220, 14%, 71%)",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus": {
-		background: "hsl(220, 13%, 28%)",
-		color: "hsl(220, 14%, 71%)",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover": {
-		background: "hsl(220, 13%, 28%)",
-		color: "hsl(220, 14%, 71%)",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus": {
-		background: "hsl(220, 13%, 28%)",
-		color: "hsl(220, 14%, 71%)",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover": {
-		background: "hsl(220, 13%, 28%)",
-		color: "hsl(220, 14%, 71%)",
-	},
-	"div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus": {
-		background: "hsl(220, 13%, 28%)",
-		color: "hsl(220, 14%, 71%)",
-	},
-	".line-highlight.line-highlight": {
-		background: "hsla(220, 100%, 80%, 0.04)",
-	},
-	".line-highlight.line-highlight:before": {
-		background: "hsl(220, 13%, 26%)",
-		color: "hsl(220, 14%, 71%)",
-		padding: "0.1em 0.6em",
-		borderRadius: "0.3em",
-		boxShadow: "0 2px 0 0 rgba(0, 0, 0, 0.2)",
-	},
-	".line-highlight.line-highlight[data-end]:after": {
-		background: "hsl(220, 13%, 26%)",
-		color: "hsl(220, 14%, 71%)",
-		padding: "0.1em 0.6em",
-		borderRadius: "0.3em",
-		boxShadow: "0 2px 0 0 rgba(0, 0, 0, 0.2)",
-	},
-	"pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before": {
-		backgroundColor: "hsla(220, 100%, 80%, 0.04)",
-	},
-	".line-numbers.line-numbers .line-numbers-rows": {
-		borderRightColor: "hsla(220, 14%, 71%, 0.15)",
-	},
-	".command-line .command-line-prompt": {
-		borderRightColor: "hsla(220, 14%, 71%, 0.15)",
-	},
-	".line-numbers .line-numbers-rows > span:before": {
-		color: "hsl(220, 14%, 45%)",
-	},
-	".command-line .command-line-prompt > span:before": {
-		color: "hsl(220, 14%, 45%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-1": {
-		color: "hsl(355, 65%, 65%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-5": {
-		color: "hsl(355, 65%, 65%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-9": {
-		color: "hsl(355, 65%, 65%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-2": {
-		color: "hsl(95, 38%, 62%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-6": {
-		color: "hsl(95, 38%, 62%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-10": {
-		color: "hsl(95, 38%, 62%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-3": {
-		color: "hsl(207, 82%, 66%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-7": {
-		color: "hsl(207, 82%, 66%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-11": {
-		color: "hsl(207, 82%, 66%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-4": {
-		color: "hsl(286, 60%, 67%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-8": {
-		color: "hsl(286, 60%, 67%)",
-	},
-	".rainbow-braces .token.token.punctuation.brace-level-12": {
-		color: "hsl(286, 60%, 67%)",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix)": {
-		backgroundColor: "hsla(353, 100%, 66%, 0.15)",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix)": {
-		backgroundColor: "hsla(353, 100%, 66%, 0.15)",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection": {
-		backgroundColor: "hsla(353, 95%, 66%, 0.25)",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "hsla(353, 95%, 66%, 0.25)",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection": {
-		backgroundColor: "hsla(353, 95%, 66%, 0.25)",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "hsla(353, 95%, 66%, 0.25)",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection": {
-		backgroundColor: "hsla(353, 95%, 66%, 0.25)",
-	},
-	"pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection": {
-		backgroundColor: "hsla(353, 95%, 66%, 0.25)",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection": {
-		backgroundColor: "hsla(353, 95%, 66%, 0.25)",
-	},
-	"pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection": {
-		backgroundColor: "hsla(353, 95%, 66%, 0.25)",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix)": {
-		backgroundColor: "hsla(137, 100%, 55%, 0.15)",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix)": {
-		backgroundColor: "hsla(137, 100%, 55%, 0.15)",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection": {
-		backgroundColor: "hsla(135, 73%, 55%, 0.25)",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "hsla(135, 73%, 55%, 0.25)",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection": {
-		backgroundColor: "hsla(135, 73%, 55%, 0.25)",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection": {
-		backgroundColor: "hsla(135, 73%, 55%, 0.25)",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection": {
-		backgroundColor: "hsla(135, 73%, 55%, 0.25)",
-	},
-	"pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection": {
-		backgroundColor: "hsla(135, 73%, 55%, 0.25)",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection": {
-		backgroundColor: "hsla(135, 73%, 55%, 0.25)",
-	},
-	"pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection": {
-		backgroundColor: "hsla(135, 73%, 55%, 0.25)",
-	},
-	".prism-previewer.prism-previewer:before": {
-		borderColor: "hsl(224, 13%, 17%)",
-	},
-	".prism-previewer-gradient.prism-previewer-gradient div": {
-		borderColor: "hsl(224, 13%, 17%)",
-		borderRadius: "0.3em",
-	},
-	".prism-previewer-color.prism-previewer-color:before": {
-		borderRadius: "0.3em",
-	},
-	".prism-previewer-easing.prism-previewer-easing:before": {
-		borderRadius: "0.3em",
-	},
-	".prism-previewer.prism-previewer:after": {
-		borderTopColor: "hsl(224, 13%, 17%)",
-	},
-	".prism-previewer-flipped.prism-previewer-flipped.after": {
-		borderBottomColor: "hsl(224, 13%, 17%)",
-	},
-	".prism-previewer-angle.prism-previewer-angle:before": {
-		background: "hsl(219, 13%, 22%)",
-	},
-	".prism-previewer-time.prism-previewer-time:before": {
-		background: "hsl(219, 13%, 22%)",
-	},
-	".prism-previewer-easing.prism-previewer-easing": {
-		background: "hsl(219, 13%, 22%)",
-	},
-	".prism-previewer-angle.prism-previewer-angle circle": {
-		stroke: "hsl(220, 14%, 71%)",
-		strokeOpacity: "1",
-	},
-	".prism-previewer-time.prism-previewer-time circle": {
-		stroke: "hsl(220, 14%, 71%)",
-		strokeOpacity: "1",
-	},
-	".prism-previewer-easing.prism-previewer-easing circle": {
-		stroke: "hsl(220, 14%, 71%)",
-		fill: "transparent",
-	},
-	".prism-previewer-easing.prism-previewer-easing path": {
-		stroke: "hsl(220, 14%, 71%)",
-	},
-	".prism-previewer-easing.prism-previewer-easing line": {
-		stroke: "hsl(220, 14%, 71%)",
-	},
-}
-export default theme

Некоторые файлы не были показаны из-за большого количества измененных файлов