Merge branch 'main' into project_search2

Piotr Osiewicz created

Change summary

.github/workflows/release_nightly.yml                              |    3 
Cargo.lock                                                         |   43 
Cargo.toml                                                         |    2 
assets/themes/src/vscode/palenight/palenight-mild-contrast.json    | 3138 
assets/themes/src/vscode/palenight/palenight-operator.json         | 3280 
assets/themes/src/vscode/palenight/palenight.json                  | 3138 
assets/themes/src/vscode/rose-pine/family.json                     |    5 
assets/themes/src/vscode/rose-pine/rose-pine-dawn.json             | 1356 
assets/themes/src/vscode/rose-pine/rose-pine-moon.json             | 1356 
assets/themes/src/vscode/rose-pine/rose-pine.json                  | 1356 
crates/activity_indicator2/src/activity_indicator.rs               |    2 
crates/assistant2/src/assistant.rs                                 |   27 
crates/assistant2/src/assistant_panel.rs                           |    7 
crates/auto_update2/src/auto_update.rs                             |   29 
crates/breadcrumbs2/Cargo.toml                                     |    2 
crates/breadcrumbs2/src/breadcrumbs.rs                             |  104 
crates/channel2/src/channel_store.rs                               |   11 
crates/channel2/src/channel_store/channel_index.rs                 |    8 
crates/client2/src/client2.rs                                      |    2 
crates/collab/Cargo.toml                                           |    2 
crates/collab/src/api.rs                                           |    3 
crates/collab2/src/tests/channel_tests.rs                          |   64 
crates/collab2/src/tests/random_channel_buffer_tests.rs            |    8 
crates/collab_ui2/src/channel_view.rs                              |    2 
crates/collab_ui2/src/chat_panel.rs                                | 1681 
crates/collab_ui2/src/chat_panel/message_editor.rs                 |  105 
crates/collab_ui2/src/collab_panel.rs                              |   64 
crates/collab_ui2/src/collab_panel/channel_modal.rs                |   13 
crates/collab_ui2/src/collab_panel/contact_finder.rs               |    2 
crates/collab_ui2/src/collab_titlebar_item.rs                      |  983 
crates/collab_ui2/src/collab_ui.rs                                 |   14 
crates/collab_ui2/src/face_pile.rs                                 |   62 
crates/collab_ui2/src/notifications.rs                             |    4 
crates/collab_ui2/src/notifications/incoming_call_notification.rs  |  164 
crates/collab_ui2/src/notifications/project_shared_notification.rs |  185 
crates/command_palette2/src/command_palette.rs                     |   30 
crates/copilot2/src/copilot2.rs                                    |   15 
crates/diagnostics2/src/diagnostics.rs                             |    2 
crates/editor/src/editor.rs                                        |    4 
crates/editor/src/rust_analyzer_ext.rs                             |   98 
crates/editor2/src/editor.rs                                       |  287 
crates/editor2/src/element.rs                                      |  556 
crates/editor2/src/hover_popover.rs                                |    2 
crates/editor2/src/rust_analyzer_ext.rs                            |  119 
crates/editor2/src/scroll.rs                                       |   13 
crates/feedback2/src/deploy_feedback_button.rs                     |    2 
crates/feedback2/src/feedback2.rs                                  |   13 
crates/feedback2/src/feedback_modal.rs                             |  317 
crates/file_finder2/src/file_finder.rs                             |    6 
crates/go_to_line2/src/go_to_line.rs                               |    5 
crates/gpui2/docs/key_dispatch.md                                  |    2 
crates/gpui2/src/action.rs                                         |  122 
crates/gpui2/src/app.rs                                            |    9 
crates/gpui2/src/element.rs                                        |   18 
crates/gpui2/src/elements/list.rs                                  |  496 
crates/gpui2/src/elements/mod.rs                                   |    2 
crates/gpui2/src/elements/uniform_list.rs                          |    2 
crates/gpui2/src/gpui2.rs                                          |   45 
crates/gpui2/src/interactive.rs                                    |    8 
crates/gpui2/src/key_dispatch.rs                                   |   14 
crates/gpui2/src/keymap/context.rs                                 |    5 
crates/gpui2/src/platform/mac/metal_renderer.rs                    |    5 
crates/gpui2/src/shared_string.rs                                  |  101 
crates/gpui2/src/styled.rs                                         |   14 
crates/gpui2/src/window.rs                                         |   24 
crates/gpui2/tests/action_macros.rs                                |   13 
crates/gpui2_macros/src/action.rs                                  |   96 
crates/gpui2_macros/src/gpui2_macros.rs                            |   12 
crates/gpui2_macros/src/register_action.rs                         |   44 
crates/install_cli2/src/install_cli2.rs                            |    2 
crates/language_selector2/src/language_selector.rs                 |    5 
crates/live_kit_client2/examples/test_app2.rs                      |    6 
crates/menu2/src/menu2.rs                                          |   19 
crates/outline2/src/outline.rs                                     |   44 
crates/project/src/lsp_command.rs                                  |    2 
crates/project/src/lsp_ext_command.rs                              |  137 
crates/project/src/project.rs                                      |    8 
crates/project2/src/lsp_command.rs                                 |    2 
crates/project2/src/lsp_ext_command.rs                             |  137 
crates/project2/src/project2.rs                                    |    8 
crates/project_panel2/src/project_panel.rs                         |   37 
crates/recent_projects2/src/projects.rs                            |    1 
crates/recent_projects2/src/recent_projects.rs                     |   13 
crates/rich_text2/src/rich_text.rs                                 |  292 
crates/rpc/proto/zed.proto                                         |   15 
crates/rpc/src/proto.rs                                            |    4 
crates/rpc2/proto/zed.proto                                        |   15 
crates/rpc2/src/proto.rs                                           |    4 
crates/search/src/project_search.rs                                |  117 
crates/search2/src/buffer_search.rs                                |   70 
crates/search2/src/mode.rs                                         |   14 
crates/search2/src/project_search.rs                               |  134 
crates/search2/src/search.rs                                       |   57 
crates/search2/src/search_bar.rs                                   |   42 
crates/settings2/src/keymap_file.rs                                |    6 
crates/storybook2/src/stories/focus.rs                             |    2 
crates/storybook2/src/story_selector.rs                            |    2 
crates/terminal2/src/terminal2.rs                                  |   15 
crates/terminal_view2/src/terminal_element.rs                      |   60 
crates/terminal_view2/src/terminal_panel.rs                        |    2 
crates/terminal_view2/src/terminal_view.rs                         |  106 
crates/theme2/src/registry.rs                                      |   13 
crates/theme2/src/theme2.rs                                        |    9 
crates/theme2/src/themes/andromeda.rs                              |  230 
crates/theme2/src/themes/ayu.rs                                    |  292 
crates/theme2/src/themes/dracula.rs                                |   95 
crates/theme2/src/themes/gruvbox.rs                                |  536 
crates/theme2/src/themes/night_owl.rs                              |  252 
crates/theme2/src/themes/noctis.rs                                 |  479 
crates/theme2/src/themes/nord.rs                                   |   92 
crates/theme2/src/themes/palenight.rs                              |  354 
crates/theme2/src/themes/rose_pine.rs                              |  391 
crates/theme2/src/themes/solarized.rs                              |  235 
crates/theme2/src/themes/synthwave_84.rs                           |  124 
crates/theme_importer/Cargo.toml                                   |    3 
crates/theme_importer/src/color.rs                                 |   54 
crates/theme_importer/src/main.rs                                  |   46 
crates/theme_importer/src/theme_printer.rs                         |    9 
crates/theme_importer/src/vscode/converter.rs                      |  184 
crates/theme_importer/src/vscode/syntax.rs                         |  358 
crates/theme_importer/src/vscode/theme.rs                          | 1411 
crates/theme_selector2/src/theme_selector.rs                       |   36 
crates/ui2/src/components.rs                                       |    2 
crates/ui2/src/components/avatar.rs                                |   69 
crates/ui2/src/components/button/button.rs                         |   47 
crates/ui2/src/components/button/button_like.rs                    |   13 
crates/ui2/src/components/context_menu.rs                          |    6 
crates/ui2/src/components/icon.rs                                  |    3 
crates/ui2/src/components/keybinding.rs                            |   12 
crates/ui2/src/components/stories.rs                               |    2 
crates/ui2/src/components/stories/context_menu.rs                  |    2 
crates/ui2/src/components/stories/keybinding.rs                    |    5 
crates/ui2/src/components/stories/tab.rs                           |  114 
crates/ui2/src/components/tab.rs                                   |  198 
crates/ui2/src/prelude.rs                                          |    2 
crates/welcome2/src/base_keymap_picker.rs                          |    5 
crates/workspace2/src/dock.rs                                      |   21 
crates/workspace2/src/modal_layer.rs                               |   68 
crates/workspace2/src/pane.rs                                      |  535 
crates/workspace2/src/status_bar.rs                                |   33 
crates/workspace2/src/workspace2.rs                                |  117 
crates/zed2/build.rs                                               |   18 
crates/zed2/src/zed2.rs                                            |   57 
crates/zed_actions2/src/lib.rs                                     |    8 
script/upload-nightly                                              |    2 
145 files changed, 15,645 insertions(+), 12,001 deletions(-)

Detailed changes

.github/workflows/release_nightly.yml 🔗

@@ -81,12 +81,11 @@ jobs:
             - name: Limit target directory size
               run: script/clear-target-dir-if-larger-than 100
 
-            - name: Set release channel to nightly, add nightly prefix to the final version
+            - name: Set release channel to nightly
               run: |
                   set -eu
                   version=$(git rev-parse --short HEAD)
                   echo "Publishing version: ${version} on release channel nightly"
-                  sed -i '' "s/version = \"\(.*\)\"/version = \"\1-nightly\"/" crates/zed2/Cargo.toml
                   echo "nightly" > crates/zed/RELEASE_CHANNEL
 
             - name: Generate license file

Cargo.lock 🔗

@@ -312,6 +312,15 @@ version = "1.0.75"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
 
+[[package]]
+name = "approx"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
+dependencies = [
+ "num-traits",
+]
+
 [[package]]
 name = "arrayref"
 version = "0.3.7"
@@ -1145,6 +1154,7 @@ dependencies = [
  "gpui2",
  "itertools 0.10.5",
  "language2",
+ "outline2",
  "project2",
  "search2",
  "settings2",
@@ -1743,7 +1753,7 @@ dependencies = [
 
 [[package]]
 name = "collab"
-version = "0.30.0"
+version = "0.30.1"
 dependencies = [
  "anyhow",
  "async-trait",
@@ -3162,6 +3172,12 @@ dependencies = [
  "regex",
 ]
 
+[[package]]
+name = "fast-srgb8"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1"
+
 [[package]]
 name = "fastrand"
 version = "1.9.0"
@@ -6263,6 +6279,28 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
 
+[[package]]
+name = "palette"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2e2f34147767aa758aa649415b50a69eeb46a67f9dc7db8011eeb3d84b351dc"
+dependencies = [
+ "approx",
+ "fast-srgb8",
+ "palette_derive",
+]
+
+[[package]]
+name = "palette_derive"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7db010ec5ff3d4385e4f133916faacd9dad0f6a09394c92d825b3aed310fa0a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.37",
+]
+
 [[package]]
 name = "parity-tokio-ipc"
 version = "0.9.0"
@@ -9696,6 +9734,7 @@ dependencies = [
  "indexmap 1.9.3",
  "json_comments",
  "log",
+ "palette",
  "rust-embed",
  "serde",
  "simplelog",
@@ -10464,7 +10503,7 @@ dependencies = [
 [[package]]
 name = "tree-sitter-vue"
 version = "0.0.1"
-source = "git+https://github.com/zed-industries/tree-sitter-vue?rev=9b6cb221ccb8d0b956fcb17e9a1efac2feefeb58#9b6cb221ccb8d0b956fcb17e9a1efac2feefeb58"
+source = "git+https://github.com/zed-industries/tree-sitter-vue?rev=6608d9d60c386f19d80af7d8132322fa11199c42#6608d9d60c386f19d80af7d8132322fa11199c42"
 dependencies = [
  "cc",
  "tree-sitter",

Cargo.toml 🔗

@@ -205,7 +205,7 @@ tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml",
 tree-sitter-lua = "0.0.14"
 tree-sitter-nix = { git = "https://github.com/nix-community/tree-sitter-nix", rev = "66e3e9ce9180ae08fc57372061006ef83f0abde7" }
 tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "786689b0562b9799ce53e824cb45a1a2a04dc673"}
-tree-sitter-vue = {git = "https://github.com/zed-industries/tree-sitter-vue", rev = "9b6cb221ccb8d0b956fcb17e9a1efac2feefeb58"}
+tree-sitter-vue = {git = "https://github.com/zed-industries/tree-sitter-vue", rev = "6608d9d60c386f19d80af7d8132322fa11199c42"}
 tree-sitter-uiua = {git = "https://github.com/shnarazk/tree-sitter-uiua", rev = "9260f11be5900beda4ee6d1a24ab8ddfaf5a19b2"}
 
 [patch.crates-io]

assets/themes/src/vscode/palenight/palenight-mild-contrast.json 🔗

@@ -1,1569 +1,1569 @@
-{

-  "name": "Palenight (Mild Contrast)",

-  "author": "Olaolu Olawuyi",

-  "maintainers": ["Olaolu Olawuyi <mrolaolu@gmail.com>"],

-  "type": "dark",

-  "semanticClass": "palenight-mild-contrast",

-  "colors": {

-    "contrastActiveBorder": null,

-    "contrastBorder": "#2C2F40",

-    "focusBorder": "#2C2F40",

-    "foreground": "#ffffff",

-    "widget.shadow": "#232635",

-    "selection.background": "#7580B850",

-    "descriptionForeground": null,

-    "errorForeground": "#EF5350",

-    "button.background": "#7e57c2cc",

-    "button.foreground": "#ffffffcc",

-    "button.hoverBackground": "#7e57c2",

-    "dropdown.background": "#292D3E",

-    "dropdown.border": "#7e57c2",

-    "dropdown.foreground": "#ffffffcc",

-    "input.background": "#313850",

-    "input.border": "#7e57c2",

-    "input.foreground": "#ffffffcc",

-    "input.placeholderForeground": "#ffffffcc",

-    "inputOption.activeBorder": "#ffffffcc",

-    "inputValidation.errorBackground": "#ef5350f2",

-    "inputValidation.errorBorder": "#EF5350",

-    "inputValidation.infoBackground": "#64b5f6f2",

-    "inputValidation.infoBorder": "#64B5F6",

-    "inputValidation.warningBackground": "#ffca28f2",

-    "inputValidation.warningBorder": "#FFCA28",

-    "scrollbar.shadow": "#292D3E00",

-    "scrollbarSlider.activeBackground": "#694CA4cc",

-    "scrollbarSlider.background": "#694CA466",

-    "scrollbarSlider.hoverBackground": "#694CA4cc",

-    "badge.background": "#7e57c2",

-    "badge.foreground": "#ffffff",

-    "progress.background": "#7e57c2",

-    "list.activeSelectionBackground": "#7e57c2",

-    "list.activeSelectionForeground": "#ffffff",

-    "list.dropBackground": "#2E3245",

-    "list.focusBackground": "#0000002e",

-    "list.focusForeground": "#ffffff",

-    "list.highlightForeground": "#ffffff",

-    "list.hoverBackground": "#0000001a",

-    "list.hoverForeground": "#ffffff",

-    "list.inactiveSelectionBackground": "#929ac90d",

-    "list.inactiveSelectionForeground": "#929ac9",

-    "activityBar.background": "#242839",

-    "activityBar.dropBackground": "#7e57c2e3",

-    "activityBar.foreground": "#eeffff",

-    "activityBar.border": "#2E3243",

-    "activityBarBadge.background": "#7e57c2",

-    "activityBarBadge.foreground": "#ffffff",

-    "sideBar.background": "#25293A",

-    "sideBar.foreground": "#6C739A",

-    "sideBar.border": "#2C2F40",

-    "sideBarTitle.foreground": "#eeffff",

-    "sideBarSectionHeader.background": "#25293A",

-    "sideBarSectionHeader.foreground": "#eeffff",

-    "editorGroup.background": "#32374C",

-    "editorGroup.border": "#2E3245",

-    "editorGroup.dropBackground": "#7e57c273",

-    "editorGroupHeader.noTabsBackground": "#32374C",

-    "editorGroupHeader.tabsBackground": "#31364a",

-    "editorGroupHeader.tabsBorder": "#2C3041",

-    "tab.activeBackground": "#25293A",

-    "tab.activeForeground": "#eeffff",

-    "tab.border": "#272B3B",

-    "tab.activeBorder": "#2C3041",

-    "tab.unfocusedActiveBorder": "#2C3041",

-    "tab.inactiveBackground": "#31364A",

-    "tab.inactiveForeground": "#929ac9",

-    "tab.unfocusedActiveForeground": null,

-    "tab.unfocusedInactiveForeground": null,

-    "editor.background": "#292D3E",

-    "editor.foreground": "#BFC7D5",

-    "editorLineNumber.foreground": "#4c5374",

-    "editorLineNumber.activeForeground": "#eeffff",

-    "editorCursor.foreground": "#7e57c2",

-    "editorCursor.background": null,

-    "editor.selectionBackground": "#7580B850",

-    "editor.selectionHighlightBackground": "#383D51",

-    "editor.inactiveSelectionBackground": "#7e57c25a",

-    "editor.wordHighlightBackground": "#32374D",

-    "editor.wordHighlightStrongBackground": "#2E3250",

-    "editor.findMatchBackground": "#2e3248fc",

-    "editor.findMatchHighlightBackground": "#7e57c233",

-    "editor.findRangeHighlightBackground": null,

-    "editor.hoverHighlightBackground": "#7e57c25a",

-    "editor.lineHighlightBackground": "#0003",

-    "editor.lineHighlightBorder": null,

-    "editorLink.activeForeground": null,

-    "editor.rangeHighlightBackground": "#7e57c25a",

-    "editorWhitespace.foreground": null,

-    "editorIndentGuide.background": "#4E557980",

-    "editorRuler.foreground": "#4E557980",

-    "editorCodeLens.foreground": "#FFCA28",

-    "editorBracketMatch.background": null,

-    "editorBracketMatch.border": null,

-    "editorOverviewRuler.currentContentForeground": "#7e57c2",

-    "editorOverviewRuler.incomingContentForeground": "#7e57c2",

-    "editorOverviewRuler.commonContentForeground": "#7e57c2",

-    "editorError.foreground": "#EF5350",

-    "editorError.border": null,

-    "editorWarning.foreground": "#FFCA28",

-    "editorWarning.border": null,

-    "editorGutter.background": null,

-    "editorGutter.modifiedBackground": "#e2b93d",

-    "editorGutter.addedBackground": "#9CCC65",

-    "editorGutter.deletedBackground": "#EF5350",

-    "diffEditor.insertedTextBackground": "#99b76d23",

-    "diffEditor.removedTextBackground": "#ef535033",

-    "editorWidget.background": "#31364a",

-    "editorWidget.border": null,

-    "editorSuggestWidget.background": "#2C3043",

-    "editorSuggestWidget.border": "#2B2F40",

-    "editorSuggestWidget.foreground": "#bfc7d5",

-    "editorSuggestWidget.highlightForeground": "#ffffff",

-    "editorSuggestWidget.selectedBackground": "#7e57c2",

-    "editorHoverWidget.background": "#292D3E",

-    "editorHoverWidget.border": "#7e57c2",

-    "debugExceptionWidget.background": "#292D3E",

-    "debugExceptionWidget.border": "#7e57c2",

-    "editorMarkerNavigation.background": "#31364a",

-    "editorMarkerNavigationError.background": "#EF5350",

-    "editorMarkerNavigationWarning.background": "#FFCA28",

-    "peekView.border": "#7e57c2",

-    "peekViewEditor.background": "#232635",

-    "peekViewEditor.matchHighlightBackground": "#7e57c25a",

-    "peekViewResult.background": "#2E3245",

-    "peekViewResult.fileForeground": "#eeffff",

-    "peekViewResult.lineForeground": "#eeffff",

-    "peekViewResult.matchHighlightBackground": "#7e57c25a",

-    "peekViewResult.selectionBackground": "#2E3250",

-    "peekViewResult.selectionForeground": "#eeffff",

-    "peekViewTitle.background": "#292D3E",

-    "peekViewTitleDescription.foreground": "#697098",

-    "peekViewTitleLabel.foreground": "#eeffff",

-    "merge.currentHeaderBackground": "#7e57c25a",

-    "merge.currentContentBackground": null,

-    "merge.incomingHeaderBackground": "#7e57c25a",

-    "merge.incomingContentBackground": null,

-    "merge.border": null,

-    "panel.background": "#25293A",

-    "panel.border": "#2C2F40",

-    "panelTitle.activeBorder": "#7e57c2",

-    "panelTitle.activeForeground": "#eeffff",

-    "panelTitle.inactiveForeground": "#bfc7d580",

-    "statusBar.background": "#25293A",

-    "statusBar.foreground": "#676E95",

-    "statusBar.border": "#2C3041",

-    "statusBar.debuggingBackground": "#202431",

-    "statusBar.debuggingForeground": null,

-    "statusBar.debuggingBorder": "#1F2330",

-    "statusBar.noFolderForeground": null,

-    "statusBar.noFolderBackground": "#292D3E",

-    "statusBar.noFolderBorder": "#25293A",

-    "statusBarItem.activeBackground": "#202431",

-    "statusBarItem.hoverBackground": "#202431",

-    "statusBarItem.prominentBackground": "#202431",

-    "statusBarItem.prominentHoverBackground": "#202431",

-    "titleBar.activeBackground": "#25293A",

-    "titleBar.activeForeground": "#eeefff",

-    "titleBar.border": "#2C3041",

-    "titleBar.inactiveBackground": "#30364c",

-    "titleBar.inactiveForeground": null,

-    "notifications.background": "#292D3E",

-    "notifications.foreground": "#ffffffcc",

-    "notificationLink.foreground": "#80CBC4",

-    "extensionButton.prominentForeground": "#ffffffcc",

-    "extensionButton.prominentBackground": "#7e57c2cc",

-    "extensionButton.prominentHoverBackground": "#7e57c2",

-    "pickerGroup.foreground": "#d1aaff",

-    "pickerGroup.border": "#2E3245",

-    "terminal.ansiWhite": "#ffffff",

-    "terminal.ansiBlack": "#676E95",

-    "terminal.ansiBlue": "#82AAFF",

-    "terminal.ansiCyan": "#89DDFF",

-    "terminal.ansiGreen": "#a9c77d",

-    "terminal.ansiMagenta": "#C792EA",

-    "terminal.ansiRed": "#ff5572",

-    "terminal.ansiYellow": "#FFCB6B",

-    "terminal.ansiBrightWhite": "#ffffff",

-    "terminal.ansiBrightBlack": "#676E95",

-    "terminal.ansiBrightBlue": "#82AAFF",

-    "terminal.ansiBrightCyan": "#89DDFF",

-    "terminal.ansiBrightGreen": "#C3E88D",

-    "terminal.ansiBrightMagenta": "#C792EA",

-    "terminal.ansiBrightRed": "#ff5572",

-    "terminal.ansiBrightYellow": "#FFCB6B",

-    "debugToolBar.background": "#292D3E",

-    "welcomePage.buttonBackground": null,

-    "welcomePage.buttonHoverBackground": null,

-    "walkThrough.embeddedEditorBackground": "#232635",

-    "gitDecoration.modifiedResourceForeground": "#e2c08de6",

-    "gitDecoration.deletedResourceForeground": "#EF535090",

-    "gitDecoration.untrackedResourceForeground": "#a9c77dff",

-    "gitDecoration.ignoredResourceForeground": "#69709890",

-    "gitDecoration.conflictingResourceForeground": "#FFEB95CC",

-    "editorActiveLineNumber.foreground": "#eeffff",

-    "breadcrumb.foreground": "#6c739a",

-    "breadcrumb.focusForeground": "#bfc7d5",

-    "breadcrumb.activeSelectionForeground": "#eeffff",

-    "breadcrumbPicker.background": "#292D3E"

-  },

-  "tokenColors": [

-    {

-      "name": "Global settings",

-      "settings": {

-        "background": "#292D3E",

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Comment",

-      "scope": "comment",

-      "settings": {

-        "foreground": "#697098",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "String",

-      "scope": "string",

-      "settings": {

-        "foreground": "#C3E88D"

-      }

-    },

-    {

-      "name": "String Quoted",

-      "scope": "string.quoted",

-      "settings": {

-        "foreground": "#C3E88D"

-      }

-    },

-    {

-      "name": "String Unquoted",

-      "scope": "string.unquoted",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Support Constant Math",

-      "scope": "support.constant.math",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Number",

-      "scope": ["constant.numeric", "constant.character.numeric"],

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Built-in constant",

-      "scope": [

-        "constant.language",

-        "punctuation.definition.constant",

-        "variable.other.constant"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "User-defined constant",

-      "scope": ["constant.character", "constant.other"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Constant Character Escape",

-      "scope": "constant.character.escape",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "RegExp String",

-      "scope": ["string.regexp", "string.regexp keyword.other"],

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Comma in functions",

-      "scope": "meta.function punctuation.separator.comma",

-      "settings": {

-        "foreground": "#eeffff"

-      }

-    },

-    {

-      "name": "Variable",

-      "scope": "variable",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Keyword",

-      "scope": ["punctuation.accessor", "keyword"],

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Storage",

-      "scope": [

-        "storage",

-        "storage.type",

-        "meta.var.expr storage.type",

-        "storage.type.property.js",

-        "storage.type.property.ts",

-        "storage.type.property.tsx",

-        "meta.class meta.method.declaration meta.var.expr storage.type.js"

-      ],

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Class name",

-      "scope": ["entity.name.class", "meta.class entity.name.type.class"],

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Inherited class",

-      "scope": "entity.other.inherited-class",

-      "settings": {

-        "foreground": "#a9c77d"

-      }

-    },

-    {

-      "name": "Function name",

-      "scope": "entity.name.function",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Function Parameters",

-      "scope": "variable.parameter",

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "Meta Tag",

-      "scope": ["punctuation.definition.tag", "meta.tag"],

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "HTML Tag names",

-      "scope": [

-        "entity.name.tag support.class.component",

-        "meta.tag.other.html",

-        "meta.tag.other.js",

-        "meta.tag.other.tsx",

-        "entity.name.tag.tsx",

-        "entity.name.tag.js",

-        "entity.name.tag",

-        "meta.tag.js",

-        "meta.tag.tsx",

-        "meta.tag.html"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Tag attribute",

-      "scope": "entity.other.attribute-name",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Entity Name Tag Custom",

-      "scope": "entity.name.tag.custom",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Library (function & constant)",

-      "scope": ["support.function", "support.constant"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Support Constant Property Value meta",

-      "scope": "support.constant.meta.property-value",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Library class/type",

-      "scope": ["support.type", "support.class"],

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Support Variable DOM",

-      "scope": "support.variable.dom",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Invalid",

-      "scope": "invalid",

-      "settings": {

-        "background": "#ff2c83",

-        "foreground": "#ffffff"

-      }

-    },

-    {

-      "name": "Invalid deprecated",

-      "scope": "invalid.deprecated",

-      "settings": {

-        "foreground": "#ffffff",

-        "background": "#d3423e"

-      }

-    },

-    {

-      "name": "Keyword Operator",

-      "scope": "keyword.operator",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Keyword Operator Relational",

-      "scope": "keyword.operator.relational",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Keyword Operator Assignment",

-      "scope": "keyword.operator.assignment",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Double-Slashed Comment",

-      "scope": "comment.line.double-slash",

-      "settings": {

-        "foreground": "#697098"

-      }

-    },

-    {

-      "name": "Object",

-      "scope": "object",

-      "settings": {

-        "foreground": "#cdebf7"

-      }

-    },

-    {

-      "name": "Null",

-      "scope": "constant.language.null",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Meta Brace",

-      "scope": "meta.brace",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Meta Delimiter Period",

-      "scope": "meta.delimiter.period",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Punctuation Definition String",

-      "scope": "punctuation.definition.string",

-      "settings": {

-        "foreground": "#d9f5dd"

-      }

-    },

-    {

-      "name": "Boolean",

-      "scope": "constant.language.boolean",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Object Comma",

-      "scope": "object.comma",

-      "settings": {

-        "foreground": "#ffffff"

-      }

-    },

-    {

-      "name": "Variable Parameter Function",

-      "scope": "variable.parameter.function",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Support Type Property Name & entity name tags",

-      "scope": [

-        "support.type.vendored.property-name",

-        "support.constant.vendored.property-value",

-        "support.type.property-name",

-        "meta.property-list entity.name.tag"

-      ],

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Entity Name tag reference in stylesheets",

-      "scope": "meta.property-list entity.name.tag.reference",

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Constant Other Color RGB Value Punctuation Definition Constant",

-      "scope": "constant.other.color.rgb-value punctuation.definition.constant",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Constant Other Color",

-      "scope": "constant.other.color",

-      "settings": {

-        "foreground": "#FFEB95"

-      }

-    },

-    {

-      "name": "Keyword Other Unit",

-      "scope": "keyword.other.unit",

-      "settings": {

-        "foreground": "#FFEB95"

-      }

-    },

-    {

-      "name": "Meta Selector",

-      "scope": "meta.selector",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Entity Other Attribute Name Id",

-      "scope": "entity.other.attribute-name.id",

-      "settings": {

-        "foreground": "#FAD430"

-      }

-    },

-    {

-      "name": "Meta Property Name",

-      "scope": "meta.property-name",

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Doctypes",

-      "scope": ["entity.name.tag.doctype", "meta.tag.sgml.doctype"],

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Punctuation Definition Parameters",

-      "scope": "punctuation.definition.parameters",

-      "settings": {

-        "foreground": "#d9f5dd"

-      }

-    },

-    {

-      "name": "Keyword Control Operator",

-      "scope": "keyword.control.operator",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Keyword Operator Logical",

-      "scope": "keyword.operator.logical",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Variable Instances",

-      "scope": [

-        "variable.instance",

-        "variable.other.instance",

-        "variable.reaedwrite.instance",

-        "variable.other.readwrite.instance"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Variable Property Other",

-      "scope": ["variable.other.property", "variable.other.object.property"],

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Entity Name Function",

-      "scope": "entity.name.function",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Keyword Operator Comparison",

-      "scope": "keyword.operator.comparison",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Support Constant, `new` keyword, Special Method Keyword",

-      "scope": [

-        "support.constant",

-        "keyword.other.special-method",

-        "keyword.other.new"

-      ],

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Support Function",

-      "scope": "support.function",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Invalid Broken",

-      "scope": "invalid.broken",

-      "settings": {

-        "foreground": "#020e14",

-        "background": "#F78C6C"

-      }

-    },

-    {

-      "name": "Invalid Unimplemented",

-      "scope": "invalid.unimplemented",

-      "settings": {

-        "background": "#8BD649",

-        "foreground": "#ffffff"

-      }

-    },

-    {

-      "name": "Invalid Illegal",

-      "scope": "invalid.illegal",

-      "settings": {

-        "foreground": "#ffffff",

-        "background": "#ec5f67"

-      }

-    },

-    {

-      "name": "Language Variable",

-      "scope": "variable.language",

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Support Variable Property",

-      "scope": "support.variable.property",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Variable Function",

-      "scope": "variable.function",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Variable Interpolation",

-      "scope": "variable.interpolation",

-      "settings": {

-        "foreground": "#ec5f67"

-      }

-    },

-    {

-      "name": "Meta Function Call",

-      "scope": "meta.function-call",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Punctuation Section Embedded",

-      "scope": "punctuation.section.embedded",

-      "settings": {

-        "foreground": "#d3423e"

-      }

-    },

-    {

-      "name": "Punctuation Tweaks",

-      "scope": [

-        "punctuation.terminator.expression",

-        "punctuation.definition.arguments",

-        "punctuation.definition.array",

-        "punctuation.section.array",

-        "meta.array"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "More Punctuation Tweaks",

-      "scope": [

-        "punctuation.definition.list.begin",

-        "punctuation.definition.list.end",

-        "punctuation.separator.arguments",

-        "punctuation.definition.list"

-      ],

-      "settings": {

-        "foreground": "#d9f5dd"

-      }

-    },

-    {

-      "name": "Template Strings",

-      "scope": "string.template meta.template.expression",

-      "settings": {

-        "foreground": "#d3423e"

-      }

-    },

-    {

-      "name": "Backtics(``) in Template Strings",

-      "scope": "string.template punctuation.definition.string",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Italics",

-      "scope": "italic",

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Bold",

-      "scope": "bold",

-      "settings": {

-        "foreground": "#ffcb6b",

-        "fontStyle": "bold"

-      }

-    },

-    {

-      "name": "Quote",

-      "scope": "quote",

-      "settings": {

-        "foreground": "#697098",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Raw Code",

-      "scope": "raw",

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "CoffeScript Variable Assignment",

-      "scope": "variable.assignment.coffee",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "CoffeScript Parameter Function",

-      "scope": "variable.parameter.function.coffee",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "CoffeeScript Assignments",

-      "scope": "variable.assignment.coffee",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "C# Readwrite Variables",

-      "scope": "variable.other.readwrite.cs",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "C# Classes & Storage types",

-      "scope": ["entity.name.type.class.cs", "storage.type.cs"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "C# Namespaces",

-      "scope": "entity.name.type.namespace.cs",

-      "settings": {

-        "foreground": "#B2CCD6"

-      }

-    },

-    {

-      "name": "Tag names in Stylesheets",

-      "scope": [

-        "entity.name.tag.css",

-        "entity.name.tag.less",

-        "entity.name.tag.custom.css"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Wildcard(*) selector in Stylesheets",

-      "scope": [

-        "entity.name.tag.wildcard.css",

-        "entity.name.tag.wildcard.less",

-        "entity.name.tag.wildcard.scss",

-        "entity.name.tag.wildcard.sass"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "(C|SC|SA|LE)SS property value unit",

-      "scope": [

-        "keyword.other.unit.css",

-        "constant.length.units.css",

-        "keyword.other.unit.less",

-        "constant.length.units.less",

-        "keyword.other.unit.scss",

-        "constant.length.units.scss",

-        "keyword.other.unit.sass",

-        "constant.length.units.sass"

-      ],

-      "settings": {

-        "foreground": "#FFEB95"

-      }

-    },

-    {

-      "name": "Attribute Name for CSS",

-      "scope": "meta.attribute-selector.css entity.other.attribute-name.attribute",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "punctuations in styled components",

-      "scope": [

-        "source.js source.css meta.property-list",

-        "source.js source.css punctuation.section",

-        "source.js source.css punctuation.terminator.rule",

-        "source.js source.css punctuation.definition.entity.end.bracket",

-        "source.js source.css punctuation.definition.entity.begin.bracket",

-        "source.js source.css punctuation.separator.key-value",

-        "source.js source.css punctuation.definition.attribute-selector",

-        "source.js source.css meta.property-list",

-        "source.js source.css meta.property-list punctuation.separator.comma",

-        "source.ts source.css punctuation.section",

-        "source.ts source.css punctuation.terminator.rule",

-        "source.ts source.css punctuation.definition.entity.end.bracket",

-        "source.ts source.css punctuation.definition.entity.begin.bracket",

-        "source.ts source.css punctuation.separator.key-value",

-        "source.ts source.css punctuation.definition.attribute-selector",

-        "source.ts source.css meta.property-list",

-        "source.ts source.css meta.property-list punctuation.separator.comma"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Elixir Classes",

-      "scope": [

-        "source.elixir support.type.elixir",

-        "source.elixir meta.module.elixir entity.name.class.elixir"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Elixir Functions",

-      "scope": "source.elixir entity.name.function",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Elixir Constants",

-      "scope": [

-        "source.elixir constant.other.symbol.elixir",

-        "source.elixir constant.other.keywords.elixir"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Elixir String Punctuations",

-      "scope": "source.elixir punctuation.definition.string",

-      "settings": {

-        "foreground": "#a9c77d"

-      }

-    },

-    {

-      "name": "Elixir",

-      "scope": [

-        "source.elixir variable.other.readwrite.module.elixir",

-        "source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir"

-      ],

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Elixir Binary Punctuations",

-      "scope": "source.elixir .punctuation.binary.elixir",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Go Function Calls",

-      "scope": "source.go meta.function-call.go",

-      "settings": {

-        "foreground": "#DDDDDD"

-      }

-    },

-    {

-      "name": "GraphQL Variables",

-      "scope": "variable.qraphql",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "ID Attribute Name in HTML",

-      "scope": "entity.other.attribute-name.id.html",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "HTML Punctuation Definition Tag",

-      "scope": "punctuation.definition.tag.html",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "HTML Doctype",

-      "scope": "meta.tag.sgml.doctype.html",

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "JavaScript Classes",

-      "scope": "meta.class entity.name.type.class.js",

-      "settings": {

-        "foreground": "#ffcb8b"

-      }

-    },

-    {

-      "name": "JavaScript Method Declaration e.g. `constructor`",

-      "scope": "meta.method.declaration storage.type.js",

-      "settings": {

-        "foreground": "#82AAFF",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "JavaScript Terminator",

-      "scope": "terminator.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Meta Punctuation Definition",

-      "scope": "meta.js punctuation.definition.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Entity Names in Code Documentations",

-      "scope": [

-        "entity.name.type.instance.jsdoc",

-        "entity.name.type.instance.phpdoc"

-      ],

-      "settings": {

-        "foreground": "#eeffff"

-      }

-    },

-    {

-      "name": "Other Variables in Code Documentations",

-      "scope": ["variable.other.jsdoc", "variable.other.phpdoc"],

-      "settings": {

-        "foreground": "#78ccf0"

-      }

-    },

-    {

-      "name": "JavaScript module imports and exports",

-      "scope": [

-        "variable.other.meta.import.js",

-        "meta.import.js variable.other",

-        "variable.other.meta.export.js",

-        "meta.export.js variable.other"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Variable Parameter Function",

-      "scope": "variable.parameter.function.js",

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "JavaScript Variable Other ReadWrite",

-      "scope": "variable.other.readwrite.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Text nested in React tags",

-      "scope": [

-        "meta.jsx.children",

-        "meta.jsx.children.js",

-        "meta.jsx.children.tsx"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript[React] Variable Other Object",

-      "scope": [

-        "variable.other.object.js",

-        "variable.other.object.jsx",

-        "meta.object-literal.key.js",

-        "meta.object-literal.key.jsx",

-        "variable.object.property.js",

-        "variable.object.property.jsx"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Variables",

-      "scope": ["variable.js", "variable.other.js"],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Entity Name Type",

-      "scope": ["entity.name.type.js", "entity.name.type.module.js"],

-      "settings": {

-        "foreground": "#ffcb8b"

-      }

-    },

-    {

-      "name": "JavaScript Support Classes",

-      "scope": "support.class.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JSON Property Names",

-      "scope": "support.type.property-name.json",

-      "settings": {

-        "foreground": "#C3E88D",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "JSON Support Constants",

-      "scope": "support.constant.json",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "JSON Property values (string)",

-      "scope": "meta.structure.dictionary.value.json string.quoted.double",

-      "settings": {

-        "foreground": "#80CBC4",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "Strings in JSON values",

-      "scope": "string.quoted.double.json punctuation.definition.string.json",

-      "settings": {

-        "foreground": "#80CBC4",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "Specific JSON Property values like null",

-      "scope": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Ruby Variables",

-      "scope": "variable.other.ruby",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Ruby Hashkeys",

-      "scope": "constant.language.symbol.hashkey.ruby",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "LESS Tag names",

-      "scope": "entity.name.tag.less",

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Attribute Name for LESS",

-      "scope": "meta.attribute-selector.less entity.other.attribute-name.attribute",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Markup Headings",

-      "scope": "markup.heading",

-      "settings": {

-        "foreground": "#82b1ff"

-      }

-    },

-    {

-      "name": "Markup Italics",

-      "scope": "markup.italic",

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Markup Bold",

-      "scope": "markup.bold",

-      "settings": {

-        "foreground": "#ffcb6b",

-        "fontStyle": "bold"

-      }

-    },

-    {

-      "name": "Markup Quote + others",

-      "scope": "markup.quote",

-      "settings": {

-        "foreground": "#697098",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Markup Raw Code + others",

-      "scope": "markup.inline.raw",

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Markup Links",

-      "scope": ["markup.underline.link", "markup.underline.link.image"],

-      "settings": {

-        "foreground": "#ff869a"

-      }

-    },

-    {

-      "name": "Markup Attributes",

-      "scope": ["markup.meta.attribute-list"],

-      "settings": {

-        "foreground": "#a9c77d"

-      }

-    },

-    {

-      "name": "Markup Admonitions",

-      "scope": "markup.admonition",

-      "settings": {

-        "fontStyle": "bold"

-      }

-    },

-    {

-      "name": "Markup Lists",

-      "scope": "markup.list.bullet",

-      "settings": {

-        "foreground": "#D9F5DD"

-      }

-    },

-    {

-      "name": "Markup Superscript and Subscript",

-      "scope": ["markup.superscript", "markup.subscript"],

-      "settings": {

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Markdown Link Title and Description",

-      "scope": [

-        "string.other.link.title.markdown",

-        "string.other.link.description.markdown"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Markdown Punctuation",

-      "scope": [

-        "punctuation.definition.string.markdown",

-        "punctuation.definition.string.begin.markdown",

-        "punctuation.definition.string.end.markdown",

-        "meta.link.inline.markdown punctuation.definition.string"

-      ],

-      "settings": {

-        "foreground": "#82b1ff"

-      }

-    },

-    {

-      "name": "Markdown MetaData Punctuation",

-      "scope": ["punctuation.definition.metadata.markdown"],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Markdown List Punctuation",

-      "scope": ["beginning.punctuation.definition.list.markdown"],

-      "settings": {

-        "foreground": "#82b1ff"

-      }

-    },

-    {

-      "name": "Asciidoc Function",

-      "scope": "entity.name.function.asciidoc",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "PHP Variables",

-      "scope": "variable.other.php",

-      "settings": {

-        "foreground": "#bec5d4"

-      }

-    },

-    {

-      "name": "Support Classes in PHP",

-      "scope": "support.class.php",

-      "settings": {

-        "foreground": "#ffcb8b"

-      }

-    },

-    {

-      "name": "Punctuations in PHP function calls",

-      "scope": "meta.function-call.php punctuation",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "PHP Global Variables",

-      "scope": "variable.other.global.php",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Declaration Punctuation in PHP Global Variables",

-      "scope": "variable.other.global.php punctuation.definition.variable",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Language Constants in Python",

-      "scope": "constant.language.python",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Python Function Parameter and Arguments",

-      "scope": [

-        "variable.parameter.function.python",

-        "meta.function-call.arguments.python"

-      ],

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "Python Function Call",

-      "scope": [

-        "meta.function-call.python",

-        "meta.function-call.generic.python"

-      ],

-      "settings": {

-        "foreground": "#B2CCD6"

-      }

-    },

-    {

-      "name": "Punctuations in Python",

-      "scope": "punctuation.python",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Decorator Functions in Python",

-      "scope": "entity.name.function.decorator.python",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Python Language Variable",

-      "scope": "source.python variable.language.special",

-      "settings": {

-        "foreground": "#8EACE3"

-      }

-    },

-    {

-      "name": "SCSS Variable",

-      "scope": [

-        "variable.scss",

-        "variable.sass",

-        "variable.parameter.url.scss",

-        "variable.parameter.url.sass"

-      ],

-      "settings": {

-        "foreground": "#DDDDDD"

-      }

-    },

-    {

-      "name": "Variables in SASS At-Rules",

-      "scope": [

-        "source.css.scss meta.at-rule variable",

-        "source.css.sass meta.at-rule variable"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Variables in SASS At-Rules",

-      "scope": [

-        "source.css.scss meta.at-rule variable",

-        "source.css.sass meta.at-rule variable"

-      ],

-      "settings": {

-        "foreground": "#bec5d4"

-      }

-    },

-    {

-      "name": "Attribute Name for SASS",

-      "scope": [

-        "meta.attribute-selector.scss entity.other.attribute-name.attribute",

-        "meta.attribute-selector.sass entity.other.attribute-name.attribute"

-      ],

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Tag names in SASS",

-      "scope": ["entity.name.tag.scss", "entity.name.tag.sass"],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "TypeScript[React] Variables and Object Properties",

-      "scope": [

-        "variable.other.readwrite.alias.ts",

-        "variable.other.readwrite.alias.tsx",

-        "variable.other.readwrite.ts",

-        "variable.other.readwrite.tsx",

-        "variable.other.object.ts",

-        "variable.other.object.tsx",

-        "variable.object.property.ts",

-        "variable.object.property.tsx",

-        "variable.other.ts",

-        "variable.other.tsx",

-        "variable.tsx",

-        "variable.ts"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "TypeScript[React] Entity Name Types",

-      "scope": ["entity.name.type.ts", "entity.name.type.tsx"],

-      "settings": {

-        "foreground": "#78ccf0"

-      }

-    },

-    {

-      "name": "TypeScript[React] Node Classes",

-      "scope": ["support.class.node.ts", "support.class.node.tsx"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "TypeScript[React] Entity Name Types as Parameters",

-      "scope": [

-        "meta.type.parameters.ts entity.name.type",

-        "meta.type.parameters.tsx entity.name.type"

-      ],

-      "settings": {

-        "foreground": "#eeffff"

-      }

-    },

-    {

-      "name": "TypeScript[React] Import/Export Punctuations",

-      "scope": [

-        "meta.import.ts punctuation.definition.block",

-        "meta.import.tsx punctuation.definition.block",

-        "meta.export.ts punctuation.definition.block",

-        "meta.export.tsx punctuation.definition.block"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "TypeScript[React] Punctuation Decorators",

-      "scope": [

-        "meta.decorator punctuation.decorator.ts",

-        "meta.decorator punctuation.decorator.tsx"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "TypeScript[React] Punctuation Decorators",

-      "scope": "meta.tag.js meta.jsx.children.tsx",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "YAML Entity Name Tags",

-      "scope": "entity.name.tag.yaml",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "handlebars variables",

-      "scope": "variable.parameter.handlebars",

-      "settings": {

-        "foreground": "#bec5d4"

-      }

-    },

-    {

-      "name": "handlebars parameters",

-      "scope": "entity.other.attribute-name.handlebars variable.parameter.handlebars",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "handlebars enitity attribute names",

-      "scope": "entity.other.attribute-name.handlebars",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "handlebars enitity attribute values",

-      "scope": "entity.other.attribute-value.handlebars variable.parameter.handlebars",

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "normalize font style of certain components",

-      "scope": [

-        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.begin.js",

-        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.end.js",

-        "meta.property-list.css meta.property-value.css variable.other.less",

-        "punctuation.section.embedded.begin.js.jsx",

-        "punctuation.section.embedded.end.js.jsx",

-        "meta.property-list.scss variable.scss",

-        "meta.property-list.sass variable.sass",

-        "keyword.operator.logical",

-        "keyword.operator.arithmetic",

-        "keyword.operator.bitwise",

-        "keyword.operator.increment",

-        "keyword.operator.ternary",

-        "keyword.operator.comparison",

-        "keyword.operator.assignment",

-        "keyword.operator.operator",

-        "keyword.operator.or.regexp",

-        "keyword.operator.expression.in",

-        "keyword.operator.type",

-        "punctuation.section.embedded.js",

-        "punctuation.definintion.string",

-        "punctuation"

-      ],

-      "settings": {

-        "fontStyle": "normal"

-      }

-    }

-  ]

-}

+{
+  "name": "Palenight (Mild Contrast)",
+  "author": "Olaolu Olawuyi",
+  "maintainers": ["Olaolu Olawuyi <mrolaolu@gmail.com>"],
+  "type": "dark",
+  "semanticClass": "palenight-mild-contrast",
+  "colors": {
+    "contrastActiveBorder": null,
+    "contrastBorder": "#2C2F40",
+    "focusBorder": "#2C2F40",
+    "foreground": "#ffffff",
+    "widget.shadow": "#232635",
+    "selection.background": "#7580B850",
+    "descriptionForeground": null,
+    "errorForeground": "#EF5350",
+    "button.background": "#7e57c2cc",
+    "button.foreground": "#ffffffcc",
+    "button.hoverBackground": "#7e57c2",
+    "dropdown.background": "#292D3E",
+    "dropdown.border": "#7e57c2",
+    "dropdown.foreground": "#ffffffcc",
+    "input.background": "#313850",
+    "input.border": "#7e57c2",
+    "input.foreground": "#ffffffcc",
+    "input.placeholderForeground": "#ffffffcc",
+    "inputOption.activeBorder": "#ffffffcc",
+    "inputValidation.errorBackground": "#ef5350f2",
+    "inputValidation.errorBorder": "#EF5350",
+    "inputValidation.infoBackground": "#64b5f6f2",
+    "inputValidation.infoBorder": "#64B5F6",
+    "inputValidation.warningBackground": "#ffca28f2",
+    "inputValidation.warningBorder": "#FFCA28",
+    "scrollbar.shadow": "#292D3E00",
+    "scrollbarSlider.activeBackground": "#694CA4cc",
+    "scrollbarSlider.background": "#694CA466",
+    "scrollbarSlider.hoverBackground": "#694CA4cc",
+    "badge.background": "#7e57c2",
+    "badge.foreground": "#ffffff",
+    "progress.background": "#7e57c2",
+    "list.activeSelectionBackground": "#7e57c2",
+    "list.activeSelectionForeground": "#ffffff",
+    "list.dropBackground": "#2E3245",
+    "list.focusBackground": "#0000002e",
+    "list.focusForeground": "#ffffff",
+    "list.highlightForeground": "#ffffff",
+    "list.hoverBackground": "#0000001a",
+    "list.hoverForeground": "#ffffff",
+    "list.inactiveSelectionBackground": "#929ac90d",
+    "list.inactiveSelectionForeground": "#929ac9",
+    "activityBar.background": "#242839",
+    "activityBar.dropBackground": "#7e57c2e3",
+    "activityBar.foreground": "#eeffff",
+    "activityBar.border": "#2E3243",
+    "activityBarBadge.background": "#7e57c2",
+    "activityBarBadge.foreground": "#ffffff",
+    "sideBar.background": "#25293A",
+    "sideBar.foreground": "#6C739A",
+    "sideBar.border": "#2C2F40",
+    "sideBarTitle.foreground": "#eeffff",
+    "sideBarSectionHeader.background": "#25293A",
+    "sideBarSectionHeader.foreground": "#eeffff",
+    "editorGroup.background": "#32374C",
+    "editorGroup.border": "#2E3245",
+    "editorGroup.dropBackground": "#7e57c273",
+    "editorGroupHeader.noTabsBackground": "#32374C",
+    "editorGroupHeader.tabsBackground": "#31364a",
+    "editorGroupHeader.tabsBorder": "#2C3041",
+    "tab.activeBackground": "#25293A",
+    "tab.activeForeground": "#eeffff",
+    "tab.border": "#272B3B",
+    "tab.activeBorder": "#2C3041",
+    "tab.unfocusedActiveBorder": "#2C3041",
+    "tab.inactiveBackground": "#31364A",
+    "tab.inactiveForeground": "#929ac9",
+    "tab.unfocusedActiveForeground": null,
+    "tab.unfocusedInactiveForeground": null,
+    "editor.background": "#292D3E",
+    "editor.foreground": "#BFC7D5",
+    "editorLineNumber.foreground": "#4c5374",
+    "editorLineNumber.activeForeground": "#eeffff",
+    "editorCursor.foreground": "#7e57c2",
+    "editorCursor.background": null,
+    "editor.selectionBackground": "#7580B850",
+    "editor.selectionHighlightBackground": "#383D51",
+    "editor.inactiveSelectionBackground": "#7e57c25a",
+    "editor.wordHighlightBackground": "#32374D",
+    "editor.wordHighlightStrongBackground": "#2E3250",
+    "editor.findMatchBackground": "#2e3248fc",
+    "editor.findMatchHighlightBackground": "#7e57c233",
+    "editor.findRangeHighlightBackground": null,
+    "editor.hoverHighlightBackground": "#7e57c25a",
+    "editor.lineHighlightBackground": "#0003",
+    "editor.lineHighlightBorder": null,
+    "editorLink.activeForeground": null,
+    "editor.rangeHighlightBackground": "#7e57c25a",
+    "editorWhitespace.foreground": null,
+    "editorIndentGuide.background": "#4E557980",
+    "editorRuler.foreground": "#4E557980",
+    "editorCodeLens.foreground": "#FFCA28",
+    "editorBracketMatch.background": null,
+    "editorBracketMatch.border": null,
+    "editorOverviewRuler.currentContentForeground": "#7e57c2",
+    "editorOverviewRuler.incomingContentForeground": "#7e57c2",
+    "editorOverviewRuler.commonContentForeground": "#7e57c2",
+    "editorError.foreground": "#EF5350",
+    "editorError.border": null,
+    "editorWarning.foreground": "#FFCA28",
+    "editorWarning.border": null,
+    "editorGutter.background": null,
+    "editorGutter.modifiedBackground": "#e2b93d",
+    "editorGutter.addedBackground": "#9CCC65",
+    "editorGutter.deletedBackground": "#EF5350",
+    "diffEditor.insertedTextBackground": "#99b76d23",
+    "diffEditor.removedTextBackground": "#ef535033",
+    "editorWidget.background": "#31364a",
+    "editorWidget.border": null,
+    "editorSuggestWidget.background": "#2C3043",
+    "editorSuggestWidget.border": "#2B2F40",
+    "editorSuggestWidget.foreground": "#bfc7d5",
+    "editorSuggestWidget.highlightForeground": "#ffffff",
+    "editorSuggestWidget.selectedBackground": "#7e57c2",
+    "editorHoverWidget.background": "#292D3E",
+    "editorHoverWidget.border": "#7e57c2",
+    "debugExceptionWidget.background": "#292D3E",
+    "debugExceptionWidget.border": "#7e57c2",
+    "editorMarkerNavigation.background": "#31364a",
+    "editorMarkerNavigationError.background": "#EF5350",
+    "editorMarkerNavigationWarning.background": "#FFCA28",
+    "peekView.border": "#7e57c2",
+    "peekViewEditor.background": "#232635",
+    "peekViewEditor.matchHighlightBackground": "#7e57c25a",
+    "peekViewResult.background": "#2E3245",
+    "peekViewResult.fileForeground": "#eeffff",
+    "peekViewResult.lineForeground": "#eeffff",
+    "peekViewResult.matchHighlightBackground": "#7e57c25a",
+    "peekViewResult.selectionBackground": "#2E3250",
+    "peekViewResult.selectionForeground": "#eeffff",
+    "peekViewTitle.background": "#292D3E",
+    "peekViewTitleDescription.foreground": "#697098",
+    "peekViewTitleLabel.foreground": "#eeffff",
+    "merge.currentHeaderBackground": "#7e57c25a",
+    "merge.currentContentBackground": null,
+    "merge.incomingHeaderBackground": "#7e57c25a",
+    "merge.incomingContentBackground": null,
+    "merge.border": null,
+    "panel.background": "#25293A",
+    "panel.border": "#2C2F40",
+    "panelTitle.activeBorder": "#7e57c2",
+    "panelTitle.activeForeground": "#eeffff",
+    "panelTitle.inactiveForeground": "#bfc7d580",
+    "statusBar.background": "#25293A",
+    "statusBar.foreground": "#676E95",
+    "statusBar.border": "#2C3041",
+    "statusBar.debuggingBackground": "#202431",
+    "statusBar.debuggingForeground": null,
+    "statusBar.debuggingBorder": "#1F2330",
+    "statusBar.noFolderForeground": null,
+    "statusBar.noFolderBackground": "#292D3E",
+    "statusBar.noFolderBorder": "#25293A",
+    "statusBarItem.activeBackground": "#202431",
+    "statusBarItem.hoverBackground": "#202431",
+    "statusBarItem.prominentBackground": "#202431",
+    "statusBarItem.prominentHoverBackground": "#202431",
+    "titleBar.activeBackground": "#25293A",
+    "titleBar.activeForeground": "#eeefff",
+    "titleBar.border": "#2C3041",
+    "titleBar.inactiveBackground": "#30364c",
+    "titleBar.inactiveForeground": null,
+    "notifications.background": "#292D3E",
+    "notifications.foreground": "#ffffffcc",
+    "notificationLink.foreground": "#80CBC4",
+    "extensionButton.prominentForeground": "#ffffffcc",
+    "extensionButton.prominentBackground": "#7e57c2cc",
+    "extensionButton.prominentHoverBackground": "#7e57c2",
+    "pickerGroup.foreground": "#d1aaff",
+    "pickerGroup.border": "#2E3245",
+    "terminal.ansiWhite": "#ffffff",
+    "terminal.ansiBlack": "#676E95",
+    "terminal.ansiBlue": "#82AAFF",
+    "terminal.ansiCyan": "#89DDFF",
+    "terminal.ansiGreen": "#a9c77d",
+    "terminal.ansiMagenta": "#C792EA",
+    "terminal.ansiRed": "#ff5572",
+    "terminal.ansiYellow": "#FFCB6B",
+    "terminal.ansiBrightWhite": "#ffffff",
+    "terminal.ansiBrightBlack": "#676E95",
+    "terminal.ansiBrightBlue": "#82AAFF",
+    "terminal.ansiBrightCyan": "#89DDFF",
+    "terminal.ansiBrightGreen": "#C3E88D",
+    "terminal.ansiBrightMagenta": "#C792EA",
+    "terminal.ansiBrightRed": "#ff5572",
+    "terminal.ansiBrightYellow": "#FFCB6B",
+    "debugToolBar.background": "#292D3E",
+    "welcomePage.buttonBackground": null,
+    "welcomePage.buttonHoverBackground": null,
+    "walkThrough.embeddedEditorBackground": "#232635",
+    "gitDecoration.modifiedResourceForeground": "#e2c08de6",
+    "gitDecoration.deletedResourceForeground": "#EF535090",
+    "gitDecoration.untrackedResourceForeground": "#a9c77dff",
+    "gitDecoration.ignoredResourceForeground": "#69709890",
+    "gitDecoration.conflictingResourceForeground": "#FFEB95CC",
+    "editorActiveLineNumber.foreground": "#eeffff",
+    "breadcrumb.foreground": "#6c739a",
+    "breadcrumb.focusForeground": "#bfc7d5",
+    "breadcrumb.activeSelectionForeground": "#eeffff",
+    "breadcrumbPicker.background": "#292D3E"
+  },
+  "tokenColors": [
+    {
+      "name": "Global settings",
+      "settings": {
+        "background": "#292D3E",
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Comment",
+      "scope": "comment",
+      "settings": {
+        "foreground": "#697098",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "String",
+      "scope": "string",
+      "settings": {
+        "foreground": "#C3E88D"
+      }
+    },
+    {
+      "name": "String Quoted",
+      "scope": "string.quoted",
+      "settings": {
+        "foreground": "#C3E88D"
+      }
+    },
+    {
+      "name": "String Unquoted",
+      "scope": "string.unquoted",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Support Constant Math",
+      "scope": "support.constant.math",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Number",
+      "scope": ["constant.numeric", "constant.character.numeric"],
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Built-in constant",
+      "scope": [
+        "constant.language",
+        "punctuation.definition.constant",
+        "variable.other.constant"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "User-defined constant",
+      "scope": ["constant.character", "constant.other"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Constant Character Escape",
+      "scope": "constant.character.escape",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "RegExp String",
+      "scope": ["string.regexp", "string.regexp keyword.other"],
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Comma in functions",
+      "scope": "meta.function punctuation.separator.comma",
+      "settings": {
+        "foreground": "#eeffff"
+      }
+    },
+    {
+      "name": "Variable",
+      "scope": "variable",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Keyword",
+      "scope": ["punctuation.accessor", "keyword"],
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Storage",
+      "scope": [
+        "storage",
+        "storage.type",
+        "meta.var.expr storage.type",
+        "storage.type.property.js",
+        "storage.type.property.ts",
+        "storage.type.property.tsx",
+        "meta.class meta.method.declaration meta.var.expr storage.type.js"
+      ],
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Class name",
+      "scope": ["entity.name.class", "meta.class entity.name.type.class"],
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Inherited class",
+      "scope": "entity.other.inherited-class",
+      "settings": {
+        "foreground": "#a9c77d"
+      }
+    },
+    {
+      "name": "Function name",
+      "scope": "entity.name.function",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Function Parameters",
+      "scope": "variable.parameter",
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "Meta Tag",
+      "scope": ["punctuation.definition.tag", "meta.tag"],
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "HTML Tag names",
+      "scope": [
+        "entity.name.tag support.class.component",
+        "meta.tag.other.html",
+        "meta.tag.other.js",
+        "meta.tag.other.tsx",
+        "entity.name.tag.tsx",
+        "entity.name.tag.js",
+        "entity.name.tag",
+        "meta.tag.js",
+        "meta.tag.tsx",
+        "meta.tag.html"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Tag attribute",
+      "scope": "entity.other.attribute-name",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Entity Name Tag Custom",
+      "scope": "entity.name.tag.custom",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Library (function & constant)",
+      "scope": ["support.function", "support.constant"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Support Constant Property Value meta",
+      "scope": "support.constant.meta.property-value",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Library class/type",
+      "scope": ["support.type", "support.class"],
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Support Variable DOM",
+      "scope": "support.variable.dom",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Invalid",
+      "scope": "invalid",
+      "settings": {
+        "background": "#ff2c83",
+        "foreground": "#ffffff"
+      }
+    },
+    {
+      "name": "Invalid deprecated",
+      "scope": "invalid.deprecated",
+      "settings": {
+        "foreground": "#ffffff",
+        "background": "#d3423e"
+      }
+    },
+    {
+      "name": "Keyword Operator",
+      "scope": "keyword.operator",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Keyword Operator Relational",
+      "scope": "keyword.operator.relational",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Keyword Operator Assignment",
+      "scope": "keyword.operator.assignment",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Double-Slashed Comment",
+      "scope": "comment.line.double-slash",
+      "settings": {
+        "foreground": "#697098"
+      }
+    },
+    {
+      "name": "Object",
+      "scope": "object",
+      "settings": {
+        "foreground": "#cdebf7"
+      }
+    },
+    {
+      "name": "Null",
+      "scope": "constant.language.null",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Meta Brace",
+      "scope": "meta.brace",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Meta Delimiter Period",
+      "scope": "meta.delimiter.period",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Punctuation Definition String",
+      "scope": "punctuation.definition.string",
+      "settings": {
+        "foreground": "#d9f5dd"
+      }
+    },
+    {
+      "name": "Boolean",
+      "scope": "constant.language.boolean",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Object Comma",
+      "scope": "object.comma",
+      "settings": {
+        "foreground": "#ffffff"
+      }
+    },
+    {
+      "name": "Variable Parameter Function",
+      "scope": "variable.parameter.function",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Support Type Property Name & entity name tags",
+      "scope": [
+        "support.type.vendored.property-name",
+        "support.constant.vendored.property-value",
+        "support.type.property-name",
+        "meta.property-list entity.name.tag"
+      ],
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Entity Name tag reference in stylesheets",
+      "scope": "meta.property-list entity.name.tag.reference",
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Constant Other Color RGB Value Punctuation Definition Constant",
+      "scope": "constant.other.color.rgb-value punctuation.definition.constant",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Constant Other Color",
+      "scope": "constant.other.color",
+      "settings": {
+        "foreground": "#FFEB95"
+      }
+    },
+    {
+      "name": "Keyword Other Unit",
+      "scope": "keyword.other.unit",
+      "settings": {
+        "foreground": "#FFEB95"
+      }
+    },
+    {
+      "name": "Meta Selector",
+      "scope": "meta.selector",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Entity Other Attribute Name Id",
+      "scope": "entity.other.attribute-name.id",
+      "settings": {
+        "foreground": "#FAD430"
+      }
+    },
+    {
+      "name": "Meta Property Name",
+      "scope": "meta.property-name",
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Doctypes",
+      "scope": ["entity.name.tag.doctype", "meta.tag.sgml.doctype"],
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Punctuation Definition Parameters",
+      "scope": "punctuation.definition.parameters",
+      "settings": {
+        "foreground": "#d9f5dd"
+      }
+    },
+    {
+      "name": "Keyword Control Operator",
+      "scope": "keyword.control.operator",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Keyword Operator Logical",
+      "scope": "keyword.operator.logical",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Variable Instances",
+      "scope": [
+        "variable.instance",
+        "variable.other.instance",
+        "variable.reaedwrite.instance",
+        "variable.other.readwrite.instance"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Variable Property Other",
+      "scope": ["variable.other.property", "variable.other.object.property"],
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Entity Name Function",
+      "scope": "entity.name.function",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Keyword Operator Comparison",
+      "scope": "keyword.operator.comparison",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Support Constant, `new` keyword, Special Method Keyword",
+      "scope": [
+        "support.constant",
+        "keyword.other.special-method",
+        "keyword.other.new"
+      ],
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Support Function",
+      "scope": "support.function",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Invalid Broken",
+      "scope": "invalid.broken",
+      "settings": {
+        "foreground": "#020e14",
+        "background": "#F78C6C"
+      }
+    },
+    {
+      "name": "Invalid Unimplemented",
+      "scope": "invalid.unimplemented",
+      "settings": {
+        "background": "#8BD649",
+        "foreground": "#ffffff"
+      }
+    },
+    {
+      "name": "Invalid Illegal",
+      "scope": "invalid.illegal",
+      "settings": {
+        "foreground": "#ffffff",
+        "background": "#ec5f67"
+      }
+    },
+    {
+      "name": "Language Variable",
+      "scope": "variable.language",
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Support Variable Property",
+      "scope": "support.variable.property",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Variable Function",
+      "scope": "variable.function",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Variable Interpolation",
+      "scope": "variable.interpolation",
+      "settings": {
+        "foreground": "#ec5f67"
+      }
+    },
+    {
+      "name": "Meta Function Call",
+      "scope": "meta.function-call",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Punctuation Section Embedded",
+      "scope": "punctuation.section.embedded",
+      "settings": {
+        "foreground": "#d3423e"
+      }
+    },
+    {
+      "name": "Punctuation Tweaks",
+      "scope": [
+        "punctuation.terminator.expression",
+        "punctuation.definition.arguments",
+        "punctuation.definition.array",
+        "punctuation.section.array",
+        "meta.array"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "More Punctuation Tweaks",
+      "scope": [
+        "punctuation.definition.list.begin",
+        "punctuation.definition.list.end",
+        "punctuation.separator.arguments",
+        "punctuation.definition.list"
+      ],
+      "settings": {
+        "foreground": "#d9f5dd"
+      }
+    },
+    {
+      "name": "Template Strings",
+      "scope": "string.template meta.template.expression",
+      "settings": {
+        "foreground": "#d3423e"
+      }
+    },
+    {
+      "name": "Backtics(``) in Template Strings",
+      "scope": "string.template punctuation.definition.string",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Italics",
+      "scope": "italic",
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Bold",
+      "scope": "bold",
+      "settings": {
+        "foreground": "#ffcb6b",
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "name": "Quote",
+      "scope": "quote",
+      "settings": {
+        "foreground": "#697098",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Raw Code",
+      "scope": "raw",
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "CoffeScript Variable Assignment",
+      "scope": "variable.assignment.coffee",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "CoffeScript Parameter Function",
+      "scope": "variable.parameter.function.coffee",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "CoffeeScript Assignments",
+      "scope": "variable.assignment.coffee",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "C# Readwrite Variables",
+      "scope": "variable.other.readwrite.cs",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "C# Classes & Storage types",
+      "scope": ["entity.name.type.class.cs", "storage.type.cs"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "C# Namespaces",
+      "scope": "entity.name.type.namespace.cs",
+      "settings": {
+        "foreground": "#B2CCD6"
+      }
+    },
+    {
+      "name": "Tag names in Stylesheets",
+      "scope": [
+        "entity.name.tag.css",
+        "entity.name.tag.less",
+        "entity.name.tag.custom.css"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Wildcard(*) selector in Stylesheets",
+      "scope": [
+        "entity.name.tag.wildcard.css",
+        "entity.name.tag.wildcard.less",
+        "entity.name.tag.wildcard.scss",
+        "entity.name.tag.wildcard.sass"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "(C|SC|SA|LE)SS property value unit",
+      "scope": [
+        "keyword.other.unit.css",
+        "constant.length.units.css",
+        "keyword.other.unit.less",
+        "constant.length.units.less",
+        "keyword.other.unit.scss",
+        "constant.length.units.scss",
+        "keyword.other.unit.sass",
+        "constant.length.units.sass"
+      ],
+      "settings": {
+        "foreground": "#FFEB95"
+      }
+    },
+    {
+      "name": "Attribute Name for CSS",
+      "scope": "meta.attribute-selector.css entity.other.attribute-name.attribute",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "punctuations in styled components",
+      "scope": [
+        "source.js source.css meta.property-list",
+        "source.js source.css punctuation.section",
+        "source.js source.css punctuation.terminator.rule",
+        "source.js source.css punctuation.definition.entity.end.bracket",
+        "source.js source.css punctuation.definition.entity.begin.bracket",
+        "source.js source.css punctuation.separator.key-value",
+        "source.js source.css punctuation.definition.attribute-selector",
+        "source.js source.css meta.property-list",
+        "source.js source.css meta.property-list punctuation.separator.comma",
+        "source.ts source.css punctuation.section",
+        "source.ts source.css punctuation.terminator.rule",
+        "source.ts source.css punctuation.definition.entity.end.bracket",
+        "source.ts source.css punctuation.definition.entity.begin.bracket",
+        "source.ts source.css punctuation.separator.key-value",
+        "source.ts source.css punctuation.definition.attribute-selector",
+        "source.ts source.css meta.property-list",
+        "source.ts source.css meta.property-list punctuation.separator.comma"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Elixir Classes",
+      "scope": [
+        "source.elixir support.type.elixir",
+        "source.elixir meta.module.elixir entity.name.class.elixir"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Elixir Functions",
+      "scope": "source.elixir entity.name.function",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Elixir Constants",
+      "scope": [
+        "source.elixir constant.other.symbol.elixir",
+        "source.elixir constant.other.keywords.elixir"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Elixir String Punctuations",
+      "scope": "source.elixir punctuation.definition.string",
+      "settings": {
+        "foreground": "#a9c77d"
+      }
+    },
+    {
+      "name": "Elixir",
+      "scope": [
+        "source.elixir variable.other.readwrite.module.elixir",
+        "source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir"
+      ],
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Elixir Binary Punctuations",
+      "scope": "source.elixir .punctuation.binary.elixir",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Go Function Calls",
+      "scope": "source.go meta.function-call.go",
+      "settings": {
+        "foreground": "#DDDDDD"
+      }
+    },
+    {
+      "name": "GraphQL Variables",
+      "scope": "variable.qraphql",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "ID Attribute Name in HTML",
+      "scope": "entity.other.attribute-name.id.html",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "HTML Punctuation Definition Tag",
+      "scope": "punctuation.definition.tag.html",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "HTML Doctype",
+      "scope": "meta.tag.sgml.doctype.html",
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "JavaScript Classes",
+      "scope": "meta.class entity.name.type.class.js",
+      "settings": {
+        "foreground": "#ffcb8b"
+      }
+    },
+    {
+      "name": "JavaScript Method Declaration e.g. `constructor`",
+      "scope": "meta.method.declaration storage.type.js",
+      "settings": {
+        "foreground": "#82AAFF",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "JavaScript Terminator",
+      "scope": "terminator.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Meta Punctuation Definition",
+      "scope": "meta.js punctuation.definition.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Entity Names in Code Documentations",
+      "scope": [
+        "entity.name.type.instance.jsdoc",
+        "entity.name.type.instance.phpdoc"
+      ],
+      "settings": {
+        "foreground": "#eeffff"
+      }
+    },
+    {
+      "name": "Other Variables in Code Documentations",
+      "scope": ["variable.other.jsdoc", "variable.other.phpdoc"],
+      "settings": {
+        "foreground": "#78ccf0"
+      }
+    },
+    {
+      "name": "JavaScript module imports and exports",
+      "scope": [
+        "variable.other.meta.import.js",
+        "meta.import.js variable.other",
+        "variable.other.meta.export.js",
+        "meta.export.js variable.other"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Variable Parameter Function",
+      "scope": "variable.parameter.function.js",
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "JavaScript Variable Other ReadWrite",
+      "scope": "variable.other.readwrite.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Text nested in React tags",
+      "scope": [
+        "meta.jsx.children",
+        "meta.jsx.children.js",
+        "meta.jsx.children.tsx"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript[React] Variable Other Object",
+      "scope": [
+        "variable.other.object.js",
+        "variable.other.object.jsx",
+        "meta.object-literal.key.js",
+        "meta.object-literal.key.jsx",
+        "variable.object.property.js",
+        "variable.object.property.jsx"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Variables",
+      "scope": ["variable.js", "variable.other.js"],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Entity Name Type",
+      "scope": ["entity.name.type.js", "entity.name.type.module.js"],
+      "settings": {
+        "foreground": "#ffcb8b"
+      }
+    },
+    {
+      "name": "JavaScript Support Classes",
+      "scope": "support.class.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JSON Property Names",
+      "scope": "support.type.property-name.json",
+      "settings": {
+        "foreground": "#C3E88D",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "JSON Support Constants",
+      "scope": "support.constant.json",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "JSON Property values (string)",
+      "scope": "meta.structure.dictionary.value.json string.quoted.double",
+      "settings": {
+        "foreground": "#80CBC4",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "Strings in JSON values",
+      "scope": "string.quoted.double.json punctuation.definition.string.json",
+      "settings": {
+        "foreground": "#80CBC4",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "Specific JSON Property values like null",
+      "scope": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Ruby Variables",
+      "scope": "variable.other.ruby",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Ruby Hashkeys",
+      "scope": "constant.language.symbol.hashkey.ruby",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "LESS Tag names",
+      "scope": "entity.name.tag.less",
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Attribute Name for LESS",
+      "scope": "meta.attribute-selector.less entity.other.attribute-name.attribute",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Markup Headings",
+      "scope": "markup.heading",
+      "settings": {
+        "foreground": "#82b1ff"
+      }
+    },
+    {
+      "name": "Markup Italics",
+      "scope": "markup.italic",
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Markup Bold",
+      "scope": "markup.bold",
+      "settings": {
+        "foreground": "#ffcb6b",
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "name": "Markup Quote + others",
+      "scope": "markup.quote",
+      "settings": {
+        "foreground": "#697098",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Markup Raw Code + others",
+      "scope": "markup.inline.raw",
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Markup Links",
+      "scope": ["markup.underline.link", "markup.underline.link.image"],
+      "settings": {
+        "foreground": "#ff869a"
+      }
+    },
+    {
+      "name": "Markup Attributes",
+      "scope": ["markup.meta.attribute-list"],
+      "settings": {
+        "foreground": "#a9c77d"
+      }
+    },
+    {
+      "name": "Markup Admonitions",
+      "scope": "markup.admonition",
+      "settings": {
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "name": "Markup Lists",
+      "scope": "markup.list.bullet",
+      "settings": {
+        "foreground": "#D9F5DD"
+      }
+    },
+    {
+      "name": "Markup Superscript and Subscript",
+      "scope": ["markup.superscript", "markup.subscript"],
+      "settings": {
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Markdown Link Title and Description",
+      "scope": [
+        "string.other.link.title.markdown",
+        "string.other.link.description.markdown"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Markdown Punctuation",
+      "scope": [
+        "punctuation.definition.string.markdown",
+        "punctuation.definition.string.begin.markdown",
+        "punctuation.definition.string.end.markdown",
+        "meta.link.inline.markdown punctuation.definition.string"
+      ],
+      "settings": {
+        "foreground": "#82b1ff"
+      }
+    },
+    {
+      "name": "Markdown MetaData Punctuation",
+      "scope": ["punctuation.definition.metadata.markdown"],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Markdown List Punctuation",
+      "scope": ["beginning.punctuation.definition.list.markdown"],
+      "settings": {
+        "foreground": "#82b1ff"
+      }
+    },
+    {
+      "name": "Asciidoc Function",
+      "scope": "entity.name.function.asciidoc",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "PHP Variables",
+      "scope": "variable.other.php",
+      "settings": {
+        "foreground": "#bec5d4"
+      }
+    },
+    {
+      "name": "Support Classes in PHP",
+      "scope": "support.class.php",
+      "settings": {
+        "foreground": "#ffcb8b"
+      }
+    },
+    {
+      "name": "Punctuations in PHP function calls",
+      "scope": "meta.function-call.php punctuation",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "PHP Global Variables",
+      "scope": "variable.other.global.php",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Declaration Punctuation in PHP Global Variables",
+      "scope": "variable.other.global.php punctuation.definition.variable",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Language Constants in Python",
+      "scope": "constant.language.python",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Python Function Parameter and Arguments",
+      "scope": [
+        "variable.parameter.function.python",
+        "meta.function-call.arguments.python"
+      ],
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "Python Function Call",
+      "scope": [
+        "meta.function-call.python",
+        "meta.function-call.generic.python"
+      ],
+      "settings": {
+        "foreground": "#B2CCD6"
+      }
+    },
+    {
+      "name": "Punctuations in Python",
+      "scope": "punctuation.python",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Decorator Functions in Python",
+      "scope": "entity.name.function.decorator.python",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Python Language Variable",
+      "scope": "source.python variable.language.special",
+      "settings": {
+        "foreground": "#8EACE3"
+      }
+    },
+    {
+      "name": "SCSS Variable",
+      "scope": [
+        "variable.scss",
+        "variable.sass",
+        "variable.parameter.url.scss",
+        "variable.parameter.url.sass"
+      ],
+      "settings": {
+        "foreground": "#DDDDDD"
+      }
+    },
+    {
+      "name": "Variables in SASS At-Rules",
+      "scope": [
+        "source.css.scss meta.at-rule variable",
+        "source.css.sass meta.at-rule variable"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Variables in SASS At-Rules",
+      "scope": [
+        "source.css.scss meta.at-rule variable",
+        "source.css.sass meta.at-rule variable"
+      ],
+      "settings": {
+        "foreground": "#bec5d4"
+      }
+    },
+    {
+      "name": "Attribute Name for SASS",
+      "scope": [
+        "meta.attribute-selector.scss entity.other.attribute-name.attribute",
+        "meta.attribute-selector.sass entity.other.attribute-name.attribute"
+      ],
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Tag names in SASS",
+      "scope": ["entity.name.tag.scss", "entity.name.tag.sass"],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "TypeScript[React] Variables and Object Properties",
+      "scope": [
+        "variable.other.readwrite.alias.ts",
+        "variable.other.readwrite.alias.tsx",
+        "variable.other.readwrite.ts",
+        "variable.other.readwrite.tsx",
+        "variable.other.object.ts",
+        "variable.other.object.tsx",
+        "variable.object.property.ts",
+        "variable.object.property.tsx",
+        "variable.other.ts",
+        "variable.other.tsx",
+        "variable.tsx",
+        "variable.ts"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "TypeScript[React] Entity Name Types",
+      "scope": ["entity.name.type.ts", "entity.name.type.tsx"],
+      "settings": {
+        "foreground": "#78ccf0"
+      }
+    },
+    {
+      "name": "TypeScript[React] Node Classes",
+      "scope": ["support.class.node.ts", "support.class.node.tsx"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "TypeScript[React] Entity Name Types as Parameters",
+      "scope": [
+        "meta.type.parameters.ts entity.name.type",
+        "meta.type.parameters.tsx entity.name.type"
+      ],
+      "settings": {
+        "foreground": "#eeffff"
+      }
+    },
+    {
+      "name": "TypeScript[React] Import/Export Punctuations",
+      "scope": [
+        "meta.import.ts punctuation.definition.block",
+        "meta.import.tsx punctuation.definition.block",
+        "meta.export.ts punctuation.definition.block",
+        "meta.export.tsx punctuation.definition.block"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "TypeScript[React] Punctuation Decorators",
+      "scope": [
+        "meta.decorator punctuation.decorator.ts",
+        "meta.decorator punctuation.decorator.tsx"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "TypeScript[React] Punctuation Decorators",
+      "scope": "meta.tag.js meta.jsx.children.tsx",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "YAML Entity Name Tags",
+      "scope": "entity.name.tag.yaml",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "handlebars variables",
+      "scope": "variable.parameter.handlebars",
+      "settings": {
+        "foreground": "#bec5d4"
+      }
+    },
+    {
+      "name": "handlebars parameters",
+      "scope": "entity.other.attribute-name.handlebars variable.parameter.handlebars",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "handlebars enitity attribute names",
+      "scope": "entity.other.attribute-name.handlebars",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "handlebars enitity attribute values",
+      "scope": "entity.other.attribute-value.handlebars variable.parameter.handlebars",
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "normalize font style of certain components",
+      "scope": [
+        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.begin.js",
+        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.end.js",
+        "meta.property-list.css meta.property-value.css variable.other.less",
+        "punctuation.section.embedded.begin.js.jsx",
+        "punctuation.section.embedded.end.js.jsx",
+        "meta.property-list.scss variable.scss",
+        "meta.property-list.sass variable.sass",
+        "keyword.operator.logical",
+        "keyword.operator.arithmetic",
+        "keyword.operator.bitwise",
+        "keyword.operator.increment",
+        "keyword.operator.ternary",
+        "keyword.operator.comparison",
+        "keyword.operator.assignment",
+        "keyword.operator.operator",
+        "keyword.operator.or.regexp",
+        "keyword.operator.expression.in",
+        "keyword.operator.type",
+        "punctuation.section.embedded.js",
+        "punctuation.definintion.string",
+        "punctuation"
+      ],
+      "settings": {
+        "fontStyle": "normal"
+      }
+    }
+  ]
+}

assets/themes/src/vscode/palenight/palenight-operator.json 🔗

@@ -1,1640 +1,1640 @@
-{

-  "name": "Palenight Operator",

-  "author": "Olaolu Olawuyi",

-  "maintainers": ["Olaolu Olawuyi <mrolaolu@gmail.com>"],

-  "type": "dark",

-  "semanticClass": "palenight-operator",

-  "colors": {

-    "contrastActiveBorder": null,

-    "contrastBorder": "#282B3C",

-    "focusBorder": "#282B3C",

-    "foreground": "#ffffff",

-    "widget.shadow": "#232635",

-    "selection.background": "#7580B850",

-    "descriptionForeground": null,

-    "errorForeground": "#EF5350",

-    "button.background": "#7e57c2cc",

-    "button.foreground": "#ffffffcc",

-    "button.hoverBackground": "#7e57c2",

-    "dropdown.background": "#292D3E",

-    "dropdown.border": "#7e57c2",

-    "dropdown.foreground": "#ffffffcc",

-    "input.background": "#313850",

-    "input.border": "#7e57c2",

-    "input.foreground": "#ffffffcc",

-    "input.placeholderForeground": "#ffffffcc",

-    "inputOption.activeBorder": "#ffffffcc",

-    "inputValidation.errorBackground": "#ef5350f2",

-    "inputValidation.errorBorder": "#EF5350",

-    "inputValidation.infoBackground": "#64b5f6f2",

-    "inputValidation.infoBorder": "#64B5F6",

-    "inputValidation.warningBackground": "#ffca28f2",

-    "inputValidation.warningBorder": "#FFCA28",

-    "scrollbar.shadow": "#292D3E00",

-    "scrollbarSlider.activeBackground": "#694CA4cc",

-    "scrollbarSlider.background": "#694CA466",

-    "scrollbarSlider.hoverBackground": "#694CA4cc",

-    "badge.background": "#7e57c2",

-    "badge.foreground": "#ffffff",

-    "progress.background": "#7e57c2",

-    "list.activeSelectionBackground": "#7e57c2",

-    "list.activeSelectionForeground": "#ffffff",

-    "list.dropBackground": "#2E3245",

-    "list.focusBackground": "#0000002e",

-    "list.focusForeground": "#ffffff",

-    "list.highlightForeground": "#ffffff",

-    "list.hoverBackground": "#0000001a",

-    "list.hoverForeground": "#ffffff",

-    "list.inactiveSelectionBackground": "#929ac90d",

-    "list.inactiveSelectionForeground": "#929ac9",

-    "activityBar.background": "#282C3D",

-    "activityBar.dropBackground": "#7e57c2e3",

-    "activityBar.foreground": "#eeffff",

-    "activityBar.border": "#282C3D",

-    "activityBarBadge.background": "#7e57c2",

-    "activityBarBadge.foreground": "#ffffff",

-    "sideBar.background": "#292D3E",

-    "sideBar.foreground": "#6C739A",

-    "sideBar.border": "#282B3C",

-    "sideBarTitle.foreground": "#eeffff",

-    "sideBarSectionHeader.background": "#292D3E",

-    "sideBarSectionHeader.foreground": "#eeffff",

-    "editorGroup.background": "#32374C",

-    "editorGroup.border": "#2E3245",

-    "editorGroup.dropBackground": "#7e57c273",

-    "editorGroupHeader.noTabsBackground": "#32374C",

-    "editorGroupHeader.tabsBackground": "#31364a",

-    "editorGroupHeader.tabsBorder": "#262A39",

-    "tab.activeBackground": "#292D3E",

-    "tab.activeForeground": "#eeffff",

-    "tab.border": "#272B3B",

-    "tab.activeBorder": "#262A39",

-    "tab.unfocusedActiveBorder": "#262A39",

-    "tab.inactiveBackground": "#31364A",

-    "tab.inactiveForeground": "#929ac9",

-    "tab.unfocusedActiveForeground": null,

-    "tab.unfocusedInactiveForeground": null,

-    "editor.background": "#292D3E",

-    "editor.foreground": "#BFC7D5",

-    "editorLineNumber.foreground": "#4c5374",

-    "editorLineNumber.activeForeground": "#eeffff",

-    "editorCursor.foreground": "#7e57c2",

-    "editorCursor.background": null,

-    "editor.selectionBackground": "#7580B850",

-    "editor.selectionHighlightBackground": "#383D51",

-    "editor.inactiveSelectionBackground": "#7e57c25a",

-    "editor.wordHighlightBackground": "#32374D",

-    "editor.wordHighlightStrongBackground": "#2E3250",

-    "editor.findMatchBackground": "#2e3248fc",

-    "editor.findMatchHighlightBackground": "#7e57c233",

-    "editor.findRangeHighlightBackground": null,

-    "editor.hoverHighlightBackground": "#7e57c25a",

-    "editor.lineHighlightBackground": "#0003",

-    "editor.lineHighlightBorder": null,

-    "editorLink.activeForeground": null,

-    "editor.rangeHighlightBackground": "#7e57c25a",

-    "editorWhitespace.foreground": null,

-    "editorIndentGuide.background": "#4E557980",

-    "editorRuler.foreground": "#4E557980",

-    "editorCodeLens.foreground": "#FFCA28",

-    "editorBracketMatch.background": null,

-    "editorBracketMatch.border": null,

-    "editorOverviewRuler.currentContentForeground": "#7e57c2",

-    "editorOverviewRuler.incomingContentForeground": "#7e57c2",

-    "editorOverviewRuler.commonContentForeground": "#7e57c2",

-    "editorError.foreground": "#EF5350",

-    "editorError.border": null,

-    "editorWarning.foreground": "#FFCA28",

-    "editorWarning.border": null,

-    "editorGutter.background": null,

-    "editorGutter.modifiedBackground": "#e2b93d",

-    "editorGutter.addedBackground": "#9CCC65",

-    "editorGutter.deletedBackground": "#EF5350",

-    "diffEditor.insertedTextBackground": "#99b76d23",

-    "diffEditor.removedTextBackground": "#ef535033",

-    "editorWidget.background": "#31364a",

-    "editorWidget.border": null,

-    "editorSuggestWidget.background": "#2C3043",

-    "editorSuggestWidget.border": "#2B2F40",

-    "editorSuggestWidget.foreground": "#bfc7d5",

-    "editorSuggestWidget.highlightForeground": "#ffffff",

-    "editorSuggestWidget.selectedBackground": "#7e57c2",

-    "editorHoverWidget.background": "#292D3E",

-    "editorHoverWidget.border": "#7e57c2",

-    "debugExceptionWidget.background": "#292D3E",

-    "debugExceptionWidget.border": "#7e57c2",

-    "editorMarkerNavigation.background": "#31364a",

-    "editorMarkerNavigationError.background": "#EF5350",

-    "editorMarkerNavigationWarning.background": "#FFCA28",

-    "peekView.border": "#7e57c2",

-    "peekViewEditor.background": "#232635",

-    "peekViewEditor.matchHighlightBackground": "#7e57c25a",

-    "peekViewResult.background": "#2E3245",

-    "peekViewResult.fileForeground": "#eeffff",

-    "peekViewResult.lineForeground": "#eeffff",

-    "peekViewResult.matchHighlightBackground": "#7e57c25a",

-    "peekViewResult.selectionBackground": "#2E3250",

-    "peekViewResult.selectionForeground": "#eeffff",

-    "peekViewTitle.background": "#292D3E",

-    "peekViewTitleDescription.foreground": "#697098",

-    "peekViewTitleLabel.foreground": "#eeffff",

-    "merge.currentHeaderBackground": "#7e57c25a",

-    "merge.currentContentBackground": null,

-    "merge.incomingHeaderBackground": "#7e57c25a",

-    "merge.incomingContentBackground": null,

-    "merge.border": null,

-    "panel.background": "#292D3E",

-    "panel.border": "#282B3C",

-    "panelTitle.activeBorder": "#7e57c2",

-    "panelTitle.activeForeground": "#eeffff",

-    "panelTitle.inactiveForeground": "#bfc7d580",

-    "statusBar.background": "#282C3D",

-    "statusBar.foreground": "#676E95",

-    "statusBar.border": "#262A39",

-    "statusBar.debuggingBackground": "#202431",

-    "statusBar.debuggingForeground": null,

-    "statusBar.debuggingBorder": "#1F2330",

-    "statusBar.noFolderForeground": null,

-    "statusBar.noFolderBackground": "#292D3E",

-    "statusBar.noFolderBorder": "#25293A",

-    "statusBarItem.activeBackground": "#202431",

-    "statusBarItem.hoverBackground": "#202431",

-    "statusBarItem.prominentBackground": "#202431",

-    "statusBarItem.prominentHoverBackground": "#202431",

-    "titleBar.activeBackground": "#292d3e",

-    "titleBar.activeForeground": "#eeefff",

-    "titleBar.border": "#30364c",

-    "titleBar.inactiveBackground": "#30364c",

-    "titleBar.inactiveForeground": null,

-    "notifications.background": "#292D3E",

-    "notifications.foreground": "#ffffffcc",

-    "notificationLink.foreground": "#80CBC4",

-    "extensionButton.prominentForeground": "#ffffffcc",

-    "extensionButton.prominentBackground": "#7e57c2cc",

-    "extensionButton.prominentHoverBackground": "#7e57c2",

-    "pickerGroup.foreground": "#d1aaff",

-    "pickerGroup.border": "#2E3245",

-    "terminal.ansiWhite": "#ffffff",

-    "terminal.ansiBlack": "#676E95",

-    "terminal.ansiBlue": "#82AAFF",

-    "terminal.ansiCyan": "#89DDFF",

-    "terminal.ansiGreen": "#a9c77d",

-    "terminal.ansiMagenta": "#C792EA",

-    "terminal.ansiRed": "#ff5572",

-    "terminal.ansiYellow": "#FFCB6B",

-    "terminal.ansiBrightWhite": "#ffffff",

-    "terminal.ansiBrightBlack": "#676E95",

-    "terminal.ansiBrightBlue": "#82AAFF",

-    "terminal.ansiBrightCyan": "#89DDFF",

-    "terminal.ansiBrightGreen": "#C3E88D",

-    "terminal.ansiBrightMagenta": "#C792EA",

-    "terminal.ansiBrightRed": "#ff5572",

-    "terminal.ansiBrightYellow": "#FFCB6B",

-    "debugToolBar.background": "#292D3E",

-    "welcomePage.buttonBackground": null,

-    "welcomePage.buttonHoverBackground": null,

-    "walkThrough.embeddedEditorBackground": "#232635",

-    "gitDecoration.modifiedResourceForeground": "#e2c08de6",

-    "gitDecoration.deletedResourceForeground": "#EF535090",

-    "gitDecoration.untrackedResourceForeground": "#a9c77dff",

-    "gitDecoration.ignoredResourceForeground": "#69709890",

-    "gitDecoration.conflictingResourceForeground": "#FFEB95CC",

-    "editorActiveLineNumber.foreground": "#eeffff",

-    "breadcrumb.foreground": "#6c739a",

-    "breadcrumb.focusForeground": "#bfc7d5",

-    "breadcrumb.activeSelectionForeground": "#eeffff",

-    "breadcrumbPicker.background": "#292D3E"

-  },

-  "tokenColors": [

-    {

-      "name": "Global settings",

-      "settings": {

-        "background": "#292D3E",

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Comment",

-      "scope": "comment",

-      "settings": {

-        "foreground": "#697098",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "String",

-      "scope": "string",

-      "settings": {

-        "foreground": "#C3E88D"

-      }

-    },

-    {

-      "name": "String Quoted",

-      "scope": "string.quoted",

-      "settings": {

-        "foreground": "#C3E88D"

-      }

-    },

-    {

-      "name": "String Unquoted",

-      "scope": "string.unquoted",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Support Constant Math",

-      "scope": "support.constant.math",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Number",

-      "scope": ["constant.numeric", "constant.character.numeric"],

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Built-in constant",

-      "scope": [

-        "constant.language",

-        "punctuation.definition.constant",

-        "variable.other.constant"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "User-defined constant",

-      "scope": ["constant.character", "constant.other"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Constant Character Escape",

-      "scope": "constant.character.escape",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "RegExp String",

-      "scope": ["string.regexp", "string.regexp keyword.other"],

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Comma in functions",

-      "scope": "meta.function punctuation.separator.comma",

-      "settings": {

-        "foreground": "#eeffff"

-      }

-    },

-    {

-      "name": "Variable",

-      "scope": "variable",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Keyword",

-      "scope": ["punctuation.accessor", "keyword"],

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Storage",

-      "scope": [

-        "storage",

-        "storage.type",

-        "meta.var.expr storage.type",

-        "storage.type.property.js",

-        "storage.type.property.ts",

-        "storage.type.property.tsx",

-        "meta.class meta.method.declaration meta.var.expr storage.type.js"

-      ],

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Class name",

-      "scope": ["entity.name.class", "meta.class entity.name.type.class"],

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Inherited class",

-      "scope": "entity.other.inherited-class",

-      "settings": {

-        "foreground": "#a9c77d"

-      }

-    },

-    {

-      "name": "Function name",

-      "scope": "entity.name.function",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Function Parameters",

-      "scope": "variable.parameter",

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "Meta Tag",

-      "scope": ["punctuation.definition.tag", "meta.tag"],

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "HTML Tag names",

-      "scope": [

-        "entity.name.tag support.class.component",

-        "meta.tag.other.html",

-        "meta.tag.other.js",

-        "meta.tag.other.tsx",

-        "entity.name.tag.tsx",

-        "entity.name.tag.js",

-        "entity.name.tag",

-        "meta.tag.js",

-        "meta.tag.tsx",

-        "meta.tag.html"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Tag attribute",

-      "scope": "entity.other.attribute-name",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Entity Name Tag Custom",

-      "scope": "entity.name.tag.custom",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Library (function & constant)",

-      "scope": ["support.function", "support.constant"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Support Constant Property Value meta",

-      "scope": "support.constant.meta.property-value",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Library class/type",

-      "scope": ["support.type", "support.class"],

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Support Variable DOM",

-      "scope": "support.variable.dom",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Invalid",

-      "scope": "invalid",

-      "settings": {

-        "background": "#ff2c83",

-        "foreground": "#ffffff"

-      }

-    },

-    {

-      "name": "Invalid deprecated",

-      "scope": "invalid.deprecated",

-      "settings": {

-        "foreground": "#ffffff",

-        "background": "#d3423e"

-      }

-    },

-    {

-      "name": "Keyword Operator",

-      "scope": "keyword.operator",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Keyword Operator Relational",

-      "scope": "keyword.operator.relational",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Keyword Operator Assignment",

-      "scope": "keyword.operator.assignment",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Double-Slashed Comment",

-      "scope": "comment.line.double-slash",

-      "settings": {

-        "foreground": "#697098"

-      }

-    },

-    {

-      "name": "Object",

-      "scope": "object",

-      "settings": {

-        "foreground": "#cdebf7"

-      }

-    },

-    {

-      "name": "Null",

-      "scope": "constant.language.null",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Meta Brace",

-      "scope": "meta.brace",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Meta Delimiter Period",

-      "scope": "meta.delimiter.period",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Punctuation Definition String",

-      "scope": "punctuation.definition.string",

-      "settings": {

-        "foreground": "#d9f5dd"

-      }

-    },

-    {

-      "name": "Boolean",

-      "scope": "constant.language.boolean",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Object Comma",

-      "scope": "object.comma",

-      "settings": {

-        "foreground": "#ffffff"

-      }

-    },

-    {

-      "name": "Variable Parameter Function",

-      "scope": "variable.parameter.function",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Support Type Property Name & entity name tags",

-      "scope": [

-        "support.type.vendored.property-name",

-        "support.constant.vendored.property-value",

-        "support.type.property-name",

-        "meta.property-list entity.name.tag"

-      ],

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Entity Name tag reference in stylesheets",

-      "scope": "meta.property-list entity.name.tag.reference",

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Constant Other Color RGB Value Punctuation Definition Constant",

-      "scope": "constant.other.color.rgb-value punctuation.definition.constant",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Constant Other Color",

-      "scope": "constant.other.color",

-      "settings": {

-        "foreground": "#FFEB95"

-      }

-    },

-    {

-      "name": "Keyword Other Unit",

-      "scope": "keyword.other.unit",

-      "settings": {

-        "foreground": "#FFEB95"

-      }

-    },

-    {

-      "name": "Meta Selector",

-      "scope": "meta.selector",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Entity Other Attribute Name Id",

-      "scope": "entity.other.attribute-name.id",

-      "settings": {

-        "foreground": "#FAD430"

-      }

-    },

-    {

-      "name": "Meta Property Name",

-      "scope": "meta.property-name",

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Doctypes",

-      "scope": ["entity.name.tag.doctype", "meta.tag.sgml.doctype"],

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Punctuation Definition Parameters",

-      "scope": "punctuation.definition.parameters",

-      "settings": {

-        "foreground": "#d9f5dd"

-      }

-    },

-    {

-      "name": "Keyword Control Operator",

-      "scope": "keyword.control.operator",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Keyword Operator Logical",

-      "scope": "keyword.operator.logical",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Variable Instances",

-      "scope": [

-        "variable.instance",

-        "variable.other.instance",

-        "variable.reaedwrite.instance",

-        "variable.other.readwrite.instance"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Variable Property Other",

-      "scope": ["variable.other.property", "variable.other.object.property"],

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Entity Name Function",

-      "scope": "entity.name.function",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Keyword Operator Comparison",

-      "scope": "keyword.operator.comparison",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Support Constant, `new` keyword, Special Method Keyword",

-      "scope": [

-        "support.constant",

-        "keyword.other.special-method",

-        "keyword.other.new"

-      ],

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Support Function",

-      "scope": "support.function",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Invalid Broken",

-      "scope": "invalid.broken",

-      "settings": {

-        "foreground": "#020e14",

-        "background": "#F78C6C"

-      }

-    },

-    {

-      "name": "Invalid Unimplemented",

-      "scope": "invalid.unimplemented",

-      "settings": {

-        "background": "#8BD649",

-        "foreground": "#ffffff"

-      }

-    },

-    {

-      "name": "Invalid Illegal",

-      "scope": "invalid.illegal",

-      "settings": {

-        "foreground": "#ffffff",

-        "background": "#ec5f67"

-      }

-    },

-    {

-      "name": "Language Variable",

-      "scope": "variable.language",

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Support Variable Property",

-      "scope": "support.variable.property",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Variable Function",

-      "scope": "variable.function",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Variable Interpolation",

-      "scope": "variable.interpolation",

-      "settings": {

-        "foreground": "#ec5f67"

-      }

-    },

-    {

-      "name": "Meta Function Call",

-      "scope": "meta.function-call",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Punctuation Section Embedded",

-      "scope": "punctuation.section.embedded",

-      "settings": {

-        "foreground": "#d3423e"

-      }

-    },

-    {

-      "name": "Punctuation Tweaks",

-      "scope": [

-        "punctuation.terminator.expression",

-        "punctuation.definition.arguments",

-        "punctuation.definition.array",

-        "punctuation.section.array",

-        "meta.array"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "More Punctuation Tweaks",

-      "scope": [

-        "punctuation.definition.list.begin",

-        "punctuation.definition.list.end",

-        "punctuation.separator.arguments",

-        "punctuation.definition.list"

-      ],

-      "settings": {

-        "foreground": "#d9f5dd"

-      }

-    },

-    {

-      "name": "Template Strings",

-      "scope": "string.template meta.template.expression",

-      "settings": {

-        "foreground": "#d3423e"

-      }

-    },

-    {

-      "name": "Backtics(``) in Template Strings",

-      "scope": "string.template punctuation.definition.string",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Italics",

-      "scope": "italic",

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Bold",

-      "scope": "bold",

-      "settings": {

-        "foreground": "#ffcb6b",

-        "fontStyle": "bold"

-      }

-    },

-    {

-      "name": "Quote",

-      "scope": "quote",

-      "settings": {

-        "foreground": "#697098",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Raw Code",

-      "scope": "raw",

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "CoffeScript Variable Assignment",

-      "scope": "variable.assignment.coffee",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "CoffeScript Parameter Function",

-      "scope": "variable.parameter.function.coffee",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "CoffeeScript Assignments",

-      "scope": "variable.assignment.coffee",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "C# Readwrite Variables",

-      "scope": "variable.other.readwrite.cs",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "C# Classes & Storage types",

-      "scope": ["entity.name.type.class.cs", "storage.type.cs"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "C# Namespaces",

-      "scope": "entity.name.type.namespace.cs",

-      "settings": {

-        "foreground": "#B2CCD6"

-      }

-    },

-    {

-      "name": "Tag names in Stylesheets",

-      "scope": [

-        "entity.name.tag.css",

-        "entity.name.tag.less",

-        "entity.name.tag.custom.css"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Wildcard(*) selector in Stylesheets",

-      "scope": [

-        "entity.name.tag.wildcard.css",

-        "entity.name.tag.wildcard.less",

-        "entity.name.tag.wildcard.scss",

-        "entity.name.tag.wildcard.sass"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "(C|SC|SA|LE)SS property value unit",

-      "scope": [

-        "keyword.other.unit.css",

-        "constant.length.units.css",

-        "keyword.other.unit.less",

-        "constant.length.units.less",

-        "keyword.other.unit.scss",

-        "constant.length.units.scss",

-        "keyword.other.unit.sass",

-        "constant.length.units.sass"

-      ],

-      "settings": {

-        "foreground": "#FFEB95"

-      }

-    },

-    {

-      "name": "Attribute Name for CSS",

-      "scope": "meta.attribute-selector.css entity.other.attribute-name.attribute",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "punctuations in styled components",

-      "scope": [

-        "source.js source.css meta.property-list",

-        "source.js source.css punctuation.section",

-        "source.js source.css punctuation.terminator.rule",

-        "source.js source.css punctuation.definition.entity.end.bracket",

-        "source.js source.css punctuation.definition.entity.begin.bracket",

-        "source.js source.css punctuation.separator.key-value",

-        "source.js source.css punctuation.definition.attribute-selector",

-        "source.js source.css meta.property-list",

-        "source.js source.css meta.property-list punctuation.separator.comma",

-        "source.ts source.css punctuation.section",

-        "source.ts source.css punctuation.terminator.rule",

-        "source.ts source.css punctuation.definition.entity.end.bracket",

-        "source.ts source.css punctuation.definition.entity.begin.bracket",

-        "source.ts source.css punctuation.separator.key-value",

-        "source.ts source.css punctuation.definition.attribute-selector",

-        "source.ts source.css meta.property-list",

-        "source.ts source.css meta.property-list punctuation.separator.comma"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Elixir Classes",

-      "scope": [

-        "source.elixir support.type.elixir",

-        "source.elixir meta.module.elixir entity.name.class.elixir"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Elixir Functions",

-      "scope": "source.elixir entity.name.function",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Elixir Constants",

-      "scope": [

-        "source.elixir constant.other.symbol.elixir",

-        "source.elixir constant.other.keywords.elixir"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Elixir String Punctuations",

-      "scope": "source.elixir punctuation.definition.string",

-      "settings": {

-        "foreground": "#a9c77d"

-      }

-    },

-    {

-      "name": "Elixir",

-      "scope": [

-        "source.elixir variable.other.readwrite.module.elixir",

-        "source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir"

-      ],

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Elixir Binary Punctuations",

-      "scope": "source.elixir .punctuation.binary.elixir",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Go Function Calls",

-      "scope": "source.go meta.function-call.go",

-      "settings": {

-        "foreground": "#DDDDDD"

-      }

-    },

-    {

-      "name": "GraphQL Variables",

-      "scope": "variable.qraphql",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "ID Attribute Name in HTML",

-      "scope": "entity.other.attribute-name.id.html",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "HTML Punctuation Definition Tag",

-      "scope": "punctuation.definition.tag.html",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "HTML Doctype",

-      "scope": "meta.tag.sgml.doctype.html",

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "JavaScript Classes",

-      "scope": "meta.class entity.name.type.class.js",

-      "settings": {

-        "foreground": "#ffcb8b"

-      }

-    },

-    {

-      "name": "JavaScript Method Declaration e.g. `constructor`",

-      "scope": "meta.method.declaration storage.type.js",

-      "settings": {

-        "foreground": "#82AAFF",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "JavaScript Terminator",

-      "scope": "terminator.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Meta Punctuation Definition",

-      "scope": "meta.js punctuation.definition.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Entity Names in Code Documentations",

-      "scope": [

-        "entity.name.type.instance.jsdoc",

-        "entity.name.type.instance.phpdoc"

-      ],

-      "settings": {

-        "foreground": "#eeffff"

-      }

-    },

-    {

-      "name": "Other Variables in Code Documentations",

-      "scope": ["variable.other.jsdoc", "variable.other.phpdoc"],

-      "settings": {

-        "foreground": "#78ccf0"

-      }

-    },

-    {

-      "name": "JavaScript module imports and exports",

-      "scope": [

-        "variable.other.meta.import.js",

-        "meta.import.js variable.other",

-        "variable.other.meta.export.js",

-        "meta.export.js variable.other"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Variable Parameter Function",

-      "scope": "variable.parameter.function.js",

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "JavaScript Variable Other ReadWrite",

-      "scope": "variable.other.readwrite.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Text nested in React tags",

-      "scope": [

-        "meta.jsx.children",

-        "meta.jsx.children.js",

-        "meta.jsx.children.tsx"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript[React] Variable Other Object",

-      "scope": [

-        "variable.other.object.js",

-        "variable.other.object.jsx",

-        "meta.object-literal.key.js",

-        "meta.object-literal.key.jsx",

-        "variable.object.property.js",

-        "variable.object.property.jsx"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Variables",

-      "scope": ["variable.js", "variable.other.js"],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Entity Name Type",

-      "scope": ["entity.name.type.js", "entity.name.type.module.js"],

-      "settings": {

-        "foreground": "#ffcb8b"

-      }

-    },

-    {

-      "name": "JavaScript Support Classes",

-      "scope": "support.class.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JSON Property Names",

-      "scope": "support.type.property-name.json",

-      "settings": {

-        "foreground": "#C3E88D",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "JSON Support Constants",

-      "scope": "support.constant.json",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "JSON Property values (string)",

-      "scope": "meta.structure.dictionary.value.json string.quoted.double",

-      "settings": {

-        "foreground": "#80CBC4",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "Strings in JSON values",

-      "scope": "string.quoted.double.json punctuation.definition.string.json",

-      "settings": {

-        "foreground": "#80CBC4",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "Specific JSON Property values like null",

-      "scope": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Ruby Variables",

-      "scope": "variable.other.ruby",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Ruby Hashkeys",

-      "scope": "constant.language.symbol.hashkey.ruby",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "LESS Tag names",

-      "scope": "entity.name.tag.less",

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Attribute Name for LESS",

-      "scope": "meta.attribute-selector.less entity.other.attribute-name.attribute",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Markup Headings",

-      "scope": "markup.heading",

-      "settings": {

-        "foreground": "#82b1ff"

-      }

-    },

-    {

-      "name": "Markup Italics",

-      "scope": "markup.italic",

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Markup Bold",

-      "scope": "markup.bold",

-      "settings": {

-        "foreground": "#ffcb6b",

-        "fontStyle": "bold"

-      }

-    },

-    {

-      "name": "Markup Quote + others",

-      "scope": "markup.quote",

-      "settings": {

-        "foreground": "#697098",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Markup Raw Code + others",

-      "scope": "markup.inline.raw",

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Markup Links",

-      "scope": ["markup.underline.link", "markup.underline.link.image"],

-      "settings": {

-        "foreground": "#ff869a"

-      }

-    },

-    {

-      "name": "Markup Attributes",

-      "scope": ["markup.meta.attribute-list"],

-      "settings": {

-        "foreground": "#a9c77d"

-      }

-    },

-    {

-      "name": "Markup Admonitions",

-      "scope": "markup.admonition",

-      "settings": {

-        "fontStyle": "bold"

-      }

-    },

-    {

-      "name": "Markup Lists",

-      "scope": "markup.list.bullet",

-      "settings": {

-        "foreground": "#D9F5DD"

-      }

-    },

-    {

-      "name": "Markup Superscript and Subscript",

-      "scope": ["markup.superscript", "markup.subscript"],

-      "settings": {

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Markdown Link Title and Description",

-      "scope": [

-        "string.other.link.title.markdown",

-        "string.other.link.description.markdown"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Markdown Punctuation",

-      "scope": [

-        "punctuation.definition.string.markdown",

-        "punctuation.definition.string.begin.markdown",

-        "punctuation.definition.string.end.markdown",

-        "meta.link.inline.markdown punctuation.definition.string"

-      ],

-      "settings": {

-        "foreground": "#82b1ff"

-      }

-    },

-    {

-      "name": "Markdown MetaData Punctuation",

-      "scope": ["punctuation.definition.metadata.markdown"],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Markdown List Punctuation",

-      "scope": ["beginning.punctuation.definition.list.markdown"],

-      "settings": {

-        "foreground": "#82b1ff"

-      }

-    },

-    {

-      "name": "Asciidoc Function",

-      "scope": "entity.name.function.asciidoc",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "PHP Variables",

-      "scope": "variable.other.php",

-      "settings": {

-        "foreground": "#bec5d4"

-      }

-    },

-    {

-      "name": "Support Classes in PHP",

-      "scope": "support.class.php",

-      "settings": {

-        "foreground": "#ffcb8b"

-      }

-    },

-    {

-      "name": "Punctuations in PHP function calls",

-      "scope": "meta.function-call.php punctuation",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "PHP Global Variables",

-      "scope": "variable.other.global.php",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Declaration Punctuation in PHP Global Variables",

-      "scope": "variable.other.global.php punctuation.definition.variable",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Language Constants in Python",

-      "scope": "constant.language.python",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Python Function Parameter and Arguments",

-      "scope": [

-        "variable.parameter.function.python",

-        "meta.function-call.arguments.python"

-      ],

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "Python Function Call",

-      "scope": [

-        "meta.function-call.python",

-        "meta.function-call.generic.python"

-      ],

-      "settings": {

-        "foreground": "#B2CCD6"

-      }

-    },

-    {

-      "name": "Punctuations in Python",

-      "scope": "punctuation.python",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Decorator Functions in Python",

-      "scope": "entity.name.function.decorator.python",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Python Language Variable",

-      "scope": "source.python variable.language.special",

-      "settings": {

-        "foreground": "#8EACE3"

-      }

-    },

-    {

-      "name": "SCSS Variable",

-      "scope": [

-        "variable.scss",

-        "variable.sass",

-        "variable.parameter.url.scss",

-        "variable.parameter.url.sass"

-      ],

-      "settings": {

-        "foreground": "#DDDDDD"

-      }

-    },

-    {

-      "name": "Variables in SASS At-Rules",

-      "scope": [

-        "source.css.scss meta.at-rule variable",

-        "source.css.sass meta.at-rule variable"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Variables in SASS At-Rules",

-      "scope": [

-        "source.css.scss meta.at-rule variable",

-        "source.css.sass meta.at-rule variable"

-      ],

-      "settings": {

-        "foreground": "#bec5d4"

-      }

-    },

-    {

-      "name": "Attribute Name for SASS",

-      "scope": [

-        "meta.attribute-selector.scss entity.other.attribute-name.attribute",

-        "meta.attribute-selector.sass entity.other.attribute-name.attribute"

-      ],

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Tag names in SASS",

-      "scope": ["entity.name.tag.scss", "entity.name.tag.sass"],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "TypeScript[React] Variables and Object Properties",

-      "scope": [

-        "variable.other.readwrite.alias.ts",

-        "variable.other.readwrite.alias.tsx",

-        "variable.other.readwrite.ts",

-        "variable.other.readwrite.tsx",

-        "variable.other.object.ts",

-        "variable.other.object.tsx",

-        "variable.object.property.ts",

-        "variable.object.property.tsx",

-        "variable.other.ts",

-        "variable.other.tsx",

-        "variable.tsx",

-        "variable.ts"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "TypeScript[React] Entity Name Types",

-      "scope": ["entity.name.type.ts", "entity.name.type.tsx"],

-      "settings": {

-        "foreground": "#78ccf0"

-      }

-    },

-    {

-      "name": "TypeScript[React] Node Classes",

-      "scope": ["support.class.node.ts", "support.class.node.tsx"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "TypeScript[React] Entity Name Types as Parameters",

-      "scope": [

-        "meta.type.parameters.ts entity.name.type",

-        "meta.type.parameters.tsx entity.name.type"

-      ],

-      "settings": {

-        "foreground": "#eeffff"

-      }

-    },

-    {

-      "name": "TypeScript[React] Import/Export Punctuations",

-      "scope": [

-        "meta.import.ts punctuation.definition.block",

-        "meta.import.tsx punctuation.definition.block",

-        "meta.export.ts punctuation.definition.block",

-        "meta.export.tsx punctuation.definition.block"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "TypeScript[React] Punctuation Decorators",

-      "scope": [

-        "meta.decorator punctuation.decorator.ts",

-        "meta.decorator punctuation.decorator.tsx"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "TypeScript[React] Punctuation Decorators",

-      "scope": "meta.tag.js meta.jsx.children.tsx",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "YAML Entity Name Tags",

-      "scope": "entity.name.tag.yaml",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "handlebars variables",

-      "scope": "variable.parameter.handlebars",

-      "settings": {

-        "foreground": "#bec5d4"

-      }

-    },

-    {

-      "name": "handlebars parameters",

-      "scope": "entity.other.attribute-name.handlebars variable.parameter.handlebars",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "handlebars enitity attribute names",

-      "scope": "entity.other.attribute-name.handlebars",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "handlebars enitity attribute values",

-      "scope": "entity.other.attribute-value.handlebars variable.parameter.handlebars",

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "normalize font style of certain components",

-      "scope": [

-        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.begin.js",

-        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.end.js",

-        "meta.property-list.css meta.property-value.css variable.other.less",

-        "punctuation.section.embedded.begin.js.jsx",

-        "punctuation.section.embedded.end.js.jsx",

-        "meta.property-list.scss variable.scss",

-        "meta.property-list.sass variable.sass",

-        "keyword.operator.logical",

-        "keyword.operator.arithmetic",

-        "keyword.operator.bitwise",

-        "keyword.operator.increment",

-        "keyword.operator.ternary",

-        "keyword.operator.comparison",

-        "keyword.operator.assignment",

-        "keyword.operator.operator",

-        "keyword.operator.or.regexp",

-        "keyword.operator.expression.in",

-        "keyword.operator.type",

-        "punctuation.section.embedded.js",

-        "punctuation.definintion.string",

-        "punctuation"

-      ],

-      "settings": {

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "italicsify for operator mono",

-      "scope": [

-        "keyword.other.unit",

-        "support.type.property-name.css",

-        "support.type.vendored.property-name.css",

-        "support.constant.vendored.property-value.css",

-        "meta.import.ts meta.block.ts variable.other.readwrite.alias.ts",

-        "meta.import.tsx meta.block.tsx variable.other.readwrite.alias.tsx",

-        "meta.import.js variable.other",

-        "meta.export.ts meta.block.ts variable.other.readwrite.alias.ts",

-        "meta.export.tsx meta.block.tsx variable.other.readwrite.alias.tsx",

-        "meta.export.js variable.other",

-        "entity.name.function.ts",

-        "entity.name.function.tsx",

-        "support.type.primitive",

-        "entity.name.tag.yaml",

-        "entity.other.attribute-name",

-        "meta.tag.sgml.doctype.html",

-        "entity.name.tag.doctype",

-        "meta.tag.sgml.doctype",

-        "entity.name.tag.custom",

-        "source.js.jsx keyword.control.flow.js",

-        "support.type.property.css",

-        "support.function.basic_functions",

-        "constant.other.color.rgb-value.hex.css",

-        "constant.other.rgb-value.css",

-        "variable.assignment.coffee",

-        "support.function.basic_functions",

-        "keyword.operator.expression.typeof",

-        "punctuation.section.embedded",

-        "keyword.operator.type.annotation",

-        "variable.object.property.ts",

-        "variable.object.property.js",

-        "variable.object.property.jsx",

-        "variable.object.property.tsx",

-        "assignment.coffee",

-        "entity.name.type.ts",

-        "support.constant.math",

-        "meta.object-literal.key",

-        "meta.var.expr storage.type",

-        "variable.scss",

-        "variable.sass",

-        "variable.other.less",

-        "variable.parameter.url.scss",

-        "variable.parameter.url.sass",

-        "parameter",

-        "string",

-        "italic",

-        "quote",

-        "keyword",

-        "storage",

-        "language",

-        "constant.language",

-        "variable.language",

-        "type .function",

-        "type.function",

-        "storage.type.class",

-        "type.var",

-        "meta.parameter",

-        "variable.parameter",

-        "meta.parameters",

-        "keyword.control",

-        "modifier",

-        "this",

-        "comment"

-      ],

-      "settings": {

-        "fontStyle": "italic"

-      }

-    }

-  ]

-}

+{
+  "name": "Palenight Operator",
+  "author": "Olaolu Olawuyi",
+  "maintainers": ["Olaolu Olawuyi <mrolaolu@gmail.com>"],
+  "type": "dark",
+  "semanticClass": "palenight-operator",
+  "colors": {
+    "contrastActiveBorder": null,
+    "contrastBorder": "#282B3C",
+    "focusBorder": "#282B3C",
+    "foreground": "#ffffff",
+    "widget.shadow": "#232635",
+    "selection.background": "#7580B850",
+    "descriptionForeground": null,
+    "errorForeground": "#EF5350",
+    "button.background": "#7e57c2cc",
+    "button.foreground": "#ffffffcc",
+    "button.hoverBackground": "#7e57c2",
+    "dropdown.background": "#292D3E",
+    "dropdown.border": "#7e57c2",
+    "dropdown.foreground": "#ffffffcc",
+    "input.background": "#313850",
+    "input.border": "#7e57c2",
+    "input.foreground": "#ffffffcc",
+    "input.placeholderForeground": "#ffffffcc",
+    "inputOption.activeBorder": "#ffffffcc",
+    "inputValidation.errorBackground": "#ef5350f2",
+    "inputValidation.errorBorder": "#EF5350",
+    "inputValidation.infoBackground": "#64b5f6f2",
+    "inputValidation.infoBorder": "#64B5F6",
+    "inputValidation.warningBackground": "#ffca28f2",
+    "inputValidation.warningBorder": "#FFCA28",
+    "scrollbar.shadow": "#292D3E00",
+    "scrollbarSlider.activeBackground": "#694CA4cc",
+    "scrollbarSlider.background": "#694CA466",
+    "scrollbarSlider.hoverBackground": "#694CA4cc",
+    "badge.background": "#7e57c2",
+    "badge.foreground": "#ffffff",
+    "progress.background": "#7e57c2",
+    "list.activeSelectionBackground": "#7e57c2",
+    "list.activeSelectionForeground": "#ffffff",
+    "list.dropBackground": "#2E3245",
+    "list.focusBackground": "#0000002e",
+    "list.focusForeground": "#ffffff",
+    "list.highlightForeground": "#ffffff",
+    "list.hoverBackground": "#0000001a",
+    "list.hoverForeground": "#ffffff",
+    "list.inactiveSelectionBackground": "#929ac90d",
+    "list.inactiveSelectionForeground": "#929ac9",
+    "activityBar.background": "#282C3D",
+    "activityBar.dropBackground": "#7e57c2e3",
+    "activityBar.foreground": "#eeffff",
+    "activityBar.border": "#282C3D",
+    "activityBarBadge.background": "#7e57c2",
+    "activityBarBadge.foreground": "#ffffff",
+    "sideBar.background": "#292D3E",
+    "sideBar.foreground": "#6C739A",
+    "sideBar.border": "#282B3C",
+    "sideBarTitle.foreground": "#eeffff",
+    "sideBarSectionHeader.background": "#292D3E",
+    "sideBarSectionHeader.foreground": "#eeffff",
+    "editorGroup.background": "#32374C",
+    "editorGroup.border": "#2E3245",
+    "editorGroup.dropBackground": "#7e57c273",
+    "editorGroupHeader.noTabsBackground": "#32374C",
+    "editorGroupHeader.tabsBackground": "#31364a",
+    "editorGroupHeader.tabsBorder": "#262A39",
+    "tab.activeBackground": "#292D3E",
+    "tab.activeForeground": "#eeffff",
+    "tab.border": "#272B3B",
+    "tab.activeBorder": "#262A39",
+    "tab.unfocusedActiveBorder": "#262A39",
+    "tab.inactiveBackground": "#31364A",
+    "tab.inactiveForeground": "#929ac9",
+    "tab.unfocusedActiveForeground": null,
+    "tab.unfocusedInactiveForeground": null,
+    "editor.background": "#292D3E",
+    "editor.foreground": "#BFC7D5",
+    "editorLineNumber.foreground": "#4c5374",
+    "editorLineNumber.activeForeground": "#eeffff",
+    "editorCursor.foreground": "#7e57c2",
+    "editorCursor.background": null,
+    "editor.selectionBackground": "#7580B850",
+    "editor.selectionHighlightBackground": "#383D51",
+    "editor.inactiveSelectionBackground": "#7e57c25a",
+    "editor.wordHighlightBackground": "#32374D",
+    "editor.wordHighlightStrongBackground": "#2E3250",
+    "editor.findMatchBackground": "#2e3248fc",
+    "editor.findMatchHighlightBackground": "#7e57c233",
+    "editor.findRangeHighlightBackground": null,
+    "editor.hoverHighlightBackground": "#7e57c25a",
+    "editor.lineHighlightBackground": "#0003",
+    "editor.lineHighlightBorder": null,
+    "editorLink.activeForeground": null,
+    "editor.rangeHighlightBackground": "#7e57c25a",
+    "editorWhitespace.foreground": null,
+    "editorIndentGuide.background": "#4E557980",
+    "editorRuler.foreground": "#4E557980",
+    "editorCodeLens.foreground": "#FFCA28",
+    "editorBracketMatch.background": null,
+    "editorBracketMatch.border": null,
+    "editorOverviewRuler.currentContentForeground": "#7e57c2",
+    "editorOverviewRuler.incomingContentForeground": "#7e57c2",
+    "editorOverviewRuler.commonContentForeground": "#7e57c2",
+    "editorError.foreground": "#EF5350",
+    "editorError.border": null,
+    "editorWarning.foreground": "#FFCA28",
+    "editorWarning.border": null,
+    "editorGutter.background": null,
+    "editorGutter.modifiedBackground": "#e2b93d",
+    "editorGutter.addedBackground": "#9CCC65",
+    "editorGutter.deletedBackground": "#EF5350",
+    "diffEditor.insertedTextBackground": "#99b76d23",
+    "diffEditor.removedTextBackground": "#ef535033",
+    "editorWidget.background": "#31364a",
+    "editorWidget.border": null,
+    "editorSuggestWidget.background": "#2C3043",
+    "editorSuggestWidget.border": "#2B2F40",
+    "editorSuggestWidget.foreground": "#bfc7d5",
+    "editorSuggestWidget.highlightForeground": "#ffffff",
+    "editorSuggestWidget.selectedBackground": "#7e57c2",
+    "editorHoverWidget.background": "#292D3E",
+    "editorHoverWidget.border": "#7e57c2",
+    "debugExceptionWidget.background": "#292D3E",
+    "debugExceptionWidget.border": "#7e57c2",
+    "editorMarkerNavigation.background": "#31364a",
+    "editorMarkerNavigationError.background": "#EF5350",
+    "editorMarkerNavigationWarning.background": "#FFCA28",
+    "peekView.border": "#7e57c2",
+    "peekViewEditor.background": "#232635",
+    "peekViewEditor.matchHighlightBackground": "#7e57c25a",
+    "peekViewResult.background": "#2E3245",
+    "peekViewResult.fileForeground": "#eeffff",
+    "peekViewResult.lineForeground": "#eeffff",
+    "peekViewResult.matchHighlightBackground": "#7e57c25a",
+    "peekViewResult.selectionBackground": "#2E3250",
+    "peekViewResult.selectionForeground": "#eeffff",
+    "peekViewTitle.background": "#292D3E",
+    "peekViewTitleDescription.foreground": "#697098",
+    "peekViewTitleLabel.foreground": "#eeffff",
+    "merge.currentHeaderBackground": "#7e57c25a",
+    "merge.currentContentBackground": null,
+    "merge.incomingHeaderBackground": "#7e57c25a",
+    "merge.incomingContentBackground": null,
+    "merge.border": null,
+    "panel.background": "#292D3E",
+    "panel.border": "#282B3C",
+    "panelTitle.activeBorder": "#7e57c2",
+    "panelTitle.activeForeground": "#eeffff",
+    "panelTitle.inactiveForeground": "#bfc7d580",
+    "statusBar.background": "#282C3D",
+    "statusBar.foreground": "#676E95",
+    "statusBar.border": "#262A39",
+    "statusBar.debuggingBackground": "#202431",
+    "statusBar.debuggingForeground": null,
+    "statusBar.debuggingBorder": "#1F2330",
+    "statusBar.noFolderForeground": null,
+    "statusBar.noFolderBackground": "#292D3E",
+    "statusBar.noFolderBorder": "#25293A",
+    "statusBarItem.activeBackground": "#202431",
+    "statusBarItem.hoverBackground": "#202431",
+    "statusBarItem.prominentBackground": "#202431",
+    "statusBarItem.prominentHoverBackground": "#202431",
+    "titleBar.activeBackground": "#292d3e",
+    "titleBar.activeForeground": "#eeefff",
+    "titleBar.border": "#30364c",
+    "titleBar.inactiveBackground": "#30364c",
+    "titleBar.inactiveForeground": null,
+    "notifications.background": "#292D3E",
+    "notifications.foreground": "#ffffffcc",
+    "notificationLink.foreground": "#80CBC4",
+    "extensionButton.prominentForeground": "#ffffffcc",
+    "extensionButton.prominentBackground": "#7e57c2cc",
+    "extensionButton.prominentHoverBackground": "#7e57c2",
+    "pickerGroup.foreground": "#d1aaff",
+    "pickerGroup.border": "#2E3245",
+    "terminal.ansiWhite": "#ffffff",
+    "terminal.ansiBlack": "#676E95",
+    "terminal.ansiBlue": "#82AAFF",
+    "terminal.ansiCyan": "#89DDFF",
+    "terminal.ansiGreen": "#a9c77d",
+    "terminal.ansiMagenta": "#C792EA",
+    "terminal.ansiRed": "#ff5572",
+    "terminal.ansiYellow": "#FFCB6B",
+    "terminal.ansiBrightWhite": "#ffffff",
+    "terminal.ansiBrightBlack": "#676E95",
+    "terminal.ansiBrightBlue": "#82AAFF",
+    "terminal.ansiBrightCyan": "#89DDFF",
+    "terminal.ansiBrightGreen": "#C3E88D",
+    "terminal.ansiBrightMagenta": "#C792EA",
+    "terminal.ansiBrightRed": "#ff5572",
+    "terminal.ansiBrightYellow": "#FFCB6B",
+    "debugToolBar.background": "#292D3E",
+    "welcomePage.buttonBackground": null,
+    "welcomePage.buttonHoverBackground": null,
+    "walkThrough.embeddedEditorBackground": "#232635",
+    "gitDecoration.modifiedResourceForeground": "#e2c08de6",
+    "gitDecoration.deletedResourceForeground": "#EF535090",
+    "gitDecoration.untrackedResourceForeground": "#a9c77dff",
+    "gitDecoration.ignoredResourceForeground": "#69709890",
+    "gitDecoration.conflictingResourceForeground": "#FFEB95CC",
+    "editorActiveLineNumber.foreground": "#eeffff",
+    "breadcrumb.foreground": "#6c739a",
+    "breadcrumb.focusForeground": "#bfc7d5",
+    "breadcrumb.activeSelectionForeground": "#eeffff",
+    "breadcrumbPicker.background": "#292D3E"
+  },
+  "tokenColors": [
+    {
+      "name": "Global settings",
+      "settings": {
+        "background": "#292D3E",
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Comment",
+      "scope": "comment",
+      "settings": {
+        "foreground": "#697098",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "String",
+      "scope": "string",
+      "settings": {
+        "foreground": "#C3E88D"
+      }
+    },
+    {
+      "name": "String Quoted",
+      "scope": "string.quoted",
+      "settings": {
+        "foreground": "#C3E88D"
+      }
+    },
+    {
+      "name": "String Unquoted",
+      "scope": "string.unquoted",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Support Constant Math",
+      "scope": "support.constant.math",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Number",
+      "scope": ["constant.numeric", "constant.character.numeric"],
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Built-in constant",
+      "scope": [
+        "constant.language",
+        "punctuation.definition.constant",
+        "variable.other.constant"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "User-defined constant",
+      "scope": ["constant.character", "constant.other"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Constant Character Escape",
+      "scope": "constant.character.escape",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "RegExp String",
+      "scope": ["string.regexp", "string.regexp keyword.other"],
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Comma in functions",
+      "scope": "meta.function punctuation.separator.comma",
+      "settings": {
+        "foreground": "#eeffff"
+      }
+    },
+    {
+      "name": "Variable",
+      "scope": "variable",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Keyword",
+      "scope": ["punctuation.accessor", "keyword"],
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Storage",
+      "scope": [
+        "storage",
+        "storage.type",
+        "meta.var.expr storage.type",
+        "storage.type.property.js",
+        "storage.type.property.ts",
+        "storage.type.property.tsx",
+        "meta.class meta.method.declaration meta.var.expr storage.type.js"
+      ],
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Class name",
+      "scope": ["entity.name.class", "meta.class entity.name.type.class"],
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Inherited class",
+      "scope": "entity.other.inherited-class",
+      "settings": {
+        "foreground": "#a9c77d"
+      }
+    },
+    {
+      "name": "Function name",
+      "scope": "entity.name.function",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Function Parameters",
+      "scope": "variable.parameter",
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "Meta Tag",
+      "scope": ["punctuation.definition.tag", "meta.tag"],
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "HTML Tag names",
+      "scope": [
+        "entity.name.tag support.class.component",
+        "meta.tag.other.html",
+        "meta.tag.other.js",
+        "meta.tag.other.tsx",
+        "entity.name.tag.tsx",
+        "entity.name.tag.js",
+        "entity.name.tag",
+        "meta.tag.js",
+        "meta.tag.tsx",
+        "meta.tag.html"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Tag attribute",
+      "scope": "entity.other.attribute-name",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Entity Name Tag Custom",
+      "scope": "entity.name.tag.custom",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Library (function & constant)",
+      "scope": ["support.function", "support.constant"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Support Constant Property Value meta",
+      "scope": "support.constant.meta.property-value",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Library class/type",
+      "scope": ["support.type", "support.class"],
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Support Variable DOM",
+      "scope": "support.variable.dom",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Invalid",
+      "scope": "invalid",
+      "settings": {
+        "background": "#ff2c83",
+        "foreground": "#ffffff"
+      }
+    },
+    {
+      "name": "Invalid deprecated",
+      "scope": "invalid.deprecated",
+      "settings": {
+        "foreground": "#ffffff",
+        "background": "#d3423e"
+      }
+    },
+    {
+      "name": "Keyword Operator",
+      "scope": "keyword.operator",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Keyword Operator Relational",
+      "scope": "keyword.operator.relational",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Keyword Operator Assignment",
+      "scope": "keyword.operator.assignment",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Double-Slashed Comment",
+      "scope": "comment.line.double-slash",
+      "settings": {
+        "foreground": "#697098"
+      }
+    },
+    {
+      "name": "Object",
+      "scope": "object",
+      "settings": {
+        "foreground": "#cdebf7"
+      }
+    },
+    {
+      "name": "Null",
+      "scope": "constant.language.null",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Meta Brace",
+      "scope": "meta.brace",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Meta Delimiter Period",
+      "scope": "meta.delimiter.period",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Punctuation Definition String",
+      "scope": "punctuation.definition.string",
+      "settings": {
+        "foreground": "#d9f5dd"
+      }
+    },
+    {
+      "name": "Boolean",
+      "scope": "constant.language.boolean",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Object Comma",
+      "scope": "object.comma",
+      "settings": {
+        "foreground": "#ffffff"
+      }
+    },
+    {
+      "name": "Variable Parameter Function",
+      "scope": "variable.parameter.function",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Support Type Property Name & entity name tags",
+      "scope": [
+        "support.type.vendored.property-name",
+        "support.constant.vendored.property-value",
+        "support.type.property-name",
+        "meta.property-list entity.name.tag"
+      ],
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Entity Name tag reference in stylesheets",
+      "scope": "meta.property-list entity.name.tag.reference",
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Constant Other Color RGB Value Punctuation Definition Constant",
+      "scope": "constant.other.color.rgb-value punctuation.definition.constant",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Constant Other Color",
+      "scope": "constant.other.color",
+      "settings": {
+        "foreground": "#FFEB95"
+      }
+    },
+    {
+      "name": "Keyword Other Unit",
+      "scope": "keyword.other.unit",
+      "settings": {
+        "foreground": "#FFEB95"
+      }
+    },
+    {
+      "name": "Meta Selector",
+      "scope": "meta.selector",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Entity Other Attribute Name Id",
+      "scope": "entity.other.attribute-name.id",
+      "settings": {
+        "foreground": "#FAD430"
+      }
+    },
+    {
+      "name": "Meta Property Name",
+      "scope": "meta.property-name",
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Doctypes",
+      "scope": ["entity.name.tag.doctype", "meta.tag.sgml.doctype"],
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Punctuation Definition Parameters",
+      "scope": "punctuation.definition.parameters",
+      "settings": {
+        "foreground": "#d9f5dd"
+      }
+    },
+    {
+      "name": "Keyword Control Operator",
+      "scope": "keyword.control.operator",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Keyword Operator Logical",
+      "scope": "keyword.operator.logical",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Variable Instances",
+      "scope": [
+        "variable.instance",
+        "variable.other.instance",
+        "variable.reaedwrite.instance",
+        "variable.other.readwrite.instance"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Variable Property Other",
+      "scope": ["variable.other.property", "variable.other.object.property"],
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Entity Name Function",
+      "scope": "entity.name.function",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Keyword Operator Comparison",
+      "scope": "keyword.operator.comparison",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Support Constant, `new` keyword, Special Method Keyword",
+      "scope": [
+        "support.constant",
+        "keyword.other.special-method",
+        "keyword.other.new"
+      ],
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Support Function",
+      "scope": "support.function",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Invalid Broken",
+      "scope": "invalid.broken",
+      "settings": {
+        "foreground": "#020e14",
+        "background": "#F78C6C"
+      }
+    },
+    {
+      "name": "Invalid Unimplemented",
+      "scope": "invalid.unimplemented",
+      "settings": {
+        "background": "#8BD649",
+        "foreground": "#ffffff"
+      }
+    },
+    {
+      "name": "Invalid Illegal",
+      "scope": "invalid.illegal",
+      "settings": {
+        "foreground": "#ffffff",
+        "background": "#ec5f67"
+      }
+    },
+    {
+      "name": "Language Variable",
+      "scope": "variable.language",
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Support Variable Property",
+      "scope": "support.variable.property",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Variable Function",
+      "scope": "variable.function",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Variable Interpolation",
+      "scope": "variable.interpolation",
+      "settings": {
+        "foreground": "#ec5f67"
+      }
+    },
+    {
+      "name": "Meta Function Call",
+      "scope": "meta.function-call",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Punctuation Section Embedded",
+      "scope": "punctuation.section.embedded",
+      "settings": {
+        "foreground": "#d3423e"
+      }
+    },
+    {
+      "name": "Punctuation Tweaks",
+      "scope": [
+        "punctuation.terminator.expression",
+        "punctuation.definition.arguments",
+        "punctuation.definition.array",
+        "punctuation.section.array",
+        "meta.array"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "More Punctuation Tweaks",
+      "scope": [
+        "punctuation.definition.list.begin",
+        "punctuation.definition.list.end",
+        "punctuation.separator.arguments",
+        "punctuation.definition.list"
+      ],
+      "settings": {
+        "foreground": "#d9f5dd"
+      }
+    },
+    {
+      "name": "Template Strings",
+      "scope": "string.template meta.template.expression",
+      "settings": {
+        "foreground": "#d3423e"
+      }
+    },
+    {
+      "name": "Backtics(``) in Template Strings",
+      "scope": "string.template punctuation.definition.string",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Italics",
+      "scope": "italic",
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Bold",
+      "scope": "bold",
+      "settings": {
+        "foreground": "#ffcb6b",
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "name": "Quote",
+      "scope": "quote",
+      "settings": {
+        "foreground": "#697098",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Raw Code",
+      "scope": "raw",
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "CoffeScript Variable Assignment",
+      "scope": "variable.assignment.coffee",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "CoffeScript Parameter Function",
+      "scope": "variable.parameter.function.coffee",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "CoffeeScript Assignments",
+      "scope": "variable.assignment.coffee",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "C# Readwrite Variables",
+      "scope": "variable.other.readwrite.cs",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "C# Classes & Storage types",
+      "scope": ["entity.name.type.class.cs", "storage.type.cs"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "C# Namespaces",
+      "scope": "entity.name.type.namespace.cs",
+      "settings": {
+        "foreground": "#B2CCD6"
+      }
+    },
+    {
+      "name": "Tag names in Stylesheets",
+      "scope": [
+        "entity.name.tag.css",
+        "entity.name.tag.less",
+        "entity.name.tag.custom.css"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Wildcard(*) selector in Stylesheets",
+      "scope": [
+        "entity.name.tag.wildcard.css",
+        "entity.name.tag.wildcard.less",
+        "entity.name.tag.wildcard.scss",
+        "entity.name.tag.wildcard.sass"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "(C|SC|SA|LE)SS property value unit",
+      "scope": [
+        "keyword.other.unit.css",
+        "constant.length.units.css",
+        "keyword.other.unit.less",
+        "constant.length.units.less",
+        "keyword.other.unit.scss",
+        "constant.length.units.scss",
+        "keyword.other.unit.sass",
+        "constant.length.units.sass"
+      ],
+      "settings": {
+        "foreground": "#FFEB95"
+      }
+    },
+    {
+      "name": "Attribute Name for CSS",
+      "scope": "meta.attribute-selector.css entity.other.attribute-name.attribute",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "punctuations in styled components",
+      "scope": [
+        "source.js source.css meta.property-list",
+        "source.js source.css punctuation.section",
+        "source.js source.css punctuation.terminator.rule",
+        "source.js source.css punctuation.definition.entity.end.bracket",
+        "source.js source.css punctuation.definition.entity.begin.bracket",
+        "source.js source.css punctuation.separator.key-value",
+        "source.js source.css punctuation.definition.attribute-selector",
+        "source.js source.css meta.property-list",
+        "source.js source.css meta.property-list punctuation.separator.comma",
+        "source.ts source.css punctuation.section",
+        "source.ts source.css punctuation.terminator.rule",
+        "source.ts source.css punctuation.definition.entity.end.bracket",
+        "source.ts source.css punctuation.definition.entity.begin.bracket",
+        "source.ts source.css punctuation.separator.key-value",
+        "source.ts source.css punctuation.definition.attribute-selector",
+        "source.ts source.css meta.property-list",
+        "source.ts source.css meta.property-list punctuation.separator.comma"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Elixir Classes",
+      "scope": [
+        "source.elixir support.type.elixir",
+        "source.elixir meta.module.elixir entity.name.class.elixir"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Elixir Functions",
+      "scope": "source.elixir entity.name.function",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Elixir Constants",
+      "scope": [
+        "source.elixir constant.other.symbol.elixir",
+        "source.elixir constant.other.keywords.elixir"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Elixir String Punctuations",
+      "scope": "source.elixir punctuation.definition.string",
+      "settings": {
+        "foreground": "#a9c77d"
+      }
+    },
+    {
+      "name": "Elixir",
+      "scope": [
+        "source.elixir variable.other.readwrite.module.elixir",
+        "source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir"
+      ],
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Elixir Binary Punctuations",
+      "scope": "source.elixir .punctuation.binary.elixir",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Go Function Calls",
+      "scope": "source.go meta.function-call.go",
+      "settings": {
+        "foreground": "#DDDDDD"
+      }
+    },
+    {
+      "name": "GraphQL Variables",
+      "scope": "variable.qraphql",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "ID Attribute Name in HTML",
+      "scope": "entity.other.attribute-name.id.html",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "HTML Punctuation Definition Tag",
+      "scope": "punctuation.definition.tag.html",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "HTML Doctype",
+      "scope": "meta.tag.sgml.doctype.html",
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "JavaScript Classes",
+      "scope": "meta.class entity.name.type.class.js",
+      "settings": {
+        "foreground": "#ffcb8b"
+      }
+    },
+    {
+      "name": "JavaScript Method Declaration e.g. `constructor`",
+      "scope": "meta.method.declaration storage.type.js",
+      "settings": {
+        "foreground": "#82AAFF",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "JavaScript Terminator",
+      "scope": "terminator.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Meta Punctuation Definition",
+      "scope": "meta.js punctuation.definition.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Entity Names in Code Documentations",
+      "scope": [
+        "entity.name.type.instance.jsdoc",
+        "entity.name.type.instance.phpdoc"
+      ],
+      "settings": {
+        "foreground": "#eeffff"
+      }
+    },
+    {
+      "name": "Other Variables in Code Documentations",
+      "scope": ["variable.other.jsdoc", "variable.other.phpdoc"],
+      "settings": {
+        "foreground": "#78ccf0"
+      }
+    },
+    {
+      "name": "JavaScript module imports and exports",
+      "scope": [
+        "variable.other.meta.import.js",
+        "meta.import.js variable.other",
+        "variable.other.meta.export.js",
+        "meta.export.js variable.other"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Variable Parameter Function",
+      "scope": "variable.parameter.function.js",
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "JavaScript Variable Other ReadWrite",
+      "scope": "variable.other.readwrite.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Text nested in React tags",
+      "scope": [
+        "meta.jsx.children",
+        "meta.jsx.children.js",
+        "meta.jsx.children.tsx"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript[React] Variable Other Object",
+      "scope": [
+        "variable.other.object.js",
+        "variable.other.object.jsx",
+        "meta.object-literal.key.js",
+        "meta.object-literal.key.jsx",
+        "variable.object.property.js",
+        "variable.object.property.jsx"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Variables",
+      "scope": ["variable.js", "variable.other.js"],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Entity Name Type",
+      "scope": ["entity.name.type.js", "entity.name.type.module.js"],
+      "settings": {
+        "foreground": "#ffcb8b"
+      }
+    },
+    {
+      "name": "JavaScript Support Classes",
+      "scope": "support.class.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JSON Property Names",
+      "scope": "support.type.property-name.json",
+      "settings": {
+        "foreground": "#C3E88D",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "JSON Support Constants",
+      "scope": "support.constant.json",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "JSON Property values (string)",
+      "scope": "meta.structure.dictionary.value.json string.quoted.double",
+      "settings": {
+        "foreground": "#80CBC4",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "Strings in JSON values",
+      "scope": "string.quoted.double.json punctuation.definition.string.json",
+      "settings": {
+        "foreground": "#80CBC4",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "Specific JSON Property values like null",
+      "scope": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Ruby Variables",
+      "scope": "variable.other.ruby",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Ruby Hashkeys",
+      "scope": "constant.language.symbol.hashkey.ruby",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "LESS Tag names",
+      "scope": "entity.name.tag.less",
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Attribute Name for LESS",
+      "scope": "meta.attribute-selector.less entity.other.attribute-name.attribute",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Markup Headings",
+      "scope": "markup.heading",
+      "settings": {
+        "foreground": "#82b1ff"
+      }
+    },
+    {
+      "name": "Markup Italics",
+      "scope": "markup.italic",
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Markup Bold",
+      "scope": "markup.bold",
+      "settings": {
+        "foreground": "#ffcb6b",
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "name": "Markup Quote + others",
+      "scope": "markup.quote",
+      "settings": {
+        "foreground": "#697098",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Markup Raw Code + others",
+      "scope": "markup.inline.raw",
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Markup Links",
+      "scope": ["markup.underline.link", "markup.underline.link.image"],
+      "settings": {
+        "foreground": "#ff869a"
+      }
+    },
+    {
+      "name": "Markup Attributes",
+      "scope": ["markup.meta.attribute-list"],
+      "settings": {
+        "foreground": "#a9c77d"
+      }
+    },
+    {
+      "name": "Markup Admonitions",
+      "scope": "markup.admonition",
+      "settings": {
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "name": "Markup Lists",
+      "scope": "markup.list.bullet",
+      "settings": {
+        "foreground": "#D9F5DD"
+      }
+    },
+    {
+      "name": "Markup Superscript and Subscript",
+      "scope": ["markup.superscript", "markup.subscript"],
+      "settings": {
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Markdown Link Title and Description",
+      "scope": [
+        "string.other.link.title.markdown",
+        "string.other.link.description.markdown"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Markdown Punctuation",
+      "scope": [
+        "punctuation.definition.string.markdown",
+        "punctuation.definition.string.begin.markdown",
+        "punctuation.definition.string.end.markdown",
+        "meta.link.inline.markdown punctuation.definition.string"
+      ],
+      "settings": {
+        "foreground": "#82b1ff"
+      }
+    },
+    {
+      "name": "Markdown MetaData Punctuation",
+      "scope": ["punctuation.definition.metadata.markdown"],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Markdown List Punctuation",
+      "scope": ["beginning.punctuation.definition.list.markdown"],
+      "settings": {
+        "foreground": "#82b1ff"
+      }
+    },
+    {
+      "name": "Asciidoc Function",
+      "scope": "entity.name.function.asciidoc",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "PHP Variables",
+      "scope": "variable.other.php",
+      "settings": {
+        "foreground": "#bec5d4"
+      }
+    },
+    {
+      "name": "Support Classes in PHP",
+      "scope": "support.class.php",
+      "settings": {
+        "foreground": "#ffcb8b"
+      }
+    },
+    {
+      "name": "Punctuations in PHP function calls",
+      "scope": "meta.function-call.php punctuation",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "PHP Global Variables",
+      "scope": "variable.other.global.php",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Declaration Punctuation in PHP Global Variables",
+      "scope": "variable.other.global.php punctuation.definition.variable",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Language Constants in Python",
+      "scope": "constant.language.python",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Python Function Parameter and Arguments",
+      "scope": [
+        "variable.parameter.function.python",
+        "meta.function-call.arguments.python"
+      ],
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "Python Function Call",
+      "scope": [
+        "meta.function-call.python",
+        "meta.function-call.generic.python"
+      ],
+      "settings": {
+        "foreground": "#B2CCD6"
+      }
+    },
+    {
+      "name": "Punctuations in Python",
+      "scope": "punctuation.python",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Decorator Functions in Python",
+      "scope": "entity.name.function.decorator.python",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Python Language Variable",
+      "scope": "source.python variable.language.special",
+      "settings": {
+        "foreground": "#8EACE3"
+      }
+    },
+    {
+      "name": "SCSS Variable",
+      "scope": [
+        "variable.scss",
+        "variable.sass",
+        "variable.parameter.url.scss",
+        "variable.parameter.url.sass"
+      ],
+      "settings": {
+        "foreground": "#DDDDDD"
+      }
+    },
+    {
+      "name": "Variables in SASS At-Rules",
+      "scope": [
+        "source.css.scss meta.at-rule variable",
+        "source.css.sass meta.at-rule variable"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Variables in SASS At-Rules",
+      "scope": [
+        "source.css.scss meta.at-rule variable",
+        "source.css.sass meta.at-rule variable"
+      ],
+      "settings": {
+        "foreground": "#bec5d4"
+      }
+    },
+    {
+      "name": "Attribute Name for SASS",
+      "scope": [
+        "meta.attribute-selector.scss entity.other.attribute-name.attribute",
+        "meta.attribute-selector.sass entity.other.attribute-name.attribute"
+      ],
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Tag names in SASS",
+      "scope": ["entity.name.tag.scss", "entity.name.tag.sass"],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "TypeScript[React] Variables and Object Properties",
+      "scope": [
+        "variable.other.readwrite.alias.ts",
+        "variable.other.readwrite.alias.tsx",
+        "variable.other.readwrite.ts",
+        "variable.other.readwrite.tsx",
+        "variable.other.object.ts",
+        "variable.other.object.tsx",
+        "variable.object.property.ts",
+        "variable.object.property.tsx",
+        "variable.other.ts",
+        "variable.other.tsx",
+        "variable.tsx",
+        "variable.ts"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "TypeScript[React] Entity Name Types",
+      "scope": ["entity.name.type.ts", "entity.name.type.tsx"],
+      "settings": {
+        "foreground": "#78ccf0"
+      }
+    },
+    {
+      "name": "TypeScript[React] Node Classes",
+      "scope": ["support.class.node.ts", "support.class.node.tsx"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "TypeScript[React] Entity Name Types as Parameters",
+      "scope": [
+        "meta.type.parameters.ts entity.name.type",
+        "meta.type.parameters.tsx entity.name.type"
+      ],
+      "settings": {
+        "foreground": "#eeffff"
+      }
+    },
+    {
+      "name": "TypeScript[React] Import/Export Punctuations",
+      "scope": [
+        "meta.import.ts punctuation.definition.block",
+        "meta.import.tsx punctuation.definition.block",
+        "meta.export.ts punctuation.definition.block",
+        "meta.export.tsx punctuation.definition.block"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "TypeScript[React] Punctuation Decorators",
+      "scope": [
+        "meta.decorator punctuation.decorator.ts",
+        "meta.decorator punctuation.decorator.tsx"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "TypeScript[React] Punctuation Decorators",
+      "scope": "meta.tag.js meta.jsx.children.tsx",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "YAML Entity Name Tags",
+      "scope": "entity.name.tag.yaml",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "handlebars variables",
+      "scope": "variable.parameter.handlebars",
+      "settings": {
+        "foreground": "#bec5d4"
+      }
+    },
+    {
+      "name": "handlebars parameters",
+      "scope": "entity.other.attribute-name.handlebars variable.parameter.handlebars",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "handlebars enitity attribute names",
+      "scope": "entity.other.attribute-name.handlebars",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "handlebars enitity attribute values",
+      "scope": "entity.other.attribute-value.handlebars variable.parameter.handlebars",
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "normalize font style of certain components",
+      "scope": [
+        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.begin.js",
+        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.end.js",
+        "meta.property-list.css meta.property-value.css variable.other.less",
+        "punctuation.section.embedded.begin.js.jsx",
+        "punctuation.section.embedded.end.js.jsx",
+        "meta.property-list.scss variable.scss",
+        "meta.property-list.sass variable.sass",
+        "keyword.operator.logical",
+        "keyword.operator.arithmetic",
+        "keyword.operator.bitwise",
+        "keyword.operator.increment",
+        "keyword.operator.ternary",
+        "keyword.operator.comparison",
+        "keyword.operator.assignment",
+        "keyword.operator.operator",
+        "keyword.operator.or.regexp",
+        "keyword.operator.expression.in",
+        "keyword.operator.type",
+        "punctuation.section.embedded.js",
+        "punctuation.definintion.string",
+        "punctuation"
+      ],
+      "settings": {
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "italicsify for operator mono",
+      "scope": [
+        "keyword.other.unit",
+        "support.type.property-name.css",
+        "support.type.vendored.property-name.css",
+        "support.constant.vendored.property-value.css",
+        "meta.import.ts meta.block.ts variable.other.readwrite.alias.ts",
+        "meta.import.tsx meta.block.tsx variable.other.readwrite.alias.tsx",
+        "meta.import.js variable.other",
+        "meta.export.ts meta.block.ts variable.other.readwrite.alias.ts",
+        "meta.export.tsx meta.block.tsx variable.other.readwrite.alias.tsx",
+        "meta.export.js variable.other",
+        "entity.name.function.ts",
+        "entity.name.function.tsx",
+        "support.type.primitive",
+        "entity.name.tag.yaml",
+        "entity.other.attribute-name",
+        "meta.tag.sgml.doctype.html",
+        "entity.name.tag.doctype",
+        "meta.tag.sgml.doctype",
+        "entity.name.tag.custom",
+        "source.js.jsx keyword.control.flow.js",
+        "support.type.property.css",
+        "support.function.basic_functions",
+        "constant.other.color.rgb-value.hex.css",
+        "constant.other.rgb-value.css",
+        "variable.assignment.coffee",
+        "support.function.basic_functions",
+        "keyword.operator.expression.typeof",
+        "punctuation.section.embedded",
+        "keyword.operator.type.annotation",
+        "variable.object.property.ts",
+        "variable.object.property.js",
+        "variable.object.property.jsx",
+        "variable.object.property.tsx",
+        "assignment.coffee",
+        "entity.name.type.ts",
+        "support.constant.math",
+        "meta.object-literal.key",
+        "meta.var.expr storage.type",
+        "variable.scss",
+        "variable.sass",
+        "variable.other.less",
+        "variable.parameter.url.scss",
+        "variable.parameter.url.sass",
+        "parameter",
+        "string",
+        "italic",
+        "quote",
+        "keyword",
+        "storage",
+        "language",
+        "constant.language",
+        "variable.language",
+        "type .function",
+        "type.function",
+        "storage.type.class",
+        "type.var",
+        "meta.parameter",
+        "variable.parameter",
+        "meta.parameters",
+        "keyword.control",
+        "modifier",
+        "this",
+        "comment"
+      ],
+      "settings": {
+        "fontStyle": "italic"
+      }
+    }
+  ]
+}

assets/themes/src/vscode/palenight/palenight.json 🔗

@@ -1,1569 +1,1569 @@
-{

-  "name": "Palenight Theme",

-  "author": "Olaolu Olawuyi",

-  "maintainers": ["Olaolu Olawuyi <mrolaolu@gmail.com>"],

-  "type": "dark",

-  "semanticClass": "palenight",

-  "colors": {

-    "contrastActiveBorder": null,

-    "contrastBorder": "#282B3C",

-    "focusBorder": "#282B3C",

-    "foreground": "#ffffff",

-    "widget.shadow": "#232635",

-    "selection.background": "#7580B850",

-    "descriptionForeground": null,

-    "errorForeground": "#EF5350",

-    "button.background": "#7e57c2cc",

-    "button.foreground": "#ffffffcc",

-    "button.hoverBackground": "#7e57c2",

-    "dropdown.background": "#292D3E",

-    "dropdown.border": "#7e57c2",

-    "dropdown.foreground": "#ffffffcc",

-    "input.background": "#313850",

-    "input.border": "#7e57c2",

-    "input.foreground": "#ffffffcc",

-    "input.placeholderForeground": "#ffffffcc",

-    "inputOption.activeBorder": "#ffffffcc",

-    "inputValidation.errorBackground": "#ef5350f2",

-    "inputValidation.errorBorder": "#EF5350",

-    "inputValidation.infoBackground": "#64b5f6f2",

-    "inputValidation.infoBorder": "#64B5F6",

-    "inputValidation.warningBackground": "#ffca28f2",

-    "inputValidation.warningBorder": "#FFCA28",

-    "scrollbar.shadow": "#292D3E00",

-    "scrollbarSlider.activeBackground": "#694CA4cc",

-    "scrollbarSlider.background": "#694CA466",

-    "scrollbarSlider.hoverBackground": "#694CA4cc",

-    "badge.background": "#7e57c2",

-    "badge.foreground": "#ffffff",

-    "progress.background": "#7e57c2",

-    "list.activeSelectionBackground": "#7e57c2",

-    "list.activeSelectionForeground": "#ffffff",

-    "list.dropBackground": "#2E3245",

-    "list.focusBackground": "#0000002e",

-    "list.focusForeground": "#ffffff",

-    "list.highlightForeground": "#ffffff",

-    "list.hoverBackground": "#0000001a",

-    "list.hoverForeground": "#ffffff",

-    "list.inactiveSelectionBackground": "#929ac90d",

-    "list.inactiveSelectionForeground": "#929ac9",

-    "activityBar.background": "#282C3D",

-    "activityBar.dropBackground": "#7e57c2e3",

-    "activityBar.foreground": "#eeffff",

-    "activityBar.border": "#282C3D",

-    "activityBarBadge.background": "#7e57c2",

-    "activityBarBadge.foreground": "#ffffff",

-    "sideBar.background": "#292D3E",

-    "sideBar.foreground": "#6C739A",

-    "sideBar.border": "#282B3C",

-    "sideBarTitle.foreground": "#eeffff",

-    "sideBarSectionHeader.background": "#292D3E",

-    "sideBarSectionHeader.foreground": "#eeffff",

-    "editorGroup.background": "#32374C",

-    "editorGroup.border": "#2E3245",

-    "editorGroup.dropBackground": "#7e57c273",

-    "editorGroupHeader.noTabsBackground": "#32374C",

-    "editorGroupHeader.tabsBackground": "#31364a",

-    "editorGroupHeader.tabsBorder": "#262A39",

-    "tab.activeBackground": "#292D3E",

-    "tab.activeForeground": "#eeffff",

-    "tab.border": "#272B3B",

-    "tab.activeBorder": "#262A39",

-    "tab.unfocusedActiveBorder": "#262A39",

-    "tab.inactiveBackground": "#31364A",

-    "tab.inactiveForeground": "#929ac9",

-    "tab.unfocusedActiveForeground": null,

-    "tab.unfocusedInactiveForeground": null,

-    "editor.background": "#292D3E",

-    "editor.foreground": "#BFC7D5",

-    "editorLineNumber.foreground": "#4c5374",

-    "editorLineNumber.activeForeground": "#eeffff",

-    "editorCursor.foreground": "#7e57c2",

-    "editorCursor.background": null,

-    "editor.selectionBackground": "#7580B850",

-    "editor.selectionHighlightBackground": "#383D51",

-    "editor.inactiveSelectionBackground": "#7e57c25a",

-    "editor.wordHighlightBackground": "#32374D",

-    "editor.wordHighlightStrongBackground": "#2E3250",

-    "editor.findMatchBackground": "#2e3248fc",

-    "editor.findMatchHighlightBackground": "#7e57c233",

-    "editor.findRangeHighlightBackground": null,

-    "editor.hoverHighlightBackground": "#7e57c25a",

-    "editor.lineHighlightBackground": "#0003",

-    "editor.lineHighlightBorder": null,

-    "editorLink.activeForeground": null,

-    "editor.rangeHighlightBackground": "#7e57c25a",

-    "editorWhitespace.foreground": null,

-    "editorIndentGuide.background": "#4E557980",

-    "editorRuler.foreground": "#4E557980",

-    "editorCodeLens.foreground": "#FFCA28",

-    "editorBracketMatch.background": null,

-    "editorBracketMatch.border": null,

-    "editorOverviewRuler.currentContentForeground": "#7e57c2",

-    "editorOverviewRuler.incomingContentForeground": "#7e57c2",

-    "editorOverviewRuler.commonContentForeground": "#7e57c2",

-    "editorError.foreground": "#EF5350",

-    "editorError.border": null,

-    "editorWarning.foreground": "#FFCA28",

-    "editorWarning.border": null,

-    "editorGutter.background": null,

-    "editorGutter.modifiedBackground": "#e2b93d",

-    "editorGutter.addedBackground": "#9CCC65",

-    "editorGutter.deletedBackground": "#EF5350",

-    "diffEditor.insertedTextBackground": "#99b76d23",

-    "diffEditor.removedTextBackground": "#ef535033",

-    "editorWidget.background": "#31364a",

-    "editorWidget.border": null,

-    "editorSuggestWidget.background": "#2C3043",

-    "editorSuggestWidget.border": "#2B2F40",

-    "editorSuggestWidget.foreground": "#bfc7d5",

-    "editorSuggestWidget.highlightForeground": "#ffffff",

-    "editorSuggestWidget.selectedBackground": "#7e57c2",

-    "editorHoverWidget.background": "#292D3E",

-    "editorHoverWidget.border": "#7e57c2",

-    "debugExceptionWidget.background": "#292D3E",

-    "debugExceptionWidget.border": "#7e57c2",

-    "editorMarkerNavigation.background": "#31364a",

-    "editorMarkerNavigationError.background": "#EF5350",

-    "editorMarkerNavigationWarning.background": "#FFCA28",

-    "peekView.border": "#7e57c2",

-    "peekViewEditor.background": "#232635",

-    "peekViewEditor.matchHighlightBackground": "#7e57c25a",

-    "peekViewResult.background": "#2E3245",

-    "peekViewResult.fileForeground": "#eeffff",

-    "peekViewResult.lineForeground": "#eeffff",

-    "peekViewResult.matchHighlightBackground": "#7e57c25a",

-    "peekViewResult.selectionBackground": "#2E3250",

-    "peekViewResult.selectionForeground": "#eeffff",

-    "peekViewTitle.background": "#292D3E",

-    "peekViewTitleDescription.foreground": "#697098",

-    "peekViewTitleLabel.foreground": "#eeffff",

-    "merge.currentHeaderBackground": "#7e57c25a",

-    "merge.currentContentBackground": null,

-    "merge.incomingHeaderBackground": "#7e57c25a",

-    "merge.incomingContentBackground": null,

-    "merge.border": null,

-    "panel.background": "#292D3E",

-    "panel.border": "#282B3C",

-    "panelTitle.activeBorder": "#7e57c2",

-    "panelTitle.activeForeground": "#eeffff",

-    "panelTitle.inactiveForeground": "#bfc7d580",

-    "statusBar.background": "#282C3D",

-    "statusBar.foreground": "#676E95",

-    "statusBar.border": "#262A39",

-    "statusBar.debuggingBackground": "#202431",

-    "statusBar.debuggingForeground": null,

-    "statusBar.debuggingBorder": "#1F2330",

-    "statusBar.noFolderForeground": null,

-    "statusBar.noFolderBackground": "#292D3E",

-    "statusBar.noFolderBorder": "#25293A",

-    "statusBarItem.activeBackground": "#202431",

-    "statusBarItem.hoverBackground": "#202431",

-    "statusBarItem.prominentBackground": "#202431",

-    "statusBarItem.prominentHoverBackground": "#202431",

-    "titleBar.activeBackground": "#292d3e",

-    "titleBar.activeForeground": "#eeefff",

-    "titleBar.border": "#30364c",

-    "titleBar.inactiveBackground": "#30364c",

-    "titleBar.inactiveForeground": null,

-    "notifications.background": "#292D3E",

-    "notifications.foreground": "#ffffffcc",

-    "notificationLink.foreground": "#80CBC4",

-    "extensionButton.prominentForeground": "#ffffffcc",

-    "extensionButton.prominentBackground": "#7e57c2cc",

-    "extensionButton.prominentHoverBackground": "#7e57c2",

-    "pickerGroup.foreground": "#d1aaff",

-    "pickerGroup.border": "#2E3245",

-    "terminal.ansiWhite": "#ffffff",

-    "terminal.ansiBlack": "#676E95",

-    "terminal.ansiBlue": "#82AAFF",

-    "terminal.ansiCyan": "#89DDFF",

-    "terminal.ansiGreen": "#a9c77d",

-    "terminal.ansiMagenta": "#C792EA",

-    "terminal.ansiRed": "#ff5572",

-    "terminal.ansiYellow": "#FFCB6B",

-    "terminal.ansiBrightWhite": "#ffffff",

-    "terminal.ansiBrightBlack": "#676E95",

-    "terminal.ansiBrightBlue": "#82AAFF",

-    "terminal.ansiBrightCyan": "#89DDFF",

-    "terminal.ansiBrightGreen": "#C3E88D",

-    "terminal.ansiBrightMagenta": "#C792EA",

-    "terminal.ansiBrightRed": "#ff5572",

-    "terminal.ansiBrightYellow": "#FFCB6B",

-    "debugToolBar.background": "#292D3E",

-    "welcomePage.buttonBackground": null,

-    "welcomePage.buttonHoverBackground": null,

-    "walkThrough.embeddedEditorBackground": "#232635",

-    "gitDecoration.modifiedResourceForeground": "#e2c08de6",

-    "gitDecoration.deletedResourceForeground": "#EF535090",

-    "gitDecoration.untrackedResourceForeground": "#a9c77dff",

-    "gitDecoration.ignoredResourceForeground": "#69709890",

-    "gitDecoration.conflictingResourceForeground": "#FFEB95CC",

-    "editorActiveLineNumber.foreground": "#eeffff",

-    "breadcrumb.foreground": "#6c739a",

-    "breadcrumb.focusForeground": "#bfc7d5",

-    "breadcrumb.activeSelectionForeground": "#eeffff",

-    "breadcrumbPicker.background": "#292D3E"

-  },

-  "tokenColors": [

-    {

-      "name": "Global settings",

-      "settings": {

-        "background": "#292D3E",

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Comment",

-      "scope": "comment",

-      "settings": {

-        "foreground": "#697098",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "String",

-      "scope": "string",

-      "settings": {

-        "foreground": "#C3E88D"

-      }

-    },

-    {

-      "name": "String Quoted",

-      "scope": "string.quoted",

-      "settings": {

-        "foreground": "#C3E88D"

-      }

-    },

-    {

-      "name": "String Unquoted",

-      "scope": "string.unquoted",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Support Constant Math",

-      "scope": "support.constant.math",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Number",

-      "scope": ["constant.numeric", "constant.character.numeric"],

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Built-in constant",

-      "scope": [

-        "constant.language",

-        "punctuation.definition.constant",

-        "variable.other.constant"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "User-defined constant",

-      "scope": ["constant.character", "constant.other"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Constant Character Escape",

-      "scope": "constant.character.escape",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "RegExp String",

-      "scope": ["string.regexp", "string.regexp keyword.other"],

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Comma in functions",

-      "scope": "meta.function punctuation.separator.comma",

-      "settings": {

-        "foreground": "#eeffff"

-      }

-    },

-    {

-      "name": "Variable",

-      "scope": "variable",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Keyword",

-      "scope": ["punctuation.accessor", "keyword"],

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Storage",

-      "scope": [

-        "storage",

-        "storage.type",

-        "meta.var.expr storage.type",

-        "storage.type.property.js",

-        "storage.type.property.ts",

-        "storage.type.property.tsx",

-        "meta.class meta.method.declaration meta.var.expr storage.type.js"

-      ],

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Class name",

-      "scope": ["entity.name.class", "meta.class entity.name.type.class"],

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Inherited class",

-      "scope": "entity.other.inherited-class",

-      "settings": {

-        "foreground": "#a9c77d"

-      }

-    },

-    {

-      "name": "Function name",

-      "scope": "entity.name.function",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Function Parameters",

-      "scope": "variable.parameter",

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "Meta Tag",

-      "scope": ["punctuation.definition.tag", "meta.tag"],

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "HTML Tag names",

-      "scope": [

-        "entity.name.tag support.class.component",

-        "meta.tag.other.html",

-        "meta.tag.other.js",

-        "meta.tag.other.tsx",

-        "entity.name.tag.tsx",

-        "entity.name.tag.js",

-        "entity.name.tag",

-        "meta.tag.js",

-        "meta.tag.tsx",

-        "meta.tag.html"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Tag attribute",

-      "scope": "entity.other.attribute-name",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Entity Name Tag Custom",

-      "scope": "entity.name.tag.custom",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Library (function & constant)",

-      "scope": ["support.function", "support.constant"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Support Constant Property Value meta",

-      "scope": "support.constant.meta.property-value",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Library class/type",

-      "scope": ["support.type", "support.class"],

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Support Variable DOM",

-      "scope": "support.variable.dom",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Invalid",

-      "scope": "invalid",

-      "settings": {

-        "background": "#ff2c83",

-        "foreground": "#ffffff"

-      }

-    },

-    {

-      "name": "Invalid deprecated",

-      "scope": "invalid.deprecated",

-      "settings": {

-        "foreground": "#ffffff",

-        "background": "#d3423e"

-      }

-    },

-    {

-      "name": "Keyword Operator",

-      "scope": "keyword.operator",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Keyword Operator Relational",

-      "scope": "keyword.operator.relational",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Keyword Operator Assignment",

-      "scope": "keyword.operator.assignment",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Double-Slashed Comment",

-      "scope": "comment.line.double-slash",

-      "settings": {

-        "foreground": "#697098"

-      }

-    },

-    {

-      "name": "Object",

-      "scope": "object",

-      "settings": {

-        "foreground": "#cdebf7"

-      }

-    },

-    {

-      "name": "Null",

-      "scope": "constant.language.null",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Meta Brace",

-      "scope": "meta.brace",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Meta Delimiter Period",

-      "scope": "meta.delimiter.period",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Punctuation Definition String",

-      "scope": "punctuation.definition.string",

-      "settings": {

-        "foreground": "#d9f5dd"

-      }

-    },

-    {

-      "name": "Boolean",

-      "scope": "constant.language.boolean",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Object Comma",

-      "scope": "object.comma",

-      "settings": {

-        "foreground": "#ffffff"

-      }

-    },

-    {

-      "name": "Variable Parameter Function",

-      "scope": "variable.parameter.function",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Support Type Property Name & entity name tags",

-      "scope": [

-        "support.type.vendored.property-name",

-        "support.constant.vendored.property-value",

-        "support.type.property-name",

-        "meta.property-list entity.name.tag"

-      ],

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Entity Name tag reference in stylesheets",

-      "scope": "meta.property-list entity.name.tag.reference",

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Constant Other Color RGB Value Punctuation Definition Constant",

-      "scope": "constant.other.color.rgb-value punctuation.definition.constant",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Constant Other Color",

-      "scope": "constant.other.color",

-      "settings": {

-        "foreground": "#FFEB95"

-      }

-    },

-    {

-      "name": "Keyword Other Unit",

-      "scope": "keyword.other.unit",

-      "settings": {

-        "foreground": "#FFEB95"

-      }

-    },

-    {

-      "name": "Meta Selector",

-      "scope": "meta.selector",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Entity Other Attribute Name Id",

-      "scope": "entity.other.attribute-name.id",

-      "settings": {

-        "foreground": "#FAD430"

-      }

-    },

-    {

-      "name": "Meta Property Name",

-      "scope": "meta.property-name",

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Doctypes",

-      "scope": ["entity.name.tag.doctype", "meta.tag.sgml.doctype"],

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Punctuation Definition Parameters",

-      "scope": "punctuation.definition.parameters",

-      "settings": {

-        "foreground": "#d9f5dd"

-      }

-    },

-    {

-      "name": "Keyword Control Operator",

-      "scope": "keyword.control.operator",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Keyword Operator Logical",

-      "scope": "keyword.operator.logical",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Variable Instances",

-      "scope": [

-        "variable.instance",

-        "variable.other.instance",

-        "variable.reaedwrite.instance",

-        "variable.other.readwrite.instance"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Variable Property Other",

-      "scope": ["variable.other.property", "variable.other.object.property"],

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Entity Name Function",

-      "scope": "entity.name.function",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Keyword Operator Comparison",

-      "scope": "keyword.operator.comparison",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Support Constant, `new` keyword, Special Method Keyword",

-      "scope": [

-        "support.constant",

-        "keyword.other.special-method",

-        "keyword.other.new"

-      ],

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Support Function",

-      "scope": "support.function",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Invalid Broken",

-      "scope": "invalid.broken",

-      "settings": {

-        "foreground": "#020e14",

-        "background": "#F78C6C"

-      }

-    },

-    {

-      "name": "Invalid Unimplemented",

-      "scope": "invalid.unimplemented",

-      "settings": {

-        "background": "#8BD649",

-        "foreground": "#ffffff"

-      }

-    },

-    {

-      "name": "Invalid Illegal",

-      "scope": "invalid.illegal",

-      "settings": {

-        "foreground": "#ffffff",

-        "background": "#ec5f67"

-      }

-    },

-    {

-      "name": "Language Variable",

-      "scope": "variable.language",

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Support Variable Property",

-      "scope": "support.variable.property",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "Variable Function",

-      "scope": "variable.function",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Variable Interpolation",

-      "scope": "variable.interpolation",

-      "settings": {

-        "foreground": "#ec5f67"

-      }

-    },

-    {

-      "name": "Meta Function Call",

-      "scope": "meta.function-call",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Punctuation Section Embedded",

-      "scope": "punctuation.section.embedded",

-      "settings": {

-        "foreground": "#d3423e"

-      }

-    },

-    {

-      "name": "Punctuation Tweaks",

-      "scope": [

-        "punctuation.terminator.expression",

-        "punctuation.definition.arguments",

-        "punctuation.definition.array",

-        "punctuation.section.array",

-        "meta.array"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "More Punctuation Tweaks",

-      "scope": [

-        "punctuation.definition.list.begin",

-        "punctuation.definition.list.end",

-        "punctuation.separator.arguments",

-        "punctuation.definition.list"

-      ],

-      "settings": {

-        "foreground": "#d9f5dd"

-      }

-    },

-    {

-      "name": "Template Strings",

-      "scope": "string.template meta.template.expression",

-      "settings": {

-        "foreground": "#d3423e"

-      }

-    },

-    {

-      "name": "Backtics(``) in Template Strings",

-      "scope": "string.template punctuation.definition.string",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Italics",

-      "scope": "italic",

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Bold",

-      "scope": "bold",

-      "settings": {

-        "foreground": "#ffcb6b",

-        "fontStyle": "bold"

-      }

-    },

-    {

-      "name": "Quote",

-      "scope": "quote",

-      "settings": {

-        "foreground": "#697098",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Raw Code",

-      "scope": "raw",

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "CoffeScript Variable Assignment",

-      "scope": "variable.assignment.coffee",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "CoffeScript Parameter Function",

-      "scope": "variable.parameter.function.coffee",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "CoffeeScript Assignments",

-      "scope": "variable.assignment.coffee",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "C# Readwrite Variables",

-      "scope": "variable.other.readwrite.cs",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "C# Classes & Storage types",

-      "scope": ["entity.name.type.class.cs", "storage.type.cs"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "C# Namespaces",

-      "scope": "entity.name.type.namespace.cs",

-      "settings": {

-        "foreground": "#B2CCD6"

-      }

-    },

-    {

-      "name": "Tag names in Stylesheets",

-      "scope": [

-        "entity.name.tag.css",

-        "entity.name.tag.less",

-        "entity.name.tag.custom.css"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Wildcard(*) selector in Stylesheets",

-      "scope": [

-        "entity.name.tag.wildcard.css",

-        "entity.name.tag.wildcard.less",

-        "entity.name.tag.wildcard.scss",

-        "entity.name.tag.wildcard.sass"

-      ],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "(C|SC|SA|LE)SS property value unit",

-      "scope": [

-        "keyword.other.unit.css",

-        "constant.length.units.css",

-        "keyword.other.unit.less",

-        "constant.length.units.less",

-        "keyword.other.unit.scss",

-        "constant.length.units.scss",

-        "keyword.other.unit.sass",

-        "constant.length.units.sass"

-      ],

-      "settings": {

-        "foreground": "#FFEB95"

-      }

-    },

-    {

-      "name": "Attribute Name for CSS",

-      "scope": "meta.attribute-selector.css entity.other.attribute-name.attribute",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "punctuations in styled components",

-      "scope": [

-        "source.js source.css meta.property-list",

-        "source.js source.css punctuation.section",

-        "source.js source.css punctuation.terminator.rule",

-        "source.js source.css punctuation.definition.entity.end.bracket",

-        "source.js source.css punctuation.definition.entity.begin.bracket",

-        "source.js source.css punctuation.separator.key-value",

-        "source.js source.css punctuation.definition.attribute-selector",

-        "source.js source.css meta.property-list",

-        "source.js source.css meta.property-list punctuation.separator.comma",

-        "source.ts source.css punctuation.section",

-        "source.ts source.css punctuation.terminator.rule",

-        "source.ts source.css punctuation.definition.entity.end.bracket",

-        "source.ts source.css punctuation.definition.entity.begin.bracket",

-        "source.ts source.css punctuation.separator.key-value",

-        "source.ts source.css punctuation.definition.attribute-selector",

-        "source.ts source.css meta.property-list",

-        "source.ts source.css meta.property-list punctuation.separator.comma"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Elixir Classes",

-      "scope": [

-        "source.elixir support.type.elixir",

-        "source.elixir meta.module.elixir entity.name.class.elixir"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Elixir Functions",

-      "scope": "source.elixir entity.name.function",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Elixir Constants",

-      "scope": [

-        "source.elixir constant.other.symbol.elixir",

-        "source.elixir constant.other.keywords.elixir"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Elixir String Punctuations",

-      "scope": "source.elixir punctuation.definition.string",

-      "settings": {

-        "foreground": "#a9c77d"

-      }

-    },

-    {

-      "name": "Elixir",

-      "scope": [

-        "source.elixir variable.other.readwrite.module.elixir",

-        "source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir"

-      ],

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Elixir Binary Punctuations",

-      "scope": "source.elixir .punctuation.binary.elixir",

-      "settings": {

-        "foreground": "#c792ea"

-      }

-    },

-    {

-      "name": "Go Function Calls",

-      "scope": "source.go meta.function-call.go",

-      "settings": {

-        "foreground": "#DDDDDD"

-      }

-    },

-    {

-      "name": "GraphQL Variables",

-      "scope": "variable.qraphql",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "ID Attribute Name in HTML",

-      "scope": "entity.other.attribute-name.id.html",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "HTML Punctuation Definition Tag",

-      "scope": "punctuation.definition.tag.html",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "HTML Doctype",

-      "scope": "meta.tag.sgml.doctype.html",

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "JavaScript Classes",

-      "scope": "meta.class entity.name.type.class.js",

-      "settings": {

-        "foreground": "#ffcb8b"

-      }

-    },

-    {

-      "name": "JavaScript Method Declaration e.g. `constructor`",

-      "scope": "meta.method.declaration storage.type.js",

-      "settings": {

-        "foreground": "#82AAFF",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "JavaScript Terminator",

-      "scope": "terminator.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Meta Punctuation Definition",

-      "scope": "meta.js punctuation.definition.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Entity Names in Code Documentations",

-      "scope": [

-        "entity.name.type.instance.jsdoc",

-        "entity.name.type.instance.phpdoc"

-      ],

-      "settings": {

-        "foreground": "#eeffff"

-      }

-    },

-    {

-      "name": "Other Variables in Code Documentations",

-      "scope": ["variable.other.jsdoc", "variable.other.phpdoc"],

-      "settings": {

-        "foreground": "#78ccf0"

-      }

-    },

-    {

-      "name": "JavaScript module imports and exports",

-      "scope": [

-        "variable.other.meta.import.js",

-        "meta.import.js variable.other",

-        "variable.other.meta.export.js",

-        "meta.export.js variable.other"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Variable Parameter Function",

-      "scope": "variable.parameter.function.js",

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "JavaScript Variable Other ReadWrite",

-      "scope": "variable.other.readwrite.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Text nested in React tags",

-      "scope": [

-        "meta.jsx.children",

-        "meta.jsx.children.js",

-        "meta.jsx.children.tsx"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript[React] Variable Other Object",

-      "scope": [

-        "variable.other.object.js",

-        "variable.other.object.jsx",

-        "meta.object-literal.key.js",

-        "meta.object-literal.key.jsx",

-        "variable.object.property.js",

-        "variable.object.property.jsx"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Variables",

-      "scope": ["variable.js", "variable.other.js"],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JavaScript Entity Name Type",

-      "scope": ["entity.name.type.js", "entity.name.type.module.js"],

-      "settings": {

-        "foreground": "#ffcb8b"

-      }

-    },

-    {

-      "name": "JavaScript Support Classes",

-      "scope": "support.class.js",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "JSON Property Names",

-      "scope": "support.type.property-name.json",

-      "settings": {

-        "foreground": "#C3E88D",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "JSON Support Constants",

-      "scope": "support.constant.json",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "JSON Property values (string)",

-      "scope": "meta.structure.dictionary.value.json string.quoted.double",

-      "settings": {

-        "foreground": "#80CBC4",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "Strings in JSON values",

-      "scope": "string.quoted.double.json punctuation.definition.string.json",

-      "settings": {

-        "foreground": "#80CBC4",

-        "fontStyle": "normal"

-      }

-    },

-    {

-      "name": "Specific JSON Property values like null",

-      "scope": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Ruby Variables",

-      "scope": "variable.other.ruby",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Ruby Hashkeys",

-      "scope": "constant.language.symbol.hashkey.ruby",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "LESS Tag names",

-      "scope": "entity.name.tag.less",

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Attribute Name for LESS",

-      "scope": "meta.attribute-selector.less entity.other.attribute-name.attribute",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Markup Headings",

-      "scope": "markup.heading",

-      "settings": {

-        "foreground": "#82b1ff"

-      }

-    },

-    {

-      "name": "Markup Italics",

-      "scope": "markup.italic",

-      "settings": {

-        "foreground": "#c792ea",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Markup Bold",

-      "scope": "markup.bold",

-      "settings": {

-        "foreground": "#ffcb6b",

-        "fontStyle": "bold"

-      }

-    },

-    {

-      "name": "Markup Quote + others",

-      "scope": "markup.quote",

-      "settings": {

-        "foreground": "#697098",

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Markup Raw Code + others",

-      "scope": "markup.inline.raw",

-      "settings": {

-        "foreground": "#80CBC4"

-      }

-    },

-    {

-      "name": "Markup Links",

-      "scope": ["markup.underline.link", "markup.underline.link.image"],

-      "settings": {

-        "foreground": "#ff869a"

-      }

-    },

-    {

-      "name": "Markup Attributes",

-      "scope": ["markup.meta.attribute-list"],

-      "settings": {

-        "foreground": "#a9c77d"

-      }

-    },

-    {

-      "name": "Markup Admonitions",

-      "scope": "markup.admonition",

-      "settings": {

-        "fontStyle": "bold"

-      }

-    },

-    {

-      "name": "Markup Lists",

-      "scope": "markup.list.bullet",

-      "settings": {

-        "foreground": "#D9F5DD"

-      }

-    },

-    {

-      "name": "Markup Superscript and Subscript",

-      "scope": ["markup.superscript", "markup.subscript"],

-      "settings": {

-        "fontStyle": "italic"

-      }

-    },

-    {

-      "name": "Markdown Link Title and Description",

-      "scope": [

-        "string.other.link.title.markdown",

-        "string.other.link.description.markdown"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Markdown Punctuation",

-      "scope": [

-        "punctuation.definition.string.markdown",

-        "punctuation.definition.string.begin.markdown",

-        "punctuation.definition.string.end.markdown",

-        "meta.link.inline.markdown punctuation.definition.string"

-      ],

-      "settings": {

-        "foreground": "#82b1ff"

-      }

-    },

-    {

-      "name": "Markdown MetaData Punctuation",

-      "scope": ["punctuation.definition.metadata.markdown"],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "Markdown List Punctuation",

-      "scope": ["beginning.punctuation.definition.list.markdown"],

-      "settings": {

-        "foreground": "#82b1ff"

-      }

-    },

-    {

-      "name": "Asciidoc Function",

-      "scope": "entity.name.function.asciidoc",

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "PHP Variables",

-      "scope": "variable.other.php",

-      "settings": {

-        "foreground": "#bec5d4"

-      }

-    },

-    {

-      "name": "Support Classes in PHP",

-      "scope": "support.class.php",

-      "settings": {

-        "foreground": "#ffcb8b"

-      }

-    },

-    {

-      "name": "Punctuations in PHP function calls",

-      "scope": "meta.function-call.php punctuation",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "PHP Global Variables",

-      "scope": "variable.other.global.php",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Declaration Punctuation in PHP Global Variables",

-      "scope": "variable.other.global.php punctuation.definition.variable",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Language Constants in Python",

-      "scope": "constant.language.python",

-      "settings": {

-        "foreground": "#ff5874"

-      }

-    },

-    {

-      "name": "Python Function Parameter and Arguments",

-      "scope": [

-        "variable.parameter.function.python",

-        "meta.function-call.arguments.python"

-      ],

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "Python Function Call",

-      "scope": [

-        "meta.function-call.python",

-        "meta.function-call.generic.python"

-      ],

-      "settings": {

-        "foreground": "#B2CCD6"

-      }

-    },

-    {

-      "name": "Punctuations in Python",

-      "scope": "punctuation.python",

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "Decorator Functions in Python",

-      "scope": "entity.name.function.decorator.python",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "Python Language Variable",

-      "scope": "source.python variable.language.special",

-      "settings": {

-        "foreground": "#8EACE3"

-      }

-    },

-    {

-      "name": "SCSS Variable",

-      "scope": [

-        "variable.scss",

-        "variable.sass",

-        "variable.parameter.url.scss",

-        "variable.parameter.url.sass"

-      ],

-      "settings": {

-        "foreground": "#DDDDDD"

-      }

-    },

-    {

-      "name": "Variables in SASS At-Rules",

-      "scope": [

-        "source.css.scss meta.at-rule variable",

-        "source.css.sass meta.at-rule variable"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "Variables in SASS At-Rules",

-      "scope": [

-        "source.css.scss meta.at-rule variable",

-        "source.css.sass meta.at-rule variable"

-      ],

-      "settings": {

-        "foreground": "#bec5d4"

-      }

-    },

-    {

-      "name": "Attribute Name for SASS",

-      "scope": [

-        "meta.attribute-selector.scss entity.other.attribute-name.attribute",

-        "meta.attribute-selector.sass entity.other.attribute-name.attribute"

-      ],

-      "settings": {

-        "foreground": "#F78C6C"

-      }

-    },

-    {

-      "name": "Tag names in SASS",

-      "scope": ["entity.name.tag.scss", "entity.name.tag.sass"],

-      "settings": {

-        "foreground": "#ff5572"

-      }

-    },

-    {

-      "name": "TypeScript[React] Variables and Object Properties",

-      "scope": [

-        "variable.other.readwrite.alias.ts",

-        "variable.other.readwrite.alias.tsx",

-        "variable.other.readwrite.ts",

-        "variable.other.readwrite.tsx",

-        "variable.other.object.ts",

-        "variable.other.object.tsx",

-        "variable.object.property.ts",

-        "variable.object.property.tsx",

-        "variable.other.ts",

-        "variable.other.tsx",

-        "variable.tsx",

-        "variable.ts"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "TypeScript[React] Entity Name Types",

-      "scope": ["entity.name.type.ts", "entity.name.type.tsx"],

-      "settings": {

-        "foreground": "#78ccf0"

-      }

-    },

-    {

-      "name": "TypeScript[React] Node Classes",

-      "scope": ["support.class.node.ts", "support.class.node.tsx"],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "TypeScript[React] Entity Name Types as Parameters",

-      "scope": [

-        "meta.type.parameters.ts entity.name.type",

-        "meta.type.parameters.tsx entity.name.type"

-      ],

-      "settings": {

-        "foreground": "#eeffff"

-      }

-    },

-    {

-      "name": "TypeScript[React] Import/Export Punctuations",

-      "scope": [

-        "meta.import.ts punctuation.definition.block",

-        "meta.import.tsx punctuation.definition.block",

-        "meta.export.ts punctuation.definition.block",

-        "meta.export.tsx punctuation.definition.block"

-      ],

-      "settings": {

-        "foreground": "#bfc7d5"

-      }

-    },

-    {

-      "name": "TypeScript[React] Punctuation Decorators",

-      "scope": [

-        "meta.decorator punctuation.decorator.ts",

-        "meta.decorator punctuation.decorator.tsx"

-      ],

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "TypeScript[React] Punctuation Decorators",

-      "scope": "meta.tag.js meta.jsx.children.tsx",

-      "settings": {

-        "foreground": "#82AAFF"

-      }

-    },

-    {

-      "name": "YAML Entity Name Tags",

-      "scope": "entity.name.tag.yaml",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "handlebars variables",

-      "scope": "variable.parameter.handlebars",

-      "settings": {

-        "foreground": "#bec5d4"

-      }

-    },

-    {

-      "name": "handlebars parameters",

-      "scope": "entity.other.attribute-name.handlebars variable.parameter.handlebars",

-      "settings": {

-        "foreground": "#ffcb6b"

-      }

-    },

-    {

-      "name": "handlebars enitity attribute names",

-      "scope": "entity.other.attribute-name.handlebars",

-      "settings": {

-        "foreground": "#89DDFF"

-      }

-    },

-    {

-      "name": "handlebars enitity attribute values",

-      "scope": "entity.other.attribute-value.handlebars variable.parameter.handlebars",

-      "settings": {

-        "foreground": "#7986E7"

-      }

-    },

-    {

-      "name": "normalize font style of certain components",

-      "scope": [

-        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.begin.js",

-        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.end.js",

-        "meta.property-list.css meta.property-value.css variable.other.less",

-        "punctuation.section.embedded.begin.js.jsx",

-        "punctuation.section.embedded.end.js.jsx",

-        "meta.property-list.scss variable.scss",

-        "meta.property-list.sass variable.sass",

-        "keyword.operator.logical",

-        "keyword.operator.arithmetic",

-        "keyword.operator.bitwise",

-        "keyword.operator.increment",

-        "keyword.operator.ternary",

-        "keyword.operator.comparison",

-        "keyword.operator.assignment",

-        "keyword.operator.operator",

-        "keyword.operator.or.regexp",

-        "keyword.operator.expression.in",

-        "keyword.operator.type",

-        "punctuation.section.embedded.js",

-        "punctuation.definintion.string",

-        "punctuation"

-      ],

-      "settings": {

-        "fontStyle": "normal"

-      }

-    }

-  ]

-}

+{
+  "name": "Palenight Theme",
+  "author": "Olaolu Olawuyi",
+  "maintainers": ["Olaolu Olawuyi <mrolaolu@gmail.com>"],
+  "type": "dark",
+  "semanticClass": "palenight",
+  "colors": {
+    "contrastActiveBorder": null,
+    "contrastBorder": "#282B3C",
+    "focusBorder": "#282B3C",
+    "foreground": "#ffffff",
+    "widget.shadow": "#232635",
+    "selection.background": "#7580B850",
+    "descriptionForeground": null,
+    "errorForeground": "#EF5350",
+    "button.background": "#7e57c2cc",
+    "button.foreground": "#ffffffcc",
+    "button.hoverBackground": "#7e57c2",
+    "dropdown.background": "#292D3E",
+    "dropdown.border": "#7e57c2",
+    "dropdown.foreground": "#ffffffcc",
+    "input.background": "#313850",
+    "input.border": "#7e57c2",
+    "input.foreground": "#ffffffcc",
+    "input.placeholderForeground": "#ffffffcc",
+    "inputOption.activeBorder": "#ffffffcc",
+    "inputValidation.errorBackground": "#ef5350f2",
+    "inputValidation.errorBorder": "#EF5350",
+    "inputValidation.infoBackground": "#64b5f6f2",
+    "inputValidation.infoBorder": "#64B5F6",
+    "inputValidation.warningBackground": "#ffca28f2",
+    "inputValidation.warningBorder": "#FFCA28",
+    "scrollbar.shadow": "#292D3E00",
+    "scrollbarSlider.activeBackground": "#694CA4cc",
+    "scrollbarSlider.background": "#694CA466",
+    "scrollbarSlider.hoverBackground": "#694CA4cc",
+    "badge.background": "#7e57c2",
+    "badge.foreground": "#ffffff",
+    "progress.background": "#7e57c2",
+    "list.activeSelectionBackground": "#7e57c2",
+    "list.activeSelectionForeground": "#ffffff",
+    "list.dropBackground": "#2E3245",
+    "list.focusBackground": "#0000002e",
+    "list.focusForeground": "#ffffff",
+    "list.highlightForeground": "#ffffff",
+    "list.hoverBackground": "#0000001a",
+    "list.hoverForeground": "#ffffff",
+    "list.inactiveSelectionBackground": "#929ac90d",
+    "list.inactiveSelectionForeground": "#929ac9",
+    "activityBar.background": "#282C3D",
+    "activityBar.dropBackground": "#7e57c2e3",
+    "activityBar.foreground": "#eeffff",
+    "activityBar.border": "#282C3D",
+    "activityBarBadge.background": "#7e57c2",
+    "activityBarBadge.foreground": "#ffffff",
+    "sideBar.background": "#292D3E",
+    "sideBar.foreground": "#6C739A",
+    "sideBar.border": "#282B3C",
+    "sideBarTitle.foreground": "#eeffff",
+    "sideBarSectionHeader.background": "#292D3E",
+    "sideBarSectionHeader.foreground": "#eeffff",
+    "editorGroup.background": "#32374C",
+    "editorGroup.border": "#2E3245",
+    "editorGroup.dropBackground": "#7e57c273",
+    "editorGroupHeader.noTabsBackground": "#32374C",
+    "editorGroupHeader.tabsBackground": "#31364a",
+    "editorGroupHeader.tabsBorder": "#262A39",
+    "tab.activeBackground": "#292D3E",
+    "tab.activeForeground": "#eeffff",
+    "tab.border": "#272B3B",
+    "tab.activeBorder": "#262A39",
+    "tab.unfocusedActiveBorder": "#262A39",
+    "tab.inactiveBackground": "#31364A",
+    "tab.inactiveForeground": "#929ac9",
+    "tab.unfocusedActiveForeground": null,
+    "tab.unfocusedInactiveForeground": null,
+    "editor.background": "#292D3E",
+    "editor.foreground": "#BFC7D5",
+    "editorLineNumber.foreground": "#4c5374",
+    "editorLineNumber.activeForeground": "#eeffff",
+    "editorCursor.foreground": "#7e57c2",
+    "editorCursor.background": null,
+    "editor.selectionBackground": "#7580B850",
+    "editor.selectionHighlightBackground": "#383D51",
+    "editor.inactiveSelectionBackground": "#7e57c25a",
+    "editor.wordHighlightBackground": "#32374D",
+    "editor.wordHighlightStrongBackground": "#2E3250",
+    "editor.findMatchBackground": "#2e3248fc",
+    "editor.findMatchHighlightBackground": "#7e57c233",
+    "editor.findRangeHighlightBackground": null,
+    "editor.hoverHighlightBackground": "#7e57c25a",
+    "editor.lineHighlightBackground": "#0003",
+    "editor.lineHighlightBorder": null,
+    "editorLink.activeForeground": null,
+    "editor.rangeHighlightBackground": "#7e57c25a",
+    "editorWhitespace.foreground": null,
+    "editorIndentGuide.background": "#4E557980",
+    "editorRuler.foreground": "#4E557980",
+    "editorCodeLens.foreground": "#FFCA28",
+    "editorBracketMatch.background": null,
+    "editorBracketMatch.border": null,
+    "editorOverviewRuler.currentContentForeground": "#7e57c2",
+    "editorOverviewRuler.incomingContentForeground": "#7e57c2",
+    "editorOverviewRuler.commonContentForeground": "#7e57c2",
+    "editorError.foreground": "#EF5350",
+    "editorError.border": null,
+    "editorWarning.foreground": "#FFCA28",
+    "editorWarning.border": null,
+    "editorGutter.background": null,
+    "editorGutter.modifiedBackground": "#e2b93d",
+    "editorGutter.addedBackground": "#9CCC65",
+    "editorGutter.deletedBackground": "#EF5350",
+    "diffEditor.insertedTextBackground": "#99b76d23",
+    "diffEditor.removedTextBackground": "#ef535033",
+    "editorWidget.background": "#31364a",
+    "editorWidget.border": null,
+    "editorSuggestWidget.background": "#2C3043",
+    "editorSuggestWidget.border": "#2B2F40",
+    "editorSuggestWidget.foreground": "#bfc7d5",
+    "editorSuggestWidget.highlightForeground": "#ffffff",
+    "editorSuggestWidget.selectedBackground": "#7e57c2",
+    "editorHoverWidget.background": "#292D3E",
+    "editorHoverWidget.border": "#7e57c2",
+    "debugExceptionWidget.background": "#292D3E",
+    "debugExceptionWidget.border": "#7e57c2",
+    "editorMarkerNavigation.background": "#31364a",
+    "editorMarkerNavigationError.background": "#EF5350",
+    "editorMarkerNavigationWarning.background": "#FFCA28",
+    "peekView.border": "#7e57c2",
+    "peekViewEditor.background": "#232635",
+    "peekViewEditor.matchHighlightBackground": "#7e57c25a",
+    "peekViewResult.background": "#2E3245",
+    "peekViewResult.fileForeground": "#eeffff",
+    "peekViewResult.lineForeground": "#eeffff",
+    "peekViewResult.matchHighlightBackground": "#7e57c25a",
+    "peekViewResult.selectionBackground": "#2E3250",
+    "peekViewResult.selectionForeground": "#eeffff",
+    "peekViewTitle.background": "#292D3E",
+    "peekViewTitleDescription.foreground": "#697098",
+    "peekViewTitleLabel.foreground": "#eeffff",
+    "merge.currentHeaderBackground": "#7e57c25a",
+    "merge.currentContentBackground": null,
+    "merge.incomingHeaderBackground": "#7e57c25a",
+    "merge.incomingContentBackground": null,
+    "merge.border": null,
+    "panel.background": "#292D3E",
+    "panel.border": "#282B3C",
+    "panelTitle.activeBorder": "#7e57c2",
+    "panelTitle.activeForeground": "#eeffff",
+    "panelTitle.inactiveForeground": "#bfc7d580",
+    "statusBar.background": "#282C3D",
+    "statusBar.foreground": "#676E95",
+    "statusBar.border": "#262A39",
+    "statusBar.debuggingBackground": "#202431",
+    "statusBar.debuggingForeground": null,
+    "statusBar.debuggingBorder": "#1F2330",
+    "statusBar.noFolderForeground": null,
+    "statusBar.noFolderBackground": "#292D3E",
+    "statusBar.noFolderBorder": "#25293A",
+    "statusBarItem.activeBackground": "#202431",
+    "statusBarItem.hoverBackground": "#202431",
+    "statusBarItem.prominentBackground": "#202431",
+    "statusBarItem.prominentHoverBackground": "#202431",
+    "titleBar.activeBackground": "#292d3e",
+    "titleBar.activeForeground": "#eeefff",
+    "titleBar.border": "#30364c",
+    "titleBar.inactiveBackground": "#30364c",
+    "titleBar.inactiveForeground": null,
+    "notifications.background": "#292D3E",
+    "notifications.foreground": "#ffffffcc",
+    "notificationLink.foreground": "#80CBC4",
+    "extensionButton.prominentForeground": "#ffffffcc",
+    "extensionButton.prominentBackground": "#7e57c2cc",
+    "extensionButton.prominentHoverBackground": "#7e57c2",
+    "pickerGroup.foreground": "#d1aaff",
+    "pickerGroup.border": "#2E3245",
+    "terminal.ansiWhite": "#ffffff",
+    "terminal.ansiBlack": "#676E95",
+    "terminal.ansiBlue": "#82AAFF",
+    "terminal.ansiCyan": "#89DDFF",
+    "terminal.ansiGreen": "#a9c77d",
+    "terminal.ansiMagenta": "#C792EA",
+    "terminal.ansiRed": "#ff5572",
+    "terminal.ansiYellow": "#FFCB6B",
+    "terminal.ansiBrightWhite": "#ffffff",
+    "terminal.ansiBrightBlack": "#676E95",
+    "terminal.ansiBrightBlue": "#82AAFF",
+    "terminal.ansiBrightCyan": "#89DDFF",
+    "terminal.ansiBrightGreen": "#C3E88D",
+    "terminal.ansiBrightMagenta": "#C792EA",
+    "terminal.ansiBrightRed": "#ff5572",
+    "terminal.ansiBrightYellow": "#FFCB6B",
+    "debugToolBar.background": "#292D3E",
+    "welcomePage.buttonBackground": null,
+    "welcomePage.buttonHoverBackground": null,
+    "walkThrough.embeddedEditorBackground": "#232635",
+    "gitDecoration.modifiedResourceForeground": "#e2c08de6",
+    "gitDecoration.deletedResourceForeground": "#EF535090",
+    "gitDecoration.untrackedResourceForeground": "#a9c77dff",
+    "gitDecoration.ignoredResourceForeground": "#69709890",
+    "gitDecoration.conflictingResourceForeground": "#FFEB95CC",
+    "editorActiveLineNumber.foreground": "#eeffff",
+    "breadcrumb.foreground": "#6c739a",
+    "breadcrumb.focusForeground": "#bfc7d5",
+    "breadcrumb.activeSelectionForeground": "#eeffff",
+    "breadcrumbPicker.background": "#292D3E"
+  },
+  "tokenColors": [
+    {
+      "name": "Global settings",
+      "settings": {
+        "background": "#292D3E",
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Comment",
+      "scope": "comment",
+      "settings": {
+        "foreground": "#697098",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "String",
+      "scope": "string",
+      "settings": {
+        "foreground": "#C3E88D"
+      }
+    },
+    {
+      "name": "String Quoted",
+      "scope": "string.quoted",
+      "settings": {
+        "foreground": "#C3E88D"
+      }
+    },
+    {
+      "name": "String Unquoted",
+      "scope": "string.unquoted",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Support Constant Math",
+      "scope": "support.constant.math",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Number",
+      "scope": ["constant.numeric", "constant.character.numeric"],
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Built-in constant",
+      "scope": [
+        "constant.language",
+        "punctuation.definition.constant",
+        "variable.other.constant"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "User-defined constant",
+      "scope": ["constant.character", "constant.other"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Constant Character Escape",
+      "scope": "constant.character.escape",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "RegExp String",
+      "scope": ["string.regexp", "string.regexp keyword.other"],
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Comma in functions",
+      "scope": "meta.function punctuation.separator.comma",
+      "settings": {
+        "foreground": "#eeffff"
+      }
+    },
+    {
+      "name": "Variable",
+      "scope": "variable",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Keyword",
+      "scope": ["punctuation.accessor", "keyword"],
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Storage",
+      "scope": [
+        "storage",
+        "storage.type",
+        "meta.var.expr storage.type",
+        "storage.type.property.js",
+        "storage.type.property.ts",
+        "storage.type.property.tsx",
+        "meta.class meta.method.declaration meta.var.expr storage.type.js"
+      ],
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Class name",
+      "scope": ["entity.name.class", "meta.class entity.name.type.class"],
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Inherited class",
+      "scope": "entity.other.inherited-class",
+      "settings": {
+        "foreground": "#a9c77d"
+      }
+    },
+    {
+      "name": "Function name",
+      "scope": "entity.name.function",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Function Parameters",
+      "scope": "variable.parameter",
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "Meta Tag",
+      "scope": ["punctuation.definition.tag", "meta.tag"],
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "HTML Tag names",
+      "scope": [
+        "entity.name.tag support.class.component",
+        "meta.tag.other.html",
+        "meta.tag.other.js",
+        "meta.tag.other.tsx",
+        "entity.name.tag.tsx",
+        "entity.name.tag.js",
+        "entity.name.tag",
+        "meta.tag.js",
+        "meta.tag.tsx",
+        "meta.tag.html"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Tag attribute",
+      "scope": "entity.other.attribute-name",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Entity Name Tag Custom",
+      "scope": "entity.name.tag.custom",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Library (function & constant)",
+      "scope": ["support.function", "support.constant"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Support Constant Property Value meta",
+      "scope": "support.constant.meta.property-value",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Library class/type",
+      "scope": ["support.type", "support.class"],
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Support Variable DOM",
+      "scope": "support.variable.dom",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Invalid",
+      "scope": "invalid",
+      "settings": {
+        "background": "#ff2c83",
+        "foreground": "#ffffff"
+      }
+    },
+    {
+      "name": "Invalid deprecated",
+      "scope": "invalid.deprecated",
+      "settings": {
+        "foreground": "#ffffff",
+        "background": "#d3423e"
+      }
+    },
+    {
+      "name": "Keyword Operator",
+      "scope": "keyword.operator",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Keyword Operator Relational",
+      "scope": "keyword.operator.relational",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Keyword Operator Assignment",
+      "scope": "keyword.operator.assignment",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Double-Slashed Comment",
+      "scope": "comment.line.double-slash",
+      "settings": {
+        "foreground": "#697098"
+      }
+    },
+    {
+      "name": "Object",
+      "scope": "object",
+      "settings": {
+        "foreground": "#cdebf7"
+      }
+    },
+    {
+      "name": "Null",
+      "scope": "constant.language.null",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Meta Brace",
+      "scope": "meta.brace",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Meta Delimiter Period",
+      "scope": "meta.delimiter.period",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Punctuation Definition String",
+      "scope": "punctuation.definition.string",
+      "settings": {
+        "foreground": "#d9f5dd"
+      }
+    },
+    {
+      "name": "Boolean",
+      "scope": "constant.language.boolean",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Object Comma",
+      "scope": "object.comma",
+      "settings": {
+        "foreground": "#ffffff"
+      }
+    },
+    {
+      "name": "Variable Parameter Function",
+      "scope": "variable.parameter.function",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Support Type Property Name & entity name tags",
+      "scope": [
+        "support.type.vendored.property-name",
+        "support.constant.vendored.property-value",
+        "support.type.property-name",
+        "meta.property-list entity.name.tag"
+      ],
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Entity Name tag reference in stylesheets",
+      "scope": "meta.property-list entity.name.tag.reference",
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Constant Other Color RGB Value Punctuation Definition Constant",
+      "scope": "constant.other.color.rgb-value punctuation.definition.constant",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Constant Other Color",
+      "scope": "constant.other.color",
+      "settings": {
+        "foreground": "#FFEB95"
+      }
+    },
+    {
+      "name": "Keyword Other Unit",
+      "scope": "keyword.other.unit",
+      "settings": {
+        "foreground": "#FFEB95"
+      }
+    },
+    {
+      "name": "Meta Selector",
+      "scope": "meta.selector",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Entity Other Attribute Name Id",
+      "scope": "entity.other.attribute-name.id",
+      "settings": {
+        "foreground": "#FAD430"
+      }
+    },
+    {
+      "name": "Meta Property Name",
+      "scope": "meta.property-name",
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Doctypes",
+      "scope": ["entity.name.tag.doctype", "meta.tag.sgml.doctype"],
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Punctuation Definition Parameters",
+      "scope": "punctuation.definition.parameters",
+      "settings": {
+        "foreground": "#d9f5dd"
+      }
+    },
+    {
+      "name": "Keyword Control Operator",
+      "scope": "keyword.control.operator",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Keyword Operator Logical",
+      "scope": "keyword.operator.logical",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Variable Instances",
+      "scope": [
+        "variable.instance",
+        "variable.other.instance",
+        "variable.reaedwrite.instance",
+        "variable.other.readwrite.instance"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Variable Property Other",
+      "scope": ["variable.other.property", "variable.other.object.property"],
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Entity Name Function",
+      "scope": "entity.name.function",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Keyword Operator Comparison",
+      "scope": "keyword.operator.comparison",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Support Constant, `new` keyword, Special Method Keyword",
+      "scope": [
+        "support.constant",
+        "keyword.other.special-method",
+        "keyword.other.new"
+      ],
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Support Function",
+      "scope": "support.function",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Invalid Broken",
+      "scope": "invalid.broken",
+      "settings": {
+        "foreground": "#020e14",
+        "background": "#F78C6C"
+      }
+    },
+    {
+      "name": "Invalid Unimplemented",
+      "scope": "invalid.unimplemented",
+      "settings": {
+        "background": "#8BD649",
+        "foreground": "#ffffff"
+      }
+    },
+    {
+      "name": "Invalid Illegal",
+      "scope": "invalid.illegal",
+      "settings": {
+        "foreground": "#ffffff",
+        "background": "#ec5f67"
+      }
+    },
+    {
+      "name": "Language Variable",
+      "scope": "variable.language",
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Support Variable Property",
+      "scope": "support.variable.property",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "Variable Function",
+      "scope": "variable.function",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Variable Interpolation",
+      "scope": "variable.interpolation",
+      "settings": {
+        "foreground": "#ec5f67"
+      }
+    },
+    {
+      "name": "Meta Function Call",
+      "scope": "meta.function-call",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Punctuation Section Embedded",
+      "scope": "punctuation.section.embedded",
+      "settings": {
+        "foreground": "#d3423e"
+      }
+    },
+    {
+      "name": "Punctuation Tweaks",
+      "scope": [
+        "punctuation.terminator.expression",
+        "punctuation.definition.arguments",
+        "punctuation.definition.array",
+        "punctuation.section.array",
+        "meta.array"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "More Punctuation Tweaks",
+      "scope": [
+        "punctuation.definition.list.begin",
+        "punctuation.definition.list.end",
+        "punctuation.separator.arguments",
+        "punctuation.definition.list"
+      ],
+      "settings": {
+        "foreground": "#d9f5dd"
+      }
+    },
+    {
+      "name": "Template Strings",
+      "scope": "string.template meta.template.expression",
+      "settings": {
+        "foreground": "#d3423e"
+      }
+    },
+    {
+      "name": "Backtics(``) in Template Strings",
+      "scope": "string.template punctuation.definition.string",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Italics",
+      "scope": "italic",
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Bold",
+      "scope": "bold",
+      "settings": {
+        "foreground": "#ffcb6b",
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "name": "Quote",
+      "scope": "quote",
+      "settings": {
+        "foreground": "#697098",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Raw Code",
+      "scope": "raw",
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "CoffeScript Variable Assignment",
+      "scope": "variable.assignment.coffee",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "CoffeScript Parameter Function",
+      "scope": "variable.parameter.function.coffee",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "CoffeeScript Assignments",
+      "scope": "variable.assignment.coffee",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "C# Readwrite Variables",
+      "scope": "variable.other.readwrite.cs",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "C# Classes & Storage types",
+      "scope": ["entity.name.type.class.cs", "storage.type.cs"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "C# Namespaces",
+      "scope": "entity.name.type.namespace.cs",
+      "settings": {
+        "foreground": "#B2CCD6"
+      }
+    },
+    {
+      "name": "Tag names in Stylesheets",
+      "scope": [
+        "entity.name.tag.css",
+        "entity.name.tag.less",
+        "entity.name.tag.custom.css"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Wildcard(*) selector in Stylesheets",
+      "scope": [
+        "entity.name.tag.wildcard.css",
+        "entity.name.tag.wildcard.less",
+        "entity.name.tag.wildcard.scss",
+        "entity.name.tag.wildcard.sass"
+      ],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "(C|SC|SA|LE)SS property value unit",
+      "scope": [
+        "keyword.other.unit.css",
+        "constant.length.units.css",
+        "keyword.other.unit.less",
+        "constant.length.units.less",
+        "keyword.other.unit.scss",
+        "constant.length.units.scss",
+        "keyword.other.unit.sass",
+        "constant.length.units.sass"
+      ],
+      "settings": {
+        "foreground": "#FFEB95"
+      }
+    },
+    {
+      "name": "Attribute Name for CSS",
+      "scope": "meta.attribute-selector.css entity.other.attribute-name.attribute",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "punctuations in styled components",
+      "scope": [
+        "source.js source.css meta.property-list",
+        "source.js source.css punctuation.section",
+        "source.js source.css punctuation.terminator.rule",
+        "source.js source.css punctuation.definition.entity.end.bracket",
+        "source.js source.css punctuation.definition.entity.begin.bracket",
+        "source.js source.css punctuation.separator.key-value",
+        "source.js source.css punctuation.definition.attribute-selector",
+        "source.js source.css meta.property-list",
+        "source.js source.css meta.property-list punctuation.separator.comma",
+        "source.ts source.css punctuation.section",
+        "source.ts source.css punctuation.terminator.rule",
+        "source.ts source.css punctuation.definition.entity.end.bracket",
+        "source.ts source.css punctuation.definition.entity.begin.bracket",
+        "source.ts source.css punctuation.separator.key-value",
+        "source.ts source.css punctuation.definition.attribute-selector",
+        "source.ts source.css meta.property-list",
+        "source.ts source.css meta.property-list punctuation.separator.comma"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Elixir Classes",
+      "scope": [
+        "source.elixir support.type.elixir",
+        "source.elixir meta.module.elixir entity.name.class.elixir"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Elixir Functions",
+      "scope": "source.elixir entity.name.function",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Elixir Constants",
+      "scope": [
+        "source.elixir constant.other.symbol.elixir",
+        "source.elixir constant.other.keywords.elixir"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Elixir String Punctuations",
+      "scope": "source.elixir punctuation.definition.string",
+      "settings": {
+        "foreground": "#a9c77d"
+      }
+    },
+    {
+      "name": "Elixir",
+      "scope": [
+        "source.elixir variable.other.readwrite.module.elixir",
+        "source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir"
+      ],
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Elixir Binary Punctuations",
+      "scope": "source.elixir .punctuation.binary.elixir",
+      "settings": {
+        "foreground": "#c792ea"
+      }
+    },
+    {
+      "name": "Go Function Calls",
+      "scope": "source.go meta.function-call.go",
+      "settings": {
+        "foreground": "#DDDDDD"
+      }
+    },
+    {
+      "name": "GraphQL Variables",
+      "scope": "variable.qraphql",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "ID Attribute Name in HTML",
+      "scope": "entity.other.attribute-name.id.html",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "HTML Punctuation Definition Tag",
+      "scope": "punctuation.definition.tag.html",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "HTML Doctype",
+      "scope": "meta.tag.sgml.doctype.html",
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "JavaScript Classes",
+      "scope": "meta.class entity.name.type.class.js",
+      "settings": {
+        "foreground": "#ffcb8b"
+      }
+    },
+    {
+      "name": "JavaScript Method Declaration e.g. `constructor`",
+      "scope": "meta.method.declaration storage.type.js",
+      "settings": {
+        "foreground": "#82AAFF",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "JavaScript Terminator",
+      "scope": "terminator.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Meta Punctuation Definition",
+      "scope": "meta.js punctuation.definition.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Entity Names in Code Documentations",
+      "scope": [
+        "entity.name.type.instance.jsdoc",
+        "entity.name.type.instance.phpdoc"
+      ],
+      "settings": {
+        "foreground": "#eeffff"
+      }
+    },
+    {
+      "name": "Other Variables in Code Documentations",
+      "scope": ["variable.other.jsdoc", "variable.other.phpdoc"],
+      "settings": {
+        "foreground": "#78ccf0"
+      }
+    },
+    {
+      "name": "JavaScript module imports and exports",
+      "scope": [
+        "variable.other.meta.import.js",
+        "meta.import.js variable.other",
+        "variable.other.meta.export.js",
+        "meta.export.js variable.other"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Variable Parameter Function",
+      "scope": "variable.parameter.function.js",
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "JavaScript Variable Other ReadWrite",
+      "scope": "variable.other.readwrite.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Text nested in React tags",
+      "scope": [
+        "meta.jsx.children",
+        "meta.jsx.children.js",
+        "meta.jsx.children.tsx"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript[React] Variable Other Object",
+      "scope": [
+        "variable.other.object.js",
+        "variable.other.object.jsx",
+        "meta.object-literal.key.js",
+        "meta.object-literal.key.jsx",
+        "variable.object.property.js",
+        "variable.object.property.jsx"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Variables",
+      "scope": ["variable.js", "variable.other.js"],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JavaScript Entity Name Type",
+      "scope": ["entity.name.type.js", "entity.name.type.module.js"],
+      "settings": {
+        "foreground": "#ffcb8b"
+      }
+    },
+    {
+      "name": "JavaScript Support Classes",
+      "scope": "support.class.js",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "JSON Property Names",
+      "scope": "support.type.property-name.json",
+      "settings": {
+        "foreground": "#C3E88D",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "JSON Support Constants",
+      "scope": "support.constant.json",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "JSON Property values (string)",
+      "scope": "meta.structure.dictionary.value.json string.quoted.double",
+      "settings": {
+        "foreground": "#80CBC4",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "Strings in JSON values",
+      "scope": "string.quoted.double.json punctuation.definition.string.json",
+      "settings": {
+        "foreground": "#80CBC4",
+        "fontStyle": "normal"
+      }
+    },
+    {
+      "name": "Specific JSON Property values like null",
+      "scope": "meta.structure.dictionary.json meta.structure.dictionary.value constant.language",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Ruby Variables",
+      "scope": "variable.other.ruby",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Ruby Hashkeys",
+      "scope": "constant.language.symbol.hashkey.ruby",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "LESS Tag names",
+      "scope": "entity.name.tag.less",
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Attribute Name for LESS",
+      "scope": "meta.attribute-selector.less entity.other.attribute-name.attribute",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Markup Headings",
+      "scope": "markup.heading",
+      "settings": {
+        "foreground": "#82b1ff"
+      }
+    },
+    {
+      "name": "Markup Italics",
+      "scope": "markup.italic",
+      "settings": {
+        "foreground": "#c792ea",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Markup Bold",
+      "scope": "markup.bold",
+      "settings": {
+        "foreground": "#ffcb6b",
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "name": "Markup Quote + others",
+      "scope": "markup.quote",
+      "settings": {
+        "foreground": "#697098",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Markup Raw Code + others",
+      "scope": "markup.inline.raw",
+      "settings": {
+        "foreground": "#80CBC4"
+      }
+    },
+    {
+      "name": "Markup Links",
+      "scope": ["markup.underline.link", "markup.underline.link.image"],
+      "settings": {
+        "foreground": "#ff869a"
+      }
+    },
+    {
+      "name": "Markup Attributes",
+      "scope": ["markup.meta.attribute-list"],
+      "settings": {
+        "foreground": "#a9c77d"
+      }
+    },
+    {
+      "name": "Markup Admonitions",
+      "scope": "markup.admonition",
+      "settings": {
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "name": "Markup Lists",
+      "scope": "markup.list.bullet",
+      "settings": {
+        "foreground": "#D9F5DD"
+      }
+    },
+    {
+      "name": "Markup Superscript and Subscript",
+      "scope": ["markup.superscript", "markup.subscript"],
+      "settings": {
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "name": "Markdown Link Title and Description",
+      "scope": [
+        "string.other.link.title.markdown",
+        "string.other.link.description.markdown"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Markdown Punctuation",
+      "scope": [
+        "punctuation.definition.string.markdown",
+        "punctuation.definition.string.begin.markdown",
+        "punctuation.definition.string.end.markdown",
+        "meta.link.inline.markdown punctuation.definition.string"
+      ],
+      "settings": {
+        "foreground": "#82b1ff"
+      }
+    },
+    {
+      "name": "Markdown MetaData Punctuation",
+      "scope": ["punctuation.definition.metadata.markdown"],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "Markdown List Punctuation",
+      "scope": ["beginning.punctuation.definition.list.markdown"],
+      "settings": {
+        "foreground": "#82b1ff"
+      }
+    },
+    {
+      "name": "Asciidoc Function",
+      "scope": "entity.name.function.asciidoc",
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "PHP Variables",
+      "scope": "variable.other.php",
+      "settings": {
+        "foreground": "#bec5d4"
+      }
+    },
+    {
+      "name": "Support Classes in PHP",
+      "scope": "support.class.php",
+      "settings": {
+        "foreground": "#ffcb8b"
+      }
+    },
+    {
+      "name": "Punctuations in PHP function calls",
+      "scope": "meta.function-call.php punctuation",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "PHP Global Variables",
+      "scope": "variable.other.global.php",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Declaration Punctuation in PHP Global Variables",
+      "scope": "variable.other.global.php punctuation.definition.variable",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Language Constants in Python",
+      "scope": "constant.language.python",
+      "settings": {
+        "foreground": "#ff5874"
+      }
+    },
+    {
+      "name": "Python Function Parameter and Arguments",
+      "scope": [
+        "variable.parameter.function.python",
+        "meta.function-call.arguments.python"
+      ],
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "Python Function Call",
+      "scope": [
+        "meta.function-call.python",
+        "meta.function-call.generic.python"
+      ],
+      "settings": {
+        "foreground": "#B2CCD6"
+      }
+    },
+    {
+      "name": "Punctuations in Python",
+      "scope": "punctuation.python",
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "Decorator Functions in Python",
+      "scope": "entity.name.function.decorator.python",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "Python Language Variable",
+      "scope": "source.python variable.language.special",
+      "settings": {
+        "foreground": "#8EACE3"
+      }
+    },
+    {
+      "name": "SCSS Variable",
+      "scope": [
+        "variable.scss",
+        "variable.sass",
+        "variable.parameter.url.scss",
+        "variable.parameter.url.sass"
+      ],
+      "settings": {
+        "foreground": "#DDDDDD"
+      }
+    },
+    {
+      "name": "Variables in SASS At-Rules",
+      "scope": [
+        "source.css.scss meta.at-rule variable",
+        "source.css.sass meta.at-rule variable"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "Variables in SASS At-Rules",
+      "scope": [
+        "source.css.scss meta.at-rule variable",
+        "source.css.sass meta.at-rule variable"
+      ],
+      "settings": {
+        "foreground": "#bec5d4"
+      }
+    },
+    {
+      "name": "Attribute Name for SASS",
+      "scope": [
+        "meta.attribute-selector.scss entity.other.attribute-name.attribute",
+        "meta.attribute-selector.sass entity.other.attribute-name.attribute"
+      ],
+      "settings": {
+        "foreground": "#F78C6C"
+      }
+    },
+    {
+      "name": "Tag names in SASS",
+      "scope": ["entity.name.tag.scss", "entity.name.tag.sass"],
+      "settings": {
+        "foreground": "#ff5572"
+      }
+    },
+    {
+      "name": "TypeScript[React] Variables and Object Properties",
+      "scope": [
+        "variable.other.readwrite.alias.ts",
+        "variable.other.readwrite.alias.tsx",
+        "variable.other.readwrite.ts",
+        "variable.other.readwrite.tsx",
+        "variable.other.object.ts",
+        "variable.other.object.tsx",
+        "variable.object.property.ts",
+        "variable.object.property.tsx",
+        "variable.other.ts",
+        "variable.other.tsx",
+        "variable.tsx",
+        "variable.ts"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "TypeScript[React] Entity Name Types",
+      "scope": ["entity.name.type.ts", "entity.name.type.tsx"],
+      "settings": {
+        "foreground": "#78ccf0"
+      }
+    },
+    {
+      "name": "TypeScript[React] Node Classes",
+      "scope": ["support.class.node.ts", "support.class.node.tsx"],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "TypeScript[React] Entity Name Types as Parameters",
+      "scope": [
+        "meta.type.parameters.ts entity.name.type",
+        "meta.type.parameters.tsx entity.name.type"
+      ],
+      "settings": {
+        "foreground": "#eeffff"
+      }
+    },
+    {
+      "name": "TypeScript[React] Import/Export Punctuations",
+      "scope": [
+        "meta.import.ts punctuation.definition.block",
+        "meta.import.tsx punctuation.definition.block",
+        "meta.export.ts punctuation.definition.block",
+        "meta.export.tsx punctuation.definition.block"
+      ],
+      "settings": {
+        "foreground": "#bfc7d5"
+      }
+    },
+    {
+      "name": "TypeScript[React] Punctuation Decorators",
+      "scope": [
+        "meta.decorator punctuation.decorator.ts",
+        "meta.decorator punctuation.decorator.tsx"
+      ],
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "TypeScript[React] Punctuation Decorators",
+      "scope": "meta.tag.js meta.jsx.children.tsx",
+      "settings": {
+        "foreground": "#82AAFF"
+      }
+    },
+    {
+      "name": "YAML Entity Name Tags",
+      "scope": "entity.name.tag.yaml",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "handlebars variables",
+      "scope": "variable.parameter.handlebars",
+      "settings": {
+        "foreground": "#bec5d4"
+      }
+    },
+    {
+      "name": "handlebars parameters",
+      "scope": "entity.other.attribute-name.handlebars variable.parameter.handlebars",
+      "settings": {
+        "foreground": "#ffcb6b"
+      }
+    },
+    {
+      "name": "handlebars enitity attribute names",
+      "scope": "entity.other.attribute-name.handlebars",
+      "settings": {
+        "foreground": "#89DDFF"
+      }
+    },
+    {
+      "name": "handlebars enitity attribute values",
+      "scope": "entity.other.attribute-value.handlebars variable.parameter.handlebars",
+      "settings": {
+        "foreground": "#7986E7"
+      }
+    },
+    {
+      "name": "normalize font style of certain components",
+      "scope": [
+        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.begin.js",
+        "meta.tag.js meta.embedded.expression.js punctuation.section.embedded.end.js",
+        "meta.property-list.css meta.property-value.css variable.other.less",
+        "punctuation.section.embedded.begin.js.jsx",
+        "punctuation.section.embedded.end.js.jsx",
+        "meta.property-list.scss variable.scss",
+        "meta.property-list.sass variable.sass",
+        "keyword.operator.logical",
+        "keyword.operator.arithmetic",
+        "keyword.operator.bitwise",
+        "keyword.operator.increment",
+        "keyword.operator.ternary",
+        "keyword.operator.comparison",
+        "keyword.operator.assignment",
+        "keyword.operator.operator",
+        "keyword.operator.or.regexp",
+        "keyword.operator.expression.in",
+        "keyword.operator.type",
+        "punctuation.section.embedded.js",
+        "punctuation.definintion.string",
+        "punctuation"
+      ],
+      "settings": {
+        "fontStyle": "normal"
+      }
+    }
+  ]
+}

assets/themes/src/vscode/rose-pine/rose-pine-dawn.json 🔗

@@ -1,680 +1,680 @@
 {
-    "name": "Rosé Pine Dawn",
-    "type": "light",
-    "colors": {
-        "activityBar.activeBorder": "#575279",
-        "activityBar.background": "#faf4ed",
-        "activityBar.dropBorder": "#f2e9e1",
-        "activityBar.foreground": "#575279",
-        "activityBar.inactiveForeground": "#797593",
-        "activityBarBadge.background": "#d7827e",
-        "activityBarBadge.foreground": "#faf4ed",
-        "badge.background": "#d7827e",
-        "badge.foreground": "#faf4ed",
-        "banner.background": "#fffaf3",
-        "banner.foreground": "#575279",
-        "banner.iconForeground": "#797593",
-        "breadcrumb.activeSelectionForeground": "#d7827e",
-        "breadcrumb.background": "#faf4ed",
-        "breadcrumb.focusForeground": "#797593",
-        "breadcrumb.foreground": "#9893a5",
-        "breadcrumbPicker.background": "#fffaf3",
-        "button.background": "#d7827e",
-        "button.foreground": "#faf4ed",
-        "button.hoverBackground": "#d7827ee6",
-        "button.secondaryBackground": "#fffaf3",
-        "button.secondaryForeground": "#575279",
-        "button.secondaryHoverBackground": "#f2e9e1",
-        "charts.blue": "#56949f",
-        "charts.foreground": "#575279",
-        "charts.green": "#286983",
-        "charts.lines": "#797593",
-        "charts.orange": "#d7827e",
-        "charts.purple": "#907aa9",
-        "charts.red": "#b4637a",
-        "charts.yellow": "#ea9d34",
-        "checkbox.background": "#fffaf3",
-        "checkbox.border": "#6e6a8614",
-        "checkbox.foreground": "#575279",
-        "debugExceptionWidget.background": "#fffaf3",
-        "debugExceptionWidget.border": "#6e6a8614",
-        "debugIcon.breakpointCurrentStackframeForeground": "#797593",
-        "debugIcon.breakpointDisabledForeground": "#797593",
-        "debugIcon.breakpointForeground": "#797593",
-        "debugIcon.breakpointStackframeForeground": "#797593",
-        "debugIcon.breakpointUnverifiedForeground": "#797593",
-        "debugIcon.continueForeground": "#797593",
-        "debugIcon.disconnectForeground": "#797593",
-        "debugIcon.pauseForeground": "#797593",
-        "debugIcon.restartForeground": "#797593",
-        "debugIcon.startForeground": "#797593",
-        "debugIcon.stepBackForeground": "#797593",
-        "debugIcon.stepIntoForeground": "#797593",
-        "debugIcon.stepOutForeground": "#797593",
-        "debugIcon.stepOverForeground": "#797593",
-        "debugIcon.stopForeground": "#b4637a",
-        "debugToolBar.background": "#fffaf3",
-        "debugToolBar.border": "#f2e9e1",
-        "descriptionForeground": "#797593",
-        "diffEditor.border": "#f2e9e1",
-        "diffEditor.diagonalFill": "#6e6a8626",
-        "diffEditor.insertedLineBackground": "#56949f26",
-        "diffEditor.insertedTextBackground": "#56949f26",
-        "diffEditor.removedLineBackground": "#b4637a26",
-        "diffEditor.removedTextBackground": "#b4637a26",
-        "diffEditorOverview.insertedForeground": "#56949f80",
-        "diffEditorOverview.removedForeground": "#b4637a80",
-        "dropdown.background": "#fffaf3",
-        "dropdown.border": "#6e6a8614",
-        "dropdown.foreground": "#575279",
-        "dropdown.listBackground": "#fffaf3",
-        "editor.background": "#faf4ed",
-        "editor.findMatchBackground": "#6e6a8626",
-        "editor.findMatchHighlightBackground": "#6e6a8626",
-        "editor.findRangeHighlightBackground": "#6e6a8626",
-        "editor.findRangeHighlightBorder": "#000000",
-        "editor.focusedStackFrameHighlightBackground": "#6e6a8614",
-        "editor.foldBackground": "#fffaf3",
-        "editor.foreground": "#575279",
-        "editor.hoverHighlightBackground": "#000000",
-        "editor.inactiveSelectionBackground": "#6e6a860d",
-        "editor.inlineValuesBackground": "#000000",
-        "editor.inlineValuesForeground": "#797593",
-        "editor.lineHighlightBackground": "#6e6a860d",
-        "editor.lineHighlightBorder": "#000000",
-        "editor.linkedEditingBackground": "#fffaf3",
-        "editor.rangeHighlightBackground": "#6e6a860d",
-        "editor.selectionBackground": "#6e6a8614",
-        "editor.selectionForeground": "#575279",
-        "editor.selectionHighlightBackground": "#6e6a8614",
-        "editor.selectionHighlightBorder": "#faf4ed",
-        "editor.snippetFinalTabstopHighlightBackground": "#6e6a8614",
-        "editor.snippetFinalTabstopHighlightBorder": "#fffaf3",
-        "editor.snippetTabstopHighlightBackground": "#6e6a8614",
-        "editor.snippetTabstopHighlightBorder": "#fffaf3",
-        "editor.stackFrameHighlightBackground": "#6e6a8614",
-        "editor.symbolHighlightBackground": "#6e6a8614",
-        "editor.symbolHighlightBorder": "#000000",
-        "editor.wordHighlightBackground": "#6e6a8614",
-        "editor.wordHighlightBorder": "#000000",
-        "editor.wordHighlightStrongBackground": "#6e6a8614",
-        "editor.wordHighlightStrongBorder": "#6e6a8614",
-        "editorBracketHighlight.foreground1": "#b4637a80",
-        "editorBracketHighlight.foreground2": "#28698380",
-        "editorBracketHighlight.foreground3": "#ea9d3480",
-        "editorBracketHighlight.foreground4": "#56949f80",
-        "editorBracketHighlight.foreground5": "#d7827e80",
-        "editorBracketHighlight.foreground6": "#907aa980",
-        "editorBracketMatch.background": "#000000",
-        "editorBracketMatch.border": "#797593",
-        "editorBracketPairGuide.activeBackground1": "#286983",
-        "editorBracketPairGuide.activeBackground2": "#d7827e",
-        "editorBracketPairGuide.activeBackground3": "#907aa9",
-        "editorBracketPairGuide.activeBackground4": "#56949f",
-        "editorBracketPairGuide.activeBackground5": "#ea9d34",
-        "editorBracketPairGuide.activeBackground6": "#b4637a",
-        "editorBracketPairGuide.background1": "#28698380",
-        "editorBracketPairGuide.background2": "#d7827e80",
-        "editorBracketPairGuide.background3": "#907aa980",
-        "editorBracketPairGuide.background4": "#56949f80",
-        "editorBracketPairGuide.background5": "#ea9d3480",
-        "editorBracketPairGuide.background6": "#b4637a80",
-        "editorCodeLens.foreground": "#d7827e",
-        "editorCursor.background": "#575279",
-        "editorCursor.foreground": "#9893a5",
-        "editorError.border": "#000000",
-        "editorError.foreground": "#b4637a",
-        "editorGhostText.foreground": "#797593",
-        "editorGroup.border": "#000000",
-        "editorGroup.dropBackground": "#fffaf3",
-        "editorGroup.emptyBackground": "#000000",
-        "editorGroup.focusedEmptyBorder": "#000000",
-        "editorGroupHeader.noTabsBackground": "#000000",
-        "editorGroupHeader.tabsBackground": "#000000",
-        "editorGroupHeader.tabsBorder": "#000000",
-        "editorGutter.addedBackground": "#56949f",
-        "editorGutter.background": "#faf4ed",
-        "editorGutter.commentRangeForeground": "#797593",
-        "editorGutter.deletedBackground": "#b4637a",
-        "editorGutter.foldingControlForeground": "#907aa9",
-        "editorGutter.modifiedBackground": "#d7827e",
-        "editorHint.border": "#000000",
-        "editorHint.foreground": "#797593",
-        "editorHoverWidget.background": "#fffaf3",
-        "editorHoverWidget.border": "#9893a580",
-        "editorHoverWidget.foreground": "#797593",
-        "editorHoverWidget.highlightForeground": "#575279",
-        "editorHoverWidget.statusBarBackground": "#000000",
-        "editorIndentGuide.activeBackground": "#9893a5",
-        "editorIndentGuide.background": "#6e6a8626",
-        "editorInfo.border": "#f2e9e1",
-        "editorInfo.foreground": "#56949f",
-        "editorInlayHint.background": "#f2e9e1",
-        "editorInlayHint.foreground": "#797593",
-        "editorInlayHint.parameterBackground": "#f2e9e1",
-        "editorInlayHint.parameterForeground": "#907aa9",
-        "editorInlayHint.typeBackground": "#f2e9e1",
-        "editorInlayHint.typeForeground": "#56949f",
-        "editorLightBulb.foreground": "#286983",
-        "editorLightBulbAutoFix.foreground": "#d7827e",
-        "editorLineNumber.activeForeground": "#575279",
-        "editorLineNumber.foreground": "#797593",
-        "editorLink.activeForeground": "#d7827e",
-        "editorMarkerNavigation.background": "#fffaf3",
-        "editorMarkerNavigationError.background": "#fffaf3",
-        "editorMarkerNavigationInfo.background": "#fffaf3",
-        "editorMarkerNavigationWarning.background": "#fffaf3",
-        "editorOverviewRuler.addedForeground": "#56949f80",
-        "editorOverviewRuler.background": "#faf4ed",
-        "editorOverviewRuler.border": "#6e6a8626",
-        "editorOverviewRuler.bracketMatchForeground": "#797593",
-        "editorOverviewRuler.commonContentForeground": "#6e6a860d",
-        "editorOverviewRuler.currentContentForeground": "#6e6a8614",
-        "editorOverviewRuler.deletedForeground": "#b4637a80",
-        "editorOverviewRuler.errorForeground": "#b4637a80",
-        "editorOverviewRuler.findMatchForeground": "#6e6a8626",
-        "editorOverviewRuler.incomingContentForeground": "#907aa980",
-        "editorOverviewRuler.infoForeground": "#56949f80",
-        "editorOverviewRuler.modifiedForeground": "#d7827e80",
-        "editorOverviewRuler.rangeHighlightForeground": "#6e6a8626",
-        "editorOverviewRuler.selectionHighlightForeground": "#6e6a8626",
-        "editorOverviewRuler.warningForeground": "#ea9d3480",
-        "editorOverviewRuler.wordHighlightForeground": "#6e6a8614",
-        "editorOverviewRuler.wordHighlightStrongForeground": "#6e6a8626",
-        "editorPane.background": "#000000",
-        "editorRuler.foreground": "#6e6a8626",
-        "editorSuggestWidget.background": "#fffaf3",
-        "editorSuggestWidget.border": "#000000",
-        "editorSuggestWidget.focusHighlightForeground": "#d7827e",
-        "editorSuggestWidget.foreground": "#797593",
-        "editorSuggestWidget.highlightForeground": "#d7827e",
-        "editorSuggestWidget.selectedBackground": "#6e6a8614",
-        "editorSuggestWidget.selectedForeground": "#575279",
-        "editorSuggestWidget.selectedIconForeground": "#575279",
-        "editorUnnecessaryCode.border": "#000000",
-        "editorUnnecessaryCode.opacity": "#57527980",
-        "editorWarning.border": "#000000",
-        "editorWarning.foreground": "#ea9d34",
-        "editorWhitespace.foreground": "#9893a5",
-        "editorWidget.background": "#fffaf3",
-        "editorWidget.border": "#f2e9e1",
-        "editorWidget.foreground": "#797593",
-        "editorWidget.resizeBorder": "#9893a5",
-        "errorForeground": "#b4637a",
-        "extensionBadge.remoteBackground": "#907aa9",
-        "extensionBadge.remoteForeground": "#faf4ed",
-        "extensionButton.prominentBackground": "#d7827e",
-        "extensionButton.prominentForeground": "#faf4ed",
-        "extensionButton.prominentHoverBackground": "#d7827ee6",
-        "extensionIcon.preReleaseForeground": "#286983",
-        "extensionIcon.starForeground": "#d7827e",
-        "extensionIcon.verifiedForeground": "#907aa9",
-        "focusBorder": "#6e6a8614",
-        "foreground": "#575279",
-        "gitDecoration.addedResourceForeground": "#56949f",
-        "gitDecoration.conflictingResourceForeground": "#b4637a",
-        "gitDecoration.deletedResourceForeground": "#797593",
-        "gitDecoration.ignoredResourceForeground": "#9893a5",
-        "gitDecoration.modifiedResourceForeground": "#d7827e",
-        "gitDecoration.renamedResourceForeground": "#286983",
-        "gitDecoration.stageDeletedResourceForeground": "#b4637a",
-        "gitDecoration.stageModifiedResourceForeground": "#907aa9",
-        "gitDecoration.submoduleResourceForeground": "#ea9d34",
-        "gitDecoration.untrackedResourceForeground": "#ea9d34",
-        "icon.foreground": "#797593",
-        "input.background": "#f2e9e180",
-        "input.border": "#6e6a8614",
-        "input.foreground": "#575279",
-        "input.placeholderForeground": "#797593",
-        "inputOption.activeBackground": "#d7827e26",
-        "inputOption.activeForeground": "#d7827e",
-        "inputValidation.errorBackground": "#fffaf3",
-        "inputValidation.errorBorder": "#6e6a8626",
-        "inputValidation.errorForeground": "#b4637a",
-        "inputValidation.infoBackground": "#fffaf3",
-        "inputValidation.infoBorder": "#6e6a8626",
-        "inputValidation.infoForeground": "#56949f",
-        "inputValidation.warningBackground": "#fffaf3",
-        "inputValidation.warningBorder": "#6e6a8626",
-        "inputValidation.warningForeground": "#56949f80",
-        "keybindingLabel.background": "#f2e9e1",
-        "keybindingLabel.border": "#6e6a8626",
-        "keybindingLabel.bottomBorder": "#6e6a8626",
-        "keybindingLabel.foreground": "#907aa9",
-        "keybindingTable.headerBackground": "#f2e9e1",
-        "keybindingTable.rowsBackground": "#fffaf3",
-        "list.activeSelectionBackground": "#6e6a8614",
-        "list.activeSelectionForeground": "#575279",
-        "list.deemphasizedForeground": "#797593",
-        "list.dropBackground": "#fffaf3",
-        "list.errorForeground": "#b4637a",
-        "list.filterMatchBackground": "#fffaf3",
-        "list.filterMatchBorder": "#d7827e",
-        "list.focusBackground": "#6e6a8626",
-        "list.focusForeground": "#575279",
-        "list.focusOutline": "#6e6a8614",
-        "list.highlightForeground": "#d7827e",
-        "list.hoverBackground": "#6e6a860d",
-        "list.hoverForeground": "#575279",
-        "list.inactiveFocusBackground": "#6e6a860d",
-        "list.inactiveSelectionBackground": "#fffaf3",
-        "list.inactiveSelectionForeground": "#575279",
-        "list.invalidItemForeground": "#b4637a",
-        "list.warningForeground": "#ea9d34",
-        "listFilterWidget.background": "#fffaf3",
-        "listFilterWidget.noMatchesOutline": "#b4637a",
-        "listFilterWidget.outline": "#f2e9e1",
-        "menu.background": "#fffaf3",
-        "menu.border": "#6e6a860d",
-        "menu.foreground": "#575279",
-        "menu.selectionBackground": "#6e6a8614",
-        "menu.selectionBorder": "#f2e9e1",
-        "menu.selectionForeground": "#575279",
-        "menu.separatorBackground": "#6e6a8626",
-        "menubar.selectionBackground": "#6e6a8614",
-        "menubar.selectionBorder": "#6e6a860d",
-        "menubar.selectionForeground": "#575279",
-        "merge.border": "#f2e9e1",
-        "merge.commonContentBackground": "#6e6a8614",
-        "merge.commonHeaderBackground": "#6e6a8614",
-        "merge.currentContentBackground": "#ea9d3480",
-        "merge.currentHeaderBackground": "#ea9d3480",
-        "merge.incomingContentBackground": "#56949f80",
-        "merge.incomingHeaderBackground": "#56949f80",
-        "minimap.background": "#fffaf3",
-        "minimap.errorHighlight": "#b4637a80",
-        "minimap.findMatchHighlight": "#6e6a8614",
-        "minimap.selectionHighlight": "#6e6a8614",
-        "minimap.warningHighlight": "#ea9d3480",
-        "minimapGutter.addedBackground": "#56949f",
-        "minimapGutter.deletedBackground": "#b4637a",
-        "minimapGutter.modifiedBackground": "#d7827e",
-        "minimapSlider.activeBackground": "#6e6a8626",
-        "minimapSlider.background": "#6e6a8614",
-        "minimapSlider.hoverBackground": "#6e6a8614",
-        "notebook.cellBorderColor": "#56949f80",
-        "notebook.cellEditorBackground": "#fffaf3",
-        "notebook.cellHoverBackground": "#f2e9e180",
-        "notebook.focusedCellBackground": "#6e6a860d",
-        "notebook.focusedCellBorder": "#56949f",
-        "notebook.outputContainerBackgroundColor": "#6e6a860d",
-        "notificationCenter.border": "#6e6a8614",
-        "notificationCenterHeader.background": "#fffaf3",
-        "notificationCenterHeader.foreground": "#797593",
-        "notificationLink.foreground": "#907aa9",
-        "notifications.background": "#fffaf3",
-        "notifications.border": "#6e6a8614",
-        "notifications.foreground": "#575279",
-        "notificationsErrorIcon.foreground": "#b4637a",
-        "notificationsInfoIcon.foreground": "#56949f",
-        "notificationsWarningIcon.foreground": "#ea9d34",
-        "notificationToast.border": "#6e6a8614",
-        "panel.background": "#fffaf3",
-        "panel.border": "#000000",
-        "panel.dropBorder": "#f2e9e1",
-        "panelInput.border": "#fffaf3",
-        "panelSection.dropBackground": "#6e6a8614",
-        "panelSectionHeader.background": "#fffaf3",
-        "panelSectionHeader.foreground": "#575279",
-        "panelTitle.activeBorder": "#6e6a8626",
-        "panelTitle.activeForeground": "#575279",
-        "panelTitle.inactiveForeground": "#797593",
-        "peekView.border": "#f2e9e1",
-        "peekViewEditor.background": "#fffaf3",
-        "peekViewEditor.matchHighlightBackground": "#6e6a8626",
-        "peekViewResult.background": "#fffaf3",
-        "peekViewResult.fileForeground": "#797593",
-        "peekViewResult.lineForeground": "#797593",
-        "peekViewResult.matchHighlightBackground": "#6e6a8626",
-        "peekViewResult.selectionBackground": "#6e6a8614",
-        "peekViewResult.selectionForeground": "#575279",
-        "peekViewTitle.background": "#f2e9e1",
-        "peekViewTitleDescription.foreground": "#797593",
-        "pickerGroup.border": "#6e6a8626",
-        "pickerGroup.foreground": "#907aa9",
-        "ports.iconRunningProcessForeground": "#d7827e",
-        "problemsErrorIcon.foreground": "#b4637a",
-        "problemsInfoIcon.foreground": "#56949f",
-        "problemsWarningIcon.foreground": "#ea9d34",
-        "progressBar.background": "#d7827e",
-        "quickInput.background": "#fffaf3",
-        "quickInput.foreground": "#797593",
-        "quickInputList.focusBackground": "#6e6a8614",
-        "quickInputList.focusForeground": "#575279",
-        "quickInputList.focusIconForeground": "#575279",
-        "scrollbar.shadow": "#fffaf34d",
-        "scrollbarSlider.activeBackground": "#28698380",
-        "scrollbarSlider.background": "#6e6a8614",
-        "scrollbarSlider.hoverBackground": "#6e6a8626",
-        "searchEditor.findMatchBackground": "#6e6a8614",
-        "selection.background": "#6e6a8626",
-        "settings.focusedRowBackground": "#fffaf3",
-        "settings.headerForeground": "#575279",
-        "settings.modifiedItemIndicator": "#d7827e",
-        "settings.focusedRowBorder": "#6e6a8614",
-        "settings.rowHoverBackground": "#fffaf3",
-        "sideBar.background": "#faf4ed",
-        "sideBar.dropBackground": "#fffaf3",
-        "sideBar.foreground": "#797593",
-        "sideBarSectionHeader.background": "#000000",
-        "sideBarSectionHeader.border": "#6e6a8614",
-        "statusBar.background": "#faf4ed",
-        "statusBar.debuggingBackground": "#907aa9",
-        "statusBar.debuggingForeground": "#faf4ed",
-        "statusBar.foreground": "#797593",
-        "statusBar.noFolderBackground": "#faf4ed",
-        "statusBar.noFolderForeground": "#797593",
-        "statusBarItem.activeBackground": "#6e6a8626",
-        "statusBarItem.hoverBackground": "#6e6a8614",
-        "statusBarItem.prominentBackground": "#f2e9e1",
-        "statusBarItem.prominentForeground": "#575279",
-        "statusBarItem.prominentHoverBackground": "#6e6a8614",
-        "statusBarItem.remoteBackground": "#faf4ed",
-        "statusBarItem.remoteForeground": "#ea9d34",
-        "statusBarItem.errorBackground": "#faf4ed",
-        "statusBarItem.errorForeground": "#b4637a",
-        "symbolIcon.arrayForeground": "#797593",
-        "symbolIcon.classForeground": "#797593",
-        "symbolIcon.colorForeground": "#797593",
-        "symbolIcon.constantForeground": "#797593",
-        "symbolIcon.constructorForeground": "#797593",
-        "symbolIcon.enumeratorForeground": "#797593",
-        "symbolIcon.enumeratorMemberForeground": "#797593",
-        "symbolIcon.eventForeground": "#797593",
-        "symbolIcon.fieldForeground": "#797593",
-        "symbolIcon.fileForeground": "#797593",
-        "symbolIcon.folderForeground": "#797593",
-        "symbolIcon.functionForeground": "#797593",
-        "symbolIcon.interfaceForeground": "#797593",
-        "symbolIcon.keyForeground": "#797593",
-        "symbolIcon.keywordForeground": "#797593",
-        "symbolIcon.methodForeground": "#797593",
-        "symbolIcon.moduleForeground": "#797593",
-        "symbolIcon.namespaceForeground": "#797593",
-        "symbolIcon.nullForeground": "#797593",
-        "symbolIcon.numberForeground": "#797593",
-        "symbolIcon.objectForeground": "#797593",
-        "symbolIcon.operatorForeground": "#797593",
-        "symbolIcon.packageForeground": "#797593",
-        "symbolIcon.propertyForeground": "#797593",
-        "symbolIcon.referenceForeground": "#797593",
-        "symbolIcon.snippetForeground": "#797593",
-        "symbolIcon.stringForeground": "#797593",
-        "symbolIcon.structForeground": "#797593",
-        "symbolIcon.textForeground": "#797593",
-        "symbolIcon.typeParameterForeground": "#797593",
-        "symbolIcon.unitForeground": "#797593",
-        "symbolIcon.variableForeground": "#797593",
-        "tab.activeBackground": "#6e6a860d",
-        "tab.activeForeground": "#575279",
-        "tab.activeModifiedBorder": "#56949f",
-        "tab.border": "#000000",
-        "tab.hoverBackground": "#6e6a8614",
-        "tab.inactiveBackground": "#000000",
-        "tab.inactiveForeground": "#797593",
-        "tab.inactiveModifiedBorder": "#56949f80",
-        "tab.lastPinnedBorder": "#9893a5",
-        "tab.unfocusedActiveBackground": "#000000",
-        "tab.unfocusedHoverBackground": "#000000",
-        "tab.unfocusedInactiveBackground": "#000000",
-        "tab.unfocusedInactiveModifiedBorder": "#56949f80",
-        "terminal.ansiBlack": "#f2e9e1",
-        "terminal.ansiBlue": "#56949f",
-        "terminal.ansiBrightBlack": "#797593",
-        "terminal.ansiBrightBlue": "#56949f",
-        "terminal.ansiBrightCyan": "#d7827e",
-        "terminal.ansiBrightGreen": "#286983",
-        "terminal.ansiBrightMagenta": "#907aa9",
-        "terminal.ansiBrightRed": "#b4637a",
-        "terminal.ansiBrightWhite": "#575279",
-        "terminal.ansiBrightYellow": "#ea9d34",
-        "terminal.ansiCyan": "#d7827e",
-        "terminal.ansiGreen": "#286983",
-        "terminal.ansiMagenta": "#907aa9",
-        "terminal.ansiRed": "#b4637a",
-        "terminal.ansiWhite": "#575279",
-        "terminal.ansiYellow": "#ea9d34",
-        "terminal.dropBackground": "#6e6a8614",
-        "terminal.foreground": "#575279",
-        "terminal.selectionBackground": "#6e6a8614",
-        "terminal.tab.activeBorder": "#575279",
-        "terminalCursor.background": "#575279",
-        "terminalCursor.foreground": "#9893a5",
-        "textBlockQuote.background": "#fffaf3",
-        "textBlockQuote.border": "#6e6a8614",
-        "textCodeBlock.background": "#fffaf3",
-        "textLink.activeForeground": "#907aa9e6",
-        "textLink.foreground": "#907aa9",
-        "textPreformat.foreground": "#ea9d34",
-        "textSeparator.foreground": "#797593",
-        "titleBar.activeBackground": "#faf4ed",
-        "titleBar.activeForeground": "#797593",
-        "titleBar.inactiveBackground": "#fffaf3",
-        "titleBar.inactiveForeground": "#797593",
-        "toolbar.activeBackground": "#6e6a8626",
-        "toolbar.hoverBackground": "#6e6a8614",
-        "tree.indentGuidesStroke": "#797593",
-        "walkThrough.embeddedEditorBackground": "#faf4ed",
-        "welcomePage.background": "#faf4ed",
-        "welcomePage.buttonBackground": "#fffaf3",
-        "welcomePage.buttonHoverBackground": "#f2e9e1",
-        "widget.shadow": "#fffaf34d",
-        "window.activeBorder": "#fffaf3",
-        "window.inactiveBorder": "#fffaf3"
-    },
-    "tokenColors": [
-        {
-            "scope": ["comment"],
-            "settings": {
-                "foreground": "#9893a5",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["constant"],
-            "settings": {
-                "foreground": "#286983"
-            }
-        },
-        {
-            "scope": ["constant.numeric", "constant.language"],
-            "settings": {
-                "foreground": "#d7827e"
-            }
-        },
-        {
-            "scope": ["entity.name"],
-            "settings": {
-                "foreground": "#d7827e"
-            }
-        },
-        {
-            "scope": [
-                "entity.name.section",
-                "entity.name.tag",
-                "entity.name.namespace",
-                "entity.name.type"
-            ],
-            "settings": {
-                "foreground": "#56949f"
-            }
-        },
-        {
-            "scope": ["entity.other.attribute-name", "entity.other.inherited-class"],
-            "settings": {
-                "foreground": "#907aa9",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["invalid"],
-            "settings": {
-                "foreground": "#b4637a"
-            }
-        },
-        {
-            "scope": ["invalid.deprecated"],
-            "settings": {
-                "foreground": "#797593"
-            }
-        },
-        {
-            "scope": ["keyword"],
-            "settings": {
-                "foreground": "#286983"
-            }
-        },
-        {
-            "scope": ["markup.inserted.diff"],
-            "settings": {
-                "foreground": "#56949f"
-            }
-        },
-        {
-            "scope": ["markup.deleted.diff"],
-            "settings": {
-                "foreground": "#b4637a"
-            }
-        },
-        {
-            "scope": "markup.heading",
-            "settings": {
-                "fontStyle": "bold"
-            }
-        },
-        {
-            "scope": "markup.bold.markdown",
-            "settings": {
-                "fontStyle": "bold"
-            }
-        },
-        {
-            "scope": "markup.italic.markdown",
-            "settings": {
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["meta.diff.range"],
-            "settings": {
-                "foreground": "#907aa9"
-            }
-        },
-        {
-            "scope": ["meta.tag", "meta.brace"],
-            "settings": {
-                "foreground": "#575279"
-            }
-        },
-        {
-            "scope": ["meta.import", "meta.export"],
-            "settings": {
-                "foreground": "#286983"
-            }
-        },
-        {
-            "scope": "meta.directive.vue",
-            "settings": {
-                "foreground": "#907aa9",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": "meta.property-name.css",
-            "settings": {
-                "foreground": "#56949f"
-            }
-        },
-        {
-            "scope": "meta.property-value.css",
-            "settings": {
-                "foreground": "#ea9d34"
-            }
-        },
-        {
-            "scope": "meta.tag.other.html",
-            "settings": {
-                "foreground": "#797593"
-            }
-        },
-        {
-            "scope": ["punctuation"],
-            "settings": {
-                "foreground": "#797593"
-            }
-        },
-        {
-            "scope": ["punctuation.accessor"],
-            "settings": {
-                "foreground": "#286983"
-            }
-        },
-        {
-            "scope": ["punctuation.definition.string"],
-            "settings": {
-                "foreground": "#ea9d34"
-            }
-        },
-        {
-            "scope": ["punctuation.definition.tag"],
-            "settings": {
-                "foreground": "#9893a5"
-            }
-        },
-        {
-            "scope": ["storage.type", "storage.modifier"],
-            "settings": {
-                "foreground": "#286983"
-            }
-        },
-        {
-            "scope": ["string"],
-            "settings": {
-                "foreground": "#ea9d34"
-            }
-        },
-        {
-            "scope": ["support"],
-            "settings": {
-                "foreground": "#56949f"
-            }
-        },
-        {
-            "scope": ["support.constant"],
-            "settings": {
-                "foreground": "#ea9d34"
-            }
-        },
-        {
-            "scope": ["support.function"],
-            "settings": {
-                "foreground": "#b4637a",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["variable"],
-            "settings": {
-                "foreground": "#d7827e",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": [
-                "variable.other",
-                "variable.language",
-                "variable.function",
-                "variable.argument"
-            ],
-            "settings": {
-                "foreground": "#575279"
-            }
-        },
-        {
-            "scope": ["variable.parameter"],
-            "settings": {
-                "foreground": "#907aa9"
-            }
-        }
-    ]
+  "name": "Rosé Pine Dawn",
+  "type": "light",
+  "colors": {
+    "activityBar.activeBorder": "#575279",
+    "activityBar.background": "#faf4ed",
+    "activityBar.dropBorder": "#f2e9e1",
+    "activityBar.foreground": "#575279",
+    "activityBar.inactiveForeground": "#797593",
+    "activityBarBadge.background": "#d7827e",
+    "activityBarBadge.foreground": "#faf4ed",
+    "badge.background": "#d7827e",
+    "badge.foreground": "#faf4ed",
+    "banner.background": "#fffaf3",
+    "banner.foreground": "#575279",
+    "banner.iconForeground": "#797593",
+    "breadcrumb.activeSelectionForeground": "#d7827e",
+    "breadcrumb.background": "#faf4ed",
+    "breadcrumb.focusForeground": "#797593",
+    "breadcrumb.foreground": "#9893a5",
+    "breadcrumbPicker.background": "#fffaf3",
+    "button.background": "#d7827e",
+    "button.foreground": "#faf4ed",
+    "button.hoverBackground": "#d7827ee6",
+    "button.secondaryBackground": "#fffaf3",
+    "button.secondaryForeground": "#575279",
+    "button.secondaryHoverBackground": "#f2e9e1",
+    "charts.blue": "#56949f",
+    "charts.foreground": "#575279",
+    "charts.green": "#286983",
+    "charts.lines": "#797593",
+    "charts.orange": "#d7827e",
+    "charts.purple": "#907aa9",
+    "charts.red": "#b4637a",
+    "charts.yellow": "#ea9d34",
+    "checkbox.background": "#fffaf3",
+    "checkbox.border": "#6e6a8614",
+    "checkbox.foreground": "#575279",
+    "debugExceptionWidget.background": "#fffaf3",
+    "debugExceptionWidget.border": "#6e6a8614",
+    "debugIcon.breakpointCurrentStackframeForeground": "#797593",
+    "debugIcon.breakpointDisabledForeground": "#797593",
+    "debugIcon.breakpointForeground": "#797593",
+    "debugIcon.breakpointStackframeForeground": "#797593",
+    "debugIcon.breakpointUnverifiedForeground": "#797593",
+    "debugIcon.continueForeground": "#797593",
+    "debugIcon.disconnectForeground": "#797593",
+    "debugIcon.pauseForeground": "#797593",
+    "debugIcon.restartForeground": "#797593",
+    "debugIcon.startForeground": "#797593",
+    "debugIcon.stepBackForeground": "#797593",
+    "debugIcon.stepIntoForeground": "#797593",
+    "debugIcon.stepOutForeground": "#797593",
+    "debugIcon.stepOverForeground": "#797593",
+    "debugIcon.stopForeground": "#b4637a",
+    "debugToolBar.background": "#fffaf3",
+    "debugToolBar.border": "#f2e9e1",
+    "descriptionForeground": "#797593",
+    "diffEditor.border": "#f2e9e1",
+    "diffEditor.diagonalFill": "#6e6a8626",
+    "diffEditor.insertedLineBackground": "#56949f26",
+    "diffEditor.insertedTextBackground": "#56949f26",
+    "diffEditor.removedLineBackground": "#b4637a26",
+    "diffEditor.removedTextBackground": "#b4637a26",
+    "diffEditorOverview.insertedForeground": "#56949f80",
+    "diffEditorOverview.removedForeground": "#b4637a80",
+    "dropdown.background": "#fffaf3",
+    "dropdown.border": "#6e6a8614",
+    "dropdown.foreground": "#575279",
+    "dropdown.listBackground": "#fffaf3",
+    "editor.background": "#faf4ed",
+    "editor.findMatchBackground": "#6e6a8626",
+    "editor.findMatchHighlightBackground": "#6e6a8626",
+    "editor.findRangeHighlightBackground": "#6e6a8626",
+    "editor.findRangeHighlightBorder": "#0000",
+    "editor.focusedStackFrameHighlightBackground": "#6e6a8614",
+    "editor.foldBackground": "#fffaf3",
+    "editor.foreground": "#575279",
+    "editor.hoverHighlightBackground": "#0000",
+    "editor.inactiveSelectionBackground": "#6e6a860d",
+    "editor.inlineValuesBackground": "#0000",
+    "editor.inlineValuesForeground": "#797593",
+    "editor.lineHighlightBackground": "#6e6a860d",
+    "editor.lineHighlightBorder": "#0000",
+    "editor.linkedEditingBackground": "#fffaf3",
+    "editor.rangeHighlightBackground": "#6e6a860d",
+    "editor.selectionBackground": "#6e6a8614",
+    "editor.selectionForeground": "#575279",
+    "editor.selectionHighlightBackground": "#6e6a8614",
+    "editor.selectionHighlightBorder": "#faf4ed",
+    "editor.snippetFinalTabstopHighlightBackground": "#6e6a8614",
+    "editor.snippetFinalTabstopHighlightBorder": "#fffaf3",
+    "editor.snippetTabstopHighlightBackground": "#6e6a8614",
+    "editor.snippetTabstopHighlightBorder": "#fffaf3",
+    "editor.stackFrameHighlightBackground": "#6e6a8614",
+    "editor.symbolHighlightBackground": "#6e6a8614",
+    "editor.symbolHighlightBorder": "#0000",
+    "editor.wordHighlightBackground": "#6e6a8614",
+    "editor.wordHighlightBorder": "#0000",
+    "editor.wordHighlightStrongBackground": "#6e6a8614",
+    "editor.wordHighlightStrongBorder": "#6e6a8614",
+    "editorBracketHighlight.foreground1": "#b4637a80",
+    "editorBracketHighlight.foreground2": "#28698380",
+    "editorBracketHighlight.foreground3": "#ea9d3480",
+    "editorBracketHighlight.foreground4": "#56949f80",
+    "editorBracketHighlight.foreground5": "#d7827e80",
+    "editorBracketHighlight.foreground6": "#907aa980",
+    "editorBracketMatch.background": "#0000",
+    "editorBracketMatch.border": "#797593",
+    "editorBracketPairGuide.activeBackground1": "#286983",
+    "editorBracketPairGuide.activeBackground2": "#d7827e",
+    "editorBracketPairGuide.activeBackground3": "#907aa9",
+    "editorBracketPairGuide.activeBackground4": "#56949f",
+    "editorBracketPairGuide.activeBackground5": "#ea9d34",
+    "editorBracketPairGuide.activeBackground6": "#b4637a",
+    "editorBracketPairGuide.background1": "#28698380",
+    "editorBracketPairGuide.background2": "#d7827e80",
+    "editorBracketPairGuide.background3": "#907aa980",
+    "editorBracketPairGuide.background4": "#56949f80",
+    "editorBracketPairGuide.background5": "#ea9d3480",
+    "editorBracketPairGuide.background6": "#b4637a80",
+    "editorCodeLens.foreground": "#d7827e",
+    "editorCursor.background": "#575279",
+    "editorCursor.foreground": "#9893a5",
+    "editorError.border": "#0000",
+    "editorError.foreground": "#b4637a",
+    "editorGhostText.foreground": "#797593",
+    "editorGroup.border": "#0000",
+    "editorGroup.dropBackground": "#fffaf3",
+    "editorGroup.emptyBackground": "#0000",
+    "editorGroup.focusedEmptyBorder": "#0000",
+    "editorGroupHeader.noTabsBackground": "#0000",
+    "editorGroupHeader.tabsBackground": "#0000",
+    "editorGroupHeader.tabsBorder": "#0000",
+    "editorGutter.addedBackground": "#56949f",
+    "editorGutter.background": "#faf4ed",
+    "editorGutter.commentRangeForeground": "#797593",
+    "editorGutter.deletedBackground": "#b4637a",
+    "editorGutter.foldingControlForeground": "#907aa9",
+    "editorGutter.modifiedBackground": "#d7827e",
+    "editorHint.border": "#0000",
+    "editorHint.foreground": "#797593",
+    "editorHoverWidget.background": "#fffaf3",
+    "editorHoverWidget.border": "#9893a580",
+    "editorHoverWidget.foreground": "#797593",
+    "editorHoverWidget.highlightForeground": "#575279",
+    "editorHoverWidget.statusBarBackground": "#0000",
+    "editorIndentGuide.activeBackground": "#9893a5",
+    "editorIndentGuide.background": "#6e6a8626",
+    "editorInfo.border": "#f2e9e1",
+    "editorInfo.foreground": "#56949f",
+    "editorInlayHint.background": "#f2e9e1",
+    "editorInlayHint.foreground": "#797593",
+    "editorInlayHint.parameterBackground": "#f2e9e1",
+    "editorInlayHint.parameterForeground": "#907aa9",
+    "editorInlayHint.typeBackground": "#f2e9e1",
+    "editorInlayHint.typeForeground": "#56949f",
+    "editorLightBulb.foreground": "#286983",
+    "editorLightBulbAutoFix.foreground": "#d7827e",
+    "editorLineNumber.activeForeground": "#575279",
+    "editorLineNumber.foreground": "#797593",
+    "editorLink.activeForeground": "#d7827e",
+    "editorMarkerNavigation.background": "#fffaf3",
+    "editorMarkerNavigationError.background": "#fffaf3",
+    "editorMarkerNavigationInfo.background": "#fffaf3",
+    "editorMarkerNavigationWarning.background": "#fffaf3",
+    "editorOverviewRuler.addedForeground": "#56949f80",
+    "editorOverviewRuler.background": "#faf4ed",
+    "editorOverviewRuler.border": "#6e6a8626",
+    "editorOverviewRuler.bracketMatchForeground": "#797593",
+    "editorOverviewRuler.commonContentForeground": "#6e6a860d",
+    "editorOverviewRuler.currentContentForeground": "#6e6a8614",
+    "editorOverviewRuler.deletedForeground": "#b4637a80",
+    "editorOverviewRuler.errorForeground": "#b4637a80",
+    "editorOverviewRuler.findMatchForeground": "#6e6a8626",
+    "editorOverviewRuler.incomingContentForeground": "#907aa980",
+    "editorOverviewRuler.infoForeground": "#56949f80",
+    "editorOverviewRuler.modifiedForeground": "#d7827e80",
+    "editorOverviewRuler.rangeHighlightForeground": "#6e6a8626",
+    "editorOverviewRuler.selectionHighlightForeground": "#6e6a8626",
+    "editorOverviewRuler.warningForeground": "#ea9d3480",
+    "editorOverviewRuler.wordHighlightForeground": "#6e6a8614",
+    "editorOverviewRuler.wordHighlightStrongForeground": "#6e6a8626",
+    "editorPane.background": "#0000",
+    "editorRuler.foreground": "#6e6a8626",
+    "editorSuggestWidget.background": "#fffaf3",
+    "editorSuggestWidget.border": "#0000",
+    "editorSuggestWidget.focusHighlightForeground": "#d7827e",
+    "editorSuggestWidget.foreground": "#797593",
+    "editorSuggestWidget.highlightForeground": "#d7827e",
+    "editorSuggestWidget.selectedBackground": "#6e6a8614",
+    "editorSuggestWidget.selectedForeground": "#575279",
+    "editorSuggestWidget.selectedIconForeground": "#575279",
+    "editorUnnecessaryCode.border": "#0000",
+    "editorUnnecessaryCode.opacity": "#57527980",
+    "editorWarning.border": "#0000",
+    "editorWarning.foreground": "#ea9d34",
+    "editorWhitespace.foreground": "#9893a5",
+    "editorWidget.background": "#fffaf3",
+    "editorWidget.border": "#f2e9e1",
+    "editorWidget.foreground": "#797593",
+    "editorWidget.resizeBorder": "#9893a5",
+    "errorForeground": "#b4637a",
+    "extensionBadge.remoteBackground": "#907aa9",
+    "extensionBadge.remoteForeground": "#faf4ed",
+    "extensionButton.prominentBackground": "#d7827e",
+    "extensionButton.prominentForeground": "#faf4ed",
+    "extensionButton.prominentHoverBackground": "#d7827ee6",
+    "extensionIcon.preReleaseForeground": "#286983",
+    "extensionIcon.starForeground": "#d7827e",
+    "extensionIcon.verifiedForeground": "#907aa9",
+    "focusBorder": "#6e6a8614",
+    "foreground": "#575279",
+    "gitDecoration.addedResourceForeground": "#56949f",
+    "gitDecoration.conflictingResourceForeground": "#b4637a",
+    "gitDecoration.deletedResourceForeground": "#797593",
+    "gitDecoration.ignoredResourceForeground": "#9893a5",
+    "gitDecoration.modifiedResourceForeground": "#d7827e",
+    "gitDecoration.renamedResourceForeground": "#286983",
+    "gitDecoration.stageDeletedResourceForeground": "#b4637a",
+    "gitDecoration.stageModifiedResourceForeground": "#907aa9",
+    "gitDecoration.submoduleResourceForeground": "#ea9d34",
+    "gitDecoration.untrackedResourceForeground": "#ea9d34",
+    "icon.foreground": "#797593",
+    "input.background": "#f2e9e180",
+    "input.border": "#6e6a8614",
+    "input.foreground": "#575279",
+    "input.placeholderForeground": "#797593",
+    "inputOption.activeBackground": "#d7827e26",
+    "inputOption.activeForeground": "#d7827e",
+    "inputValidation.errorBackground": "#fffaf3",
+    "inputValidation.errorBorder": "#6e6a8626",
+    "inputValidation.errorForeground": "#b4637a",
+    "inputValidation.infoBackground": "#fffaf3",
+    "inputValidation.infoBorder": "#6e6a8626",
+    "inputValidation.infoForeground": "#56949f",
+    "inputValidation.warningBackground": "#fffaf3",
+    "inputValidation.warningBorder": "#6e6a8626",
+    "inputValidation.warningForeground": "#56949f80",
+    "keybindingLabel.background": "#f2e9e1",
+    "keybindingLabel.border": "#6e6a8626",
+    "keybindingLabel.bottomBorder": "#6e6a8626",
+    "keybindingLabel.foreground": "#907aa9",
+    "keybindingTable.headerBackground": "#f2e9e1",
+    "keybindingTable.rowsBackground": "#fffaf3",
+    "list.activeSelectionBackground": "#6e6a8614",
+    "list.activeSelectionForeground": "#575279",
+    "list.deemphasizedForeground": "#797593",
+    "list.dropBackground": "#fffaf3",
+    "list.errorForeground": "#b4637a",
+    "list.filterMatchBackground": "#fffaf3",
+    "list.filterMatchBorder": "#d7827e",
+    "list.focusBackground": "#6e6a8626",
+    "list.focusForeground": "#575279",
+    "list.focusOutline": "#6e6a8614",
+    "list.highlightForeground": "#d7827e",
+    "list.hoverBackground": "#6e6a860d",
+    "list.hoverForeground": "#575279",
+    "list.inactiveFocusBackground": "#6e6a860d",
+    "list.inactiveSelectionBackground": "#fffaf3",
+    "list.inactiveSelectionForeground": "#575279",
+    "list.invalidItemForeground": "#b4637a",
+    "list.warningForeground": "#ea9d34",
+    "listFilterWidget.background": "#fffaf3",
+    "listFilterWidget.noMatchesOutline": "#b4637a",
+    "listFilterWidget.outline": "#f2e9e1",
+    "menu.background": "#fffaf3",
+    "menu.border": "#6e6a860d",
+    "menu.foreground": "#575279",
+    "menu.selectionBackground": "#6e6a8614",
+    "menu.selectionBorder": "#f2e9e1",
+    "menu.selectionForeground": "#575279",
+    "menu.separatorBackground": "#6e6a8626",
+    "menubar.selectionBackground": "#6e6a8614",
+    "menubar.selectionBorder": "#6e6a860d",
+    "menubar.selectionForeground": "#575279",
+    "merge.border": "#f2e9e1",
+    "merge.commonContentBackground": "#6e6a8614",
+    "merge.commonHeaderBackground": "#6e6a8614",
+    "merge.currentContentBackground": "#ea9d3480",
+    "merge.currentHeaderBackground": "#ea9d3480",
+    "merge.incomingContentBackground": "#56949f80",
+    "merge.incomingHeaderBackground": "#56949f80",
+    "minimap.background": "#fffaf3",
+    "minimap.errorHighlight": "#b4637a80",
+    "minimap.findMatchHighlight": "#6e6a8614",
+    "minimap.selectionHighlight": "#6e6a8614",
+    "minimap.warningHighlight": "#ea9d3480",
+    "minimapGutter.addedBackground": "#56949f",
+    "minimapGutter.deletedBackground": "#b4637a",
+    "minimapGutter.modifiedBackground": "#d7827e",
+    "minimapSlider.activeBackground": "#6e6a8626",
+    "minimapSlider.background": "#6e6a8614",
+    "minimapSlider.hoverBackground": "#6e6a8614",
+    "notebook.cellBorderColor": "#56949f80",
+    "notebook.cellEditorBackground": "#fffaf3",
+    "notebook.cellHoverBackground": "#f2e9e180",
+    "notebook.focusedCellBackground": "#6e6a860d",
+    "notebook.focusedCellBorder": "#56949f",
+    "notebook.outputContainerBackgroundColor": "#6e6a860d",
+    "notificationCenter.border": "#6e6a8614",
+    "notificationCenterHeader.background": "#fffaf3",
+    "notificationCenterHeader.foreground": "#797593",
+    "notificationLink.foreground": "#907aa9",
+    "notifications.background": "#fffaf3",
+    "notifications.border": "#6e6a8614",
+    "notifications.foreground": "#575279",
+    "notificationsErrorIcon.foreground": "#b4637a",
+    "notificationsInfoIcon.foreground": "#56949f",
+    "notificationsWarningIcon.foreground": "#ea9d34",
+    "notificationToast.border": "#6e6a8614",
+    "panel.background": "#fffaf3",
+    "panel.border": "#0000",
+    "panel.dropBorder": "#f2e9e1",
+    "panelInput.border": "#fffaf3",
+    "panelSection.dropBackground": "#6e6a8614",
+    "panelSectionHeader.background": "#fffaf3",
+    "panelSectionHeader.foreground": "#575279",
+    "panelTitle.activeBorder": "#6e6a8626",
+    "panelTitle.activeForeground": "#575279",
+    "panelTitle.inactiveForeground": "#797593",
+    "peekView.border": "#f2e9e1",
+    "peekViewEditor.background": "#fffaf3",
+    "peekViewEditor.matchHighlightBackground": "#6e6a8626",
+    "peekViewResult.background": "#fffaf3",
+    "peekViewResult.fileForeground": "#797593",
+    "peekViewResult.lineForeground": "#797593",
+    "peekViewResult.matchHighlightBackground": "#6e6a8626",
+    "peekViewResult.selectionBackground": "#6e6a8614",
+    "peekViewResult.selectionForeground": "#575279",
+    "peekViewTitle.background": "#f2e9e1",
+    "peekViewTitleDescription.foreground": "#797593",
+    "pickerGroup.border": "#6e6a8626",
+    "pickerGroup.foreground": "#907aa9",
+    "ports.iconRunningProcessForeground": "#d7827e",
+    "problemsErrorIcon.foreground": "#b4637a",
+    "problemsInfoIcon.foreground": "#56949f",
+    "problemsWarningIcon.foreground": "#ea9d34",
+    "progressBar.background": "#d7827e",
+    "quickInput.background": "#fffaf3",
+    "quickInput.foreground": "#797593",
+    "quickInputList.focusBackground": "#6e6a8614",
+    "quickInputList.focusForeground": "#575279",
+    "quickInputList.focusIconForeground": "#575279",
+    "scrollbar.shadow": "#fffaf34d",
+    "scrollbarSlider.activeBackground": "#28698380",
+    "scrollbarSlider.background": "#6e6a8614",
+    "scrollbarSlider.hoverBackground": "#6e6a8626",
+    "searchEditor.findMatchBackground": "#6e6a8614",
+    "selection.background": "#6e6a8626",
+    "settings.focusedRowBackground": "#fffaf3",
+    "settings.headerForeground": "#575279",
+    "settings.modifiedItemIndicator": "#d7827e",
+    "settings.focusedRowBorder": "#6e6a8614",
+    "settings.rowHoverBackground": "#fffaf3",
+    "sideBar.background": "#faf4ed",
+    "sideBar.dropBackground": "#fffaf3",
+    "sideBar.foreground": "#797593",
+    "sideBarSectionHeader.background": "#0000",
+    "sideBarSectionHeader.border": "#6e6a8614",
+    "statusBar.background": "#faf4ed",
+    "statusBar.debuggingBackground": "#907aa9",
+    "statusBar.debuggingForeground": "#faf4ed",
+    "statusBar.foreground": "#797593",
+    "statusBar.noFolderBackground": "#faf4ed",
+    "statusBar.noFolderForeground": "#797593",
+    "statusBarItem.activeBackground": "#6e6a8626",
+    "statusBarItem.hoverBackground": "#6e6a8614",
+    "statusBarItem.prominentBackground": "#f2e9e1",
+    "statusBarItem.prominentForeground": "#575279",
+    "statusBarItem.prominentHoverBackground": "#6e6a8614",
+    "statusBarItem.remoteBackground": "#faf4ed",
+    "statusBarItem.remoteForeground": "#ea9d34",
+    "statusBarItem.errorBackground": "#faf4ed",
+    "statusBarItem.errorForeground": "#b4637a",
+    "symbolIcon.arrayForeground": "#797593",
+    "symbolIcon.classForeground": "#797593",
+    "symbolIcon.colorForeground": "#797593",
+    "symbolIcon.constantForeground": "#797593",
+    "symbolIcon.constructorForeground": "#797593",
+    "symbolIcon.enumeratorForeground": "#797593",
+    "symbolIcon.enumeratorMemberForeground": "#797593",
+    "symbolIcon.eventForeground": "#797593",
+    "symbolIcon.fieldForeground": "#797593",
+    "symbolIcon.fileForeground": "#797593",
+    "symbolIcon.folderForeground": "#797593",
+    "symbolIcon.functionForeground": "#797593",
+    "symbolIcon.interfaceForeground": "#797593",
+    "symbolIcon.keyForeground": "#797593",
+    "symbolIcon.keywordForeground": "#797593",
+    "symbolIcon.methodForeground": "#797593",
+    "symbolIcon.moduleForeground": "#797593",
+    "symbolIcon.namespaceForeground": "#797593",
+    "symbolIcon.nullForeground": "#797593",
+    "symbolIcon.numberForeground": "#797593",
+    "symbolIcon.objectForeground": "#797593",
+    "symbolIcon.operatorForeground": "#797593",
+    "symbolIcon.packageForeground": "#797593",
+    "symbolIcon.propertyForeground": "#797593",
+    "symbolIcon.referenceForeground": "#797593",
+    "symbolIcon.snippetForeground": "#797593",
+    "symbolIcon.stringForeground": "#797593",
+    "symbolIcon.structForeground": "#797593",
+    "symbolIcon.textForeground": "#797593",
+    "symbolIcon.typeParameterForeground": "#797593",
+    "symbolIcon.unitForeground": "#797593",
+    "symbolIcon.variableForeground": "#797593",
+    "tab.activeBackground": "#6e6a860d",
+    "tab.activeForeground": "#575279",
+    "tab.activeModifiedBorder": "#56949f",
+    "tab.border": "#0000",
+    "tab.hoverBackground": "#6e6a8614",
+    "tab.inactiveBackground": "#0000",
+    "tab.inactiveForeground": "#797593",
+    "tab.inactiveModifiedBorder": "#56949f80",
+    "tab.lastPinnedBorder": "#9893a5",
+    "tab.unfocusedActiveBackground": "#0000",
+    "tab.unfocusedHoverBackground": "#0000",
+    "tab.unfocusedInactiveBackground": "#0000",
+    "tab.unfocusedInactiveModifiedBorder": "#56949f80",
+    "terminal.ansiBlack": "#f2e9e1",
+    "terminal.ansiBlue": "#56949f",
+    "terminal.ansiBrightBlack": "#797593",
+    "terminal.ansiBrightBlue": "#56949f",
+    "terminal.ansiBrightCyan": "#d7827e",
+    "terminal.ansiBrightGreen": "#286983",
+    "terminal.ansiBrightMagenta": "#907aa9",
+    "terminal.ansiBrightRed": "#b4637a",
+    "terminal.ansiBrightWhite": "#575279",
+    "terminal.ansiBrightYellow": "#ea9d34",
+    "terminal.ansiCyan": "#d7827e",
+    "terminal.ansiGreen": "#286983",
+    "terminal.ansiMagenta": "#907aa9",
+    "terminal.ansiRed": "#b4637a",
+    "terminal.ansiWhite": "#575279",
+    "terminal.ansiYellow": "#ea9d34",
+    "terminal.dropBackground": "#6e6a8614",
+    "terminal.foreground": "#575279",
+    "terminal.selectionBackground": "#6e6a8614",
+    "terminal.tab.activeBorder": "#575279",
+    "terminalCursor.background": "#575279",
+    "terminalCursor.foreground": "#9893a5",
+    "textBlockQuote.background": "#fffaf3",
+    "textBlockQuote.border": "#6e6a8614",
+    "textCodeBlock.background": "#fffaf3",
+    "textLink.activeForeground": "#907aa9e6",
+    "textLink.foreground": "#907aa9",
+    "textPreformat.foreground": "#ea9d34",
+    "textSeparator.foreground": "#797593",
+    "titleBar.activeBackground": "#faf4ed",
+    "titleBar.activeForeground": "#797593",
+    "titleBar.inactiveBackground": "#fffaf3",
+    "titleBar.inactiveForeground": "#797593",
+    "toolbar.activeBackground": "#6e6a8626",
+    "toolbar.hoverBackground": "#6e6a8614",
+    "tree.indentGuidesStroke": "#797593",
+    "walkThrough.embeddedEditorBackground": "#faf4ed",
+    "welcomePage.background": "#faf4ed",
+    "welcomePage.buttonBackground": "#fffaf3",
+    "welcomePage.buttonHoverBackground": "#f2e9e1",
+    "widget.shadow": "#fffaf34d",
+    "window.activeBorder": "#fffaf3",
+    "window.inactiveBorder": "#fffaf3"
+  },
+  "tokenColors": [
+    {
+      "scope": ["comment"],
+      "settings": {
+        "foreground": "#9893a5",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": ["constant"],
+      "settings": {
+        "foreground": "#286983"
+      }
+    },
+    {
+      "scope": ["constant.numeric", "constant.language"],
+      "settings": {
+        "foreground": "#d7827e"
+      }
+    },
+    {
+      "scope": ["entity.name"],
+      "settings": {
+        "foreground": "#d7827e"
+      }
+    },
+    {
+      "scope": [
+        "entity.name.section",
+        "entity.name.tag",
+        "entity.name.namespace",
+        "entity.name.type"
+      ],
+      "settings": {
+        "foreground": "#56949f"
+      }
+    },
+    {
+      "scope": ["entity.other.attribute-name", "entity.other.inherited-class"],
+      "settings": {
+        "foreground": "#907aa9",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": ["invalid"],
+      "settings": {
+        "foreground": "#b4637a"
+      }
+    },
+    {
+      "scope": ["invalid.deprecated"],
+      "settings": {
+        "foreground": "#797593"
+      }
+    },
+    {
+      "scope": ["keyword"],
+      "settings": {
+        "foreground": "#286983"
+      }
+    },
+    {
+      "scope": ["markup.inserted.diff"],
+      "settings": {
+        "foreground": "#56949f"
+      }
+    },
+    {
+      "scope": ["markup.deleted.diff"],
+      "settings": {
+        "foreground": "#b4637a"
+      }
+    },
+    {
+      "scope": "markup.heading",
+      "settings": {
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "scope": "markup.bold.markdown",
+      "settings": {
+        "fontStyle": "bold"
+      }
+    },
+    {
+      "scope": "markup.italic.markdown",
+      "settings": {
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": ["meta.diff.range"],
+      "settings": {
+        "foreground": "#907aa9"
+      }
+    },
+    {
+      "scope": ["meta.tag", "meta.brace"],
+      "settings": {
+        "foreground": "#575279"
+      }
+    },
+    {
+      "scope": ["meta.import", "meta.export"],
+      "settings": {
+        "foreground": "#286983"
+      }
+    },
+    {
+      "scope": "meta.directive.vue",
+      "settings": {
+        "foreground": "#907aa9",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": "meta.property-name.css",
+      "settings": {
+        "foreground": "#56949f"
+      }
+    },
+    {
+      "scope": "meta.property-value.css",
+      "settings": {
+        "foreground": "#ea9d34"
+      }
+    },
+    {
+      "scope": "meta.tag.other.html",
+      "settings": {
+        "foreground": "#797593"
+      }
+    },
+    {
+      "scope": ["punctuation"],
+      "settings": {
+        "foreground": "#797593"
+      }
+    },
+    {
+      "scope": ["punctuation.accessor"],
+      "settings": {
+        "foreground": "#286983"
+      }
+    },
+    {
+      "scope": ["punctuation.definition.string"],
+      "settings": {
+        "foreground": "#ea9d34"
+      }
+    },
+    {
+      "scope": ["punctuation.definition.tag"],
+      "settings": {
+        "foreground": "#9893a5"
+      }
+    },
+    {
+      "scope": ["storage.type", "storage.modifier"],
+      "settings": {
+        "foreground": "#286983"
+      }
+    },
+    {
+      "scope": ["string"],
+      "settings": {
+        "foreground": "#ea9d34"
+      }
+    },
+    {
+      "scope": ["support"],
+      "settings": {
+        "foreground": "#56949f"
+      }
+    },
+    {
+      "scope": ["support.constant"],
+      "settings": {
+        "foreground": "#ea9d34"
+      }
+    },
+    {
+      "scope": ["support.function"],
+      "settings": {
+        "foreground": "#b4637a",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": ["variable"],
+      "settings": {
+        "foreground": "#d7827e",
+        "fontStyle": "italic"
+      }
+    },
+    {
+      "scope": [
+        "variable.other",
+        "variable.language",
+        "variable.function",
+        "variable.argument"
+      ],
+      "settings": {
+        "foreground": "#575279"
+      }
+    },
+    {
+      "scope": ["variable.parameter"],
+      "settings": {
+        "foreground": "#907aa9"
+      }
+    }
+  ]
 }

assets/themes/src/vscode/rose-pine/rose-pine-moon.json 🔗

@@ -1,680 +1,680 @@
 {
-    "name": "Rosé Pine Moon",
-    "type": "dark",
-    "colors": {
-        "activityBar.activeBorder": "#e0def4",
-        "activityBar.background": "#232136",
-        "activityBar.dropBorder": "#393552",
-        "activityBar.foreground": "#e0def4",
-        "activityBar.inactiveForeground": "#908caa",
-        "activityBarBadge.background": "#ea9a97",
-        "activityBarBadge.foreground": "#232136",
-        "badge.background": "#ea9a97",
-        "badge.foreground": "#232136",
-        "banner.background": "#2a273f",
-        "banner.foreground": "#e0def4",
-        "banner.iconForeground": "#908caa",
-        "breadcrumb.activeSelectionForeground": "#ea9a97",
-        "breadcrumb.background": "#232136",
-        "breadcrumb.focusForeground": "#908caa",
-        "breadcrumb.foreground": "#6e6a86",
-        "breadcrumbPicker.background": "#2a273f",
-        "button.background": "#ea9a97",
-        "button.foreground": "#232136",
-        "button.hoverBackground": "#ea9a97e6",
-        "button.secondaryBackground": "#2a273f",
-        "button.secondaryForeground": "#e0def4",
-        "button.secondaryHoverBackground": "#393552",
-        "charts.blue": "#9ccfd8",
-        "charts.foreground": "#e0def4",
-        "charts.green": "#3e8fb0",
-        "charts.lines": "#908caa",
-        "charts.orange": "#ea9a97",
-        "charts.purple": "#c4a7e7",
-        "charts.red": "#eb6f92",
-        "charts.yellow": "#f6c177",
-        "checkbox.background": "#2a273f",
-        "checkbox.border": "#817c9c26",
-        "checkbox.foreground": "#e0def4",
-        "debugExceptionWidget.background": "#2a273f",
-        "debugExceptionWidget.border": "#817c9c26",
-        "debugIcon.breakpointCurrentStackframeForeground": "#908caa",
-        "debugIcon.breakpointDisabledForeground": "#908caa",
-        "debugIcon.breakpointForeground": "#908caa",
-        "debugIcon.breakpointStackframeForeground": "#908caa",
-        "debugIcon.breakpointUnverifiedForeground": "#908caa",
-        "debugIcon.continueForeground": "#908caa",
-        "debugIcon.disconnectForeground": "#908caa",
-        "debugIcon.pauseForeground": "#908caa",
-        "debugIcon.restartForeground": "#908caa",
-        "debugIcon.startForeground": "#908caa",
-        "debugIcon.stepBackForeground": "#908caa",
-        "debugIcon.stepIntoForeground": "#908caa",
-        "debugIcon.stepOutForeground": "#908caa",
-        "debugIcon.stepOverForeground": "#908caa",
-        "debugIcon.stopForeground": "#eb6f92",
-        "debugToolBar.background": "#2a273f",
-        "debugToolBar.border": "#393552",
-        "descriptionForeground": "#908caa",
-        "diffEditor.border": "#393552",
-        "diffEditor.diagonalFill": "#817c9c4d",
-        "diffEditor.insertedLineBackground": "#9ccfd826",
-        "diffEditor.insertedTextBackground": "#9ccfd826",
-        "diffEditor.removedLineBackground": "#eb6f9226",
-        "diffEditor.removedTextBackground": "#eb6f9226",
-        "diffEditorOverview.insertedForeground": "#9ccfd880",
-        "diffEditorOverview.removedForeground": "#eb6f9280",
-        "dropdown.background": "#2a273f",
-        "dropdown.border": "#817c9c26",
-        "dropdown.foreground": "#e0def4",
-        "dropdown.listBackground": "#2a273f",
-        "editor.background": "#232136",
-        "editor.findMatchBackground": "#817c9c4d",
-        "editor.findMatchHighlightBackground": "#817c9c4d",
-        "editor.findRangeHighlightBackground": "#817c9c4d",
-        "editor.findRangeHighlightBorder": "#000000",
-        "editor.focusedStackFrameHighlightBackground": "#817c9c26",
-        "editor.foldBackground": "#2a273f",
-        "editor.foreground": "#e0def4",
-        "editor.hoverHighlightBackground": "#000000",
-        "editor.inactiveSelectionBackground": "#817c9c14",
-        "editor.inlineValuesBackground": "#000000",
-        "editor.inlineValuesForeground": "#908caa",
-        "editor.lineHighlightBackground": "#817c9c14",
-        "editor.lineHighlightBorder": "#000000",
-        "editor.linkedEditingBackground": "#2a273f",
-        "editor.rangeHighlightBackground": "#817c9c14",
-        "editor.selectionBackground": "#817c9c26",
-        "editor.selectionForeground": "#e0def4",
-        "editor.selectionHighlightBackground": "#817c9c26",
-        "editor.selectionHighlightBorder": "#232136",
-        "editor.snippetFinalTabstopHighlightBackground": "#817c9c26",
-        "editor.snippetFinalTabstopHighlightBorder": "#2a273f",
-        "editor.snippetTabstopHighlightBackground": "#817c9c26",
-        "editor.snippetTabstopHighlightBorder": "#2a273f",
-        "editor.stackFrameHighlightBackground": "#817c9c26",
-        "editor.symbolHighlightBackground": "#817c9c26",
-        "editor.symbolHighlightBorder": "#000000",
-        "editor.wordHighlightBackground": "#817c9c26",
-        "editor.wordHighlightBorder": "#000000",
-        "editor.wordHighlightStrongBackground": "#817c9c26",
-        "editor.wordHighlightStrongBorder": "#817c9c26",
-        "editorBracketHighlight.foreground1": "#eb6f9280",
-        "editorBracketHighlight.foreground2": "#3e8fb080",
-        "editorBracketHighlight.foreground3": "#f6c17780",
-        "editorBracketHighlight.foreground4": "#9ccfd880",
-        "editorBracketHighlight.foreground5": "#ea9a9780",
-        "editorBracketHighlight.foreground6": "#c4a7e780",
-        "editorBracketMatch.background": "#000000",
-        "editorBracketMatch.border": "#908caa",
-        "editorBracketPairGuide.activeBackground1": "#3e8fb0",
-        "editorBracketPairGuide.activeBackground2": "#ea9a97",
-        "editorBracketPairGuide.activeBackground3": "#c4a7e7",
-        "editorBracketPairGuide.activeBackground4": "#9ccfd8",
-        "editorBracketPairGuide.activeBackground5": "#f6c177",
-        "editorBracketPairGuide.activeBackground6": "#eb6f92",
-        "editorBracketPairGuide.background1": "#3e8fb080",
-        "editorBracketPairGuide.background2": "#ea9a9780",
-        "editorBracketPairGuide.background3": "#c4a7e780",
-        "editorBracketPairGuide.background4": "#9ccfd880",
-        "editorBracketPairGuide.background5": "#f6c17780",
-        "editorBracketPairGuide.background6": "#eb6f9280",
-        "editorCodeLens.foreground": "#ea9a97",
-        "editorCursor.background": "#e0def4",
-        "editorCursor.foreground": "#6e6a86",
-        "editorError.border": "#000000",
-        "editorError.foreground": "#eb6f92",
-        "editorGhostText.foreground": "#908caa",
-        "editorGroup.border": "#000000",
-        "editorGroup.dropBackground": "#2a273f",
-        "editorGroup.emptyBackground": "#000000",
-        "editorGroup.focusedEmptyBorder": "#000000",
-        "editorGroupHeader.noTabsBackground": "#000000",
-        "editorGroupHeader.tabsBackground": "#000000",
-        "editorGroupHeader.tabsBorder": "#000000",
-        "editorGutter.addedBackground": "#9ccfd8",
-        "editorGutter.background": "#232136",
-        "editorGutter.commentRangeForeground": "#908caa",
-        "editorGutter.deletedBackground": "#eb6f92",
-        "editorGutter.foldingControlForeground": "#c4a7e7",
-        "editorGutter.modifiedBackground": "#ea9a97",
-        "editorHint.border": "#000000",
-        "editorHint.foreground": "#908caa",
-        "editorHoverWidget.background": "#2a273f",
-        "editorHoverWidget.border": "#6e6a8680",
-        "editorHoverWidget.foreground": "#908caa",
-        "editorHoverWidget.highlightForeground": "#e0def4",
-        "editorHoverWidget.statusBarBackground": "#000000",
-        "editorIndentGuide.activeBackground": "#6e6a86",
-        "editorIndentGuide.background": "#817c9c4d",
-        "editorInfo.border": "#393552",
-        "editorInfo.foreground": "#9ccfd8",
-        "editorInlayHint.background": "#393552",
-        "editorInlayHint.foreground": "#908caa",
-        "editorInlayHint.parameterBackground": "#393552",
-        "editorInlayHint.parameterForeground": "#c4a7e7",
-        "editorInlayHint.typeBackground": "#393552",
-        "editorInlayHint.typeForeground": "#9ccfd8",
-        "editorLightBulb.foreground": "#3e8fb0",
-        "editorLightBulbAutoFix.foreground": "#ea9a97",
-        "editorLineNumber.activeForeground": "#e0def4",
-        "editorLineNumber.foreground": "#908caa",
-        "editorLink.activeForeground": "#ea9a97",
-        "editorMarkerNavigation.background": "#2a273f",
-        "editorMarkerNavigationError.background": "#2a273f",
-        "editorMarkerNavigationInfo.background": "#2a273f",
-        "editorMarkerNavigationWarning.background": "#2a273f",
-        "editorOverviewRuler.addedForeground": "#9ccfd880",
-        "editorOverviewRuler.background": "#232136",
-        "editorOverviewRuler.border": "#817c9c4d",
-        "editorOverviewRuler.bracketMatchForeground": "#908caa",
-        "editorOverviewRuler.commonContentForeground": "#817c9c14",
-        "editorOverviewRuler.currentContentForeground": "#817c9c26",
-        "editorOverviewRuler.deletedForeground": "#eb6f9280",
-        "editorOverviewRuler.errorForeground": "#eb6f9280",
-        "editorOverviewRuler.findMatchForeground": "#817c9c4d",
-        "editorOverviewRuler.incomingContentForeground": "#c4a7e780",
-        "editorOverviewRuler.infoForeground": "#9ccfd880",
-        "editorOverviewRuler.modifiedForeground": "#ea9a9780",
-        "editorOverviewRuler.rangeHighlightForeground": "#817c9c4d",
-        "editorOverviewRuler.selectionHighlightForeground": "#817c9c4d",
-        "editorOverviewRuler.warningForeground": "#f6c17780",
-        "editorOverviewRuler.wordHighlightForeground": "#817c9c26",
-        "editorOverviewRuler.wordHighlightStrongForeground": "#817c9c4d",
-        "editorPane.background": "#000000",
-        "editorRuler.foreground": "#817c9c4d",
-        "editorSuggestWidget.background": "#2a273f",
-        "editorSuggestWidget.border": "#000000",
-        "editorSuggestWidget.focusHighlightForeground": "#ea9a97",
-        "editorSuggestWidget.foreground": "#908caa",
-        "editorSuggestWidget.highlightForeground": "#ea9a97",
-        "editorSuggestWidget.selectedBackground": "#817c9c26",
-        "editorSuggestWidget.selectedForeground": "#e0def4",
-        "editorSuggestWidget.selectedIconForeground": "#e0def4",
-        "editorUnnecessaryCode.border": "#000000",
-        "editorUnnecessaryCode.opacity": "#e0def480",
-        "editorWarning.border": "#000000",
-        "editorWarning.foreground": "#f6c177",
-        "editorWhitespace.foreground": "#6e6a86",
-        "editorWidget.background": "#2a273f",
-        "editorWidget.border": "#393552",
-        "editorWidget.foreground": "#908caa",
-        "editorWidget.resizeBorder": "#6e6a86",
-        "errorForeground": "#eb6f92",
-        "extensionBadge.remoteBackground": "#c4a7e7",
-        "extensionBadge.remoteForeground": "#232136",
-        "extensionButton.prominentBackground": "#ea9a97",
-        "extensionButton.prominentForeground": "#232136",
-        "extensionButton.prominentHoverBackground": "#ea9a97e6",
-        "extensionIcon.preReleaseForeground": "#3e8fb0",
-        "extensionIcon.starForeground": "#ea9a97",
-        "extensionIcon.verifiedForeground": "#c4a7e7",
-        "focusBorder": "#817c9c26",
-        "foreground": "#e0def4",
-        "gitDecoration.addedResourceForeground": "#9ccfd8",
-        "gitDecoration.conflictingResourceForeground": "#eb6f92",
-        "gitDecoration.deletedResourceForeground": "#908caa",
-        "gitDecoration.ignoredResourceForeground": "#6e6a86",
-        "gitDecoration.modifiedResourceForeground": "#ea9a97",
-        "gitDecoration.renamedResourceForeground": "#3e8fb0",
-        "gitDecoration.stageDeletedResourceForeground": "#eb6f92",
-        "gitDecoration.stageModifiedResourceForeground": "#c4a7e7",
-        "gitDecoration.submoduleResourceForeground": "#f6c177",
-        "gitDecoration.untrackedResourceForeground": "#f6c177",
-        "icon.foreground": "#908caa",
-        "input.background": "#39355280",
-        "input.border": "#817c9c26",
-        "input.foreground": "#e0def4",
-        "input.placeholderForeground": "#908caa",
-        "inputOption.activeBackground": "#ea9a9726",
-        "inputOption.activeForeground": "#ea9a97",
-        "inputValidation.errorBackground": "#2a273f",
-        "inputValidation.errorBorder": "#817c9c4d",
-        "inputValidation.errorForeground": "#eb6f92",
-        "inputValidation.infoBackground": "#2a273f",
-        "inputValidation.infoBorder": "#817c9c4d",
-        "inputValidation.infoForeground": "#9ccfd8",
-        "inputValidation.warningBackground": "#2a273f",
-        "inputValidation.warningBorder": "#817c9c4d",
-        "inputValidation.warningForeground": "#9ccfd880",
-        "keybindingLabel.background": "#393552",
-        "keybindingLabel.border": "#817c9c4d",
-        "keybindingLabel.bottomBorder": "#817c9c4d",
-        "keybindingLabel.foreground": "#c4a7e7",
-        "keybindingTable.headerBackground": "#393552",
-        "keybindingTable.rowsBackground": "#2a273f",
-        "list.activeSelectionBackground": "#817c9c26",
-        "list.activeSelectionForeground": "#e0def4",
-        "list.deemphasizedForeground": "#908caa",
-        "list.dropBackground": "#2a273f",
-        "list.errorForeground": "#eb6f92",
-        "list.filterMatchBackground": "#2a273f",
-        "list.filterMatchBorder": "#ea9a97",
-        "list.focusBackground": "#817c9c4d",
-        "list.focusForeground": "#e0def4",
-        "list.focusOutline": "#817c9c26",
-        "list.highlightForeground": "#ea9a97",
-        "list.hoverBackground": "#817c9c14",
-        "list.hoverForeground": "#e0def4",
-        "list.inactiveFocusBackground": "#817c9c14",
-        "list.inactiveSelectionBackground": "#2a273f",
-        "list.inactiveSelectionForeground": "#e0def4",
-        "list.invalidItemForeground": "#eb6f92",
-        "list.warningForeground": "#f6c177",
-        "listFilterWidget.background": "#2a273f",
-        "listFilterWidget.noMatchesOutline": "#eb6f92",
-        "listFilterWidget.outline": "#393552",
-        "menu.background": "#2a273f",
-        "menu.border": "#817c9c14",
-        "menu.foreground": "#e0def4",
-        "menu.selectionBackground": "#817c9c26",
-        "menu.selectionBorder": "#393552",
-        "menu.selectionForeground": "#e0def4",
-        "menu.separatorBackground": "#817c9c4d",
-        "menubar.selectionBackground": "#817c9c26",
-        "menubar.selectionBorder": "#817c9c14",
-        "menubar.selectionForeground": "#e0def4",
-        "merge.border": "#393552",
-        "merge.commonContentBackground": "#817c9c26",
-        "merge.commonHeaderBackground": "#817c9c26",
-        "merge.currentContentBackground": "#f6c17780",
-        "merge.currentHeaderBackground": "#f6c17780",
-        "merge.incomingContentBackground": "#9ccfd880",
-        "merge.incomingHeaderBackground": "#9ccfd880",
-        "minimap.background": "#2a273f",
-        "minimap.errorHighlight": "#eb6f9280",
-        "minimap.findMatchHighlight": "#817c9c26",
-        "minimap.selectionHighlight": "#817c9c26",
-        "minimap.warningHighlight": "#f6c17780",
-        "minimapGutter.addedBackground": "#9ccfd8",
-        "minimapGutter.deletedBackground": "#eb6f92",
-        "minimapGutter.modifiedBackground": "#ea9a97",
-        "minimapSlider.activeBackground": "#817c9c4d",
-        "minimapSlider.background": "#817c9c26",
-        "minimapSlider.hoverBackground": "#817c9c26",
-        "notebook.cellBorderColor": "#9ccfd880",
-        "notebook.cellEditorBackground": "#2a273f",
-        "notebook.cellHoverBackground": "#39355280",
-        "notebook.focusedCellBackground": "#817c9c14",
-        "notebook.focusedCellBorder": "#9ccfd8",
-        "notebook.outputContainerBackgroundColor": "#817c9c14",
-        "notificationCenter.border": "#817c9c26",
-        "notificationCenterHeader.background": "#2a273f",
-        "notificationCenterHeader.foreground": "#908caa",
-        "notificationLink.foreground": "#c4a7e7",
-        "notifications.background": "#2a273f",
-        "notifications.border": "#817c9c26",
-        "notifications.foreground": "#e0def4",
-        "notificationsErrorIcon.foreground": "#eb6f92",
-        "notificationsInfoIcon.foreground": "#9ccfd8",
-        "notificationsWarningIcon.foreground": "#f6c177",
-        "notificationToast.border": "#817c9c26",
-        "panel.background": "#2a273f",
-        "panel.border": "#000000",
-        "panel.dropBorder": "#393552",
-        "panelInput.border": "#2a273f",
-        "panelSection.dropBackground": "#817c9c26",
-        "panelSectionHeader.background": "#2a273f",
-        "panelSectionHeader.foreground": "#e0def4",
-        "panelTitle.activeBorder": "#817c9c4d",
-        "panelTitle.activeForeground": "#e0def4",
-        "panelTitle.inactiveForeground": "#908caa",
-        "peekView.border": "#393552",
-        "peekViewEditor.background": "#2a273f",
-        "peekViewEditor.matchHighlightBackground": "#817c9c4d",
-        "peekViewResult.background": "#2a273f",
-        "peekViewResult.fileForeground": "#908caa",
-        "peekViewResult.lineForeground": "#908caa",
-        "peekViewResult.matchHighlightBackground": "#817c9c4d",
-        "peekViewResult.selectionBackground": "#817c9c26",
-        "peekViewResult.selectionForeground": "#e0def4",
-        "peekViewTitle.background": "#393552",
-        "peekViewTitleDescription.foreground": "#908caa",
-        "pickerGroup.border": "#817c9c4d",
-        "pickerGroup.foreground": "#c4a7e7",
-        "ports.iconRunningProcessForeground": "#ea9a97",
-        "problemsErrorIcon.foreground": "#eb6f92",
-        "problemsInfoIcon.foreground": "#9ccfd8",
-        "problemsWarningIcon.foreground": "#f6c177",
-        "progressBar.background": "#ea9a97",
-        "quickInput.background": "#2a273f",
-        "quickInput.foreground": "#908caa",
-        "quickInputList.focusBackground": "#817c9c26",
-        "quickInputList.focusForeground": "#e0def4",
-        "quickInputList.focusIconForeground": "#e0def4",
-        "scrollbar.shadow": "#2a273f4d",
-        "scrollbarSlider.activeBackground": "#3e8fb080",
-        "scrollbarSlider.background": "#817c9c26",
-        "scrollbarSlider.hoverBackground": "#817c9c4d",
-        "searchEditor.findMatchBackground": "#817c9c26",
-        "selection.background": "#817c9c4d",
-        "settings.focusedRowBackground": "#2a273f",
-        "settings.headerForeground": "#e0def4",
-        "settings.modifiedItemIndicator": "#ea9a97",
-        "settings.focusedRowBorder": "#817c9c26",
-        "settings.rowHoverBackground": "#2a273f",
-        "sideBar.background": "#232136",
-        "sideBar.dropBackground": "#2a273f",
-        "sideBar.foreground": "#908caa",
-        "sideBarSectionHeader.background": "#000000",
-        "sideBarSectionHeader.border": "#817c9c26",
-        "statusBar.background": "#232136",
-        "statusBar.debuggingBackground": "#c4a7e7",
-        "statusBar.debuggingForeground": "#232136",
-        "statusBar.foreground": "#908caa",
-        "statusBar.noFolderBackground": "#232136",
-        "statusBar.noFolderForeground": "#908caa",
-        "statusBarItem.activeBackground": "#817c9c4d",
-        "statusBarItem.hoverBackground": "#817c9c26",
-        "statusBarItem.prominentBackground": "#393552",
-        "statusBarItem.prominentForeground": "#e0def4",
-        "statusBarItem.prominentHoverBackground": "#817c9c26",
-        "statusBarItem.remoteBackground": "#232136",
-        "statusBarItem.remoteForeground": "#f6c177",
-        "statusBarItem.errorBackground": "#232136",
-        "statusBarItem.errorForeground": "#eb6f92",
-        "symbolIcon.arrayForeground": "#908caa",
-        "symbolIcon.classForeground": "#908caa",
-        "symbolIcon.colorForeground": "#908caa",
-        "symbolIcon.constantForeground": "#908caa",
-        "symbolIcon.constructorForeground": "#908caa",
-        "symbolIcon.enumeratorForeground": "#908caa",
-        "symbolIcon.enumeratorMemberForeground": "#908caa",
-        "symbolIcon.eventForeground": "#908caa",
-        "symbolIcon.fieldForeground": "#908caa",
-        "symbolIcon.fileForeground": "#908caa",
-        "symbolIcon.folderForeground": "#908caa",
-        "symbolIcon.functionForeground": "#908caa",
-        "symbolIcon.interfaceForeground": "#908caa",
-        "symbolIcon.keyForeground": "#908caa",
-        "symbolIcon.keywordForeground": "#908caa",
-        "symbolIcon.methodForeground": "#908caa",
-        "symbolIcon.moduleForeground": "#908caa",
-        "symbolIcon.namespaceForeground": "#908caa",
-        "symbolIcon.nullForeground": "#908caa",
-        "symbolIcon.numberForeground": "#908caa",
-        "symbolIcon.objectForeground": "#908caa",
-        "symbolIcon.operatorForeground": "#908caa",
-        "symbolIcon.packageForeground": "#908caa",
-        "symbolIcon.propertyForeground": "#908caa",
-        "symbolIcon.referenceForeground": "#908caa",
-        "symbolIcon.snippetForeground": "#908caa",
-        "symbolIcon.stringForeground": "#908caa",
-        "symbolIcon.structForeground": "#908caa",
-        "symbolIcon.textForeground": "#908caa",
-        "symbolIcon.typeParameterForeground": "#908caa",
-        "symbolIcon.unitForeground": "#908caa",
-        "symbolIcon.variableForeground": "#908caa",
-        "tab.activeBackground": "#817c9c14",
-        "tab.activeForeground": "#e0def4",
-        "tab.activeModifiedBorder": "#9ccfd8",
-        "tab.border": "#000000",
-        "tab.hoverBackground": "#817c9c26",
-        "tab.inactiveBackground": "#000000",
-        "tab.inactiveForeground": "#908caa",
-        "tab.inactiveModifiedBorder": "#9ccfd880",
-        "tab.lastPinnedBorder": "#6e6a86",
-        "tab.unfocusedActiveBackground": "#000000",
-        "tab.unfocusedHoverBackground": "#000000",
-        "tab.unfocusedInactiveBackground": "#000000",
-        "tab.unfocusedInactiveModifiedBorder": "#9ccfd880",
-        "terminal.ansiBlack": "#393552",
-        "terminal.ansiBlue": "#9ccfd8",
-        "terminal.ansiBrightBlack": "#908caa",
-        "terminal.ansiBrightBlue": "#9ccfd8",
-        "terminal.ansiBrightCyan": "#ea9a97",
-        "terminal.ansiBrightGreen": "#3e8fb0",
-        "terminal.ansiBrightMagenta": "#c4a7e7",
-        "terminal.ansiBrightRed": "#eb6f92",
-        "terminal.ansiBrightWhite": "#e0def4",
-        "terminal.ansiBrightYellow": "#f6c177",
-        "terminal.ansiCyan": "#ea9a97",
-        "terminal.ansiGreen": "#3e8fb0",
-        "terminal.ansiMagenta": "#c4a7e7",
-        "terminal.ansiRed": "#eb6f92",
-        "terminal.ansiWhite": "#e0def4",
-        "terminal.ansiYellow": "#f6c177",
-        "terminal.dropBackground": "#817c9c26",
-        "terminal.foreground": "#e0def4",
-        "terminal.selectionBackground": "#817c9c26",
-        "terminal.tab.activeBorder": "#e0def4",
-        "terminalCursor.background": "#e0def4",
-        "terminalCursor.foreground": "#6e6a86",
-        "textBlockQuote.background": "#2a273f",
-        "textBlockQuote.border": "#817c9c26",
-        "textCodeBlock.background": "#2a273f",
-        "textLink.activeForeground": "#c4a7e7e6",
-        "textLink.foreground": "#c4a7e7",
-        "textPreformat.foreground": "#f6c177",
-        "textSeparator.foreground": "#908caa",
-        "titleBar.activeBackground": "#232136",
-        "titleBar.activeForeground": "#908caa",
-        "titleBar.inactiveBackground": "#2a273f",
-        "titleBar.inactiveForeground": "#908caa",
-        "toolbar.activeBackground": "#817c9c4d",
-        "toolbar.hoverBackground": "#817c9c26",
-        "tree.indentGuidesStroke": "#908caa",
-        "walkThrough.embeddedEditorBackground": "#232136",
-        "welcomePage.background": "#232136",
-        "welcomePage.buttonBackground": "#2a273f",
-        "welcomePage.buttonHoverBackground": "#393552",
-        "widget.shadow": "#2a273f4d",
-        "window.activeBorder": "#2a273f",
-        "window.inactiveBorder": "#2a273f"
-    },
-    "tokenColors": [
-        {
-            "scope": ["comment"],
-            "settings": {
-                "foreground": "#6e6a86",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["constant"],
-            "settings": {
-                "foreground": "#3e8fb0"
-            }
-        },
-        {
-            "scope": ["constant.numeric", "constant.language"],
-            "settings": {
-                "foreground": "#ea9a97"
-            }
-        },
-        {
-            "scope": ["entity.name"],
-            "settings": {
-                "foreground": "#ea9a97"
-            }
-        },
-        {
-            "scope": [
-                "entity.name.section",
-                "entity.name.tag",
-                "entity.name.namespace",
-                "entity.name.type"
-            ],
-            "settings": {
-                "foreground": "#9ccfd8"
-            }
-        },
-        {
-            "scope": ["entity.other.attribute-name", "entity.other.inherited-class"],
-            "settings": {
-                "foreground": "#c4a7e7",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["invalid"],
-            "settings": {
-                "foreground": "#eb6f92"
-            }
-        },
-        {
-            "scope": ["invalid.deprecated"],
-            "settings": {
-                "foreground": "#908caa"
-            }
-        },
-        {
-            "scope": ["keyword"],
-            "settings": {
-                "foreground": "#3e8fb0"
-            }
-        },
-        {
-            "scope": ["markup.inserted.diff"],
-            "settings": {
-                "foreground": "#9ccfd8"
-            }
-        },
-        {
-            "scope": ["markup.deleted.diff"],
-            "settings": {
-                "foreground": "#eb6f92"
-            }
-        },
-        {
-            "scope": "markup.heading",
-            "settings": {
-                "fontStyle": "bold"
-            }
-        },
-        {
-            "scope": "markup.bold.markdown",
-            "settings": {
-                "fontStyle": "bold"
-            }
-        },
-        {
-            "scope": "markup.italic.markdown",
-            "settings": {
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["meta.diff.range"],
-            "settings": {
-                "foreground": "#c4a7e7"
-            }
-        },
-        {
-            "scope": ["meta.tag", "meta.brace"],
-            "settings": {
-                "foreground": "#e0def4"
-            }
-        },
-        {
-            "scope": ["meta.import", "meta.export"],
-            "settings": {
-                "foreground": "#3e8fb0"
-            }
-        },
-        {
-            "scope": "meta.directive.vue",
-            "settings": {
-                "foreground": "#c4a7e7",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": "meta.property-name.css",
-            "settings": {
-                "foreground": "#9ccfd8"
-            }
-        },
-        {
-            "scope": "meta.property-value.css",
-            "settings": {
-                "foreground": "#f6c177"
-            }
-        },
-        {
-            "scope": "meta.tag.other.html",
-            "settings": {
-                "foreground": "#908caa"
-            }
-        },
-        {
-            "scope": ["punctuation"],
-            "settings": {
-                "foreground": "#908caa"
-            }
-        },
-        {
-            "scope": ["punctuation.accessor"],
-            "settings": {
-                "foreground": "#3e8fb0"
-            }
-        },
-        {
-            "scope": ["punctuation.definition.string"],
-            "settings": {
-                "foreground": "#f6c177"
-            }
-        },
-        {
-            "scope": ["punctuation.definition.tag"],
-            "settings": {
-                "foreground": "#6e6a86"
-            }
-        },
-        {
-            "scope": ["storage.type", "storage.modifier"],
-            "settings": {
-                "foreground": "#3e8fb0"
-            }
-        },
-        {
-            "scope": ["string"],
-            "settings": {
-                "foreground": "#f6c177"
-            }
-        },
-        {
-            "scope": ["support"],
-            "settings": {
-                "foreground": "#9ccfd8"
-            }
-        },
-        {
-            "scope": ["support.constant"],
-            "settings": {
-                "foreground": "#f6c177"
-            }
-        },
-        {
-            "scope": ["support.function"],
-            "settings": {
-                "foreground": "#eb6f92",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["variable"],
-            "settings": {
-                "foreground": "#ea9a97",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": [
-                "variable.other",
-                "variable.language",
-                "variable.function",
-                "variable.argument"
-            ],
-            "settings": {
-                "foreground": "#e0def4"
-            }
-        },
-        {
-            "scope": ["variable.parameter"],
-            "settings": {
-                "foreground": "#c4a7e7"
-            }
-        }
-    ]
+	"name": "Rosé Pine Moon",
+	"type": "dark",
+	"colors": {
+		"activityBar.activeBorder": "#e0def4",
+		"activityBar.background": "#232136",
+		"activityBar.dropBorder": "#393552",
+		"activityBar.foreground": "#e0def4",
+		"activityBar.inactiveForeground": "#908caa",
+		"activityBarBadge.background": "#ea9a97",
+		"activityBarBadge.foreground": "#232136",
+		"badge.background": "#ea9a97",
+		"badge.foreground": "#232136",
+		"banner.background": "#2a273f",
+		"banner.foreground": "#e0def4",
+		"banner.iconForeground": "#908caa",
+		"breadcrumb.activeSelectionForeground": "#ea9a97",
+		"breadcrumb.background": "#232136",
+		"breadcrumb.focusForeground": "#908caa",
+		"breadcrumb.foreground": "#6e6a86",
+		"breadcrumbPicker.background": "#2a273f",
+		"button.background": "#ea9a97",
+		"button.foreground": "#232136",
+		"button.hoverBackground": "#ea9a97e6",
+		"button.secondaryBackground": "#2a273f",
+		"button.secondaryForeground": "#e0def4",
+		"button.secondaryHoverBackground": "#393552",
+		"charts.blue": "#9ccfd8",
+		"charts.foreground": "#e0def4",
+		"charts.green": "#3e8fb0",
+		"charts.lines": "#908caa",
+		"charts.orange": "#ea9a97",
+		"charts.purple": "#c4a7e7",
+		"charts.red": "#eb6f92",
+		"charts.yellow": "#f6c177",
+		"checkbox.background": "#2a273f",
+		"checkbox.border": "#817c9c26",
+		"checkbox.foreground": "#e0def4",
+		"debugExceptionWidget.background": "#2a273f",
+		"debugExceptionWidget.border": "#817c9c26",
+		"debugIcon.breakpointCurrentStackframeForeground": "#908caa",
+		"debugIcon.breakpointDisabledForeground": "#908caa",
+		"debugIcon.breakpointForeground": "#908caa",
+		"debugIcon.breakpointStackframeForeground": "#908caa",
+		"debugIcon.breakpointUnverifiedForeground": "#908caa",
+		"debugIcon.continueForeground": "#908caa",
+		"debugIcon.disconnectForeground": "#908caa",
+		"debugIcon.pauseForeground": "#908caa",
+		"debugIcon.restartForeground": "#908caa",
+		"debugIcon.startForeground": "#908caa",
+		"debugIcon.stepBackForeground": "#908caa",
+		"debugIcon.stepIntoForeground": "#908caa",
+		"debugIcon.stepOutForeground": "#908caa",
+		"debugIcon.stepOverForeground": "#908caa",
+		"debugIcon.stopForeground": "#eb6f92",
+		"debugToolBar.background": "#2a273f",
+		"debugToolBar.border": "#393552",
+		"descriptionForeground": "#908caa",
+		"diffEditor.border": "#393552",
+		"diffEditor.diagonalFill": "#817c9c4d",
+		"diffEditor.insertedLineBackground": "#9ccfd826",
+		"diffEditor.insertedTextBackground": "#9ccfd826",
+		"diffEditor.removedLineBackground": "#eb6f9226",
+		"diffEditor.removedTextBackground": "#eb6f9226",
+		"diffEditorOverview.insertedForeground": "#9ccfd880",
+		"diffEditorOverview.removedForeground": "#eb6f9280",
+		"dropdown.background": "#2a273f",
+		"dropdown.border": "#817c9c26",
+		"dropdown.foreground": "#e0def4",
+		"dropdown.listBackground": "#2a273f",
+		"editor.background": "#232136",
+		"editor.findMatchBackground": "#817c9c4d",
+		"editor.findMatchHighlightBackground": "#817c9c4d",
+		"editor.findRangeHighlightBackground": "#817c9c4d",
+		"editor.findRangeHighlightBorder": "#0000",
+		"editor.focusedStackFrameHighlightBackground": "#817c9c26",
+		"editor.foldBackground": "#2a273f",
+		"editor.foreground": "#e0def4",
+		"editor.hoverHighlightBackground": "#0000",
+		"editor.inactiveSelectionBackground": "#817c9c14",
+		"editor.inlineValuesBackground": "#0000",
+		"editor.inlineValuesForeground": "#908caa",
+		"editor.lineHighlightBackground": "#817c9c14",
+		"editor.lineHighlightBorder": "#0000",
+		"editor.linkedEditingBackground": "#2a273f",
+		"editor.rangeHighlightBackground": "#817c9c14",
+		"editor.selectionBackground": "#817c9c26",
+		"editor.selectionForeground": "#e0def4",
+		"editor.selectionHighlightBackground": "#817c9c26",
+		"editor.selectionHighlightBorder": "#232136",
+		"editor.snippetFinalTabstopHighlightBackground": "#817c9c26",
+		"editor.snippetFinalTabstopHighlightBorder": "#2a273f",
+		"editor.snippetTabstopHighlightBackground": "#817c9c26",
+		"editor.snippetTabstopHighlightBorder": "#2a273f",
+		"editor.stackFrameHighlightBackground": "#817c9c26",
+		"editor.symbolHighlightBackground": "#817c9c26",
+		"editor.symbolHighlightBorder": "#0000",
+		"editor.wordHighlightBackground": "#817c9c26",
+		"editor.wordHighlightBorder": "#0000",
+		"editor.wordHighlightStrongBackground": "#817c9c26",
+		"editor.wordHighlightStrongBorder": "#817c9c26",
+		"editorBracketHighlight.foreground1": "#eb6f9280",
+		"editorBracketHighlight.foreground2": "#3e8fb080",
+		"editorBracketHighlight.foreground3": "#f6c17780",
+		"editorBracketHighlight.foreground4": "#9ccfd880",
+		"editorBracketHighlight.foreground5": "#ea9a9780",
+		"editorBracketHighlight.foreground6": "#c4a7e780",
+		"editorBracketMatch.background": "#0000",
+		"editorBracketMatch.border": "#908caa",
+		"editorBracketPairGuide.activeBackground1": "#3e8fb0",
+		"editorBracketPairGuide.activeBackground2": "#ea9a97",
+		"editorBracketPairGuide.activeBackground3": "#c4a7e7",
+		"editorBracketPairGuide.activeBackground4": "#9ccfd8",
+		"editorBracketPairGuide.activeBackground5": "#f6c177",
+		"editorBracketPairGuide.activeBackground6": "#eb6f92",
+		"editorBracketPairGuide.background1": "#3e8fb080",
+		"editorBracketPairGuide.background2": "#ea9a9780",
+		"editorBracketPairGuide.background3": "#c4a7e780",
+		"editorBracketPairGuide.background4": "#9ccfd880",
+		"editorBracketPairGuide.background5": "#f6c17780",
+		"editorBracketPairGuide.background6": "#eb6f9280",
+		"editorCodeLens.foreground": "#ea9a97",
+		"editorCursor.background": "#e0def4",
+		"editorCursor.foreground": "#6e6a86",
+		"editorError.border": "#0000",
+		"editorError.foreground": "#eb6f92",
+		"editorGhostText.foreground": "#908caa",
+		"editorGroup.border": "#0000",
+		"editorGroup.dropBackground": "#2a273f",
+		"editorGroup.emptyBackground": "#0000",
+		"editorGroup.focusedEmptyBorder": "#0000",
+		"editorGroupHeader.noTabsBackground": "#0000",
+		"editorGroupHeader.tabsBackground": "#0000",
+		"editorGroupHeader.tabsBorder": "#0000",
+		"editorGutter.addedBackground": "#9ccfd8",
+		"editorGutter.background": "#232136",
+		"editorGutter.commentRangeForeground": "#908caa",
+		"editorGutter.deletedBackground": "#eb6f92",
+		"editorGutter.foldingControlForeground": "#c4a7e7",
+		"editorGutter.modifiedBackground": "#ea9a97",
+		"editorHint.border": "#0000",
+		"editorHint.foreground": "#908caa",
+		"editorHoverWidget.background": "#2a273f",
+		"editorHoverWidget.border": "#6e6a8680",
+		"editorHoverWidget.foreground": "#908caa",
+		"editorHoverWidget.highlightForeground": "#e0def4",
+		"editorHoverWidget.statusBarBackground": "#0000",
+		"editorIndentGuide.activeBackground": "#6e6a86",
+		"editorIndentGuide.background": "#817c9c4d",
+		"editorInfo.border": "#393552",
+		"editorInfo.foreground": "#9ccfd8",
+		"editorInlayHint.background": "#393552",
+		"editorInlayHint.foreground": "#908caa",
+		"editorInlayHint.parameterBackground": "#393552",
+		"editorInlayHint.parameterForeground": "#c4a7e7",
+		"editorInlayHint.typeBackground": "#393552",
+		"editorInlayHint.typeForeground": "#9ccfd8",
+		"editorLightBulb.foreground": "#3e8fb0",
+		"editorLightBulbAutoFix.foreground": "#ea9a97",
+		"editorLineNumber.activeForeground": "#e0def4",
+		"editorLineNumber.foreground": "#908caa",
+		"editorLink.activeForeground": "#ea9a97",
+		"editorMarkerNavigation.background": "#2a273f",
+		"editorMarkerNavigationError.background": "#2a273f",
+		"editorMarkerNavigationInfo.background": "#2a273f",
+		"editorMarkerNavigationWarning.background": "#2a273f",
+		"editorOverviewRuler.addedForeground": "#9ccfd880",
+		"editorOverviewRuler.background": "#232136",
+		"editorOverviewRuler.border": "#817c9c4d",
+		"editorOverviewRuler.bracketMatchForeground": "#908caa",
+		"editorOverviewRuler.commonContentForeground": "#817c9c14",
+		"editorOverviewRuler.currentContentForeground": "#817c9c26",
+		"editorOverviewRuler.deletedForeground": "#eb6f9280",
+		"editorOverviewRuler.errorForeground": "#eb6f9280",
+		"editorOverviewRuler.findMatchForeground": "#817c9c4d",
+		"editorOverviewRuler.incomingContentForeground": "#c4a7e780",
+		"editorOverviewRuler.infoForeground": "#9ccfd880",
+		"editorOverviewRuler.modifiedForeground": "#ea9a9780",
+		"editorOverviewRuler.rangeHighlightForeground": "#817c9c4d",
+		"editorOverviewRuler.selectionHighlightForeground": "#817c9c4d",
+		"editorOverviewRuler.warningForeground": "#f6c17780",
+		"editorOverviewRuler.wordHighlightForeground": "#817c9c26",
+		"editorOverviewRuler.wordHighlightStrongForeground": "#817c9c4d",
+		"editorPane.background": "#0000",
+		"editorRuler.foreground": "#817c9c4d",
+		"editorSuggestWidget.background": "#2a273f",
+		"editorSuggestWidget.border": "#0000",
+		"editorSuggestWidget.focusHighlightForeground": "#ea9a97",
+		"editorSuggestWidget.foreground": "#908caa",
+		"editorSuggestWidget.highlightForeground": "#ea9a97",
+		"editorSuggestWidget.selectedBackground": "#817c9c26",
+		"editorSuggestWidget.selectedForeground": "#e0def4",
+		"editorSuggestWidget.selectedIconForeground": "#e0def4",
+		"editorUnnecessaryCode.border": "#0000",
+		"editorUnnecessaryCode.opacity": "#e0def480",
+		"editorWarning.border": "#0000",
+		"editorWarning.foreground": "#f6c177",
+		"editorWhitespace.foreground": "#6e6a86",
+		"editorWidget.background": "#2a273f",
+		"editorWidget.border": "#393552",
+		"editorWidget.foreground": "#908caa",
+		"editorWidget.resizeBorder": "#6e6a86",
+		"errorForeground": "#eb6f92",
+		"extensionBadge.remoteBackground": "#c4a7e7",
+		"extensionBadge.remoteForeground": "#232136",
+		"extensionButton.prominentBackground": "#ea9a97",
+		"extensionButton.prominentForeground": "#232136",
+		"extensionButton.prominentHoverBackground": "#ea9a97e6",
+		"extensionIcon.preReleaseForeground": "#3e8fb0",
+		"extensionIcon.starForeground": "#ea9a97",
+		"extensionIcon.verifiedForeground": "#c4a7e7",
+		"focusBorder": "#817c9c26",
+		"foreground": "#e0def4",
+		"gitDecoration.addedResourceForeground": "#9ccfd8",
+		"gitDecoration.conflictingResourceForeground": "#eb6f92",
+		"gitDecoration.deletedResourceForeground": "#908caa",
+		"gitDecoration.ignoredResourceForeground": "#6e6a86",
+		"gitDecoration.modifiedResourceForeground": "#ea9a97",
+		"gitDecoration.renamedResourceForeground": "#3e8fb0",
+		"gitDecoration.stageDeletedResourceForeground": "#eb6f92",
+		"gitDecoration.stageModifiedResourceForeground": "#c4a7e7",
+		"gitDecoration.submoduleResourceForeground": "#f6c177",
+		"gitDecoration.untrackedResourceForeground": "#f6c177",
+		"icon.foreground": "#908caa",
+		"input.background": "#39355280",
+		"input.border": "#817c9c26",
+		"input.foreground": "#e0def4",
+		"input.placeholderForeground": "#908caa",
+		"inputOption.activeBackground": "#ea9a9726",
+		"inputOption.activeForeground": "#ea9a97",
+		"inputValidation.errorBackground": "#2a273f",
+		"inputValidation.errorBorder": "#817c9c4d",
+		"inputValidation.errorForeground": "#eb6f92",
+		"inputValidation.infoBackground": "#2a273f",
+		"inputValidation.infoBorder": "#817c9c4d",
+		"inputValidation.infoForeground": "#9ccfd8",
+		"inputValidation.warningBackground": "#2a273f",
+		"inputValidation.warningBorder": "#817c9c4d",
+		"inputValidation.warningForeground": "#9ccfd880",
+		"keybindingLabel.background": "#393552",
+		"keybindingLabel.border": "#817c9c4d",
+		"keybindingLabel.bottomBorder": "#817c9c4d",
+		"keybindingLabel.foreground": "#c4a7e7",
+		"keybindingTable.headerBackground": "#393552",
+		"keybindingTable.rowsBackground": "#2a273f",
+		"list.activeSelectionBackground": "#817c9c26",
+		"list.activeSelectionForeground": "#e0def4",
+		"list.deemphasizedForeground": "#908caa",
+		"list.dropBackground": "#2a273f",
+		"list.errorForeground": "#eb6f92",
+		"list.filterMatchBackground": "#2a273f",
+		"list.filterMatchBorder": "#ea9a97",
+		"list.focusBackground": "#817c9c4d",
+		"list.focusForeground": "#e0def4",
+		"list.focusOutline": "#817c9c26",
+		"list.highlightForeground": "#ea9a97",
+		"list.hoverBackground": "#817c9c14",
+		"list.hoverForeground": "#e0def4",
+		"list.inactiveFocusBackground": "#817c9c14",
+		"list.inactiveSelectionBackground": "#2a273f",
+		"list.inactiveSelectionForeground": "#e0def4",
+		"list.invalidItemForeground": "#eb6f92",
+		"list.warningForeground": "#f6c177",
+		"listFilterWidget.background": "#2a273f",
+		"listFilterWidget.noMatchesOutline": "#eb6f92",
+		"listFilterWidget.outline": "#393552",
+		"menu.background": "#2a273f",
+		"menu.border": "#817c9c14",
+		"menu.foreground": "#e0def4",
+		"menu.selectionBackground": "#817c9c26",
+		"menu.selectionBorder": "#393552",
+		"menu.selectionForeground": "#e0def4",
+		"menu.separatorBackground": "#817c9c4d",
+		"menubar.selectionBackground": "#817c9c26",
+		"menubar.selectionBorder": "#817c9c14",
+		"menubar.selectionForeground": "#e0def4",
+		"merge.border": "#393552",
+		"merge.commonContentBackground": "#817c9c26",
+		"merge.commonHeaderBackground": "#817c9c26",
+		"merge.currentContentBackground": "#f6c17780",
+		"merge.currentHeaderBackground": "#f6c17780",
+		"merge.incomingContentBackground": "#9ccfd880",
+		"merge.incomingHeaderBackground": "#9ccfd880",
+		"minimap.background": "#2a273f",
+		"minimap.errorHighlight": "#eb6f9280",
+		"minimap.findMatchHighlight": "#817c9c26",
+		"minimap.selectionHighlight": "#817c9c26",
+		"minimap.warningHighlight": "#f6c17780",
+		"minimapGutter.addedBackground": "#9ccfd8",
+		"minimapGutter.deletedBackground": "#eb6f92",
+		"minimapGutter.modifiedBackground": "#ea9a97",
+		"minimapSlider.activeBackground": "#817c9c4d",
+		"minimapSlider.background": "#817c9c26",
+		"minimapSlider.hoverBackground": "#817c9c26",
+		"notebook.cellBorderColor": "#9ccfd880",
+		"notebook.cellEditorBackground": "#2a273f",
+		"notebook.cellHoverBackground": "#39355280",
+		"notebook.focusedCellBackground": "#817c9c14",
+		"notebook.focusedCellBorder": "#9ccfd8",
+		"notebook.outputContainerBackgroundColor": "#817c9c14",
+		"notificationCenter.border": "#817c9c26",
+		"notificationCenterHeader.background": "#2a273f",
+		"notificationCenterHeader.foreground": "#908caa",
+		"notificationLink.foreground": "#c4a7e7",
+		"notifications.background": "#2a273f",
+		"notifications.border": "#817c9c26",
+		"notifications.foreground": "#e0def4",
+		"notificationsErrorIcon.foreground": "#eb6f92",
+		"notificationsInfoIcon.foreground": "#9ccfd8",
+		"notificationsWarningIcon.foreground": "#f6c177",
+		"notificationToast.border": "#817c9c26",
+		"panel.background": "#2a273f",
+		"panel.border": "#0000",
+		"panel.dropBorder": "#393552",
+		"panelInput.border": "#2a273f",
+		"panelSection.dropBackground": "#817c9c26",
+		"panelSectionHeader.background": "#2a273f",
+		"panelSectionHeader.foreground": "#e0def4",
+		"panelTitle.activeBorder": "#817c9c4d",
+		"panelTitle.activeForeground": "#e0def4",
+		"panelTitle.inactiveForeground": "#908caa",
+		"peekView.border": "#393552",
+		"peekViewEditor.background": "#2a273f",
+		"peekViewEditor.matchHighlightBackground": "#817c9c4d",
+		"peekViewResult.background": "#2a273f",
+		"peekViewResult.fileForeground": "#908caa",
+		"peekViewResult.lineForeground": "#908caa",
+		"peekViewResult.matchHighlightBackground": "#817c9c4d",
+		"peekViewResult.selectionBackground": "#817c9c26",
+		"peekViewResult.selectionForeground": "#e0def4",
+		"peekViewTitle.background": "#393552",
+		"peekViewTitleDescription.foreground": "#908caa",
+		"pickerGroup.border": "#817c9c4d",
+		"pickerGroup.foreground": "#c4a7e7",
+		"ports.iconRunningProcessForeground": "#ea9a97",
+		"problemsErrorIcon.foreground": "#eb6f92",
+		"problemsInfoIcon.foreground": "#9ccfd8",
+		"problemsWarningIcon.foreground": "#f6c177",
+		"progressBar.background": "#ea9a97",
+		"quickInput.background": "#2a273f",
+		"quickInput.foreground": "#908caa",
+		"quickInputList.focusBackground": "#817c9c26",
+		"quickInputList.focusForeground": "#e0def4",
+		"quickInputList.focusIconForeground": "#e0def4",
+		"scrollbar.shadow": "#2a273f4d",
+		"scrollbarSlider.activeBackground": "#3e8fb080",
+		"scrollbarSlider.background": "#817c9c26",
+		"scrollbarSlider.hoverBackground": "#817c9c4d",
+		"searchEditor.findMatchBackground": "#817c9c26",
+		"selection.background": "#817c9c4d",
+		"settings.focusedRowBackground": "#2a273f",
+		"settings.headerForeground": "#e0def4",
+		"settings.modifiedItemIndicator": "#ea9a97",
+		"settings.focusedRowBorder": "#817c9c26",
+		"settings.rowHoverBackground": "#2a273f",
+		"sideBar.background": "#232136",
+		"sideBar.dropBackground": "#2a273f",
+		"sideBar.foreground": "#908caa",
+		"sideBarSectionHeader.background": "#0000",
+		"sideBarSectionHeader.border": "#817c9c26",
+		"statusBar.background": "#232136",
+		"statusBar.debuggingBackground": "#c4a7e7",
+		"statusBar.debuggingForeground": "#232136",
+		"statusBar.foreground": "#908caa",
+		"statusBar.noFolderBackground": "#232136",
+		"statusBar.noFolderForeground": "#908caa",
+		"statusBarItem.activeBackground": "#817c9c4d",
+		"statusBarItem.hoverBackground": "#817c9c26",
+		"statusBarItem.prominentBackground": "#393552",
+		"statusBarItem.prominentForeground": "#e0def4",
+		"statusBarItem.prominentHoverBackground": "#817c9c26",
+		"statusBarItem.remoteBackground": "#232136",
+		"statusBarItem.remoteForeground": "#f6c177",
+		"statusBarItem.errorBackground": "#232136",
+		"statusBarItem.errorForeground": "#eb6f92",
+		"symbolIcon.arrayForeground": "#908caa",
+		"symbolIcon.classForeground": "#908caa",
+		"symbolIcon.colorForeground": "#908caa",
+		"symbolIcon.constantForeground": "#908caa",
+		"symbolIcon.constructorForeground": "#908caa",
+		"symbolIcon.enumeratorForeground": "#908caa",
+		"symbolIcon.enumeratorMemberForeground": "#908caa",
+		"symbolIcon.eventForeground": "#908caa",
+		"symbolIcon.fieldForeground": "#908caa",
+		"symbolIcon.fileForeground": "#908caa",
+		"symbolIcon.folderForeground": "#908caa",
+		"symbolIcon.functionForeground": "#908caa",
+		"symbolIcon.interfaceForeground": "#908caa",
+		"symbolIcon.keyForeground": "#908caa",
+		"symbolIcon.keywordForeground": "#908caa",
+		"symbolIcon.methodForeground": "#908caa",
+		"symbolIcon.moduleForeground": "#908caa",
+		"symbolIcon.namespaceForeground": "#908caa",
+		"symbolIcon.nullForeground": "#908caa",
+		"symbolIcon.numberForeground": "#908caa",
+		"symbolIcon.objectForeground": "#908caa",
+		"symbolIcon.operatorForeground": "#908caa",
+		"symbolIcon.packageForeground": "#908caa",
+		"symbolIcon.propertyForeground": "#908caa",
+		"symbolIcon.referenceForeground": "#908caa",
+		"symbolIcon.snippetForeground": "#908caa",
+		"symbolIcon.stringForeground": "#908caa",
+		"symbolIcon.structForeground": "#908caa",
+		"symbolIcon.textForeground": "#908caa",
+		"symbolIcon.typeParameterForeground": "#908caa",
+		"symbolIcon.unitForeground": "#908caa",
+		"symbolIcon.variableForeground": "#908caa",
+		"tab.activeBackground": "#817c9c14",
+		"tab.activeForeground": "#e0def4",
+		"tab.activeModifiedBorder": "#9ccfd8",
+		"tab.border": "#0000",
+		"tab.hoverBackground": "#817c9c26",
+		"tab.inactiveBackground": "#0000",
+		"tab.inactiveForeground": "#908caa",
+		"tab.inactiveModifiedBorder": "#9ccfd880",
+		"tab.lastPinnedBorder": "#6e6a86",
+		"tab.unfocusedActiveBackground": "#0000",
+		"tab.unfocusedHoverBackground": "#0000",
+		"tab.unfocusedInactiveBackground": "#0000",
+		"tab.unfocusedInactiveModifiedBorder": "#9ccfd880",
+		"terminal.ansiBlack": "#393552",
+		"terminal.ansiBlue": "#9ccfd8",
+		"terminal.ansiBrightBlack": "#908caa",
+		"terminal.ansiBrightBlue": "#9ccfd8",
+		"terminal.ansiBrightCyan": "#ea9a97",
+		"terminal.ansiBrightGreen": "#3e8fb0",
+		"terminal.ansiBrightMagenta": "#c4a7e7",
+		"terminal.ansiBrightRed": "#eb6f92",
+		"terminal.ansiBrightWhite": "#e0def4",
+		"terminal.ansiBrightYellow": "#f6c177",
+		"terminal.ansiCyan": "#ea9a97",
+		"terminal.ansiGreen": "#3e8fb0",
+		"terminal.ansiMagenta": "#c4a7e7",
+		"terminal.ansiRed": "#eb6f92",
+		"terminal.ansiWhite": "#e0def4",
+		"terminal.ansiYellow": "#f6c177",
+		"terminal.dropBackground": "#817c9c26",
+		"terminal.foreground": "#e0def4",
+		"terminal.selectionBackground": "#817c9c26",
+		"terminal.tab.activeBorder": "#e0def4",
+		"terminalCursor.background": "#e0def4",
+		"terminalCursor.foreground": "#6e6a86",
+		"textBlockQuote.background": "#2a273f",
+		"textBlockQuote.border": "#817c9c26",
+		"textCodeBlock.background": "#2a273f",
+		"textLink.activeForeground": "#c4a7e7e6",
+		"textLink.foreground": "#c4a7e7",
+		"textPreformat.foreground": "#f6c177",
+		"textSeparator.foreground": "#908caa",
+		"titleBar.activeBackground": "#232136",
+		"titleBar.activeForeground": "#908caa",
+		"titleBar.inactiveBackground": "#2a273f",
+		"titleBar.inactiveForeground": "#908caa",
+		"toolbar.activeBackground": "#817c9c4d",
+		"toolbar.hoverBackground": "#817c9c26",
+		"tree.indentGuidesStroke": "#908caa",
+		"walkThrough.embeddedEditorBackground": "#232136",
+		"welcomePage.background": "#232136",
+		"welcomePage.buttonBackground": "#2a273f",
+		"welcomePage.buttonHoverBackground": "#393552",
+		"widget.shadow": "#2a273f4d",
+		"window.activeBorder": "#2a273f",
+		"window.inactiveBorder": "#2a273f"
+	},
+	"tokenColors": [
+		{
+			"scope": ["comment"],
+			"settings": {
+				"foreground": "#6e6a86",
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": ["constant"],
+			"settings": {
+				"foreground": "#3e8fb0"
+			}
+		},
+		{
+			"scope": ["constant.numeric", "constant.language"],
+			"settings": {
+				"foreground": "#ea9a97"
+			}
+		},
+		{
+			"scope": ["entity.name"],
+			"settings": {
+				"foreground": "#ea9a97"
+			}
+		},
+		{
+			"scope": [
+				"entity.name.section",
+				"entity.name.tag",
+				"entity.name.namespace",
+				"entity.name.type"
+			],
+			"settings": {
+				"foreground": "#9ccfd8"
+			}
+		},
+		{
+			"scope": ["entity.other.attribute-name", "entity.other.inherited-class"],
+			"settings": {
+				"foreground": "#c4a7e7",
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": ["invalid"],
+			"settings": {
+				"foreground": "#eb6f92"
+			}
+		},
+		{
+			"scope": ["invalid.deprecated"],
+			"settings": {
+				"foreground": "#908caa"
+			}
+		},
+		{
+			"scope": ["keyword"],
+			"settings": {
+				"foreground": "#3e8fb0"
+			}
+		},
+		{
+			"scope": ["markup.inserted.diff"],
+			"settings": {
+				"foreground": "#9ccfd8"
+			}
+		},
+		{
+			"scope": ["markup.deleted.diff"],
+			"settings": {
+				"foreground": "#eb6f92"
+			}
+		},
+		{
+			"scope": "markup.heading",
+			"settings": {
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"scope": "markup.bold.markdown",
+			"settings": {
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"scope": "markup.italic.markdown",
+			"settings": {
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": ["meta.diff.range"],
+			"settings": {
+				"foreground": "#c4a7e7"
+			}
+		},
+		{
+			"scope": ["meta.tag", "meta.brace"],
+			"settings": {
+				"foreground": "#e0def4"
+			}
+		},
+		{
+			"scope": ["meta.import", "meta.export"],
+			"settings": {
+				"foreground": "#3e8fb0"
+			}
+		},
+		{
+			"scope": "meta.directive.vue",
+			"settings": {
+				"foreground": "#c4a7e7",
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": "meta.property-name.css",
+			"settings": {
+				"foreground": "#9ccfd8"
+			}
+		},
+		{
+			"scope": "meta.property-value.css",
+			"settings": {
+				"foreground": "#f6c177"
+			}
+		},
+		{
+			"scope": "meta.tag.other.html",
+			"settings": {
+				"foreground": "#908caa"
+			}
+		},
+		{
+			"scope": ["punctuation"],
+			"settings": {
+				"foreground": "#908caa"
+			}
+		},
+		{
+			"scope": ["punctuation.accessor"],
+			"settings": {
+				"foreground": "#3e8fb0"
+			}
+		},
+		{
+			"scope": ["punctuation.definition.string"],
+			"settings": {
+				"foreground": "#f6c177"
+			}
+		},
+		{
+			"scope": ["punctuation.definition.tag"],
+			"settings": {
+				"foreground": "#6e6a86"
+			}
+		},
+		{
+			"scope": ["storage.type", "storage.modifier"],
+			"settings": {
+				"foreground": "#3e8fb0"
+			}
+		},
+		{
+			"scope": ["string"],
+			"settings": {
+				"foreground": "#f6c177"
+			}
+		},
+		{
+			"scope": ["support"],
+			"settings": {
+				"foreground": "#9ccfd8"
+			}
+		},
+		{
+			"scope": ["support.constant"],
+			"settings": {
+				"foreground": "#f6c177"
+			}
+		},
+		{
+			"scope": ["support.function"],
+			"settings": {
+				"foreground": "#eb6f92",
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": ["variable"],
+			"settings": {
+				"foreground": "#ea9a97",
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": [
+				"variable.other",
+				"variable.language",
+				"variable.function",
+				"variable.argument"
+			],
+			"settings": {
+				"foreground": "#e0def4"
+			}
+		},
+		{
+			"scope": ["variable.parameter"],
+			"settings": {
+				"foreground": "#c4a7e7"
+			}
+		}
+	]
 }

assets/themes/src/vscode/rose-pine/rose-pine.json 🔗

@@ -1,680 +1,680 @@
 {
-    "name": "Rosé Pine",
-    "type": "dark",
-    "colors": {
-        "activityBar.activeBorder": "#e0def4",
-        "activityBar.background": "#191724",
-        "activityBar.dropBorder": "#26233a",
-        "activityBar.foreground": "#e0def4",
-        "activityBar.inactiveForeground": "#908caa",
-        "activityBarBadge.background": "#ebbcba",
-        "activityBarBadge.foreground": "#191724",
-        "badge.background": "#ebbcba",
-        "badge.foreground": "#191724",
-        "banner.background": "#1f1d2e",
-        "banner.foreground": "#e0def4",
-        "banner.iconForeground": "#908caa",
-        "breadcrumb.activeSelectionForeground": "#ebbcba",
-        "breadcrumb.background": "#191724",
-        "breadcrumb.focusForeground": "#908caa",
-        "breadcrumb.foreground": "#6e6a86",
-        "breadcrumbPicker.background": "#1f1d2e",
-        "button.background": "#ebbcba",
-        "button.foreground": "#191724",
-        "button.hoverBackground": "#ebbcbae6",
-        "button.secondaryBackground": "#1f1d2e",
-        "button.secondaryForeground": "#e0def4",
-        "button.secondaryHoverBackground": "#26233a",
-        "charts.blue": "#9ccfd8",
-        "charts.foreground": "#e0def4",
-        "charts.green": "#31748f",
-        "charts.lines": "#908caa",
-        "charts.orange": "#ebbcba",
-        "charts.purple": "#c4a7e7",
-        "charts.red": "#eb6f92",
-        "charts.yellow": "#f6c177",
-        "checkbox.background": "#1f1d2e",
-        "checkbox.border": "#6e6a8633",
-        "checkbox.foreground": "#e0def4",
-        "debugExceptionWidget.background": "#1f1d2e",
-        "debugExceptionWidget.border": "#6e6a8633",
-        "debugIcon.breakpointCurrentStackframeForeground": "#908caa",
-        "debugIcon.breakpointDisabledForeground": "#908caa",
-        "debugIcon.breakpointForeground": "#908caa",
-        "debugIcon.breakpointStackframeForeground": "#908caa",
-        "debugIcon.breakpointUnverifiedForeground": "#908caa",
-        "debugIcon.continueForeground": "#908caa",
-        "debugIcon.disconnectForeground": "#908caa",
-        "debugIcon.pauseForeground": "#908caa",
-        "debugIcon.restartForeground": "#908caa",
-        "debugIcon.startForeground": "#908caa",
-        "debugIcon.stepBackForeground": "#908caa",
-        "debugIcon.stepIntoForeground": "#908caa",
-        "debugIcon.stepOutForeground": "#908caa",
-        "debugIcon.stepOverForeground": "#908caa",
-        "debugIcon.stopForeground": "#eb6f92",
-        "debugToolBar.background": "#1f1d2e",
-        "debugToolBar.border": "#26233a",
-        "descriptionForeground": "#908caa",
-        "diffEditor.border": "#26233a",
-        "diffEditor.diagonalFill": "#6e6a8666",
-        "diffEditor.insertedLineBackground": "#9ccfd826",
-        "diffEditor.insertedTextBackground": "#9ccfd826",
-        "diffEditor.removedLineBackground": "#eb6f9226",
-        "diffEditor.removedTextBackground": "#eb6f9226",
-        "diffEditorOverview.insertedForeground": "#9ccfd880",
-        "diffEditorOverview.removedForeground": "#eb6f9280",
-        "dropdown.background": "#1f1d2e",
-        "dropdown.border": "#6e6a8633",
-        "dropdown.foreground": "#e0def4",
-        "dropdown.listBackground": "#1f1d2e",
-        "editor.background": "#191724",
-        "editor.findMatchBackground": "#6e6a8666",
-        "editor.findMatchHighlightBackground": "#6e6a8666",
-        "editor.findRangeHighlightBackground": "#6e6a8666",
-        "editor.findRangeHighlightBorder": "#000000",
-        "editor.focusedStackFrameHighlightBackground": "#6e6a8633",
-        "editor.foldBackground": "#1f1d2e",
-        "editor.foreground": "#e0def4",
-        "editor.hoverHighlightBackground": "#000000",
-        "editor.inactiveSelectionBackground": "#6e6a861a",
-        "editor.inlineValuesBackground": "#000000",
-        "editor.inlineValuesForeground": "#908caa",
-        "editor.lineHighlightBackground": "#6e6a861a",
-        "editor.lineHighlightBorder": "#000000",
-        "editor.linkedEditingBackground": "#1f1d2e",
-        "editor.rangeHighlightBackground": "#6e6a861a",
-        "editor.selectionBackground": "#6e6a8633",
-        "editor.selectionForeground": "#e0def4",
-        "editor.selectionHighlightBackground": "#6e6a8633",
-        "editor.selectionHighlightBorder": "#191724",
-        "editor.snippetFinalTabstopHighlightBackground": "#6e6a8633",
-        "editor.snippetFinalTabstopHighlightBorder": "#1f1d2e",
-        "editor.snippetTabstopHighlightBackground": "#6e6a8633",
-        "editor.snippetTabstopHighlightBorder": "#1f1d2e",
-        "editor.stackFrameHighlightBackground": "#6e6a8633",
-        "editor.symbolHighlightBackground": "#6e6a8633",
-        "editor.symbolHighlightBorder": "#000000",
-        "editor.wordHighlightBackground": "#6e6a8633",
-        "editor.wordHighlightBorder": "#000000",
-        "editor.wordHighlightStrongBackground": "#6e6a8633",
-        "editor.wordHighlightStrongBorder": "#6e6a8633",
-        "editorBracketHighlight.foreground1": "#eb6f9280",
-        "editorBracketHighlight.foreground2": "#31748f80",
-        "editorBracketHighlight.foreground3": "#f6c17780",
-        "editorBracketHighlight.foreground4": "#9ccfd880",
-        "editorBracketHighlight.foreground5": "#ebbcba80",
-        "editorBracketHighlight.foreground6": "#c4a7e780",
-        "editorBracketMatch.background": "#000000",
-        "editorBracketMatch.border": "#908caa",
-        "editorBracketPairGuide.activeBackground1": "#31748f",
-        "editorBracketPairGuide.activeBackground2": "#ebbcba",
-        "editorBracketPairGuide.activeBackground3": "#c4a7e7",
-        "editorBracketPairGuide.activeBackground4": "#9ccfd8",
-        "editorBracketPairGuide.activeBackground5": "#f6c177",
-        "editorBracketPairGuide.activeBackground6": "#eb6f92",
-        "editorBracketPairGuide.background1": "#31748f80",
-        "editorBracketPairGuide.background2": "#ebbcba80",
-        "editorBracketPairGuide.background3": "#c4a7e780",
-        "editorBracketPairGuide.background4": "#9ccfd880",
-        "editorBracketPairGuide.background5": "#f6c17780",
-        "editorBracketPairGuide.background6": "#eb6f9280",
-        "editorCodeLens.foreground": "#ebbcba",
-        "editorCursor.background": "#e0def4",
-        "editorCursor.foreground": "#6e6a86",
-        "editorError.border": "#000000",
-        "editorError.foreground": "#eb6f92",
-        "editorGhostText.foreground": "#908caa",
-        "editorGroup.border": "#000000",
-        "editorGroup.dropBackground": "#1f1d2e",
-        "editorGroup.emptyBackground": "#000000",
-        "editorGroup.focusedEmptyBorder": "#000000",
-        "editorGroupHeader.noTabsBackground": "#000000",
-        "editorGroupHeader.tabsBackground": "#000000",
-        "editorGroupHeader.tabsBorder": "#000000",
-        "editorGutter.addedBackground": "#9ccfd8",
-        "editorGutter.background": "#191724",
-        "editorGutter.commentRangeForeground": "#908caa",
-        "editorGutter.deletedBackground": "#eb6f92",
-        "editorGutter.foldingControlForeground": "#c4a7e7",
-        "editorGutter.modifiedBackground": "#ebbcba",
-        "editorHint.border": "#000000",
-        "editorHint.foreground": "#908caa",
-        "editorHoverWidget.background": "#1f1d2e",
-        "editorHoverWidget.border": "#6e6a8680",
-        "editorHoverWidget.foreground": "#908caa",
-        "editorHoverWidget.highlightForeground": "#e0def4",
-        "editorHoverWidget.statusBarBackground": "#000000",
-        "editorIndentGuide.activeBackground": "#6e6a86",
-        "editorIndentGuide.background": "#6e6a8666",
-        "editorInfo.border": "#26233a",
-        "editorInfo.foreground": "#9ccfd8",
-        "editorInlayHint.background": "#26233a",
-        "editorInlayHint.foreground": "#908caa",
-        "editorInlayHint.parameterBackground": "#26233a",
-        "editorInlayHint.parameterForeground": "#c4a7e7",
-        "editorInlayHint.typeBackground": "#26233a",
-        "editorInlayHint.typeForeground": "#9ccfd8",
-        "editorLightBulb.foreground": "#31748f",
-        "editorLightBulbAutoFix.foreground": "#ebbcba",
-        "editorLineNumber.activeForeground": "#e0def4",
-        "editorLineNumber.foreground": "#908caa",
-        "editorLink.activeForeground": "#ebbcba",
-        "editorMarkerNavigation.background": "#1f1d2e",
-        "editorMarkerNavigationError.background": "#1f1d2e",
-        "editorMarkerNavigationInfo.background": "#1f1d2e",
-        "editorMarkerNavigationWarning.background": "#1f1d2e",
-        "editorOverviewRuler.addedForeground": "#9ccfd880",
-        "editorOverviewRuler.background": "#191724",
-        "editorOverviewRuler.border": "#6e6a8666",
-        "editorOverviewRuler.bracketMatchForeground": "#908caa",
-        "editorOverviewRuler.commonContentForeground": "#6e6a861a",
-        "editorOverviewRuler.currentContentForeground": "#6e6a8633",
-        "editorOverviewRuler.deletedForeground": "#eb6f9280",
-        "editorOverviewRuler.errorForeground": "#eb6f9280",
-        "editorOverviewRuler.findMatchForeground": "#6e6a8666",
-        "editorOverviewRuler.incomingContentForeground": "#c4a7e780",
-        "editorOverviewRuler.infoForeground": "#9ccfd880",
-        "editorOverviewRuler.modifiedForeground": "#ebbcba80",
-        "editorOverviewRuler.rangeHighlightForeground": "#6e6a8666",
-        "editorOverviewRuler.selectionHighlightForeground": "#6e6a8666",
-        "editorOverviewRuler.warningForeground": "#f6c17780",
-        "editorOverviewRuler.wordHighlightForeground": "#6e6a8633",
-        "editorOverviewRuler.wordHighlightStrongForeground": "#6e6a8666",
-        "editorPane.background": "#000000",
-        "editorRuler.foreground": "#6e6a8666",
-        "editorSuggestWidget.background": "#1f1d2e",
-        "editorSuggestWidget.border": "#000000",
-        "editorSuggestWidget.focusHighlightForeground": "#ebbcba",
-        "editorSuggestWidget.foreground": "#908caa",
-        "editorSuggestWidget.highlightForeground": "#ebbcba",
-        "editorSuggestWidget.selectedBackground": "#6e6a8633",
-        "editorSuggestWidget.selectedForeground": "#e0def4",
-        "editorSuggestWidget.selectedIconForeground": "#e0def4",
-        "editorUnnecessaryCode.border": "#000000",
-        "editorUnnecessaryCode.opacity": "#e0def480",
-        "editorWarning.border": "#000000",
-        "editorWarning.foreground": "#f6c177",
-        "editorWhitespace.foreground": "#6e6a86",
-        "editorWidget.background": "#1f1d2e",
-        "editorWidget.border": "#26233a",
-        "editorWidget.foreground": "#908caa",
-        "editorWidget.resizeBorder": "#6e6a86",
-        "errorForeground": "#eb6f92",
-        "extensionBadge.remoteBackground": "#c4a7e7",
-        "extensionBadge.remoteForeground": "#191724",
-        "extensionButton.prominentBackground": "#ebbcba",
-        "extensionButton.prominentForeground": "#191724",
-        "extensionButton.prominentHoverBackground": "#ebbcbae6",
-        "extensionIcon.preReleaseForeground": "#31748f",
-        "extensionIcon.starForeground": "#ebbcba",
-        "extensionIcon.verifiedForeground": "#c4a7e7",
-        "focusBorder": "#6e6a8633",
-        "foreground": "#e0def4",
-        "gitDecoration.addedResourceForeground": "#9ccfd8",
-        "gitDecoration.conflictingResourceForeground": "#eb6f92",
-        "gitDecoration.deletedResourceForeground": "#908caa",
-        "gitDecoration.ignoredResourceForeground": "#6e6a86",
-        "gitDecoration.modifiedResourceForeground": "#ebbcba",
-        "gitDecoration.renamedResourceForeground": "#31748f",
-        "gitDecoration.stageDeletedResourceForeground": "#eb6f92",
-        "gitDecoration.stageModifiedResourceForeground": "#c4a7e7",
-        "gitDecoration.submoduleResourceForeground": "#f6c177",
-        "gitDecoration.untrackedResourceForeground": "#f6c177",
-        "icon.foreground": "#908caa",
-        "input.background": "#26233a80",
-        "input.border": "#6e6a8633",
-        "input.foreground": "#e0def4",
-        "input.placeholderForeground": "#908caa",
-        "inputOption.activeBackground": "#ebbcba26",
-        "inputOption.activeForeground": "#ebbcba",
-        "inputValidation.errorBackground": "#1f1d2e",
-        "inputValidation.errorBorder": "#6e6a8666",
-        "inputValidation.errorForeground": "#eb6f92",
-        "inputValidation.infoBackground": "#1f1d2e",
-        "inputValidation.infoBorder": "#6e6a8666",
-        "inputValidation.infoForeground": "#9ccfd8",
-        "inputValidation.warningBackground": "#1f1d2e",
-        "inputValidation.warningBorder": "#6e6a8666",
-        "inputValidation.warningForeground": "#9ccfd880",
-        "keybindingLabel.background": "#26233a",
-        "keybindingLabel.border": "#6e6a8666",
-        "keybindingLabel.bottomBorder": "#6e6a8666",
-        "keybindingLabel.foreground": "#c4a7e7",
-        "keybindingTable.headerBackground": "#26233a",
-        "keybindingTable.rowsBackground": "#1f1d2e",
-        "list.activeSelectionBackground": "#6e6a8633",
-        "list.activeSelectionForeground": "#e0def4",
-        "list.deemphasizedForeground": "#908caa",
-        "list.dropBackground": "#1f1d2e",
-        "list.errorForeground": "#eb6f92",
-        "list.filterMatchBackground": "#1f1d2e",
-        "list.filterMatchBorder": "#ebbcba",
-        "list.focusBackground": "#6e6a8666",
-        "list.focusForeground": "#e0def4",
-        "list.focusOutline": "#6e6a8633",
-        "list.highlightForeground": "#ebbcba",
-        "list.hoverBackground": "#6e6a861a",
-        "list.hoverForeground": "#e0def4",
-        "list.inactiveFocusBackground": "#6e6a861a",
-        "list.inactiveSelectionBackground": "#1f1d2e",
-        "list.inactiveSelectionForeground": "#e0def4",
-        "list.invalidItemForeground": "#eb6f92",
-        "list.warningForeground": "#f6c177",
-        "listFilterWidget.background": "#1f1d2e",
-        "listFilterWidget.noMatchesOutline": "#eb6f92",
-        "listFilterWidget.outline": "#26233a",
-        "menu.background": "#1f1d2e",
-        "menu.border": "#6e6a861a",
-        "menu.foreground": "#e0def4",
-        "menu.selectionBackground": "#6e6a8633",
-        "menu.selectionBorder": "#26233a",
-        "menu.selectionForeground": "#e0def4",
-        "menu.separatorBackground": "#6e6a8666",
-        "menubar.selectionBackground": "#6e6a8633",
-        "menubar.selectionBorder": "#6e6a861a",
-        "menubar.selectionForeground": "#e0def4",
-        "merge.border": "#26233a",
-        "merge.commonContentBackground": "#6e6a8633",
-        "merge.commonHeaderBackground": "#6e6a8633",
-        "merge.currentContentBackground": "#f6c17780",
-        "merge.currentHeaderBackground": "#f6c17780",
-        "merge.incomingContentBackground": "#9ccfd880",
-        "merge.incomingHeaderBackground": "#9ccfd880",
-        "minimap.background": "#1f1d2e",
-        "minimap.errorHighlight": "#eb6f9280",
-        "minimap.findMatchHighlight": "#6e6a8633",
-        "minimap.selectionHighlight": "#6e6a8633",
-        "minimap.warningHighlight": "#f6c17780",
-        "minimapGutter.addedBackground": "#9ccfd8",
-        "minimapGutter.deletedBackground": "#eb6f92",
-        "minimapGutter.modifiedBackground": "#ebbcba",
-        "minimapSlider.activeBackground": "#6e6a8666",
-        "minimapSlider.background": "#6e6a8633",
-        "minimapSlider.hoverBackground": "#6e6a8633",
-        "notebook.cellBorderColor": "#9ccfd880",
-        "notebook.cellEditorBackground": "#1f1d2e",
-        "notebook.cellHoverBackground": "#26233a80",
-        "notebook.focusedCellBackground": "#6e6a861a",
-        "notebook.focusedCellBorder": "#9ccfd8",
-        "notebook.outputContainerBackgroundColor": "#6e6a861a",
-        "notificationCenter.border": "#6e6a8633",
-        "notificationCenterHeader.background": "#1f1d2e",
-        "notificationCenterHeader.foreground": "#908caa",
-        "notificationLink.foreground": "#c4a7e7",
-        "notifications.background": "#1f1d2e",
-        "notifications.border": "#6e6a8633",
-        "notifications.foreground": "#e0def4",
-        "notificationsErrorIcon.foreground": "#eb6f92",
-        "notificationsInfoIcon.foreground": "#9ccfd8",
-        "notificationsWarningIcon.foreground": "#f6c177",
-        "notificationToast.border": "#6e6a8633",
-        "panel.background": "#1f1d2e",
-        "panel.border": "#000000",
-        "panel.dropBorder": "#26233a",
-        "panelInput.border": "#1f1d2e",
-        "panelSection.dropBackground": "#6e6a8633",
-        "panelSectionHeader.background": "#1f1d2e",
-        "panelSectionHeader.foreground": "#e0def4",
-        "panelTitle.activeBorder": "#6e6a8666",
-        "panelTitle.activeForeground": "#e0def4",
-        "panelTitle.inactiveForeground": "#908caa",
-        "peekView.border": "#26233a",
-        "peekViewEditor.background": "#1f1d2e",
-        "peekViewEditor.matchHighlightBackground": "#6e6a8666",
-        "peekViewResult.background": "#1f1d2e",
-        "peekViewResult.fileForeground": "#908caa",
-        "peekViewResult.lineForeground": "#908caa",
-        "peekViewResult.matchHighlightBackground": "#6e6a8666",
-        "peekViewResult.selectionBackground": "#6e6a8633",
-        "peekViewResult.selectionForeground": "#e0def4",
-        "peekViewTitle.background": "#26233a",
-        "peekViewTitleDescription.foreground": "#908caa",
-        "pickerGroup.border": "#6e6a8666",
-        "pickerGroup.foreground": "#c4a7e7",
-        "ports.iconRunningProcessForeground": "#ebbcba",
-        "problemsErrorIcon.foreground": "#eb6f92",
-        "problemsInfoIcon.foreground": "#9ccfd8",
-        "problemsWarningIcon.foreground": "#f6c177",
-        "progressBar.background": "#ebbcba",
-        "quickInput.background": "#1f1d2e",
-        "quickInput.foreground": "#908caa",
-        "quickInputList.focusBackground": "#6e6a8633",
-        "quickInputList.focusForeground": "#e0def4",
-        "quickInputList.focusIconForeground": "#e0def4",
-        "scrollbar.shadow": "#1f1d2e4d",
-        "scrollbarSlider.activeBackground": "#31748f80",
-        "scrollbarSlider.background": "#6e6a8633",
-        "scrollbarSlider.hoverBackground": "#6e6a8666",
-        "searchEditor.findMatchBackground": "#6e6a8633",
-        "selection.background": "#6e6a8666",
-        "settings.focusedRowBackground": "#1f1d2e",
-        "settings.headerForeground": "#e0def4",
-        "settings.modifiedItemIndicator": "#ebbcba",
-        "settings.focusedRowBorder": "#6e6a8633",
-        "settings.rowHoverBackground": "#1f1d2e",
-        "sideBar.background": "#191724",
-        "sideBar.dropBackground": "#1f1d2e",
-        "sideBar.foreground": "#908caa",
-        "sideBarSectionHeader.background": "#000000",
-        "sideBarSectionHeader.border": "#6e6a8633",
-        "statusBar.background": "#191724",
-        "statusBar.debuggingBackground": "#c4a7e7",
-        "statusBar.debuggingForeground": "#191724",
-        "statusBar.foreground": "#908caa",
-        "statusBar.noFolderBackground": "#191724",
-        "statusBar.noFolderForeground": "#908caa",
-        "statusBarItem.activeBackground": "#6e6a8666",
-        "statusBarItem.hoverBackground": "#6e6a8633",
-        "statusBarItem.prominentBackground": "#26233a",
-        "statusBarItem.prominentForeground": "#e0def4",
-        "statusBarItem.prominentHoverBackground": "#6e6a8633",
-        "statusBarItem.remoteBackground": "#191724",
-        "statusBarItem.remoteForeground": "#f6c177",
-        "statusBarItem.errorBackground": "#191724",
-        "statusBarItem.errorForeground": "#eb6f92",
-        "symbolIcon.arrayForeground": "#908caa",
-        "symbolIcon.classForeground": "#908caa",
-        "symbolIcon.colorForeground": "#908caa",
-        "symbolIcon.constantForeground": "#908caa",
-        "symbolIcon.constructorForeground": "#908caa",
-        "symbolIcon.enumeratorForeground": "#908caa",
-        "symbolIcon.enumeratorMemberForeground": "#908caa",
-        "symbolIcon.eventForeground": "#908caa",
-        "symbolIcon.fieldForeground": "#908caa",
-        "symbolIcon.fileForeground": "#908caa",
-        "symbolIcon.folderForeground": "#908caa",
-        "symbolIcon.functionForeground": "#908caa",
-        "symbolIcon.interfaceForeground": "#908caa",
-        "symbolIcon.keyForeground": "#908caa",
-        "symbolIcon.keywordForeground": "#908caa",
-        "symbolIcon.methodForeground": "#908caa",
-        "symbolIcon.moduleForeground": "#908caa",
-        "symbolIcon.namespaceForeground": "#908caa",
-        "symbolIcon.nullForeground": "#908caa",
-        "symbolIcon.numberForeground": "#908caa",
-        "symbolIcon.objectForeground": "#908caa",
-        "symbolIcon.operatorForeground": "#908caa",
-        "symbolIcon.packageForeground": "#908caa",
-        "symbolIcon.propertyForeground": "#908caa",
-        "symbolIcon.referenceForeground": "#908caa",
-        "symbolIcon.snippetForeground": "#908caa",
-        "symbolIcon.stringForeground": "#908caa",
-        "symbolIcon.structForeground": "#908caa",
-        "symbolIcon.textForeground": "#908caa",
-        "symbolIcon.typeParameterForeground": "#908caa",
-        "symbolIcon.unitForeground": "#908caa",
-        "symbolIcon.variableForeground": "#908caa",
-        "tab.activeBackground": "#6e6a861a",
-        "tab.activeForeground": "#e0def4",
-        "tab.activeModifiedBorder": "#9ccfd8",
-        "tab.border": "#000000",
-        "tab.hoverBackground": "#6e6a8633",
-        "tab.inactiveBackground": "#000000",
-        "tab.inactiveForeground": "#908caa",
-        "tab.inactiveModifiedBorder": "#9ccfd880",
-        "tab.lastPinnedBorder": "#6e6a86",
-        "tab.unfocusedActiveBackground": "#000000",
-        "tab.unfocusedHoverBackground": "#000000",
-        "tab.unfocusedInactiveBackground": "#000000",
-        "tab.unfocusedInactiveModifiedBorder": "#9ccfd880",
-        "terminal.ansiBlack": "#26233a",
-        "terminal.ansiBlue": "#9ccfd8",
-        "terminal.ansiBrightBlack": "#908caa",
-        "terminal.ansiBrightBlue": "#9ccfd8",
-        "terminal.ansiBrightCyan": "#ebbcba",
-        "terminal.ansiBrightGreen": "#31748f",
-        "terminal.ansiBrightMagenta": "#c4a7e7",
-        "terminal.ansiBrightRed": "#eb6f92",
-        "terminal.ansiBrightWhite": "#e0def4",
-        "terminal.ansiBrightYellow": "#f6c177",
-        "terminal.ansiCyan": "#ebbcba",
-        "terminal.ansiGreen": "#31748f",
-        "terminal.ansiMagenta": "#c4a7e7",
-        "terminal.ansiRed": "#eb6f92",
-        "terminal.ansiWhite": "#e0def4",
-        "terminal.ansiYellow": "#f6c177",
-        "terminal.dropBackground": "#6e6a8633",
-        "terminal.foreground": "#e0def4",
-        "terminal.selectionBackground": "#6e6a8633",
-        "terminal.tab.activeBorder": "#e0def4",
-        "terminalCursor.background": "#e0def4",
-        "terminalCursor.foreground": "#6e6a86",
-        "textBlockQuote.background": "#1f1d2e",
-        "textBlockQuote.border": "#6e6a8633",
-        "textCodeBlock.background": "#1f1d2e",
-        "textLink.activeForeground": "#c4a7e7e6",
-        "textLink.foreground": "#c4a7e7",
-        "textPreformat.foreground": "#f6c177",
-        "textSeparator.foreground": "#908caa",
-        "titleBar.activeBackground": "#191724",
-        "titleBar.activeForeground": "#908caa",
-        "titleBar.inactiveBackground": "#1f1d2e",
-        "titleBar.inactiveForeground": "#908caa",
-        "toolbar.activeBackground": "#6e6a8666",
-        "toolbar.hoverBackground": "#6e6a8633",
-        "tree.indentGuidesStroke": "#908caa",
-        "walkThrough.embeddedEditorBackground": "#191724",
-        "welcomePage.background": "#191724",
-        "welcomePage.buttonBackground": "#1f1d2e",
-        "welcomePage.buttonHoverBackground": "#26233a",
-        "widget.shadow": "#1f1d2e4d",
-        "window.activeBorder": "#1f1d2e",
-        "window.inactiveBorder": "#1f1d2e"
-    },
-    "tokenColors": [
-        {
-            "scope": ["comment"],
-            "settings": {
-                "foreground": "#6e6a86",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["constant"],
-            "settings": {
-                "foreground": "#31748f"
-            }
-        },
-        {
-            "scope": ["constant.numeric", "constant.language"],
-            "settings": {
-                "foreground": "#ebbcba"
-            }
-        },
-        {
-            "scope": ["entity.name"],
-            "settings": {
-                "foreground": "#ebbcba"
-            }
-        },
-        {
-            "scope": [
-                "entity.name.section",
-                "entity.name.tag",
-                "entity.name.namespace",
-                "entity.name.type"
-            ],
-            "settings": {
-                "foreground": "#9ccfd8"
-            }
-        },
-        {
-            "scope": ["entity.other.attribute-name", "entity.other.inherited-class"],
-            "settings": {
-                "foreground": "#c4a7e7",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["invalid"],
-            "settings": {
-                "foreground": "#eb6f92"
-            }
-        },
-        {
-            "scope": ["invalid.deprecated"],
-            "settings": {
-                "foreground": "#908caa"
-            }
-        },
-        {
-            "scope": ["keyword"],
-            "settings": {
-                "foreground": "#31748f"
-            }
-        },
-        {
-            "scope": ["markup.inserted.diff"],
-            "settings": {
-                "foreground": "#9ccfd8"
-            }
-        },
-        {
-            "scope": ["markup.deleted.diff"],
-            "settings": {
-                "foreground": "#eb6f92"
-            }
-        },
-        {
-            "scope": "markup.heading",
-            "settings": {
-                "fontStyle": "bold"
-            }
-        },
-        {
-            "scope": "markup.bold.markdown",
-            "settings": {
-                "fontStyle": "bold"
-            }
-        },
-        {
-            "scope": "markup.italic.markdown",
-            "settings": {
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["meta.diff.range"],
-            "settings": {
-                "foreground": "#c4a7e7"
-            }
-        },
-        {
-            "scope": ["meta.tag", "meta.brace"],
-            "settings": {
-                "foreground": "#e0def4"
-            }
-        },
-        {
-            "scope": ["meta.import", "meta.export"],
-            "settings": {
-                "foreground": "#31748f"
-            }
-        },
-        {
-            "scope": "meta.directive.vue",
-            "settings": {
-                "foreground": "#c4a7e7",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": "meta.property-name.css",
-            "settings": {
-                "foreground": "#9ccfd8"
-            }
-        },
-        {
-            "scope": "meta.property-value.css",
-            "settings": {
-                "foreground": "#f6c177"
-            }
-        },
-        {
-            "scope": "meta.tag.other.html",
-            "settings": {
-                "foreground": "#908caa"
-            }
-        },
-        {
-            "scope": ["punctuation"],
-            "settings": {
-                "foreground": "#908caa"
-            }
-        },
-        {
-            "scope": ["punctuation.accessor"],
-            "settings": {
-                "foreground": "#31748f"
-            }
-        },
-        {
-            "scope": ["punctuation.definition.string"],
-            "settings": {
-                "foreground": "#f6c177"
-            }
-        },
-        {
-            "scope": ["punctuation.definition.tag"],
-            "settings": {
-                "foreground": "#6e6a86"
-            }
-        },
-        {
-            "scope": ["storage.type", "storage.modifier"],
-            "settings": {
-                "foreground": "#31748f"
-            }
-        },
-        {
-            "scope": ["string"],
-            "settings": {
-                "foreground": "#f6c177"
-            }
-        },
-        {
-            "scope": ["support"],
-            "settings": {
-                "foreground": "#9ccfd8"
-            }
-        },
-        {
-            "scope": ["support.constant"],
-            "settings": {
-                "foreground": "#f6c177"
-            }
-        },
-        {
-            "scope": ["support.function"],
-            "settings": {
-                "foreground": "#eb6f92",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": ["variable"],
-            "settings": {
-                "foreground": "#ebbcba",
-                "fontStyle": "italic"
-            }
-        },
-        {
-            "scope": [
-                "variable.other",
-                "variable.language",
-                "variable.function",
-                "variable.argument"
-            ],
-            "settings": {
-                "foreground": "#e0def4"
-            }
-        },
-        {
-            "scope": ["variable.parameter"],
-            "settings": {
-                "foreground": "#c4a7e7"
-            }
-        }
-    ]
+	"name": "Rosé Pine",
+	"type": "dark",
+	"colors": {
+		"activityBar.activeBorder": "#e0def4",
+		"activityBar.background": "#191724",
+		"activityBar.dropBorder": "#26233a",
+		"activityBar.foreground": "#e0def4",
+		"activityBar.inactiveForeground": "#908caa",
+		"activityBarBadge.background": "#ebbcba",
+		"activityBarBadge.foreground": "#191724",
+		"badge.background": "#ebbcba",
+		"badge.foreground": "#191724",
+		"banner.background": "#1f1d2e",
+		"banner.foreground": "#e0def4",
+		"banner.iconForeground": "#908caa",
+		"breadcrumb.activeSelectionForeground": "#ebbcba",
+		"breadcrumb.background": "#191724",
+		"breadcrumb.focusForeground": "#908caa",
+		"breadcrumb.foreground": "#6e6a86",
+		"breadcrumbPicker.background": "#1f1d2e",
+		"button.background": "#ebbcba",
+		"button.foreground": "#191724",
+		"button.hoverBackground": "#ebbcbae6",
+		"button.secondaryBackground": "#1f1d2e",
+		"button.secondaryForeground": "#e0def4",
+		"button.secondaryHoverBackground": "#26233a",
+		"charts.blue": "#9ccfd8",
+		"charts.foreground": "#e0def4",
+		"charts.green": "#31748f",
+		"charts.lines": "#908caa",
+		"charts.orange": "#ebbcba",
+		"charts.purple": "#c4a7e7",
+		"charts.red": "#eb6f92",
+		"charts.yellow": "#f6c177",
+		"checkbox.background": "#1f1d2e",
+		"checkbox.border": "#6e6a8633",
+		"checkbox.foreground": "#e0def4",
+		"debugExceptionWidget.background": "#1f1d2e",
+		"debugExceptionWidget.border": "#6e6a8633",
+		"debugIcon.breakpointCurrentStackframeForeground": "#908caa",
+		"debugIcon.breakpointDisabledForeground": "#908caa",
+		"debugIcon.breakpointForeground": "#908caa",
+		"debugIcon.breakpointStackframeForeground": "#908caa",
+		"debugIcon.breakpointUnverifiedForeground": "#908caa",
+		"debugIcon.continueForeground": "#908caa",
+		"debugIcon.disconnectForeground": "#908caa",
+		"debugIcon.pauseForeground": "#908caa",
+		"debugIcon.restartForeground": "#908caa",
+		"debugIcon.startForeground": "#908caa",
+		"debugIcon.stepBackForeground": "#908caa",
+		"debugIcon.stepIntoForeground": "#908caa",
+		"debugIcon.stepOutForeground": "#908caa",
+		"debugIcon.stepOverForeground": "#908caa",
+		"debugIcon.stopForeground": "#eb6f92",
+		"debugToolBar.background": "#1f1d2e",
+		"debugToolBar.border": "#26233a",
+		"descriptionForeground": "#908caa",
+		"diffEditor.border": "#26233a",
+		"diffEditor.diagonalFill": "#6e6a8666",
+		"diffEditor.insertedLineBackground": "#9ccfd826",
+		"diffEditor.insertedTextBackground": "#9ccfd826",
+		"diffEditor.removedLineBackground": "#eb6f9226",
+		"diffEditor.removedTextBackground": "#eb6f9226",
+		"diffEditorOverview.insertedForeground": "#9ccfd880",
+		"diffEditorOverview.removedForeground": "#eb6f9280",
+		"dropdown.background": "#1f1d2e",
+		"dropdown.border": "#6e6a8633",
+		"dropdown.foreground": "#e0def4",
+		"dropdown.listBackground": "#1f1d2e",
+		"editor.background": "#191724",
+		"editor.findMatchBackground": "#6e6a8666",
+		"editor.findMatchHighlightBackground": "#6e6a8666",
+		"editor.findRangeHighlightBackground": "#6e6a8666",
+		"editor.findRangeHighlightBorder": "#0000",
+		"editor.focusedStackFrameHighlightBackground": "#6e6a8633",
+		"editor.foldBackground": "#1f1d2e",
+		"editor.foreground": "#e0def4",
+		"editor.hoverHighlightBackground": "#0000",
+		"editor.inactiveSelectionBackground": "#6e6a861a",
+		"editor.inlineValuesBackground": "#0000",
+		"editor.inlineValuesForeground": "#908caa",
+		"editor.lineHighlightBackground": "#6e6a861a",
+		"editor.lineHighlightBorder": "#0000",
+		"editor.linkedEditingBackground": "#1f1d2e",
+		"editor.rangeHighlightBackground": "#6e6a861a",
+		"editor.selectionBackground": "#6e6a8633",
+		"editor.selectionForeground": "#e0def4",
+		"editor.selectionHighlightBackground": "#6e6a8633",
+		"editor.selectionHighlightBorder": "#191724",
+		"editor.snippetFinalTabstopHighlightBackground": "#6e6a8633",
+		"editor.snippetFinalTabstopHighlightBorder": "#1f1d2e",
+		"editor.snippetTabstopHighlightBackground": "#6e6a8633",
+		"editor.snippetTabstopHighlightBorder": "#1f1d2e",
+		"editor.stackFrameHighlightBackground": "#6e6a8633",
+		"editor.symbolHighlightBackground": "#6e6a8633",
+		"editor.symbolHighlightBorder": "#0000",
+		"editor.wordHighlightBackground": "#6e6a8633",
+		"editor.wordHighlightBorder": "#0000",
+		"editor.wordHighlightStrongBackground": "#6e6a8633",
+		"editor.wordHighlightStrongBorder": "#6e6a8633",
+		"editorBracketHighlight.foreground1": "#eb6f9280",
+		"editorBracketHighlight.foreground2": "#31748f80",
+		"editorBracketHighlight.foreground3": "#f6c17780",
+		"editorBracketHighlight.foreground4": "#9ccfd880",
+		"editorBracketHighlight.foreground5": "#ebbcba80",
+		"editorBracketHighlight.foreground6": "#c4a7e780",
+		"editorBracketMatch.background": "#0000",
+		"editorBracketMatch.border": "#908caa",
+		"editorBracketPairGuide.activeBackground1": "#31748f",
+		"editorBracketPairGuide.activeBackground2": "#ebbcba",
+		"editorBracketPairGuide.activeBackground3": "#c4a7e7",
+		"editorBracketPairGuide.activeBackground4": "#9ccfd8",
+		"editorBracketPairGuide.activeBackground5": "#f6c177",
+		"editorBracketPairGuide.activeBackground6": "#eb6f92",
+		"editorBracketPairGuide.background1": "#31748f80",
+		"editorBracketPairGuide.background2": "#ebbcba80",
+		"editorBracketPairGuide.background3": "#c4a7e780",
+		"editorBracketPairGuide.background4": "#9ccfd880",
+		"editorBracketPairGuide.background5": "#f6c17780",
+		"editorBracketPairGuide.background6": "#eb6f9280",
+		"editorCodeLens.foreground": "#ebbcba",
+		"editorCursor.background": "#e0def4",
+		"editorCursor.foreground": "#6e6a86",
+		"editorError.border": "#0000",
+		"editorError.foreground": "#eb6f92",
+		"editorGhostText.foreground": "#908caa",
+		"editorGroup.border": "#0000",
+		"editorGroup.dropBackground": "#1f1d2e",
+		"editorGroup.emptyBackground": "#0000",
+		"editorGroup.focusedEmptyBorder": "#0000",
+		"editorGroupHeader.noTabsBackground": "#0000",
+		"editorGroupHeader.tabsBackground": "#0000",
+		"editorGroupHeader.tabsBorder": "#0000",
+		"editorGutter.addedBackground": "#9ccfd8",
+		"editorGutter.background": "#191724",
+		"editorGutter.commentRangeForeground": "#908caa",
+		"editorGutter.deletedBackground": "#eb6f92",
+		"editorGutter.foldingControlForeground": "#c4a7e7",
+		"editorGutter.modifiedBackground": "#ebbcba",
+		"editorHint.border": "#0000",
+		"editorHint.foreground": "#908caa",
+		"editorHoverWidget.background": "#1f1d2e",
+		"editorHoverWidget.border": "#6e6a8680",
+		"editorHoverWidget.foreground": "#908caa",
+		"editorHoverWidget.highlightForeground": "#e0def4",
+		"editorHoverWidget.statusBarBackground": "#0000",
+		"editorIndentGuide.activeBackground": "#6e6a86",
+		"editorIndentGuide.background": "#6e6a8666",
+		"editorInfo.border": "#26233a",
+		"editorInfo.foreground": "#9ccfd8",
+		"editorInlayHint.background": "#26233a",
+		"editorInlayHint.foreground": "#908caa",
+		"editorInlayHint.parameterBackground": "#26233a",
+		"editorInlayHint.parameterForeground": "#c4a7e7",
+		"editorInlayHint.typeBackground": "#26233a",
+		"editorInlayHint.typeForeground": "#9ccfd8",
+		"editorLightBulb.foreground": "#31748f",
+		"editorLightBulbAutoFix.foreground": "#ebbcba",
+		"editorLineNumber.activeForeground": "#e0def4",
+		"editorLineNumber.foreground": "#908caa",
+		"editorLink.activeForeground": "#ebbcba",
+		"editorMarkerNavigation.background": "#1f1d2e",
+		"editorMarkerNavigationError.background": "#1f1d2e",
+		"editorMarkerNavigationInfo.background": "#1f1d2e",
+		"editorMarkerNavigationWarning.background": "#1f1d2e",
+		"editorOverviewRuler.addedForeground": "#9ccfd880",
+		"editorOverviewRuler.background": "#191724",
+		"editorOverviewRuler.border": "#6e6a8666",
+		"editorOverviewRuler.bracketMatchForeground": "#908caa",
+		"editorOverviewRuler.commonContentForeground": "#6e6a861a",
+		"editorOverviewRuler.currentContentForeground": "#6e6a8633",
+		"editorOverviewRuler.deletedForeground": "#eb6f9280",
+		"editorOverviewRuler.errorForeground": "#eb6f9280",
+		"editorOverviewRuler.findMatchForeground": "#6e6a8666",
+		"editorOverviewRuler.incomingContentForeground": "#c4a7e780",
+		"editorOverviewRuler.infoForeground": "#9ccfd880",
+		"editorOverviewRuler.modifiedForeground": "#ebbcba80",
+		"editorOverviewRuler.rangeHighlightForeground": "#6e6a8666",
+		"editorOverviewRuler.selectionHighlightForeground": "#6e6a8666",
+		"editorOverviewRuler.warningForeground": "#f6c17780",
+		"editorOverviewRuler.wordHighlightForeground": "#6e6a8633",
+		"editorOverviewRuler.wordHighlightStrongForeground": "#6e6a8666",
+		"editorPane.background": "#0000",
+		"editorRuler.foreground": "#6e6a8666",
+		"editorSuggestWidget.background": "#1f1d2e",
+		"editorSuggestWidget.border": "#0000",
+		"editorSuggestWidget.focusHighlightForeground": "#ebbcba",
+		"editorSuggestWidget.foreground": "#908caa",
+		"editorSuggestWidget.highlightForeground": "#ebbcba",
+		"editorSuggestWidget.selectedBackground": "#6e6a8633",
+		"editorSuggestWidget.selectedForeground": "#e0def4",
+		"editorSuggestWidget.selectedIconForeground": "#e0def4",
+		"editorUnnecessaryCode.border": "#0000",
+		"editorUnnecessaryCode.opacity": "#e0def480",
+		"editorWarning.border": "#0000",
+		"editorWarning.foreground": "#f6c177",
+		"editorWhitespace.foreground": "#6e6a86",
+		"editorWidget.background": "#1f1d2e",
+		"editorWidget.border": "#26233a",
+		"editorWidget.foreground": "#908caa",
+		"editorWidget.resizeBorder": "#6e6a86",
+		"errorForeground": "#eb6f92",
+		"extensionBadge.remoteBackground": "#c4a7e7",
+		"extensionBadge.remoteForeground": "#191724",
+		"extensionButton.prominentBackground": "#ebbcba",
+		"extensionButton.prominentForeground": "#191724",
+		"extensionButton.prominentHoverBackground": "#ebbcbae6",
+		"extensionIcon.preReleaseForeground": "#31748f",
+		"extensionIcon.starForeground": "#ebbcba",
+		"extensionIcon.verifiedForeground": "#c4a7e7",
+		"focusBorder": "#6e6a8633",
+		"foreground": "#e0def4",
+		"gitDecoration.addedResourceForeground": "#9ccfd8",
+		"gitDecoration.conflictingResourceForeground": "#eb6f92",
+		"gitDecoration.deletedResourceForeground": "#908caa",
+		"gitDecoration.ignoredResourceForeground": "#6e6a86",
+		"gitDecoration.modifiedResourceForeground": "#ebbcba",
+		"gitDecoration.renamedResourceForeground": "#31748f",
+		"gitDecoration.stageDeletedResourceForeground": "#eb6f92",
+		"gitDecoration.stageModifiedResourceForeground": "#c4a7e7",
+		"gitDecoration.submoduleResourceForeground": "#f6c177",
+		"gitDecoration.untrackedResourceForeground": "#f6c177",
+		"icon.foreground": "#908caa",
+		"input.background": "#26233a80",
+		"input.border": "#6e6a8633",
+		"input.foreground": "#e0def4",
+		"input.placeholderForeground": "#908caa",
+		"inputOption.activeBackground": "#ebbcba26",
+		"inputOption.activeForeground": "#ebbcba",
+		"inputValidation.errorBackground": "#1f1d2e",
+		"inputValidation.errorBorder": "#6e6a8666",
+		"inputValidation.errorForeground": "#eb6f92",
+		"inputValidation.infoBackground": "#1f1d2e",
+		"inputValidation.infoBorder": "#6e6a8666",
+		"inputValidation.infoForeground": "#9ccfd8",
+		"inputValidation.warningBackground": "#1f1d2e",
+		"inputValidation.warningBorder": "#6e6a8666",
+		"inputValidation.warningForeground": "#9ccfd880",
+		"keybindingLabel.background": "#26233a",
+		"keybindingLabel.border": "#6e6a8666",
+		"keybindingLabel.bottomBorder": "#6e6a8666",
+		"keybindingLabel.foreground": "#c4a7e7",
+		"keybindingTable.headerBackground": "#26233a",
+		"keybindingTable.rowsBackground": "#1f1d2e",
+		"list.activeSelectionBackground": "#6e6a8633",
+		"list.activeSelectionForeground": "#e0def4",
+		"list.deemphasizedForeground": "#908caa",
+		"list.dropBackground": "#1f1d2e",
+		"list.errorForeground": "#eb6f92",
+		"list.filterMatchBackground": "#1f1d2e",
+		"list.filterMatchBorder": "#ebbcba",
+		"list.focusBackground": "#6e6a8666",
+		"list.focusForeground": "#e0def4",
+		"list.focusOutline": "#6e6a8633",
+		"list.highlightForeground": "#ebbcba",
+		"list.hoverBackground": "#6e6a861a",
+		"list.hoverForeground": "#e0def4",
+		"list.inactiveFocusBackground": "#6e6a861a",
+		"list.inactiveSelectionBackground": "#1f1d2e",
+		"list.inactiveSelectionForeground": "#e0def4",
+		"list.invalidItemForeground": "#eb6f92",
+		"list.warningForeground": "#f6c177",
+		"listFilterWidget.background": "#1f1d2e",
+		"listFilterWidget.noMatchesOutline": "#eb6f92",
+		"listFilterWidget.outline": "#26233a",
+		"menu.background": "#1f1d2e",
+		"menu.border": "#6e6a861a",
+		"menu.foreground": "#e0def4",
+		"menu.selectionBackground": "#6e6a8633",
+		"menu.selectionBorder": "#26233a",
+		"menu.selectionForeground": "#e0def4",
+		"menu.separatorBackground": "#6e6a8666",
+		"menubar.selectionBackground": "#6e6a8633",
+		"menubar.selectionBorder": "#6e6a861a",
+		"menubar.selectionForeground": "#e0def4",
+		"merge.border": "#26233a",
+		"merge.commonContentBackground": "#6e6a8633",
+		"merge.commonHeaderBackground": "#6e6a8633",
+		"merge.currentContentBackground": "#f6c17780",
+		"merge.currentHeaderBackground": "#f6c17780",
+		"merge.incomingContentBackground": "#9ccfd880",
+		"merge.incomingHeaderBackground": "#9ccfd880",
+		"minimap.background": "#1f1d2e",
+		"minimap.errorHighlight": "#eb6f9280",
+		"minimap.findMatchHighlight": "#6e6a8633",
+		"minimap.selectionHighlight": "#6e6a8633",
+		"minimap.warningHighlight": "#f6c17780",
+		"minimapGutter.addedBackground": "#9ccfd8",
+		"minimapGutter.deletedBackground": "#eb6f92",
+		"minimapGutter.modifiedBackground": "#ebbcba",
+		"minimapSlider.activeBackground": "#6e6a8666",
+		"minimapSlider.background": "#6e6a8633",
+		"minimapSlider.hoverBackground": "#6e6a8633",
+		"notebook.cellBorderColor": "#9ccfd880",
+		"notebook.cellEditorBackground": "#1f1d2e",
+		"notebook.cellHoverBackground": "#26233a80",
+		"notebook.focusedCellBackground": "#6e6a861a",
+		"notebook.focusedCellBorder": "#9ccfd8",
+		"notebook.outputContainerBackgroundColor": "#6e6a861a",
+		"notificationCenter.border": "#6e6a8633",
+		"notificationCenterHeader.background": "#1f1d2e",
+		"notificationCenterHeader.foreground": "#908caa",
+		"notificationLink.foreground": "#c4a7e7",
+		"notifications.background": "#1f1d2e",
+		"notifications.border": "#6e6a8633",
+		"notifications.foreground": "#e0def4",
+		"notificationsErrorIcon.foreground": "#eb6f92",
+		"notificationsInfoIcon.foreground": "#9ccfd8",
+		"notificationsWarningIcon.foreground": "#f6c177",
+		"notificationToast.border": "#6e6a8633",
+		"panel.background": "#1f1d2e",
+		"panel.border": "#0000",
+		"panel.dropBorder": "#26233a",
+		"panelInput.border": "#1f1d2e",
+		"panelSection.dropBackground": "#6e6a8633",
+		"panelSectionHeader.background": "#1f1d2e",
+		"panelSectionHeader.foreground": "#e0def4",
+		"panelTitle.activeBorder": "#6e6a8666",
+		"panelTitle.activeForeground": "#e0def4",
+		"panelTitle.inactiveForeground": "#908caa",
+		"peekView.border": "#26233a",
+		"peekViewEditor.background": "#1f1d2e",
+		"peekViewEditor.matchHighlightBackground": "#6e6a8666",
+		"peekViewResult.background": "#1f1d2e",
+		"peekViewResult.fileForeground": "#908caa",
+		"peekViewResult.lineForeground": "#908caa",
+		"peekViewResult.matchHighlightBackground": "#6e6a8666",
+		"peekViewResult.selectionBackground": "#6e6a8633",
+		"peekViewResult.selectionForeground": "#e0def4",
+		"peekViewTitle.background": "#26233a",
+		"peekViewTitleDescription.foreground": "#908caa",
+		"pickerGroup.border": "#6e6a8666",
+		"pickerGroup.foreground": "#c4a7e7",
+		"ports.iconRunningProcessForeground": "#ebbcba",
+		"problemsErrorIcon.foreground": "#eb6f92",
+		"problemsInfoIcon.foreground": "#9ccfd8",
+		"problemsWarningIcon.foreground": "#f6c177",
+		"progressBar.background": "#ebbcba",
+		"quickInput.background": "#1f1d2e",
+		"quickInput.foreground": "#908caa",
+		"quickInputList.focusBackground": "#6e6a8633",
+		"quickInputList.focusForeground": "#e0def4",
+		"quickInputList.focusIconForeground": "#e0def4",
+		"scrollbar.shadow": "#1f1d2e4d",
+		"scrollbarSlider.activeBackground": "#31748f80",
+		"scrollbarSlider.background": "#6e6a8633",
+		"scrollbarSlider.hoverBackground": "#6e6a8666",
+		"searchEditor.findMatchBackground": "#6e6a8633",
+		"selection.background": "#6e6a8666",
+		"settings.focusedRowBackground": "#1f1d2e",
+		"settings.headerForeground": "#e0def4",
+		"settings.modifiedItemIndicator": "#ebbcba",
+		"settings.focusedRowBorder": "#6e6a8633",
+		"settings.rowHoverBackground": "#1f1d2e",
+		"sideBar.background": "#191724",
+		"sideBar.dropBackground": "#1f1d2e",
+		"sideBar.foreground": "#908caa",
+		"sideBarSectionHeader.background": "#0000",
+		"sideBarSectionHeader.border": "#6e6a8633",
+		"statusBar.background": "#191724",
+		"statusBar.debuggingBackground": "#c4a7e7",
+		"statusBar.debuggingForeground": "#191724",
+		"statusBar.foreground": "#908caa",
+		"statusBar.noFolderBackground": "#191724",
+		"statusBar.noFolderForeground": "#908caa",
+		"statusBarItem.activeBackground": "#6e6a8666",
+		"statusBarItem.hoverBackground": "#6e6a8633",
+		"statusBarItem.prominentBackground": "#26233a",
+		"statusBarItem.prominentForeground": "#e0def4",
+		"statusBarItem.prominentHoverBackground": "#6e6a8633",
+		"statusBarItem.remoteBackground": "#191724",
+		"statusBarItem.remoteForeground": "#f6c177",
+		"statusBarItem.errorBackground": "#191724",
+		"statusBarItem.errorForeground": "#eb6f92",
+		"symbolIcon.arrayForeground": "#908caa",
+		"symbolIcon.classForeground": "#908caa",
+		"symbolIcon.colorForeground": "#908caa",
+		"symbolIcon.constantForeground": "#908caa",
+		"symbolIcon.constructorForeground": "#908caa",
+		"symbolIcon.enumeratorForeground": "#908caa",
+		"symbolIcon.enumeratorMemberForeground": "#908caa",
+		"symbolIcon.eventForeground": "#908caa",
+		"symbolIcon.fieldForeground": "#908caa",
+		"symbolIcon.fileForeground": "#908caa",
+		"symbolIcon.folderForeground": "#908caa",
+		"symbolIcon.functionForeground": "#908caa",
+		"symbolIcon.interfaceForeground": "#908caa",
+		"symbolIcon.keyForeground": "#908caa",
+		"symbolIcon.keywordForeground": "#908caa",
+		"symbolIcon.methodForeground": "#908caa",
+		"symbolIcon.moduleForeground": "#908caa",
+		"symbolIcon.namespaceForeground": "#908caa",
+		"symbolIcon.nullForeground": "#908caa",
+		"symbolIcon.numberForeground": "#908caa",
+		"symbolIcon.objectForeground": "#908caa",
+		"symbolIcon.operatorForeground": "#908caa",
+		"symbolIcon.packageForeground": "#908caa",
+		"symbolIcon.propertyForeground": "#908caa",
+		"symbolIcon.referenceForeground": "#908caa",
+		"symbolIcon.snippetForeground": "#908caa",
+		"symbolIcon.stringForeground": "#908caa",
+		"symbolIcon.structForeground": "#908caa",
+		"symbolIcon.textForeground": "#908caa",
+		"symbolIcon.typeParameterForeground": "#908caa",
+		"symbolIcon.unitForeground": "#908caa",
+		"symbolIcon.variableForeground": "#908caa",
+		"tab.activeBackground": "#6e6a861a",
+		"tab.activeForeground": "#e0def4",
+		"tab.activeModifiedBorder": "#9ccfd8",
+		"tab.border": "#0000",
+		"tab.hoverBackground": "#6e6a8633",
+		"tab.inactiveBackground": "#0000",
+		"tab.inactiveForeground": "#908caa",
+		"tab.inactiveModifiedBorder": "#9ccfd880",
+		"tab.lastPinnedBorder": "#6e6a86",
+		"tab.unfocusedActiveBackground": "#0000",
+		"tab.unfocusedHoverBackground": "#0000",
+		"tab.unfocusedInactiveBackground": "#0000",
+		"tab.unfocusedInactiveModifiedBorder": "#9ccfd880",
+		"terminal.ansiBlack": "#26233a",
+		"terminal.ansiBlue": "#9ccfd8",
+		"terminal.ansiBrightBlack": "#908caa",
+		"terminal.ansiBrightBlue": "#9ccfd8",
+		"terminal.ansiBrightCyan": "#ebbcba",
+		"terminal.ansiBrightGreen": "#31748f",
+		"terminal.ansiBrightMagenta": "#c4a7e7",
+		"terminal.ansiBrightRed": "#eb6f92",
+		"terminal.ansiBrightWhite": "#e0def4",
+		"terminal.ansiBrightYellow": "#f6c177",
+		"terminal.ansiCyan": "#ebbcba",
+		"terminal.ansiGreen": "#31748f",
+		"terminal.ansiMagenta": "#c4a7e7",
+		"terminal.ansiRed": "#eb6f92",
+		"terminal.ansiWhite": "#e0def4",
+		"terminal.ansiYellow": "#f6c177",
+		"terminal.dropBackground": "#6e6a8633",
+		"terminal.foreground": "#e0def4",
+		"terminal.selectionBackground": "#6e6a8633",
+		"terminal.tab.activeBorder": "#e0def4",
+		"terminalCursor.background": "#e0def4",
+		"terminalCursor.foreground": "#6e6a86",
+		"textBlockQuote.background": "#1f1d2e",
+		"textBlockQuote.border": "#6e6a8633",
+		"textCodeBlock.background": "#1f1d2e",
+		"textLink.activeForeground": "#c4a7e7e6",
+		"textLink.foreground": "#c4a7e7",
+		"textPreformat.foreground": "#f6c177",
+		"textSeparator.foreground": "#908caa",
+		"titleBar.activeBackground": "#191724",
+		"titleBar.activeForeground": "#908caa",
+		"titleBar.inactiveBackground": "#1f1d2e",
+		"titleBar.inactiveForeground": "#908caa",
+		"toolbar.activeBackground": "#6e6a8666",
+		"toolbar.hoverBackground": "#6e6a8633",
+		"tree.indentGuidesStroke": "#908caa",
+		"walkThrough.embeddedEditorBackground": "#191724",
+		"welcomePage.background": "#191724",
+		"welcomePage.buttonBackground": "#1f1d2e",
+		"welcomePage.buttonHoverBackground": "#26233a",
+		"widget.shadow": "#1f1d2e4d",
+		"window.activeBorder": "#1f1d2e",
+		"window.inactiveBorder": "#1f1d2e"
+	},
+	"tokenColors": [
+		{
+			"scope": ["comment"],
+			"settings": {
+				"foreground": "#6e6a86",
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": ["constant"],
+			"settings": {
+				"foreground": "#31748f"
+			}
+		},
+		{
+			"scope": ["constant.numeric", "constant.language"],
+			"settings": {
+				"foreground": "#ebbcba"
+			}
+		},
+		{
+			"scope": ["entity.name"],
+			"settings": {
+				"foreground": "#ebbcba"
+			}
+		},
+		{
+			"scope": [
+				"entity.name.section",
+				"entity.name.tag",
+				"entity.name.namespace",
+				"entity.name.type"
+			],
+			"settings": {
+				"foreground": "#9ccfd8"
+			}
+		},
+		{
+			"scope": ["entity.other.attribute-name", "entity.other.inherited-class"],
+			"settings": {
+				"foreground": "#c4a7e7",
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": ["invalid"],
+			"settings": {
+				"foreground": "#eb6f92"
+			}
+		},
+		{
+			"scope": ["invalid.deprecated"],
+			"settings": {
+				"foreground": "#908caa"
+			}
+		},
+		{
+			"scope": ["keyword"],
+			"settings": {
+				"foreground": "#31748f"
+			}
+		},
+		{
+			"scope": ["markup.inserted.diff"],
+			"settings": {
+				"foreground": "#9ccfd8"
+			}
+		},
+		{
+			"scope": ["markup.deleted.diff"],
+			"settings": {
+				"foreground": "#eb6f92"
+			}
+		},
+		{
+			"scope": "markup.heading",
+			"settings": {
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"scope": "markup.bold.markdown",
+			"settings": {
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"scope": "markup.italic.markdown",
+			"settings": {
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": ["meta.diff.range"],
+			"settings": {
+				"foreground": "#c4a7e7"
+			}
+		},
+		{
+			"scope": ["meta.tag", "meta.brace"],
+			"settings": {
+				"foreground": "#e0def4"
+			}
+		},
+		{
+			"scope": ["meta.import", "meta.export"],
+			"settings": {
+				"foreground": "#31748f"
+			}
+		},
+		{
+			"scope": "meta.directive.vue",
+			"settings": {
+				"foreground": "#c4a7e7",
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": "meta.property-name.css",
+			"settings": {
+				"foreground": "#9ccfd8"
+			}
+		},
+		{
+			"scope": "meta.property-value.css",
+			"settings": {
+				"foreground": "#f6c177"
+			}
+		},
+		{
+			"scope": "meta.tag.other.html",
+			"settings": {
+				"foreground": "#908caa"
+			}
+		},
+		{
+			"scope": ["punctuation"],
+			"settings": {
+				"foreground": "#908caa"
+			}
+		},
+		{
+			"scope": ["punctuation.accessor"],
+			"settings": {
+				"foreground": "#31748f"
+			}
+		},
+		{
+			"scope": ["punctuation.definition.string"],
+			"settings": {
+				"foreground": "#f6c177"
+			}
+		},
+		{
+			"scope": ["punctuation.definition.tag"],
+			"settings": {
+				"foreground": "#6e6a86"
+			}
+		},
+		{
+			"scope": ["storage.type", "storage.modifier"],
+			"settings": {
+				"foreground": "#31748f"
+			}
+		},
+		{
+			"scope": ["string"],
+			"settings": {
+				"foreground": "#f6c177"
+			}
+		},
+		{
+			"scope": ["support"],
+			"settings": {
+				"foreground": "#9ccfd8"
+			}
+		},
+		{
+			"scope": ["support.constant"],
+			"settings": {
+				"foreground": "#f6c177"
+			}
+		},
+		{
+			"scope": ["support.function"],
+			"settings": {
+				"foreground": "#eb6f92",
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": ["variable"],
+			"settings": {
+				"foreground": "#ebbcba",
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"scope": [
+				"variable.other",
+				"variable.language",
+				"variable.function",
+				"variable.argument"
+			],
+			"settings": {
+				"foreground": "#e0def4"
+			}
+		},
+		{
+			"scope": ["variable.parameter"],
+			"settings": {
+				"foreground": "#c4a7e7"
+			}
+		}
+	]
 }

crates/activity_indicator2/src/activity_indicator.rs 🔗

@@ -14,7 +14,7 @@ use ui::h_stack;
 use util::ResultExt;
 use workspace::{item::ItemHandle, StatusItemView, Workspace};
 
-actions!(ShowErrorMessage);
+actions!(activity_indicator, [ShowErrorMessage]);
 
 const DOWNLOAD_ICON: &str = "icons/download.svg";
 const WARNING_ICON: &str = "icons/warning.svg";

crates/assistant2/src/assistant.rs 🔗

@@ -12,23 +12,26 @@ use chrono::{DateTime, Local};
 use collections::HashMap;
 use fs::Fs;
 use futures::StreamExt;
-use gpui::{actions, AppContext};
+use gpui::{actions, AppContext, SharedString};
 use regex::Regex;
 use serde::{Deserialize, Serialize};
 use std::{cmp::Reverse, ffi::OsStr, path::PathBuf, sync::Arc};
 use util::paths::CONVERSATIONS_DIR;
 
 actions!(
-    NewConversation,
-    Assist,
-    Split,
-    CycleMessageRole,
-    QuoteSelection,
-    ToggleFocus,
-    ResetKey,
-    InlineAssist,
-    ToggleIncludeConversation,
-    ToggleRetrieveContext,
+    assistant,
+    [
+        NewConversation,
+        Assist,
+        Split,
+        CycleMessageRole,
+        QuoteSelection,
+        ToggleFocus,
+        ResetKey,
+        InlineAssist,
+        ToggleIncludeConversation,
+        ToggleRetrieveContext,
+    ]
 );
 
 #[derive(
@@ -47,7 +50,7 @@ struct MessageMetadata {
 enum MessageStatus {
     Pending,
     Done,
-    Error(Arc<str>),
+    Error(SharedString),
 }
 
 #[derive(Serialize, Deserialize)]

crates/assistant2/src/assistant_panel.rs 🔗

@@ -1628,8 +1628,9 @@ impl Conversation {
                                     metadata.status = MessageStatus::Done;
                                 }
                                 Err(error) => {
-                                    metadata.status =
-                                        MessageStatus::Error(error.to_string().trim().into());
+                                    metadata.status = MessageStatus::Error(SharedString::from(
+                                        error.to_string().trim().to_string(),
+                                    ));
                                 }
                             }
                             cx.notify();
@@ -2273,7 +2274,7 @@ impl ConversationEditor {
                                         Some(
                                             div()
                                                 .id("error")
-                                                .tooltip(move |cx| Tooltip::text(&error, cx))
+                                                .tooltip(move |cx| Tooltip::text(error.clone(), cx))
                                                 .child(IconElement::new(Icon::XCircle)),
                                         )
                                     } else {

crates/auto_update2/src/auto_update.rs 🔗

@@ -26,10 +26,13 @@ const POLL_INTERVAL: Duration = Duration::from_secs(60 * 60);
 
 //todo!(remove CheckThatAutoUpdaterWorks)
 actions!(
-    Check,
-    DismissErrorMessage,
-    ViewReleaseNotes,
-    CheckThatAutoUpdaterWorks
+    auto_update,
+    [
+        Check,
+        DismissErrorMessage,
+        ViewReleaseNotes,
+        CheckThatAutoUpdaterWorks
+    ]
 );
 
 #[derive(Serialize)]
@@ -85,15 +88,7 @@ pub fn init(http_client: Arc<dyn HttpClient>, server_url: String, cx: &mut AppCo
     AutoUpdateSetting::register(cx);
 
     cx.observe_new_views(|workspace: &mut Workspace, _cx| {
-        workspace
-            .register_action(|_, action: &Check, cx| check(action, cx))
-            .register_action(|_, _action: &CheckThatAutoUpdaterWorks, cx| {
-                let prompt = cx.prompt(gpui::PromptLevel::Info, "It does!", &["Ok"]);
-                cx.spawn(|_, _cx| async move {
-                    prompt.await.ok();
-                })
-                .detach();
-            });
+        workspace.register_action(|_, action: &Check, cx| check(action, cx));
 
         // @nate - code to trigger update notification on launch
         // workspace.show_notification(0, _cx, |cx| {
@@ -130,9 +125,15 @@ pub fn init(http_client: Arc<dyn HttpClient>, server_url: String, cx: &mut AppCo
     }
 }
 
-pub fn check(_: &Check, cx: &mut AppContext) {
+pub fn check(_: &Check, cx: &mut ViewContext<Workspace>) {
     if let Some(updater) = AutoUpdater::get(cx) {
         updater.update(cx, |updater, cx| updater.poll(cx));
+    } else {
+        drop(cx.prompt(
+            gpui::PromptLevel::Info,
+            "Auto-updates disabled for non-bundled app.",
+            &["Ok"],
+        ));
     }
 }
 

crates/breadcrumbs2/Cargo.toml 🔗

@@ -19,7 +19,7 @@ search = { package = "search2", path = "../search2" }
 settings = { package = "settings2", path = "../settings2" }
 theme = { package = "theme2", path = "../theme2" }
 workspace = { package = "workspace2", path = "../workspace2" }
-# outline = { path = "../outline" }
+outline = { package = "outline2", path = "../outline2" }
 itertools = "0.10"
 
 [dev-dependencies]

crates/breadcrumbs2/src/breadcrumbs.rs 🔗

@@ -1,13 +1,14 @@
+use editor::Editor;
 use gpui::{
     Div, Element, EventEmitter, IntoElement, ParentElement, Render, StyledText, Subscription,
-    ViewContext, WeakView,
+    ViewContext,
 };
 use itertools::Itertools;
 use theme::ActiveTheme;
-use ui::{prelude::*, ButtonLike, ButtonStyle, Label};
+use ui::{prelude::*, ButtonLike, ButtonStyle, Label, Tooltip};
 use workspace::{
     item::{ItemEvent, ItemHandle},
-    ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace,
+    ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView,
 };
 
 pub enum Event {
@@ -18,16 +19,14 @@ pub struct Breadcrumbs {
     pane_focused: bool,
     active_item: Option<Box<dyn ItemHandle>>,
     subscription: Option<Subscription>,
-    _workspace: WeakView<Workspace>,
 }
 
 impl Breadcrumbs {
-    pub fn new(workspace: &Workspace) -> Self {
+    pub fn new() -> Self {
         Self {
             pane_focused: false,
             active_item: Default::default(),
             subscription: Default::default(),
-            _workspace: workspace.weak_handle(),
         }
     }
 }
@@ -62,97 +61,24 @@ impl Render for Breadcrumbs {
             Label::new("›").into_any_element()
         });
 
+        let editor = active_item
+            .downcast::<Editor>()
+            .map(|editor| editor.downgrade());
+
         element.child(
             ButtonLike::new("toggle outline view")
                 .style(ButtonStyle::Subtle)
                 .child(h_stack().gap_1().children(breadcrumbs))
-                // We disable the button when it is not focused
-                // due to ... @julia what was the reason again?
-                .disabled(!self.pane_focused)
-                .on_click(move |_, _cx| {
-                    todo!("outline::toggle");
-                    // this.update(cx, |this, cx| {
-                    //     if let Some(workspace) = this.workspace.upgrade() {
-                    //         workspace.update(cx, |_workspace, _cx| {
-                    //             outline::toggle(workspace, &Default::default(), cx)
-                    //         })
-                    //     }
-                    // })
-                    // .ok();
-                }),
+                .on_click(move |_, cx| {
+                    if let Some(editor) = editor.as_ref().and_then(|editor| editor.upgrade()) {
+                        outline::toggle(editor, &outline::Toggle, cx)
+                    }
+                })
+                .tooltip(|cx| Tooltip::for_action("Show symbol outline", &outline::Toggle, cx)),
         )
     }
 }
 
-// impl View for Breadcrumbs {
-//     fn ui_name() -> &'static str {
-//         "Breadcrumbs"
-//     }
-
-//     fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
-//         let active_item = match &self.active_item {
-//             Some(active_item) => active_item,
-//             None => return Empty::new().into_any(),
-//         };
-//         let not_editor = active_item.downcast::<editor::Editor>().is_none();
-
-//         let theme = theme::current(cx).clone();
-//         let style = &theme.workspace.toolbar.breadcrumbs;
-
-//         let breadcrumbs = match active_item.breadcrumbs(&theme, cx) {
-//             Some(breadcrumbs) => breadcrumbs,
-//             None => return Empty::new().into_any(),
-//         }
-//         .into_iter()
-//         .map(|breadcrumb| {
-//             Text::new(
-//                 breadcrumb.text,
-//                 theme.workspace.toolbar.breadcrumbs.default.text.clone(),
-//             )
-//             .with_highlights(breadcrumb.highlights.unwrap_or_default())
-//             .into_any()
-//         });
-
-//         let crumbs = Flex::row()
-//             .with_children(Itertools::intersperse_with(breadcrumbs, || {
-//                 Label::new(" › ", style.default.text.clone()).into_any()
-//             }))
-//             .constrained()
-//             .with_height(theme.workspace.toolbar.breadcrumb_height)
-//             .contained();
-
-//         if not_editor || !self.pane_focused {
-//             return crumbs
-//                 .with_style(style.default.container)
-//                 .aligned()
-//                 .left()
-//                 .into_any();
-//         }
-
-//         MouseEventHandler::new::<Breadcrumbs, _>(0, cx, |state, _| {
-//             let style = style.style_for(state);
-//             crumbs.with_style(style.container)
-//         })
-//         .on_click(MouseButton::Left, |_, this, cx| {
-//             if let Some(workspace) = this.workspace.upgrade(cx) {
-//                 workspace.update(cx, |workspace, cx| {
-//                     outline::toggle(workspace, &Default::default(), cx)
-//                 })
-//             }
-//         })
-//         .with_tooltip::<Breadcrumbs>(
-//             0,
-//             "Show symbol outline".to_owned(),
-//             Some(Box::new(outline::Toggle)),
-//             theme.tooltip.clone(),
-//             cx,
-//         )
-//         .aligned()
-//         .left()
-//         .into_any()
-//     }
-// }
-
 impl ToolbarItemView for Breadcrumbs {
     fn set_active_pane_item(
         &mut self,

crates/channel2/src/channel_store.rs 🔗

@@ -8,7 +8,8 @@ use collections::{hash_map, HashMap, HashSet};
 use db::RELEASE_CHANNEL;
 use futures::{channel::mpsc, future::Shared, Future, FutureExt, StreamExt};
 use gpui::{
-    AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, Task, WeakModel,
+    AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, SharedString, Task,
+    WeakModel,
 };
 use rpc::{
     proto::{self, ChannelVisibility},
@@ -46,7 +47,7 @@ pub struct ChannelStore {
 #[derive(Clone, Debug, PartialEq)]
 pub struct Channel {
     pub id: ChannelId,
-    pub name: String,
+    pub name: SharedString,
     pub visibility: proto::ChannelVisibility,
     pub role: proto::ChannelRole,
     pub unseen_note_version: Option<(u64, clock::Global)>,
@@ -895,14 +896,16 @@ impl ChannelStore {
                 .channel_invitations
                 .binary_search_by_key(&channel.id, |c| c.id)
             {
-                Ok(ix) => Arc::make_mut(&mut self.channel_invitations[ix]).name = channel.name,
+                Ok(ix) => {
+                    Arc::make_mut(&mut self.channel_invitations[ix]).name = channel.name.into()
+                }
                 Err(ix) => self.channel_invitations.insert(
                     ix,
                     Arc::new(Channel {
                         id: channel.id,
                         visibility: channel.visibility(),
                         role: channel.role(),
-                        name: channel.name,
+                        name: channel.name.into(),
                         unseen_note_version: None,
                         unseen_message_id: None,
                         parent_path: channel.parent_path,

crates/channel2/src/channel_store/channel_index.rs 🔗

@@ -104,7 +104,7 @@ impl<'a> ChannelPathsInsertGuard<'a> {
 
             existing_channel.visibility = channel_proto.visibility();
             existing_channel.role = channel_proto.role();
-            existing_channel.name = channel_proto.name;
+            existing_channel.name = channel_proto.name.into();
         } else {
             self.channels_by_id.insert(
                 channel_proto.id,
@@ -112,7 +112,7 @@ impl<'a> ChannelPathsInsertGuard<'a> {
                     id: channel_proto.id,
                     visibility: channel_proto.visibility(),
                     role: channel_proto.role(),
-                    name: channel_proto.name,
+                    name: channel_proto.name.into(),
                     unseen_note_version: None,
                     unseen_message_id: None,
                     parent_path: channel_proto.parent_path,
@@ -146,11 +146,11 @@ fn channel_path_sorting_key<'a>(
     let (parent_path, name) = channels_by_id
         .get(&id)
         .map_or((&[] as &[_], None), |channel| {
-            (channel.parent_path.as_slice(), Some(channel.name.as_str()))
+            (channel.parent_path.as_slice(), Some(channel.name.as_ref()))
         });
     parent_path
         .iter()
-        .filter_map(|id| Some(channels_by_id.get(id)?.name.as_str()))
+        .filter_map(|id| Some(channels_by_id.get(id)?.name.as_ref()))
         .chain(name)
 }
 

crates/client2/src/client2.rs 🔗

@@ -70,7 +70,7 @@ pub const ZED_SECRET_CLIENT_TOKEN: &str = "618033988749894";
 pub const INITIAL_RECONNECTION_DELAY: Duration = Duration::from_millis(100);
 pub const CONNECTION_TIMEOUT: Duration = Duration::from_secs(5);
 
-actions!(SignIn, SignOut, Reconnect);
+actions!(client, [SignIn, SignOut, Reconnect]);
 
 pub fn init_settings(cx: &mut AppContext) {
     TelemetrySettings::register(cx);

crates/collab/Cargo.toml 🔗

@@ -3,7 +3,7 @@ authors = ["Nathan Sobo <nathan@zed.dev>"]
 default-run = "collab"
 edition = "2021"
 name = "collab"
-version = "0.30.0"
+version = "0.30.1"
 publish = false
 
 [[bin]]

crates/collab/src/api.rs 🔗

@@ -116,12 +116,13 @@ struct CreateUserResponse {
 #[derive(Debug, Deserialize)]
 struct Panic {
     version: String,
+    release_channel: String,
     text: String,
 }
 
 #[instrument(skip(panic))]
 async fn trace_panic(panic: Json<Panic>) -> Result<()> {
-    tracing::error!(version = %panic.version, text = %panic.text, "panic report");
+    tracing::error!(version = %panic.version, release_channel = %panic.release_channel, text = %panic.text, "panic report");
     Ok(())
 }
 

crates/collab2/src/tests/channel_tests.rs 🔗

@@ -7,7 +7,7 @@ use call::ActiveCall;
 use channel::{ChannelId, ChannelMembership, ChannelStore};
 use client::User;
 use futures::future::try_join_all;
-use gpui::{BackgroundExecutor, Model, TestAppContext};
+use gpui::{BackgroundExecutor, Model, SharedString, TestAppContext};
 use rpc::{
     proto::{self, ChannelRole},
     RECEIVE_TIMEOUT,
@@ -46,13 +46,13 @@ async fn test_core_channels(
         &[
             ExpectedChannel {
                 id: channel_a_id,
-                name: "channel-a".to_string(),
+                name: "channel-a".into(),
                 depth: 0,
                 role: ChannelRole::Admin,
             },
             ExpectedChannel {
                 id: channel_b_id,
-                name: "channel-b".to_string(),
+                name: "channel-b".into(),
                 depth: 1,
                 role: ChannelRole::Admin,
             },
@@ -92,7 +92,7 @@ async fn test_core_channels(
         cx_b,
         &[ExpectedChannel {
             id: channel_a_id,
-            name: "channel-a".to_string(),
+            name: "channel-a".into(),
             depth: 0,
             role: ChannelRole::Member,
         }],
@@ -140,13 +140,13 @@ async fn test_core_channels(
         &[
             ExpectedChannel {
                 id: channel_a_id,
-                name: "channel-a".to_string(),
+                name: "channel-a".into(),
                 role: ChannelRole::Member,
                 depth: 0,
             },
             ExpectedChannel {
                 id: channel_b_id,
-                name: "channel-b".to_string(),
+                name: "channel-b".into(),
                 role: ChannelRole::Member,
                 depth: 1,
             },
@@ -168,19 +168,19 @@ async fn test_core_channels(
         &[
             ExpectedChannel {
                 id: channel_a_id,
-                name: "channel-a".to_string(),
+                name: "channel-a".into(),
                 role: ChannelRole::Member,
                 depth: 0,
             },
             ExpectedChannel {
                 id: channel_b_id,
-                name: "channel-b".to_string(),
+                name: "channel-b".into(),
                 role: ChannelRole::Member,
                 depth: 1,
             },
             ExpectedChannel {
                 id: channel_c_id,
-                name: "channel-c".to_string(),
+                name: "channel-c".into(),
                 role: ChannelRole::Member,
                 depth: 2,
             },
@@ -211,19 +211,19 @@ async fn test_core_channels(
         &[
             ExpectedChannel {
                 id: channel_a_id,
-                name: "channel-a".to_string(),
+                name: "channel-a".into(),
                 depth: 0,
                 role: ChannelRole::Admin,
             },
             ExpectedChannel {
                 id: channel_b_id,
-                name: "channel-b".to_string(),
+                name: "channel-b".into(),
                 depth: 1,
                 role: ChannelRole::Admin,
             },
             ExpectedChannel {
                 id: channel_c_id,
-                name: "channel-c".to_string(),
+                name: "channel-c".into(),
                 depth: 2,
                 role: ChannelRole::Admin,
             },
@@ -245,7 +245,7 @@ async fn test_core_channels(
         cx_a,
         &[ExpectedChannel {
             id: channel_a_id,
-            name: "channel-a".to_string(),
+            name: "channel-a".into(),
             depth: 0,
             role: ChannelRole::Admin,
         }],
@@ -255,7 +255,7 @@ async fn test_core_channels(
         cx_b,
         &[ExpectedChannel {
             id: channel_a_id,
-            name: "channel-a".to_string(),
+            name: "channel-a".into(),
             depth: 0,
             role: ChannelRole::Admin,
         }],
@@ -278,7 +278,7 @@ async fn test_core_channels(
         cx_a,
         &[ExpectedChannel {
             id: channel_a_id,
-            name: "channel-a".to_string(),
+            name: "channel-a".into(),
             depth: 0,
             role: ChannelRole::Admin,
         }],
@@ -309,7 +309,7 @@ async fn test_core_channels(
         cx_a,
         &[ExpectedChannel {
             id: channel_a_id,
-            name: "channel-a-renamed".to_string(),
+            name: "channel-a-renamed".into(),
             depth: 0,
             role: ChannelRole::Admin,
         }],
@@ -418,7 +418,7 @@ async fn test_channel_room(
         cx_b,
         &[ExpectedChannel {
             id: zed_id,
-            name: "zed".to_string(),
+            name: "zed".into(),
             depth: 0,
             role: ChannelRole::Member,
         }],
@@ -680,7 +680,7 @@ async fn test_permissions_update_while_invited(
         &[ExpectedChannel {
             depth: 0,
             id: rust_id,
-            name: "rust".to_string(),
+            name: "rust".into(),
             role: ChannelRole::Member,
         }],
     );
@@ -708,7 +708,7 @@ async fn test_permissions_update_while_invited(
         &[ExpectedChannel {
             depth: 0,
             id: rust_id,
-            name: "rust".to_string(),
+            name: "rust".into(),
             role: ChannelRole::Member,
         }],
     );
@@ -747,7 +747,7 @@ async fn test_channel_rename(
         &[ExpectedChannel {
             depth: 0,
             id: rust_id,
-            name: "rust-archive".to_string(),
+            name: "rust-archive".into(),
             role: ChannelRole::Admin,
         }],
     );
@@ -759,7 +759,7 @@ async fn test_channel_rename(
         &[ExpectedChannel {
             depth: 0,
             id: rust_id,
-            name: "rust-archive".to_string(),
+            name: "rust-archive".into(),
             role: ChannelRole::Member,
         }],
     );
@@ -888,7 +888,7 @@ async fn test_lost_channel_creation(
         &[ExpectedChannel {
             depth: 0,
             id: channel_id,
-            name: "x".to_string(),
+            name: "x".into(),
             role: ChannelRole::Member,
         }],
     );
@@ -912,13 +912,13 @@ async fn test_lost_channel_creation(
             ExpectedChannel {
                 depth: 0,
                 id: channel_id,
-                name: "x".to_string(),
+                name: "x".into(),
                 role: ChannelRole::Admin,
             },
             ExpectedChannel {
                 depth: 1,
                 id: subchannel_id,
-                name: "subchannel".to_string(),
+                name: "subchannel".into(),
                 role: ChannelRole::Admin,
             },
         ],
@@ -943,13 +943,13 @@ async fn test_lost_channel_creation(
             ExpectedChannel {
                 depth: 0,
                 id: channel_id,
-                name: "x".to_string(),
+                name: "x".into(),
                 role: ChannelRole::Member,
             },
             ExpectedChannel {
                 depth: 1,
                 id: subchannel_id,
-                name: "subchannel".to_string(),
+                name: "subchannel".into(),
                 role: ChannelRole::Member,
             },
         ],
@@ -1221,13 +1221,13 @@ async fn test_channel_membership_notifications(
             ExpectedChannel {
                 depth: 0,
                 id: zed_channel,
-                name: "zed".to_string(),
+                name: "zed".into(),
                 role: ChannelRole::Guest,
             },
             ExpectedChannel {
                 depth: 1,
                 id: vim_channel,
-                name: "vim".to_string(),
+                name: "vim".into(),
                 role: ChannelRole::Member,
             },
         ],
@@ -1250,13 +1250,13 @@ async fn test_channel_membership_notifications(
             ExpectedChannel {
                 depth: 0,
                 id: zed_channel,
-                name: "zed".to_string(),
+                name: "zed".into(),
                 role: ChannelRole::Guest,
             },
             ExpectedChannel {
                 depth: 1,
                 id: vim_channel,
-                name: "vim".to_string(),
+                name: "vim".into(),
                 role: ChannelRole::Guest,
             },
         ],
@@ -1476,7 +1476,7 @@ async fn test_channel_moving(
 struct ExpectedChannel {
     depth: usize,
     id: ChannelId,
-    name: String,
+    name: SharedString,
     role: ChannelRole,
 }
 
@@ -1515,7 +1515,7 @@ fn assert_channels(
                 .ordered_channels()
                 .map(|(depth, channel)| ExpectedChannel {
                     depth,
-                    name: channel.name.clone(),
+                    name: channel.name.clone().into(),
                     id: channel.id,
                     role: channel.role,
                 })

crates/collab2/src/tests/random_channel_buffer_tests.rs 🔗

@@ -3,7 +3,7 @@ use crate::db::ChannelRole;
 use super::{run_randomized_test, RandomizedTest, TestClient, TestError, TestServer, UserTestPlan};
 use anyhow::Result;
 use async_trait::async_trait;
-use gpui::{BackgroundExecutor, TestAppContext};
+use gpui::{BackgroundExecutor, SharedString, TestAppContext};
 use rand::prelude::*;
 use serde_derive::{Deserialize, Serialize};
 use std::{
@@ -30,13 +30,13 @@ struct RandomChannelBufferTest;
 #[derive(Clone, Serialize, Deserialize)]
 enum ChannelBufferOperation {
     JoinChannelNotes {
-        channel_name: String,
+        channel_name: SharedString,
     },
     LeaveChannelNotes {
-        channel_name: String,
+        channel_name: SharedString,
     },
     EditChannelNotes {
-        channel_name: String,
+        channel_name: SharedString,
         edits: Vec<(Range<usize>, Arc<str>)>,
     },
     Noop,

crates/collab_ui2/src/channel_view.rs 🔗

@@ -26,7 +26,7 @@ use workspace::{
     ItemNavHistory, Pane, SaveIntent, ViewId, Workspace, WorkspaceId,
 };
 
-actions!(Deploy);
+actions!(collab, [Deploy]);
 
 pub fn init(cx: &mut AppContext) {
     register_followable_item::<ChannelView>(cx)

crates/collab_ui2/src/chat_panel.rs 🔗

@@ -1,983 +1,698 @@
-// use crate::{
-//     channel_view::ChannelView, is_channels_feature_enabled, render_avatar, ChatPanelSettings,
-// };
-// use anyhow::Result;
-// use call::ActiveCall;
-// use channel::{ChannelChat, ChannelChatEvent, ChannelMessageId, ChannelStore};
-// use client::Client;
-// use collections::HashMap;
-// use db::kvp::KEY_VALUE_STORE;
-// use editor::Editor;
-// use gpui::{
-//     actions,
-//     elements::*,
-//     platform::{CursorStyle, MouseButton},
-//     serde_json,
-//     views::{ItemType, Select, SelectStyle},
-//     AnyViewHandle, AppContext, AsyncAppContext, Entity, ModelHandle, Subscription, Task, View,
-//     ViewContext, ViewHandle, WeakViewHandle,
-// };
-// use language::LanguageRegistry;
-// use menu::Confirm;
-// use message_editor::MessageEditor;
-// use project::Fs;
-// use rich_text::RichText;
-// use serde::{Deserialize, Serialize};
-// use settings::SettingsStore;
-// use std::sync::Arc;
-// use theme::{IconButton, Theme};
-// use time::{OffsetDateTime, UtcOffset};
-// use util::{ResultExt, TryFutureExt};
-// use workspace::{
-//     dock::{DockPosition, Panel},
-//     Workspace,
-// };
-
-// mod message_editor;
-
-// const MESSAGE_LOADING_THRESHOLD: usize = 50;
-// const CHAT_PANEL_KEY: &'static str = "ChatPanel";
-
-// pub struct ChatPanel {
-//     client: Arc<Client>,
-//     channel_store: ModelHandle<ChannelStore>,
-//     languages: Arc<LanguageRegistry>,
-//     active_chat: Option<(ModelHandle<ChannelChat>, Subscription)>,
-//     message_list: ListState<ChatPanel>,
-//     input_editor: ViewHandle<MessageEditor>,
-//     channel_select: ViewHandle<Select>,
-//     local_timezone: UtcOffset,
-//     fs: Arc<dyn Fs>,
-//     width: Option<f32>,
-//     active: bool,
-//     pending_serialization: Task<Option<()>>,
-//     subscriptions: Vec<gpui::Subscription>,
-//     workspace: WeakViewHandle<Workspace>,
-//     is_scrolled_to_bottom: bool,
-//     has_focus: bool,
-//     markdown_data: HashMap<ChannelMessageId, RichText>,
-// }
-
-// #[derive(Serialize, Deserialize)]
-// struct SerializedChatPanel {
-//     width: Option<f32>,
-// }
-
-// #[derive(Debug)]
-// pub enum Event {
-//     DockPositionChanged,
-//     Focus,
-//     Dismissed,
-// }
-
-// actions!(
-//     chat_panel,
-//     [LoadMoreMessages, ToggleFocus, OpenChannelNotes, JoinCall]
-// );
-
-// pub fn init(cx: &mut AppContext) {
-//     cx.add_action(ChatPanel::send);
-//     cx.add_action(ChatPanel::load_more_messages);
-//     cx.add_action(ChatPanel::open_notes);
-//     cx.add_action(ChatPanel::join_call);
-// }
-
-// impl ChatPanel {
-//     pub fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> ViewHandle<Self> {
-//         let fs = workspace.app_state().fs.clone();
-//         let client = workspace.app_state().client.clone();
-//         let channel_store = ChannelStore::global(cx);
-//         let languages = workspace.app_state().languages.clone();
-
-//         let input_editor = cx.add_view(|cx| {
-//             MessageEditor::new(
-//                 languages.clone(),
-//                 channel_store.clone(),
-//                 cx.add_view(|cx| {
-//                     Editor::auto_height(
-//                         4,
-//                         Some(Arc::new(|theme| theme.chat_panel.input_editor.clone())),
-//                         cx,
-//                     )
-//                 }),
-//                 cx,
-//             )
-//         });
-
-//         let workspace_handle = workspace.weak_handle();
-
-//         let channel_select = cx.add_view(|cx| {
-//             let channel_store = channel_store.clone();
-//             let workspace = workspace_handle.clone();
-//             Select::new(0, cx, {
-//                 move |ix, item_type, is_hovered, cx| {
-//                     Self::render_channel_name(
-//                         &channel_store,
-//                         ix,
-//                         item_type,
-//                         is_hovered,
-//                         workspace,
-//                         cx,
-//                     )
-//                 }
-//             })
-//             .with_style(move |cx| {
-//                 let style = &theme::current(cx).chat_panel.channel_select;
-//                 SelectStyle {
-//                     header: Default::default(),
-//                     menu: style.menu,
-//                 }
-//             })
-//         });
-
-//         let mut message_list =
-//             ListState::<Self>::new(0, Orientation::Bottom, 10., move |this, ix, cx| {
-//                 this.render_message(ix, cx)
-//             });
-//         message_list.set_scroll_handler(|visible_range, count, this, cx| {
-//             if visible_range.start < MESSAGE_LOADING_THRESHOLD {
-//                 this.load_more_messages(&LoadMoreMessages, cx);
-//             }
-//             this.is_scrolled_to_bottom = visible_range.end == count;
-//         });
-
-//         cx.add_view(|cx| {
-//             let mut this = Self {
-//                 fs,
-//                 client,
-//                 channel_store,
-//                 languages,
-//                 active_chat: Default::default(),
-//                 pending_serialization: Task::ready(None),
-//                 message_list,
-//                 input_editor,
-//                 channel_select,
-//                 local_timezone: cx.platform().local_timezone(),
-//                 has_focus: false,
-//                 subscriptions: Vec::new(),
-//                 workspace: workspace_handle,
-//                 is_scrolled_to_bottom: true,
-//                 active: false,
-//                 width: None,
-//                 markdown_data: Default::default(),
-//             };
-
-//             let mut old_dock_position = this.position(cx);
-//             this.subscriptions
-//                 .push(
-//                     cx.observe_global::<SettingsStore, _>(move |this: &mut Self, cx| {
-//                         let new_dock_position = this.position(cx);
-//                         if new_dock_position != old_dock_position {
-//                             old_dock_position = new_dock_position;
-//                             cx.emit(Event::DockPositionChanged);
-//                         }
-//                         cx.notify();
-//                     }),
-//                 );
-
-//             this.update_channel_count(cx);
-//             cx.observe(&this.channel_store, |this, _, cx| {
-//                 this.update_channel_count(cx)
-//             })
-//             .detach();
-
-//             cx.observe(&this.channel_select, |this, channel_select, cx| {
-//                 let selected_ix = channel_select.read(cx).selected_index();
-
-//                 let selected_channel_id = this
-//                     .channel_store
-//                     .read(cx)
-//                     .channel_at(selected_ix)
-//                     .map(|e| e.id);
-//                 if let Some(selected_channel_id) = selected_channel_id {
-//                     this.select_channel(selected_channel_id, None, cx)
-//                         .detach_and_log_err(cx);
-//                 }
-//             })
-//             .detach();
-
-//             this
-//         })
-//     }
-
-//     pub fn is_scrolled_to_bottom(&self) -> bool {
-//         self.is_scrolled_to_bottom
-//     }
-
-//     pub fn active_chat(&self) -> Option<ModelHandle<ChannelChat>> {
-//         self.active_chat.as_ref().map(|(chat, _)| chat.clone())
-//     }
-
-//     pub fn load(
-//         workspace: WeakViewHandle<Workspace>,
-//         cx: AsyncAppContext,
-//     ) -> Task<Result<ViewHandle<Self>>> {
-//         cx.spawn(|mut cx| async move {
-//             let serialized_panel = if let Some(panel) = cx
-//                 .background()
-//                 .spawn(async move { KEY_VALUE_STORE.read_kvp(CHAT_PANEL_KEY) })
-//                 .await
-//                 .log_err()
-//                 .flatten()
-//             {
-//                 Some(serde_json::from_str::<SerializedChatPanel>(&panel)?)
-//             } else {
-//                 None
-//             };
-
-//             workspace.update(&mut cx, |workspace, cx| {
-//                 let panel = Self::new(workspace, cx);
-//                 if let Some(serialized_panel) = serialized_panel {
-//                     panel.update(cx, |panel, cx| {
-//                         panel.width = serialized_panel.width;
-//                         cx.notify();
-//                     });
-//                 }
-//                 panel
-//             })
-//         })
-//     }
-
-//     fn serialize(&mut self, cx: &mut ViewContext<Self>) {
-//         let width = self.width;
-//         self.pending_serialization = cx.background().spawn(
-//             async move {
-//                 KEY_VALUE_STORE
-//                     .write_kvp(
-//                         CHAT_PANEL_KEY.into(),
-//                         serde_json::to_string(&SerializedChatPanel { width })?,
-//                     )
-//                     .await?;
-//                 anyhow::Ok(())
-//             }
-//             .log_err(),
-//         );
-//     }
-
-//     fn update_channel_count(&mut self, cx: &mut ViewContext<Self>) {
-//         let channel_count = self.channel_store.read(cx).channel_count();
-//         self.channel_select.update(cx, |select, cx| {
-//             select.set_item_count(channel_count, cx);
-//         });
-//     }
-
-//     fn set_active_chat(&mut self, chat: ModelHandle<ChannelChat>, cx: &mut ViewContext<Self>) {
-//         if self.active_chat.as_ref().map(|e| &e.0) != Some(&chat) {
-//             let channel_id = chat.read(cx).channel_id;
-//             {
-//                 self.markdown_data.clear();
-//                 let chat = chat.read(cx);
-//                 self.message_list.reset(chat.message_count());
-
-//                 let channel_name = chat.channel(cx).map(|channel| channel.name.clone());
-//                 self.input_editor.update(cx, |editor, cx| {
-//                     editor.set_channel(channel_id, channel_name, cx);
-//                 });
-//             };
-//             let subscription = cx.subscribe(&chat, Self::channel_did_change);
-//             self.active_chat = Some((chat, subscription));
-//             self.acknowledge_last_message(cx);
-//             self.channel_select.update(cx, |select, cx| {
-//                 if let Some(ix) = self.channel_store.read(cx).index_of_channel(channel_id) {
-//                     select.set_selected_index(ix, cx);
-//                 }
-//             });
-//             cx.notify();
-//         }
-//     }
-
-//     fn channel_did_change(
-//         &mut self,
-//         _: ModelHandle<ChannelChat>,
-//         event: &ChannelChatEvent,
-//         cx: &mut ViewContext<Self>,
-//     ) {
-//         match event {
-//             ChannelChatEvent::MessagesUpdated {
-//                 old_range,
-//                 new_count,
-//             } => {
-//                 self.message_list.splice(old_range.clone(), *new_count);
-//                 if self.active {
-//                     self.acknowledge_last_message(cx);
-//                 }
-//             }
-//             ChannelChatEvent::NewMessage {
-//                 channel_id,
-//                 message_id,
-//             } => {
-//                 if !self.active {
-//                     self.channel_store.update(cx, |store, cx| {
-//                         store.new_message(*channel_id, *message_id, cx)
-//                     })
-//                 }
-//             }
-//         }
-//         cx.notify();
-//     }
-
-//     fn acknowledge_last_message(&mut self, cx: &mut ViewContext<'_, '_, ChatPanel>) {
-//         if self.active && self.is_scrolled_to_bottom {
-//             if let Some((chat, _)) = &self.active_chat {
-//                 chat.update(cx, |chat, cx| {
-//                     chat.acknowledge_last_message(cx);
-//                 });
-//             }
-//         }
-//     }
-
-//     fn render_channel(&self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
-//         let theme = theme::current(cx);
-//         Flex::column()
-//             .with_child(
-//                 ChildView::new(&self.channel_select, cx)
-//                     .contained()
-//                     .with_style(theme.chat_panel.channel_select.container),
-//             )
-//             .with_child(self.render_active_channel_messages(&theme))
-//             .with_child(self.render_input_box(&theme, cx))
-//             .into_any()
-//     }
-
-//     fn render_active_channel_messages(&self, theme: &Arc<Theme>) -> AnyElement<Self> {
-//         let messages = if self.active_chat.is_some() {
-//             List::new(self.message_list.clone())
-//                 .contained()
-//                 .with_style(theme.chat_panel.list)
-//                 .into_any()
-//         } else {
-//             Empty::new().into_any()
-//         };
-
-//         messages.flex(1., true).into_any()
-//     }
-
-//     fn render_message(&mut self, ix: usize, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
-//         let (message, is_continuation, is_last, is_admin) = self
-//             .active_chat
-//             .as_ref()
-//             .unwrap()
-//             .0
-//             .update(cx, |active_chat, cx| {
-//                 let is_admin = self
-//                     .channel_store
-//                     .read(cx)
-//                     .is_channel_admin(active_chat.channel_id);
-
-//                 let last_message = active_chat.message(ix.saturating_sub(1));
-//                 let this_message = active_chat.message(ix).clone();
-//                 let is_continuation = last_message.id != this_message.id
-//                     && this_message.sender.id == last_message.sender.id;
-
-//                 if let ChannelMessageId::Saved(id) = this_message.id {
-//                     if this_message
-//                         .mentions
-//                         .iter()
-//                         .any(|(_, user_id)| Some(*user_id) == self.client.user_id())
-//                     {
-//                         active_chat.acknowledge_message(id);
-//                     }
-//                 }
-
-//                 (
-//                     this_message,
-//                     is_continuation,
-//                     active_chat.message_count() == ix + 1,
-//                     is_admin,
-//                 )
-//             });
-
-//         let is_pending = message.is_pending();
-//         let theme = theme::current(cx);
-//         let text = self.markdown_data.entry(message.id).or_insert_with(|| {
-//             Self::render_markdown_with_mentions(&self.languages, self.client.id(), &message)
-//         });
-
-//         let now = OffsetDateTime::now_utc();
-
-//         let style = if is_pending {
-//             &theme.chat_panel.pending_message
-//         } else if is_continuation {
-//             &theme.chat_panel.continuation_message
-//         } else {
-//             &theme.chat_panel.message
-//         };
-
-//         let belongs_to_user = Some(message.sender.id) == self.client.user_id();
-//         let message_id_to_remove = if let (ChannelMessageId::Saved(id), true) =
-//             (message.id, belongs_to_user || is_admin)
-//         {
-//             Some(id)
-//         } else {
-//             None
-//         };
-
-//         enum MessageBackgroundHighlight {}
-//         MouseEventHandler::new::<MessageBackgroundHighlight, _>(ix, cx, |state, cx| {
-//             let container = style.style_for(state);
-//             if is_continuation {
-//                 Flex::row()
-//                     .with_child(
-//                         text.element(
-//                             theme.editor.syntax.clone(),
-//                             theme.chat_panel.rich_text.clone(),
-//                             cx,
-//                         )
-//                         .flex(1., true),
-//                     )
-//                     .with_child(render_remove(message_id_to_remove, cx, &theme))
-//                     .contained()
-//                     .with_style(*container)
-//                     .with_margin_bottom(if is_last {
-//                         theme.chat_panel.last_message_bottom_spacing
-//                     } else {
-//                         0.
-//                     })
-//                     .into_any()
-//             } else {
-//                 Flex::column()
-//                     .with_child(
-//                         Flex::row()
-//                             .with_child(
-//                                 Flex::row()
-//                                     .with_child(render_avatar(
-//                                         message.sender.avatar.clone(),
-//                                         &theme.chat_panel.avatar,
-//                                         theme.chat_panel.avatar_container,
-//                                     ))
-//                                     .with_child(
-//                                         Label::new(
-//                                             message.sender.github_login.clone(),
-//                                             theme.chat_panel.message_sender.text.clone(),
-//                                         )
-//                                         .contained()
-//                                         .with_style(theme.chat_panel.message_sender.container),
-//                                     )
-//                                     .with_child(
-//                                         Label::new(
-//                                             format_timestamp(
-//                                                 message.timestamp,
-//                                                 now,
-//                                                 self.local_timezone,
-//                                             ),
-//                                             theme.chat_panel.message_timestamp.text.clone(),
-//                                         )
-//                                         .contained()
-//                                         .with_style(theme.chat_panel.message_timestamp.container),
-//                                     )
-//                                     .align_children_center()
-//                                     .flex(1., true),
-//                             )
-//                             .with_child(render_remove(message_id_to_remove, cx, &theme))
-//                             .align_children_center(),
-//                     )
-//                     .with_child(
-//                         Flex::row()
-//                             .with_child(
-//                                 text.element(
-//                                     theme.editor.syntax.clone(),
-//                                     theme.chat_panel.rich_text.clone(),
-//                                     cx,
-//                                 )
-//                                 .flex(1., true),
-//                             )
-//                             // Add a spacer to make everything line up
-//                             .with_child(render_remove(None, cx, &theme)),
-//                     )
-//                     .contained()
-//                     .with_style(*container)
-//                     .with_margin_bottom(if is_last {
-//                         theme.chat_panel.last_message_bottom_spacing
-//                     } else {
-//                         0.
-//                     })
-//                     .into_any()
-//             }
-//         })
-//         .into_any()
-//     }
-
-//     fn render_markdown_with_mentions(
-//         language_registry: &Arc<LanguageRegistry>,
-//         current_user_id: u64,
-//         message: &channel::ChannelMessage,
-//     ) -> RichText {
-//         let mentions = message
-//             .mentions
-//             .iter()
-//             .map(|(range, user_id)| rich_text::Mention {
-//                 range: range.clone(),
-//                 is_self_mention: *user_id == current_user_id,
-//             })
-//             .collect::<Vec<_>>();
-
-//         rich_text::render_markdown(message.body.clone(), &mentions, language_registry, None)
-//     }
-
-//     fn render_input_box(&self, theme: &Arc<Theme>, cx: &AppContext) -> AnyElement<Self> {
-//         ChildView::new(&self.input_editor, cx)
-//             .contained()
-//             .with_style(theme.chat_panel.input_editor.container)
-//             .into_any()
-//     }
-
-//     fn render_channel_name(
-//         channel_store: &ModelHandle<ChannelStore>,
-//         ix: usize,
-//         item_type: ItemType,
-//         is_hovered: bool,
-//         workspace: WeakViewHandle<Workspace>,
-//         cx: &mut ViewContext<Select>,
-//     ) -> AnyElement<Select> {
-//         let theme = theme::current(cx);
-//         let tooltip_style = &theme.tooltip;
-//         let theme = &theme.chat_panel;
-//         let style = match (&item_type, is_hovered) {
-//             (ItemType::Header, _) => &theme.channel_select.header,
-//             (ItemType::Selected, _) => &theme.channel_select.active_item,
-//             (ItemType::Unselected, false) => &theme.channel_select.item,
-//             (ItemType::Unselected, true) => &theme.channel_select.hovered_item,
-//         };
-
-//         let channel = &channel_store.read(cx).channel_at(ix).unwrap();
-//         let channel_id = channel.id;
-
-//         let mut row = Flex::row()
-//             .with_child(
-//                 Label::new("#".to_string(), style.hash.text.clone())
-//                     .contained()
-//                     .with_style(style.hash.container),
-//             )
-//             .with_child(Label::new(channel.name.clone(), style.name.clone()));
-
-//         if matches!(item_type, ItemType::Header) {
-//             row.add_children([
-//                 MouseEventHandler::new::<OpenChannelNotes, _>(0, cx, |mouse_state, _| {
-//                     render_icon_button(theme.icon_button.style_for(mouse_state), "icons/file.svg")
-//                 })
-//                 .on_click(MouseButton::Left, move |_, _, cx| {
-//                     if let Some(workspace) = workspace.upgrade(cx) {
-//                         ChannelView::open(channel_id, workspace, cx).detach();
-//                     }
-//                 })
-//                 .with_tooltip::<OpenChannelNotes>(
-//                     channel_id as usize,
-//                     "Open Notes",
-//                     Some(Box::new(OpenChannelNotes)),
-//                     tooltip_style.clone(),
-//                     cx,
-//                 )
-//                 .flex_float(),
-//                 MouseEventHandler::new::<ActiveCall, _>(0, cx, |mouse_state, _| {
-//                     render_icon_button(
-//                         theme.icon_button.style_for(mouse_state),
-//                         "icons/speaker-loud.svg",
-//                     )
-//                 })
-//                 .on_click(MouseButton::Left, move |_, _, cx| {
-//                     ActiveCall::global(cx)
-//                         .update(cx, |call, cx| call.join_channel(channel_id, cx))
-//                         .detach_and_log_err(cx);
-//                 })
-//                 .with_tooltip::<ActiveCall>(
-//                     channel_id as usize,
-//                     "Join Call",
-//                     Some(Box::new(JoinCall)),
-//                     tooltip_style.clone(),
-//                     cx,
-//                 )
-//                 .flex_float(),
-//             ]);
-//         }
-
-//         row.align_children_center()
-//             .contained()
-//             .with_style(style.container)
-//             .into_any()
-//     }
-
-//     fn render_sign_in_prompt(
-//         &self,
-//         theme: &Arc<Theme>,
-//         cx: &mut ViewContext<Self>,
-//     ) -> AnyElement<Self> {
-//         enum SignInPromptLabel {}
-
-//         MouseEventHandler::new::<SignInPromptLabel, _>(0, cx, |mouse_state, _| {
-//             Label::new(
-//                 "Sign in to use chat".to_string(),
-//                 theme
-//                     .chat_panel
-//                     .sign_in_prompt
-//                     .style_for(mouse_state)
-//                     .clone(),
-//             )
-//         })
-//         .with_cursor_style(CursorStyle::PointingHand)
-//         .on_click(MouseButton::Left, move |_, this, cx| {
-//             let client = this.client.clone();
-//             cx.spawn(|this, mut cx| async move {
-//                 if client
-//                     .authenticate_and_connect(true, &cx)
-//                     .log_err()
-//                     .await
-//                     .is_some()
-//                 {
-//                     this.update(&mut cx, |this, cx| {
-//                         if cx.handle().is_focused(cx) {
-//                             cx.focus(&this.input_editor);
-//                         }
-//                     })
-//                     .ok();
-//                 }
-//             })
-//             .detach();
-//         })
-//         .aligned()
-//         .into_any()
-//     }
-
-//     fn send(&mut self, _: &Confirm, cx: &mut ViewContext<Self>) {
-//         if let Some((chat, _)) = self.active_chat.as_ref() {
-//             let message = self
-//                 .input_editor
-//                 .update(cx, |editor, cx| editor.take_message(cx));
-
-//             if let Some(task) = chat
-//                 .update(cx, |chat, cx| chat.send_message(message, cx))
-//                 .log_err()
-//             {
-//                 task.detach();
-//             }
-//         }
-//     }
-
-//     fn remove_message(&mut self, id: u64, cx: &mut ViewContext<Self>) {
-//         if let Some((chat, _)) = self.active_chat.as_ref() {
-//             chat.update(cx, |chat, cx| chat.remove_message(id, cx).detach())
-//         }
-//     }
-
-//     fn load_more_messages(&mut self, _: &LoadMoreMessages, cx: &mut ViewContext<Self>) {
-//         if let Some((chat, _)) = self.active_chat.as_ref() {
-//             chat.update(cx, |channel, cx| {
-//                 if let Some(task) = channel.load_more_messages(cx) {
-//                     task.detach();
-//                 }
-//             })
-//         }
-//     }
-
-//     pub fn select_channel(
-//         &mut self,
-//         selected_channel_id: u64,
-//         scroll_to_message_id: Option<u64>,
-//         cx: &mut ViewContext<ChatPanel>,
-//     ) -> Task<Result<()>> {
-//         let open_chat = self
-//             .active_chat
-//             .as_ref()
-//             .and_then(|(chat, _)| {
-//                 (chat.read(cx).channel_id == selected_channel_id)
-//                     .then(|| Task::ready(anyhow::Ok(chat.clone())))
-//             })
-//             .unwrap_or_else(|| {
-//                 self.channel_store.update(cx, |store, cx| {
-//                     store.open_channel_chat(selected_channel_id, cx)
-//                 })
-//             });
-
-//         cx.spawn(|this, mut cx| async move {
-//             let chat = open_chat.await?;
-//             this.update(&mut cx, |this, cx| {
-//                 this.set_active_chat(chat.clone(), cx);
-//             })?;
-
-//             if let Some(message_id) = scroll_to_message_id {
-//                 if let Some(item_ix) =
-//                     ChannelChat::load_history_since_message(chat.clone(), message_id, cx.clone())
-//                         .await
-//                 {
-//                     this.update(&mut cx, |this, cx| {
-//                         if this.active_chat.as_ref().map_or(false, |(c, _)| *c == chat) {
-//                             this.message_list.scroll_to(ListOffset {
-//                                 item_ix,
-//                                 offset_in_item: 0.,
-//                             });
-//                             cx.notify();
-//                         }
-//                     })?;
-//                 }
-//             }
-
-//             Ok(())
-//         })
-//     }
-
-//     fn open_notes(&mut self, _: &OpenChannelNotes, cx: &mut ViewContext<Self>) {
-//         if let Some((chat, _)) = &self.active_chat {
-//             let channel_id = chat.read(cx).channel_id;
-//             if let Some(workspace) = self.workspace.upgrade(cx) {
-//                 ChannelView::open(channel_id, workspace, cx).detach();
-//             }
-//         }
-//     }
-
-//     fn join_call(&mut self, _: &JoinCall, cx: &mut ViewContext<Self>) {
-//         if let Some((chat, _)) = &self.active_chat {
-//             let channel_id = chat.read(cx).channel_id;
-//             ActiveCall::global(cx)
-//                 .update(cx, |call, cx| call.join_channel(channel_id, cx))
-//                 .detach_and_log_err(cx);
-//         }
-//     }
-// }
-
-// fn render_remove(
-//     message_id_to_remove: Option<u64>,
-//     cx: &mut ViewContext<'_, '_, ChatPanel>,
-//     theme: &Arc<Theme>,
-// ) -> AnyElement<ChatPanel> {
-//     enum DeleteMessage {}
-
-//     message_id_to_remove
-//         .map(|id| {
-//             MouseEventHandler::new::<DeleteMessage, _>(id as usize, cx, |mouse_state, _| {
-//                 let button_style = theme.chat_panel.icon_button.style_for(mouse_state);
-//                 render_icon_button(button_style, "icons/x.svg")
-//                     .aligned()
-//                     .into_any()
-//             })
-//             .with_padding(Padding::uniform(2.))
-//             .with_cursor_style(CursorStyle::PointingHand)
-//             .on_click(MouseButton::Left, move |_, this, cx| {
-//                 this.remove_message(id, cx);
-//             })
-//             .flex_float()
-//             .into_any()
-//         })
-//         .unwrap_or_else(|| {
-//             let style = theme.chat_panel.icon_button.default;
-
-//             Empty::new()
-//                 .constrained()
-//                 .with_width(style.icon_width)
-//                 .aligned()
-//                 .constrained()
-//                 .with_width(style.button_width)
-//                 .with_height(style.button_width)
-//                 .contained()
-//                 .with_uniform_padding(2.)
-//                 .flex_float()
-//                 .into_any()
-//         })
-// }
-
-// impl Entity for ChatPanel {
-//     type Event = Event;
-// }
-
-// impl View for ChatPanel {
-//     fn ui_name() -> &'static str {
-//         "ChatPanel"
-//     }
-
-//     fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
-//         let theme = theme::current(cx);
-//         let element = if self.client.user_id().is_some() {
-//             self.render_channel(cx)
-//         } else {
-//             self.render_sign_in_prompt(&theme, cx)
-//         };
-//         element
-//             .contained()
-//             .with_style(theme.chat_panel.container)
-//             .constrained()
-//             .with_min_width(150.)
-//             .into_any()
-//     }
-
-//     fn focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext<Self>) {
-//         self.has_focus = true;
-//         if matches!(
-//             *self.client.status().borrow(),
-//             client::Status::Connected { .. }
-//         ) {
-//             let editor = self.input_editor.read(cx).editor.clone();
-//             cx.focus(&editor);
-//         }
-//     }
-
-//     fn focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {
-//         self.has_focus = false;
-//     }
-// }
-
-// impl Panel for ChatPanel {
-//     fn position(&self, cx: &gpui::WindowContext) -> DockPosition {
-//         settings::get::<ChatPanelSettings>(cx).dock
-//     }
-
-//     fn position_is_valid(&self, position: DockPosition) -> bool {
-//         matches!(position, DockPosition::Left | DockPosition::Right)
-//     }
-
-//     fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>) {
-//         settings::update_settings_file::<ChatPanelSettings>(self.fs.clone(), cx, move |settings| {
-//             settings.dock = Some(position)
-//         });
-//     }
-
-//     fn size(&self, cx: &gpui::WindowContext) -> f32 {
-//         self.width
-//             .unwrap_or_else(|| settings::get::<ChatPanelSettings>(cx).default_width)
-//     }
-
-//     fn set_size(&mut self, size: Option<f32>, cx: &mut ViewContext<Self>) {
-//         self.width = size;
-//         self.serialize(cx);
-//         cx.notify();
-//     }
-
-//     fn set_active(&mut self, active: bool, cx: &mut ViewContext<Self>) {
-//         self.active = active;
-//         if active {
-//             self.acknowledge_last_message(cx);
-//             if !is_channels_feature_enabled(cx) {
-//                 cx.emit(Event::Dismissed);
-//             }
-//         }
-//     }
-
-//     fn icon_path(&self, cx: &gpui::WindowContext) -> Option<&'static str> {
-//         (settings::get::<ChatPanelSettings>(cx).button && is_channels_feature_enabled(cx))
-//             .then(|| "icons/conversations.svg")
-//     }
-
-//     fn icon_tooltip(&self) -> (String, Option<Box<dyn gpui::Action>>) {
-//         ("Chat Panel".to_string(), Some(Box::new(ToggleFocus)))
-//     }
-
-//     fn should_change_position_on_event(event: &Self::Event) -> bool {
-//         matches!(event, Event::DockPositionChanged)
-//     }
-
-//     fn should_close_on_event(event: &Self::Event) -> bool {
-//         matches!(event, Event::Dismissed)
-//     }
-
-//     fn has_focus(&self, _cx: &gpui::WindowContext) -> bool {
-//         self.has_focus
-//     }
-
-//     fn is_focus_event(event: &Self::Event) -> bool {
-//         matches!(event, Event::Focus)
-//     }
-// }
-
-// fn format_timestamp(
-//     mut timestamp: OffsetDateTime,
-//     mut now: OffsetDateTime,
-//     local_timezone: UtcOffset,
-// ) -> String {
-//     timestamp = timestamp.to_offset(local_timezone);
-//     now = now.to_offset(local_timezone);
-
-//     let today = now.date();
-//     let date = timestamp.date();
-//     let mut hour = timestamp.hour();
-//     let mut part = "am";
-//     if hour > 12 {
-//         hour -= 12;
-//         part = "pm";
-//     }
-//     if date == today {
-//         format!("{:02}:{:02}{}", hour, timestamp.minute(), part)
-//     } else if date.next_day() == Some(today) {
-//         format!("yesterday at {:02}:{:02}{}", hour, timestamp.minute(), part)
-//     } else {
-//         format!("{:02}/{}/{}", date.month() as u32, date.day(), date.year())
-//     }
-// }
-
-// fn render_icon_button<V: View>(style: &IconButton, svg_path: &'static str) -> impl Element<V> {
-//     Svg::new(svg_path)
-//         .with_color(style.color)
-//         .constrained()
-//         .with_width(style.icon_width)
-//         .aligned()
-//         .constrained()
-//         .with_width(style.button_width)
-//         .with_height(style.button_width)
-//         .contained()
-//         .with_style(style.container)
-// }
-
-// #[cfg(test)]
-// mod tests {
-//     use super::*;
-//     use gpui::fonts::HighlightStyle;
-//     use pretty_assertions::assert_eq;
-//     use rich_text::{BackgroundKind, Highlight, RenderedRegion};
-//     use util::test::marked_text_ranges;
-
-//     #[gpui::test]
-//     fn test_render_markdown_with_mentions() {
-//         let language_registry = Arc::new(LanguageRegistry::test());
-//         let (body, ranges) = marked_text_ranges("*hi*, «@abc», let's **call** «@fgh»", false);
-//         let message = channel::ChannelMessage {
-//             id: ChannelMessageId::Saved(0),
-//             body,
-//             timestamp: OffsetDateTime::now_utc(),
-//             sender: Arc::new(client::User {
-//                 github_login: "fgh".into(),
-//                 avatar: None,
-//                 id: 103,
-//             }),
-//             nonce: 5,
-//             mentions: vec![(ranges[0].clone(), 101), (ranges[1].clone(), 102)],
-//         };
-
-//         let message = ChatPanel::render_markdown_with_mentions(&language_registry, 102, &message);
-
-//         // Note that the "'" was replaced with ’ due to smart punctuation.
-//         let (body, ranges) = marked_text_ranges("«hi», «@abc», let’s «call» «@fgh»", false);
-//         assert_eq!(message.text, body);
-//         assert_eq!(
-//             message.highlights,
-//             vec![
-//                 (
-//                     ranges[0].clone(),
-//                     HighlightStyle {
-//                         italic: Some(true),
-//                         ..Default::default()
-//                     }
-//                     .into()
-//                 ),
-//                 (ranges[1].clone(), Highlight::Mention),
-//                 (
-//                     ranges[2].clone(),
-//                     HighlightStyle {
-//                         weight: Some(gpui::fonts::Weight::BOLD),
-//                         ..Default::default()
-//                     }
-//                     .into()
-//                 ),
-//                 (ranges[3].clone(), Highlight::SelfMention)
-//             ]
-//         );
-//         assert_eq!(
-//             message.regions,
-//             vec![
-//                 RenderedRegion {
-//                     background_kind: Some(BackgroundKind::Mention),
-//                     link_url: None
-//                 },
-//                 RenderedRegion {
-//                     background_kind: Some(BackgroundKind::SelfMention),
-//                     link_url: None
-//                 },
-//             ]
-//         );
-//     }
-// }
+use crate::{channel_view::ChannelView, is_channels_feature_enabled, ChatPanelSettings};
+use anyhow::Result;
+use call::ActiveCall;
+use channel::{ChannelChat, ChannelChatEvent, ChannelMessageId, ChannelStore};
+use client::Client;
+use collections::HashMap;
+use db::kvp::KEY_VALUE_STORE;
+use editor::Editor;
+use gpui::{
+    actions, div, list, prelude::*, px, serde_json, AnyElement, AppContext, AsyncWindowContext,
+    ClickEvent, Div, ElementId, EventEmitter, FocusableView, ListOffset, ListScrollEvent,
+    ListState, Model, Render, Subscription, Task, View, ViewContext, VisualContext, WeakView,
+};
+use language::LanguageRegistry;
+use menu::Confirm;
+use message_editor::MessageEditor;
+use project::Fs;
+use rich_text::RichText;
+use serde::{Deserialize, Serialize};
+use settings::{Settings, SettingsStore};
+use std::sync::Arc;
+use theme::ActiveTheme as _;
+use time::{OffsetDateTime, UtcOffset};
+use ui::{
+    h_stack, prelude::WindowContext, v_stack, Avatar, Button, ButtonCommon as _, Clickable, Icon,
+    IconButton, Label, Tooltip,
+};
+use util::{ResultExt, TryFutureExt};
+use workspace::{
+    dock::{DockPosition, Panel, PanelEvent},
+    Workspace,
+};
+
+mod message_editor;
+
+const MESSAGE_LOADING_THRESHOLD: usize = 50;
+const CHAT_PANEL_KEY: &'static str = "ChatPanel";
+
+pub fn init(cx: &mut AppContext) {
+    cx.observe_new_views(|workspace: &mut Workspace, _| {
+        workspace.register_action(|workspace, _: &ToggleFocus, cx| {
+            workspace.toggle_panel_focus::<ChatPanel>(cx);
+        });
+    })
+    .detach();
+}
+
+pub struct ChatPanel {
+    client: Arc<Client>,
+    channel_store: Model<ChannelStore>,
+    languages: Arc<LanguageRegistry>,
+    message_list: ListState,
+    active_chat: Option<(Model<ChannelChat>, Subscription)>,
+    input_editor: View<MessageEditor>,
+    local_timezone: UtcOffset,
+    fs: Arc<dyn Fs>,
+    width: Option<f32>,
+    active: bool,
+    pending_serialization: Task<Option<()>>,
+    subscriptions: Vec<gpui::Subscription>,
+    workspace: WeakView<Workspace>,
+    is_scrolled_to_bottom: bool,
+    markdown_data: HashMap<ChannelMessageId, RichText>,
+}
+
+#[derive(Serialize, Deserialize)]
+struct SerializedChatPanel {
+    width: Option<f32>,
+}
+
+#[derive(Debug)]
+pub enum Event {
+    DockPositionChanged,
+    Focus,
+    Dismissed,
+}
+
+actions!(chat_panel, [ToggleFocus]);
+
+impl ChatPanel {
+    pub fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> View<Self> {
+        let fs = workspace.app_state().fs.clone();
+        let client = workspace.app_state().client.clone();
+        let channel_store = ChannelStore::global(cx);
+        let languages = workspace.app_state().languages.clone();
+
+        let input_editor = cx.build_view(|cx| {
+            MessageEditor::new(
+                languages.clone(),
+                channel_store.clone(),
+                cx.build_view(|cx| Editor::auto_height(4, cx)),
+                cx,
+            )
+        });
+
+        let workspace_handle = workspace.weak_handle();
+
+        cx.build_view(|cx| {
+            let view: View<ChatPanel> = cx.view().clone();
+            let message_list =
+                ListState::new(0, gpui::ListAlignment::Bottom, px(1000.), move |ix, cx| {
+                    view.update(cx, |view, cx| view.render_message(ix, cx))
+                });
+
+            message_list.set_scroll_handler(cx.listener(|this, event: &ListScrollEvent, cx| {
+                if event.visible_range.start < MESSAGE_LOADING_THRESHOLD {
+                    this.load_more_messages(cx);
+                }
+                this.is_scrolled_to_bottom = event.visible_range.end == event.count;
+            }));
+
+            let mut this = Self {
+                fs,
+                client,
+                channel_store,
+                languages,
+                message_list,
+                active_chat: Default::default(),
+                pending_serialization: Task::ready(None),
+                input_editor,
+                local_timezone: cx.local_timezone(),
+                subscriptions: Vec::new(),
+                workspace: workspace_handle,
+                is_scrolled_to_bottom: true,
+                active: false,
+                width: None,
+                markdown_data: Default::default(),
+            };
+
+            let mut old_dock_position = this.position(cx);
+            this.subscriptions.push(cx.observe_global::<SettingsStore>(
+                move |this: &mut Self, cx| {
+                    let new_dock_position = this.position(cx);
+                    if new_dock_position != old_dock_position {
+                        old_dock_position = new_dock_position;
+                        cx.emit(Event::DockPositionChanged);
+                    }
+                    cx.notify();
+                },
+            ));
+
+            this
+        })
+    }
+
+    pub fn is_scrolled_to_bottom(&self) -> bool {
+        self.is_scrolled_to_bottom
+    }
+
+    pub fn active_chat(&self) -> Option<Model<ChannelChat>> {
+        self.active_chat.as_ref().map(|(chat, _)| chat.clone())
+    }
+
+    pub fn load(
+        workspace: WeakView<Workspace>,
+        cx: AsyncWindowContext,
+    ) -> Task<Result<View<Self>>> {
+        cx.spawn(|mut cx| async move {
+            let serialized_panel = if let Some(panel) = cx
+                .background_executor()
+                .spawn(async move { KEY_VALUE_STORE.read_kvp(CHAT_PANEL_KEY) })
+                .await
+                .log_err()
+                .flatten()
+            {
+                Some(serde_json::from_str::<SerializedChatPanel>(&panel)?)
+            } else {
+                None
+            };
+
+            workspace.update(&mut cx, |workspace, cx| {
+                let panel = Self::new(workspace, cx);
+                if let Some(serialized_panel) = serialized_panel {
+                    panel.update(cx, |panel, cx| {
+                        panel.width = serialized_panel.width;
+                        cx.notify();
+                    });
+                }
+                panel
+            })
+        })
+    }
+
+    fn serialize(&mut self, cx: &mut ViewContext<Self>) {
+        let width = self.width;
+        self.pending_serialization = cx.background_executor().spawn(
+            async move {
+                KEY_VALUE_STORE
+                    .write_kvp(
+                        CHAT_PANEL_KEY.into(),
+                        serde_json::to_string(&SerializedChatPanel { width })?,
+                    )
+                    .await?;
+                anyhow::Ok(())
+            }
+            .log_err(),
+        );
+    }
+
+    fn set_active_chat(&mut self, chat: Model<ChannelChat>, cx: &mut ViewContext<Self>) {
+        if self.active_chat.as_ref().map(|e| &e.0) != Some(&chat) {
+            let channel_id = chat.read(cx).channel_id;
+            {
+                self.markdown_data.clear();
+                let chat = chat.read(cx);
+                self.message_list.reset(chat.message_count());
+
+                let channel_name = chat.channel(cx).map(|channel| channel.name.clone());
+                self.input_editor.update(cx, |editor, cx| {
+                    editor.set_channel(channel_id, channel_name, cx);
+                });
+            };
+            let subscription = cx.subscribe(&chat, Self::channel_did_change);
+            self.active_chat = Some((chat, subscription));
+            self.acknowledge_last_message(cx);
+            cx.notify();
+        }
+    }
+
+    fn channel_did_change(
+        &mut self,
+        _: Model<ChannelChat>,
+        event: &ChannelChatEvent,
+        cx: &mut ViewContext<Self>,
+    ) {
+        match event {
+            ChannelChatEvent::MessagesUpdated {
+                old_range,
+                new_count,
+            } => {
+                self.message_list.splice(old_range.clone(), *new_count);
+                if self.active {
+                    self.acknowledge_last_message(cx);
+                }
+            }
+            ChannelChatEvent::NewMessage {
+                channel_id,
+                message_id,
+            } => {
+                if !self.active {
+                    self.channel_store.update(cx, |store, cx| {
+                        store.new_message(*channel_id, *message_id, cx)
+                    })
+                }
+            }
+        }
+        cx.notify();
+    }
+
+    fn acknowledge_last_message(&mut self, cx: &mut ViewContext<Self>) {
+        if self.active && self.is_scrolled_to_bottom {
+            if let Some((chat, _)) = &self.active_chat {
+                chat.update(cx, |chat, cx| {
+                    chat.acknowledge_last_message(cx);
+                });
+            }
+        }
+    }
+
+    fn render_channel(&self, cx: &mut ViewContext<Self>) -> AnyElement {
+        v_stack()
+            .full()
+            .on_action(cx.listener(Self::send))
+            .child(
+                h_stack()
+                    .w_full()
+                    .h_7()
+                    .justify_between()
+                    .z_index(1)
+                    .bg(cx.theme().colors().background)
+                    .child(Label::new(
+                        self.active_chat
+                            .as_ref()
+                            .and_then(|c| Some(format!("#{}", c.0.read(cx).channel(cx)?.name)))
+                            .unwrap_or_default(),
+                    ))
+                    .child(
+                        h_stack()
+                            .child(
+                                IconButton::new("notes", Icon::File)
+                                    .on_click(cx.listener(Self::open_notes))
+                                    .tooltip(|cx| Tooltip::text("Open notes", cx)),
+                            )
+                            .child(
+                                IconButton::new("call", Icon::AudioOn)
+                                    .on_click(cx.listener(Self::join_call))
+                                    .tooltip(|cx| Tooltip::text("Join call", cx)),
+                            ),
+                    ),
+            )
+            .child(div().grow().child(self.render_active_channel_messages(cx)))
+            .child(
+                div()
+                    .z_index(1)
+                    .p_2()
+                    .bg(cx.theme().colors().background)
+                    .child(self.input_editor.clone()),
+            )
+            .into_any()
+    }
+
+    fn render_active_channel_messages(&self, _cx: &mut ViewContext<Self>) -> AnyElement {
+        if self.active_chat.is_some() {
+            list(self.message_list.clone()).full().into_any_element()
+        } else {
+            div().into_any_element()
+        }
+    }
+
+    fn render_message(&mut self, ix: usize, cx: &mut ViewContext<Self>) -> AnyElement {
+        let active_chat = &self.active_chat.as_ref().unwrap().0;
+        let (message, is_continuation, is_admin) = active_chat.update(cx, |active_chat, cx| {
+            let is_admin = self
+                .channel_store
+                .read(cx)
+                .is_channel_admin(active_chat.channel_id);
+
+            let last_message = active_chat.message(ix.saturating_sub(1));
+            let this_message = active_chat.message(ix).clone();
+            let is_continuation = last_message.id != this_message.id
+                && this_message.sender.id == last_message.sender.id;
+
+            if let ChannelMessageId::Saved(id) = this_message.id {
+                if this_message
+                    .mentions
+                    .iter()
+                    .any(|(_, user_id)| Some(*user_id) == self.client.user_id())
+                {
+                    active_chat.acknowledge_message(id);
+                }
+            }
+
+            (this_message, is_continuation, is_admin)
+        });
+
+        let _is_pending = message.is_pending();
+        let text = self.markdown_data.entry(message.id).or_insert_with(|| {
+            Self::render_markdown_with_mentions(&self.languages, self.client.id(), &message)
+        });
+
+        let now = OffsetDateTime::now_utc();
+
+        let belongs_to_user = Some(message.sender.id) == self.client.user_id();
+        let message_id_to_remove = if let (ChannelMessageId::Saved(id), true) =
+            (message.id, belongs_to_user || is_admin)
+        {
+            Some(id)
+        } else {
+            None
+        };
+
+        let element_id: ElementId = match message.id {
+            ChannelMessageId::Saved(id) => ("saved-message", id).into(),
+            ChannelMessageId::Pending(id) => ("pending-message", id).into(),
+        };
+
+        let mut result = v_stack()
+            .w_full()
+            .id(element_id)
+            .relative()
+            .group("")
+            .mb_1();
+
+        if !is_continuation {
+            result = result.child(
+                h_stack()
+                    .children(
+                        message
+                            .sender
+                            .avatar
+                            .clone()
+                            .map(|avatar| Avatar::data(avatar)),
+                    )
+                    .child(Label::new(message.sender.github_login.clone()))
+                    .child(Label::new(format_timestamp(
+                        message.timestamp,
+                        now,
+                        self.local_timezone,
+                    ))),
+            );
+        }
+
+        result
+            .child(text.element("body".into(), cx))
+            .child(
+                div()
+                    .invisible()
+                    .absolute()
+                    .top_1()
+                    .right_2()
+                    .w_8()
+                    .group_hover("", |this| this.visible())
+                    .child(render_remove(message_id_to_remove, cx)),
+            )
+            .into_any()
+    }
+
+    fn render_markdown_with_mentions(
+        language_registry: &Arc<LanguageRegistry>,
+        current_user_id: u64,
+        message: &channel::ChannelMessage,
+    ) -> RichText {
+        let mentions = message
+            .mentions
+            .iter()
+            .map(|(range, user_id)| rich_text::Mention {
+                range: range.clone(),
+                is_self_mention: *user_id == current_user_id,
+            })
+            .collect::<Vec<_>>();
+
+        rich_text::render_markdown(message.body.clone(), &mentions, language_registry, None)
+    }
+
+    fn render_sign_in_prompt(&self, cx: &mut ViewContext<Self>) -> AnyElement {
+        Button::new("sign-in", "Sign in to use chat")
+            .on_click(cx.listener(move |this, _, cx| {
+                let client = this.client.clone();
+                cx.spawn(|this, mut cx| async move {
+                    if client
+                        .authenticate_and_connect(true, &cx)
+                        .log_err()
+                        .await
+                        .is_some()
+                    {
+                        this.update(&mut cx, |_, cx| {
+                            cx.focus_self();
+                        })
+                        .ok();
+                    }
+                })
+                .detach();
+            }))
+            .into_any_element()
+    }
+
+    fn send(&mut self, _: &Confirm, cx: &mut ViewContext<Self>) {
+        if let Some((chat, _)) = self.active_chat.as_ref() {
+            let message = self
+                .input_editor
+                .update(cx, |editor, cx| editor.take_message(cx));
+
+            if let Some(task) = chat
+                .update(cx, |chat, cx| chat.send_message(message, cx))
+                .log_err()
+            {
+                task.detach();
+            }
+        }
+    }
+
+    fn remove_message(&mut self, id: u64, cx: &mut ViewContext<Self>) {
+        if let Some((chat, _)) = self.active_chat.as_ref() {
+            chat.update(cx, |chat, cx| chat.remove_message(id, cx).detach())
+        }
+    }
+
+    fn load_more_messages(&mut self, cx: &mut ViewContext<Self>) {
+        if let Some((chat, _)) = self.active_chat.as_ref() {
+            chat.update(cx, |channel, cx| {
+                if let Some(task) = channel.load_more_messages(cx) {
+                    task.detach();
+                }
+            })
+        }
+    }
+
+    pub fn select_channel(
+        &mut self,
+        selected_channel_id: u64,
+        scroll_to_message_id: Option<u64>,
+        cx: &mut ViewContext<ChatPanel>,
+    ) -> Task<Result<()>> {
+        let open_chat = self
+            .active_chat
+            .as_ref()
+            .and_then(|(chat, _)| {
+                (chat.read(cx).channel_id == selected_channel_id)
+                    .then(|| Task::ready(anyhow::Ok(chat.clone())))
+            })
+            .unwrap_or_else(|| {
+                self.channel_store.update(cx, |store, cx| {
+                    store.open_channel_chat(selected_channel_id, cx)
+                })
+            });
+
+        cx.spawn(|this, mut cx| async move {
+            let chat = open_chat.await?;
+            this.update(&mut cx, |this, cx| {
+                this.set_active_chat(chat.clone(), cx);
+            })?;
+
+            if let Some(message_id) = scroll_to_message_id {
+                if let Some(item_ix) =
+                    ChannelChat::load_history_since_message(chat.clone(), message_id, (*cx).clone())
+                        .await
+                {
+                    this.update(&mut cx, |this, cx| {
+                        if this.active_chat.as_ref().map_or(false, |(c, _)| *c == chat) {
+                            this.message_list.scroll_to(ListOffset {
+                                item_ix,
+                                offset_in_item: px(0.0),
+                            });
+                            cx.notify();
+                        }
+                    })?;
+                }
+            }
+
+            Ok(())
+        })
+    }
+
+    fn open_notes(&mut self, _: &ClickEvent, cx: &mut ViewContext<Self>) {
+        if let Some((chat, _)) = &self.active_chat {
+            let channel_id = chat.read(cx).channel_id;
+            if let Some(workspace) = self.workspace.upgrade() {
+                ChannelView::open(channel_id, workspace, cx).detach();
+            }
+        }
+    }
+
+    fn join_call(&mut self, _: &ClickEvent, cx: &mut ViewContext<Self>) {
+        if let Some((chat, _)) = &self.active_chat {
+            let channel_id = chat.read(cx).channel_id;
+            ActiveCall::global(cx)
+                .update(cx, |call, cx| call.join_channel(channel_id, cx))
+                .detach_and_log_err(cx);
+        }
+    }
+}
+
+fn render_remove(message_id_to_remove: Option<u64>, cx: &mut ViewContext<ChatPanel>) -> AnyElement {
+    if let Some(message_id) = message_id_to_remove {
+        IconButton::new(("remove", message_id), Icon::XCircle)
+            .on_click(cx.listener(move |this, _, cx| {
+                this.remove_message(message_id, cx);
+            }))
+            .into_any_element()
+    } else {
+        div().into_any_element()
+    }
+}
+
+impl EventEmitter<Event> for ChatPanel {}
+
+impl Render for ChatPanel {
+    type Element = Div;
+
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+        div()
+            .full()
+            .child(if self.client.user_id().is_some() {
+                self.render_channel(cx)
+            } else {
+                self.render_sign_in_prompt(cx)
+            })
+            .min_w(px(150.))
+    }
+}
+
+impl FocusableView for ChatPanel {
+    fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle {
+        self.input_editor.read(cx).focus_handle(cx)
+    }
+}
+
+impl Panel for ChatPanel {
+    fn position(&self, cx: &gpui::WindowContext) -> DockPosition {
+        ChatPanelSettings::get_global(cx).dock
+    }
+
+    fn position_is_valid(&self, position: DockPosition) -> bool {
+        matches!(position, DockPosition::Left | DockPosition::Right)
+    }
+
+    fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>) {
+        settings::update_settings_file::<ChatPanelSettings>(self.fs.clone(), cx, move |settings| {
+            settings.dock = Some(position)
+        });
+    }
+
+    fn size(&self, cx: &gpui::WindowContext) -> f32 {
+        self.width
+            .unwrap_or_else(|| ChatPanelSettings::get_global(cx).default_width)
+    }
+
+    fn set_size(&mut self, size: Option<f32>, cx: &mut ViewContext<Self>) {
+        self.width = size;
+        self.serialize(cx);
+        cx.notify();
+    }
+
+    fn set_active(&mut self, active: bool, cx: &mut ViewContext<Self>) {
+        self.active = active;
+        if active {
+            self.acknowledge_last_message(cx);
+            if !is_channels_feature_enabled(cx) {
+                cx.emit(Event::Dismissed);
+            }
+        }
+    }
+
+    fn persistent_name() -> &'static str {
+        "ChatPanel"
+    }
+
+    fn icon(&self, _cx: &WindowContext) -> Option<ui::Icon> {
+        Some(ui::Icon::MessageBubbles)
+    }
+
+    fn toggle_action(&self) -> Box<dyn gpui::Action> {
+        Box::new(ToggleFocus)
+    }
+}
+
+impl EventEmitter<PanelEvent> for ChatPanel {}
+
+fn format_timestamp(
+    mut timestamp: OffsetDateTime,
+    mut now: OffsetDateTime,
+    local_timezone: UtcOffset,
+) -> String {
+    timestamp = timestamp.to_offset(local_timezone);
+    now = now.to_offset(local_timezone);
+
+    let today = now.date();
+    let date = timestamp.date();
+    let mut hour = timestamp.hour();
+    let mut part = "am";
+    if hour > 12 {
+        hour -= 12;
+        part = "pm";
+    }
+    if date == today {
+        format!("{:02}:{:02}{}", hour, timestamp.minute(), part)
+    } else if date.next_day() == Some(today) {
+        format!("yesterday at {:02}:{:02}{}", hour, timestamp.minute(), part)
+    } else {
+        format!("{:02}/{}/{}", date.month() as u32, date.day(), date.year())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use gpui::HighlightStyle;
+    use pretty_assertions::assert_eq;
+    use rich_text::Highlight;
+    use util::test::marked_text_ranges;
+
+    #[gpui::test]
+    fn test_render_markdown_with_mentions() {
+        let language_registry = Arc::new(LanguageRegistry::test());
+        let (body, ranges) = marked_text_ranges("*hi*, «@abc», let's **call** «@fgh»", false);
+        let message = channel::ChannelMessage {
+            id: ChannelMessageId::Saved(0),
+            body,
+            timestamp: OffsetDateTime::now_utc(),
+            sender: Arc::new(client::User {
+                github_login: "fgh".into(),
+                avatar: None,
+                id: 103,
+            }),
+            nonce: 5,
+            mentions: vec![(ranges[0].clone(), 101), (ranges[1].clone(), 102)],
+        };
+
+        let message = ChatPanel::render_markdown_with_mentions(&language_registry, 102, &message);
+
+        // Note that the "'" was replaced with ’ due to smart punctuation.
+        let (body, ranges) = marked_text_ranges("«hi», «@abc», let’s «call» «@fgh»", false);
+        assert_eq!(message.text, body);
+        assert_eq!(
+            message.highlights,
+            vec![
+                (
+                    ranges[0].clone(),
+                    HighlightStyle {
+                        font_style: Some(gpui::FontStyle::Italic),
+                        ..Default::default()
+                    }
+                    .into()
+                ),
+                (ranges[1].clone(), Highlight::Mention),
+                (
+                    ranges[2].clone(),
+                    HighlightStyle {
+                        font_weight: Some(gpui::FontWeight::BOLD),
+                        ..Default::default()
+                    }
+                    .into()
+                ),
+                (ranges[3].clone(), Highlight::SelfMention)
+            ]
+        );
+    }
+}

crates/collab_ui2/src/chat_panel/message_editor.rs 🔗

@@ -3,13 +3,14 @@ use client::UserId;
 use collections::HashMap;
 use editor::{AnchorRangeExt, Editor};
 use gpui::{
-    elements::ChildView, AnyElement, AsyncAppContext, Element, Entity, ModelHandle, Task, View,
-    ViewContext, ViewHandle, WeakViewHandle,
+    AnyView, AsyncWindowContext, FocusableView, Model, Render, SharedString, Task, View,
+    ViewContext, WeakView,
 };
 use language::{language_settings::SoftWrap, Buffer, BufferSnapshot, LanguageRegistry};
 use lazy_static::lazy_static;
 use project::search::SearchQuery;
 use std::{sync::Arc, time::Duration};
+use workspace::item::ItemHandle;
 
 const MENTIONS_DEBOUNCE_INTERVAL: Duration = Duration::from_millis(50);
 
@@ -19,8 +20,8 @@ lazy_static! {
 }
 
 pub struct MessageEditor {
-    pub editor: ViewHandle<Editor>,
-    channel_store: ModelHandle<ChannelStore>,
+    pub editor: View<Editor>,
+    channel_store: Model<ChannelStore>,
     users: HashMap<String, UserId>,
     mentions: Vec<UserId>,
     mentions_task: Option<Task<()>>,
@@ -30,8 +31,8 @@ pub struct MessageEditor {
 impl MessageEditor {
     pub fn new(
         language_registry: Arc<LanguageRegistry>,
-        channel_store: ModelHandle<ChannelStore>,
-        editor: ViewHandle<Editor>,
+        channel_store: Model<ChannelStore>,
+        editor: View<Editor>,
         cx: &mut ViewContext<Self>,
     ) -> Self {
         editor.update(cx, |editor, cx| {
@@ -48,15 +49,13 @@ impl MessageEditor {
         cx.subscribe(&buffer, Self::on_buffer_event).detach();
 
         let markdown = language_registry.language_for_name("Markdown");
-        cx.app_context()
-            .spawn(|mut cx| async move {
-                let markdown = markdown.await?;
-                buffer.update(&mut cx, |buffer, cx| {
-                    buffer.set_language(Some(markdown), cx)
-                });
-                anyhow::Ok(())
+        cx.spawn(|_, mut cx| async move {
+            let markdown = markdown.await?;
+            buffer.update(&mut cx, |buffer, cx| {
+                buffer.set_language(Some(markdown), cx)
             })
-            .detach_and_log_err(cx);
+        })
+        .detach_and_log_err(cx);
 
         Self {
             editor,
@@ -71,7 +70,7 @@ impl MessageEditor {
     pub fn set_channel(
         &mut self,
         channel_id: u64,
-        channel_name: Option<String>,
+        channel_name: Option<SharedString>,
         cx: &mut ViewContext<Self>,
     ) {
         self.editor.update(cx, |editor, cx| {
@@ -132,26 +131,28 @@ impl MessageEditor {
 
     fn on_buffer_event(
         &mut self,
-        buffer: ModelHandle<Buffer>,
+        buffer: Model<Buffer>,
         event: &language::Event,
         cx: &mut ViewContext<Self>,
     ) {
         if let language::Event::Reparsed | language::Event::Edited = event {
             let buffer = buffer.read(cx).snapshot();
             self.mentions_task = Some(cx.spawn(|this, cx| async move {
-                cx.background().timer(MENTIONS_DEBOUNCE_INTERVAL).await;
+                cx.background_executor()
+                    .timer(MENTIONS_DEBOUNCE_INTERVAL)
+                    .await;
                 Self::find_mentions(this, buffer, cx).await;
             }));
         }
     }
 
     async fn find_mentions(
-        this: WeakViewHandle<MessageEditor>,
+        this: WeakView<MessageEditor>,
         buffer: BufferSnapshot,
-        mut cx: AsyncAppContext,
+        mut cx: AsyncWindowContext,
     ) {
         let (buffer, ranges) = cx
-            .background()
+            .background_executor()
             .spawn(async move {
                 let ranges = MENTIONS_SEARCH.search(&buffer, None).await;
                 (buffer, ranges)
@@ -180,11 +181,7 @@ impl MessageEditor {
                 }
 
                 editor.clear_highlights::<Self>(cx);
-                editor.highlight_text::<Self>(
-                    anchor_ranges,
-                    theme::current(cx).chat_panel.rich_text.mention_highlight,
-                    cx,
-                )
+                editor.highlight_text::<Self>(anchor_ranges, gpui::red().into(), cx)
             });
 
             this.mentions = mentioned_user_ids;
@@ -192,21 +189,17 @@ impl MessageEditor {
         })
         .ok();
     }
-}
 
-impl Entity for MessageEditor {
-    type Event = ();
+    pub(crate) fn focus_handle(&self, cx: &gpui::AppContext) -> gpui::FocusHandle {
+        self.editor.read(cx).focus_handle(cx)
+    }
 }
 
-impl View for MessageEditor {
-    fn render(&mut self, cx: &mut ViewContext<'_, '_, Self>) -> AnyElement<Self> {
-        ChildView::new(&self.editor, cx).into_any()
-    }
+impl Render for MessageEditor {
+    type Element = AnyView;
 
-    fn focus_in(&mut self, _: gpui::AnyViewHandle, cx: &mut ViewContext<Self>) {
-        if cx.is_self_focused() {
-            cx.focus(&self.editor);
-        }
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
+        self.editor.to_any()
     }
 }
 
@@ -214,7 +207,7 @@ impl View for MessageEditor {
 mod tests {
     use super::*;
     use client::{Client, User, UserStore};
-    use gpui::{TestAppContext, WindowHandle};
+    use gpui::{Context as _, TestAppContext, VisualContext as _};
     use language::{Language, LanguageConfig};
     use rpc::proto;
     use settings::SettingsStore;
@@ -222,8 +215,17 @@ mod tests {
 
     #[gpui::test]
     async fn test_message_editor(cx: &mut TestAppContext) {
-        let editor = init_test(cx);
-        let editor = editor.root(cx);
+        let language_registry = init_test(cx);
+
+        let (editor, cx) = cx.add_window_view(|cx| {
+            MessageEditor::new(
+                language_registry,
+                ChannelStore::global(cx),
+                cx.build_view(|cx| Editor::auto_height(4, cx)),
+                cx,
+            )
+        });
+        cx.executor().run_until_parked();
 
         editor.update(cx, |editor, cx| {
             editor.set_members(
@@ -255,7 +257,7 @@ mod tests {
             });
         });
 
-        cx.foreground().advance_clock(MENTIONS_DEBOUNCE_INTERVAL);
+        cx.executor().advance_clock(MENTIONS_DEBOUNCE_INTERVAL);
 
         editor.update(cx, |editor, cx| {
             let (text, ranges) = marked_text_ranges("Hello, «@a-b»! Have you met «@C_D»?", false);
@@ -269,15 +271,14 @@ mod tests {
         });
     }
 
-    fn init_test(cx: &mut TestAppContext) -> WindowHandle<MessageEditor> {
-        cx.foreground().forbid_parking();
-
+    fn init_test(cx: &mut TestAppContext) -> Arc<LanguageRegistry> {
         cx.update(|cx| {
             let http = FakeHttpClient::with_404_response();
             let client = Client::new(http.clone(), cx);
-            let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http, cx));
-            cx.set_global(SettingsStore::test(cx));
-            theme::init((), cx);
+            let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http, cx));
+            let settings = SettingsStore::test(cx);
+            cx.set_global(settings);
+            theme::init(theme::LoadThemes::JustBase, cx);
             language::init(cx);
             editor::init(cx);
             client::init(&client, cx);
@@ -292,16 +293,6 @@ mod tests {
             },
             Some(tree_sitter_markdown::language()),
         )));
-
-        let editor = cx.add_window(|cx| {
-            MessageEditor::new(
-                language_registry,
-                ChannelStore::global(cx),
-                cx.add_view(|cx| Editor::auto_height(4, None, cx)),
-                cx,
-            )
-        });
-        cx.foreground().run_until_parked();
-        editor
+        language_registry
     }
 }

crates/collab_ui2/src/collab_panel.rs 🔗

@@ -92,7 +92,7 @@ use theme::{ActiveTheme, ThemeSettings};
 //     channel_id: ChannelId,
 // }
 
-#[derive(Action, PartialEq, Debug, Clone, Serialize, Deserialize)]
+#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
 pub struct OpenChannelNotes {
     pub channel_id: ChannelId,
 }
@@ -122,15 +122,20 @@ pub struct OpenChannelNotes {
 //     to: ChannelId,
 // }
 
+impl_actions!(collab_panel, [OpenChannelNotes]);
+
 actions!(
-    ToggleFocus,
-    Remove,
-    Secondary,
-    CollapseSelectedChannel,
-    ExpandSelectedChannel,
-    StartMoveChannel,
-    MoveSelected,
-    InsertSpace,
+    collab_panel,
+    [
+        ToggleFocus,
+        Remove,
+        Secondary,
+        CollapseSelectedChannel,
+        ExpandSelectedChannel,
+        StartMoveChannel,
+        MoveSelected,
+        InsertSpace,
+    ]
 );
 
 // impl_actions!(
@@ -169,12 +174,12 @@ use editor::Editor;
 use feature_flags::{ChannelsAlpha, FeatureFlagAppExt, FeatureFlagViewExt};
 use fuzzy::{match_strings, StringMatchCandidate};
 use gpui::{
-    actions, canvas, div, img, overlay, point, prelude::*, px, rems, serde_json, size, Action,
-    AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div, EventEmitter,
-    FocusHandle, Focusable, FocusableView, Hsla, InteractiveElement, IntoElement, Length, Model,
-    MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Quad, Render, RenderOnce,
-    ScrollHandle, SharedString, Size, Stateful, Styled, Subscription, Task, View, ViewContext,
-    VisualContext, WeakView,
+    actions, canvas, div, img, impl_actions, overlay, point, prelude::*, px, rems, serde_json,
+    size, Action, AppContext, AsyncWindowContext, Bounds, ClipboardItem, DismissEvent, Div,
+    EventEmitter, FocusHandle, Focusable, FocusableView, Hsla, InteractiveElement, IntoElement,
+    Length, Model, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Quad, Render,
+    RenderOnce, ScrollHandle, SharedString, Size, Stateful, Styled, Subscription, Task, View,
+    ViewContext, VisualContext, WeakView,
 };
 use project::{Fs, Project};
 use serde_derive::{Deserialize, Serialize};
@@ -192,6 +197,7 @@ use workspace::{
 };
 
 use crate::channel_view::ChannelView;
+use crate::chat_panel::ChatPanel;
 use crate::{face_pile::FacePile, CollaborationPanelSettings};
 
 use self::channel_modal::ChannelModal;
@@ -852,7 +858,7 @@ impl CollabPanel {
                     .extend(channel_store.ordered_channels().enumerate().map(
                         |(ix, (_, channel))| StringMatchCandidate {
                             id: ix,
-                            string: channel.name.clone(),
+                            string: channel.name.clone().into(),
                             char_bag: channel.name.chars().collect(),
                         },
                     ));
@@ -2102,14 +2108,13 @@ impl CollabPanel {
         };
         cx.window_context().defer(move |cx| {
             workspace.update(cx, |workspace, cx| {
-                todo!();
-                // if let Some(panel) = workspace.focus_panel::<ChatPanel>(cx) {
-                //     panel.update(cx, |panel, cx| {
-                //         panel
-                //             .select_channel(channel_id, None, cx)
-                //             .detach_and_log_err(cx);
-                //     });
-                // }
+                if let Some(panel) = workspace.focus_panel::<ChatPanel>(cx) {
+                    panel.update(cx, |panel, cx| {
+                        panel
+                            .select_channel(channel_id, None, cx)
+                            .detach_and_log_err(cx);
+                    });
+                }
             });
         });
     }
@@ -2262,7 +2267,7 @@ impl CollabPanel {
                         }
                     };
 
-                    Some(channel.name.as_str())
+                    Some(channel.name.as_ref())
                 });
 
                 if let Some(name) = channel_name {
@@ -2603,9 +2608,14 @@ impl CollabPanel {
                                                     Color::Default
                                                 } else {
                                                     Color::Muted
+                                                })
+                                                .on_click(cx.listener(move |this, _, cx| {
+                                                    this.join_channel_chat(channel_id, cx)
+                                                }))
+                                                .tooltip(|cx| {
+                                                    Tooltip::text("Open channel chat", cx)
                                                 }),
-                                            )
-                                            .tooltip(|cx| Tooltip::text("Open channel chat", cx)),
+                                            ),
                                     )
                                     .child(
                                         div()

crates/collab_ui2/src/collab_panel/channel_modal.rs 🔗

@@ -13,12 +13,16 @@ use picker::{Picker, PickerDelegate};
 use std::sync::Arc;
 use ui::prelude::*;
 use util::TryFutureExt;
+use workspace::ModalView;
 
 actions!(
-    SelectNextControl,
-    ToggleMode,
-    ToggleMemberAdmin,
-    RemoveMember
+    channel_modal,
+    [
+        SelectNextControl,
+        ToggleMode,
+        ToggleMemberAdmin,
+        RemoveMember
+    ]
 );
 
 // pub fn init(cx: &mut AppContext) {
@@ -140,6 +144,7 @@ impl ChannelModal {
 }
 
 impl EventEmitter<DismissEvent> for ChannelModal {}
+impl ModalView for ChannelModal {}
 
 impl FocusableView for ChannelModal {
     fn focus_handle(&self, cx: &AppContext) -> gpui::FocusHandle {

crates/collab_ui2/src/collab_panel/contact_finder.rs 🔗

@@ -9,6 +9,7 @@ use std::sync::Arc;
 use theme::ActiveTheme as _;
 use ui::prelude::*;
 use util::{ResultExt as _, TryFutureExt};
+use workspace::ModalView;
 
 pub fn init(cx: &mut AppContext) {
     //Picker::<ContactFinderDelegate>::init(cx);
@@ -95,6 +96,7 @@ pub struct ContactFinderDelegate {
 }
 
 impl EventEmitter<DismissEvent> for ContactFinder {}
+impl ModalView for ContactFinder {}
 
 impl FocusableView for ContactFinder {
     fn focus_handle(&self, cx: &AppContext) -> FocusHandle {

crates/collab_ui2/src/collab_titlebar_item.rs 🔗

@@ -1,42 +1,14 @@
-// use crate::{
-//     face_pile::FacePile, toggle_deafen, toggle_mute, toggle_screen_sharing, LeaveCall,
-//     ToggleDeafen, ToggleMute, ToggleScreenSharing,
-// };
-// use auto_update::AutoUpdateStatus;
-// use call::{ActiveCall, ParticipantLocation, Room};
-// use client::{proto::PeerId, Client, SignIn, SignOut, User, UserStore};
-// use clock::ReplicaId;
-// use context_menu::{ContextMenu, ContextMenuItem};
-// use gpui::{
-//     actions,
-//     color::Color,
-//     elements::*,
-//     geometry::{rect::RectF, vector::vec2f, PathBuilder},
-//     json::{self, ToJson},
-//     platform::{CursorStyle, MouseButton},
-//     AppContext, Entity, ImageData, ModelHandle, Subscription, View, ViewContext, ViewHandle,
-//     WeakViewHandle,
-// };
-// use picker::PickerEvent;
-// use project::{Project, RepositoryEntry};
-// use recent_projects::{build_recent_projects, RecentProjects};
-// use std::{ops::Range, sync::Arc};
-// use theme::{AvatarStyle, Theme};
-// use util::ResultExt;
-// use vcs_menu::{build_branch_list, BranchList, OpenRecent as ToggleVcsMenu};
-// use workspace::{FollowNextCollaborator, Workspace, WORKSPACE_DB};
-
-use std::sync::Arc;
-
-use call::ActiveCall;
-use client::{Client, UserStore};
+use crate::face_pile::FacePile;
+use call::{ActiveCall, ParticipantLocation, Room};
+use client::{proto::PeerId, Client, ParticipantIndex, User, UserStore};
 use gpui::{
-    actions, div, px, rems, AppContext, Div, Element, InteractiveElement, IntoElement, Model,
-    MouseButton, ParentElement, Render, RenderOnce, Stateful, StatefulInteractiveElement, Styled,
+    actions, canvas, div, point, px, rems, AppContext, Div, Element, Hsla, InteractiveElement,
+    IntoElement, Model, ParentElement, Path, Render, Stateful, StatefulInteractiveElement, Styled,
     Subscription, ViewContext, VisualContext, WeakView, WindowBounds,
 };
 use project::{Project, RepositoryEntry};
-use theme::ActiveTheme;
+use std::sync::Arc;
+use theme::{ActiveTheme, PlayerColors};
 use ui::{
     h_stack, popover_menu, prelude::*, Avatar, Button, ButtonLike, ButtonStyle, ContextMenu, Icon,
     IconButton, IconElement, KeyBinding, Tooltip,
@@ -44,30 +16,20 @@ use ui::{
 use util::ResultExt;
 use workspace::{notifications::NotifyResultExt, Workspace};
 
-use crate::face_pile::FacePile;
-
 const MAX_PROJECT_NAME_LENGTH: usize = 40;
 const MAX_BRANCH_NAME_LENGTH: usize = 40;
 
 actions!(
-    ShareProject,
-    UnshareProject,
-    ToggleUserMenu,
-    ToggleProjectMenu,
-    SwitchBranch
+    collab,
+    [
+        ShareProject,
+        UnshareProject,
+        ToggleUserMenu,
+        ToggleProjectMenu,
+        SwitchBranch
+    ]
 );
 
-// actions!(
-//     collab,
-//     [
-//         ToggleUserMenu,
-//         ToggleProjectMenu,
-//         SwitchBranch,
-//         ShareProject,
-//         UnshareProject,
-//     ]
-// );
-
 pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(|workspace: &mut Workspace, cx| {
         let titlebar_item = cx.build_view(|cx| CollabTitlebarItem::new(workspace, cx));
@@ -83,11 +45,8 @@ pub fn init(cx: &mut AppContext) {
 
 pub struct CollabTitlebarItem {
     project: Model<Project>,
-    #[allow(unused)] // todo!()
     user_store: Model<UserStore>,
-    #[allow(unused)] // todo!()
     client: Arc<Client>,
-    #[allow(unused)] // todo!()
     workspace: WeakView<Workspace>,
     //branch_popover: Option<ViewHandle<BranchList>>,
     //project_popover: Option<ViewHandle<recent_projects::RecentProjects>>,
@@ -99,28 +58,11 @@ impl Render for CollabTitlebarItem {
     type Element = Stateful<Div>;
 
     fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
-        let room = ActiveCall::global(cx).read(cx).room();
-        let is_in_room = room.is_some();
-        let is_shared = is_in_room && self.project.read(cx).is_shared();
+        let room = ActiveCall::global(cx).read(cx).room().cloned();
         let current_user = self.user_store.read(cx).current_user();
         let client = self.client.clone();
-        let remote_participants = room.map(|room| {
-            room.read(cx)
-                .remote_participants()
-                .values()
-                .map(|participant| (participant.user.clone(), participant.peer_id))
-                .collect::<Vec<_>>()
-        });
-        let is_muted = room.map_or(false, |room| room.read(cx).is_muted(cx));
-        let is_deafened = room
-            .and_then(|room| room.read(cx).is_deafened())
-            .unwrap_or(false);
-        let speakers_icon = if is_deafened {
-            ui::Icon::AudioOff
-        } else {
-            ui::Icon::AudioOn
-        };
-        let workspace = self.workspace.clone();
+        let project_id = self.project.read(cx).remote_id();
+
         h_stack()
             .id("titlebar")
             .justify_between()
@@ -141,262 +83,223 @@ impl Render for CollabTitlebarItem {
                     cx.zoom_window();
                 }
             })
+            // left side
             .child(
                 h_stack()
                     .gap_1()
-                    .when(is_in_room, |this| {
-                        this.children(self.render_project_owner(cx))
-                    })
+                    .children(self.render_project_host(cx))
                     .child(self.render_project_name(cx))
-                    .children(self.render_project_branch(cx)),
-            )
-            .when_some(
-                remote_participants.zip(current_user.clone()),
-                |this, (remote_participants, current_user)| {
-                    let mut pile = FacePile::default();
-                    pile.extend(
-                        current_user
-                            .avatar
-                            .clone()
-                            .map(|avatar| {
-                                div().child(Avatar::data(avatar.clone())).into_any_element()
-                            })
-                            .into_iter()
-                            .chain(remote_participants.into_iter().filter_map(
-                                |(user, peer_id)| {
-                                    let avatar = user.avatar.as_ref()?;
+                    .children(self.render_project_branch(cx))
+                    .when_some(
+                        current_user.clone().zip(client.peer_id()).zip(room.clone()),
+                        |this, ((current_user, peer_id), room)| {
+                            let player_colors = cx.theme().players();
+                            let room = room.read(cx);
+                            let mut remote_participants =
+                                room.remote_participants().values().collect::<Vec<_>>();
+                            remote_participants.sort_by_key(|p| p.participant_index.0);
+
+                            this.children(self.render_collaborator(
+                                &current_user,
+                                peer_id,
+                                true,
+                                room.is_speaking(),
+                                room.is_muted(cx),
+                                &room,
+                                project_id,
+                                &current_user,
+                            ))
+                            .children(
+                                remote_participants.iter().filter_map(|collaborator| {
+                                    let is_present = project_id.map_or(false, |project_id| {
+                                        collaborator.location
+                                            == ParticipantLocation::SharedProject { project_id }
+                                    });
+
+                                    let face_pile = self.render_collaborator(
+                                        &collaborator.user,
+                                        collaborator.peer_id,
+                                        is_present,
+                                        collaborator.speaking,
+                                        collaborator.muted,
+                                        &room,
+                                        project_id,
+                                        &current_user,
+                                    )?;
+
                                     Some(
-                                        div()
-                                            .child(
-                                                Avatar::data(avatar.clone())
-                                                    .into_element()
-                                                    .into_any(),
-                                            )
-                                            .on_mouse_down(MouseButton::Left, {
-                                                let workspace = workspace.clone();
-                                                move |_, cx| {
-                                                    workspace
-                                                        .update(cx, |this, cx| {
-                                                            this.open_shared_screen(peer_id, cx);
+                                        v_stack()
+                                            .id(("collaborator", collaborator.user.id))
+                                            .child(face_pile)
+                                            .child(render_color_ribbon(
+                                                collaborator.participant_index,
+                                                player_colors,
+                                            ))
+                                            .cursor_pointer()
+                                            .on_click({
+                                                let peer_id = collaborator.peer_id;
+                                                cx.listener(move |this, _, cx| {
+                                                    this.workspace
+                                                        .update(cx, |workspace, cx| {
+                                                            workspace.follow(peer_id, cx);
                                                         })
-                                                        .log_err();
-                                                }
+                                                        .ok();
+                                                })
                                             })
-                                            .into_any_element(),
+                                            .tooltip({
+                                                let login = collaborator.user.github_login.clone();
+                                                move |cx| {
+                                                    Tooltip::text(format!("Follow {login}"), cx)
+                                                }
+                                            }),
                                     )
+                                }),
+                            )
+                        },
+                    ),
+            )
+            // right side
+            .child(
+                h_stack()
+                    .gap_1()
+                    .when_some(room, |this, room| {
+                        let room = room.read(cx);
+                        let is_shared = self.project.read(cx).is_shared();
+                        let is_muted = room.is_muted(cx);
+                        let is_deafened = room.is_deafened().unwrap_or(false);
+
+                        this.child(
+                            Button::new(
+                                "toggle_sharing",
+                                if is_shared { "Unshare" } else { "Share" },
+                            )
+                            .style(ButtonStyle::Subtle)
+                            .on_click(cx.listener(
+                                move |this, _, cx| {
+                                    if is_shared {
+                                        this.unshare_project(&Default::default(), cx);
+                                    } else {
+                                        this.share_project(&Default::default(), cx);
+                                    }
                                 },
                             )),
-                    );
-                    this.child(pile.render(cx))
-                },
-            )
-            .child(div().flex_1())
-            .when(is_in_room, |this| {
-                this.child(
-                    h_stack()
-                        .gap_1()
+                        )
                         .child(
-                            h_stack()
-                                .gap_1()
-                                .child(
-                                    Button::new(
-                                        "toggle_sharing",
-                                        if is_shared { "Unshare" } else { "Share" },
-                                    )
-                                    .style(ButtonStyle::Subtle)
-                                    .on_click(cx.listener(
-                                        move |this, _, cx| {
-                                            if is_shared {
-                                                this.unshare_project(&Default::default(), cx);
-                                            } else {
-                                                this.share_project(&Default::default(), cx);
-                                            }
-                                        },
-                                    )),
-                                )
-                                .child(
-                                    IconButton::new("leave-call", ui::Icon::Exit)
-                                        .style(ButtonStyle::Subtle)
-                                        .on_click(move |_, cx| {
-                                            ActiveCall::global(cx)
-                                                .update(cx, |call, cx| call.hang_up(cx))
-                                                .detach_and_log_err(cx);
-                                        }),
-                                ),
+                            IconButton::new("leave-call", ui::Icon::Exit)
+                                .style(ButtonStyle::Subtle)
+                                .on_click(move |_, cx| {
+                                    ActiveCall::global(cx)
+                                        .update(cx, |call, cx| call.hang_up(cx))
+                                        .detach_and_log_err(cx);
+                                }),
                         )
                         .child(
-                            h_stack()
-                                .gap_1()
-                                .child(
-                                    IconButton::new(
-                                        "mute-microphone",
-                                        if is_muted {
-                                            ui::Icon::MicMute
-                                        } else {
-                                            ui::Icon::Mic
-                                        },
-                                    )
-                                    .style(ButtonStyle::Subtle)
-                                    .selected(is_muted)
-                                    .on_click(move |_, cx| {
-                                        crate::toggle_mute(&Default::default(), cx)
-                                    }),
-                                )
-                                .child(
-                                    IconButton::new("mute-sound", speakers_icon)
-                                        .style(ButtonStyle::Subtle)
-                                        .selected(is_deafened.clone())
-                                        .tooltip(move |cx| {
-                                            Tooltip::with_meta(
-                                                "Deafen Audio",
-                                                None,
-                                                "Mic will be muted",
-                                                cx,
-                                            )
+                            IconButton::new(
+                                "mute-microphone",
+                                if is_muted {
+                                    ui::Icon::MicMute
+                                } else {
+                                    ui::Icon::Mic
+                                },
+                            )
+                            .style(ButtonStyle::Subtle)
+                            .selected(is_muted)
+                            .on_click(move |_, cx| crate::toggle_mute(&Default::default(), cx)),
+                        )
+                        .child(
+                            IconButton::new(
+                                "mute-sound",
+                                if is_deafened {
+                                    ui::Icon::AudioOff
+                                } else {
+                                    ui::Icon::AudioOn
+                                },
+                            )
+                            .style(ButtonStyle::Subtle)
+                            .selected(is_deafened.clone())
+                            .tooltip(move |cx| {
+                                Tooltip::with_meta("Deafen Audio", None, "Mic will be muted", cx)
+                            })
+                            .on_click(move |_, cx| crate::toggle_mute(&Default::default(), cx)),
+                        )
+                        .child(
+                            IconButton::new("screen-share", ui::Icon::Screen)
+                                .style(ButtonStyle::Subtle)
+                                .on_click(move |_, cx| {
+                                    crate::toggle_screen_sharing(&Default::default(), cx)
+                                }),
+                        )
+                    })
+                    .child(h_stack().px_1p5().map(|this| {
+                        if let Some(user) = current_user {
+                            this.when_some(user.avatar.clone(), |this, avatar| {
+                                // TODO: Finish implementing user menu popover
+                                //
+                                this.child(
+                                    popover_menu("user-menu")
+                                        .menu(|cx| {
+                                            ContextMenu::build(cx, |menu, _| menu.header("ADADA"))
                                         })
-                                        .on_click(move |_, cx| {
-                                            crate::toggle_mute(&Default::default(), cx)
-                                        }),
-                                )
-                                .child(
-                                    IconButton::new("screen-share", ui::Icon::Screen)
-                                        .style(ButtonStyle::Subtle)
-                                        .on_click(move |_, cx| {
-                                            crate::toggle_screen_sharing(&Default::default(), cx)
-                                        }),
-                                )
-                                .pl_2(),
-                        ),
-                )
-            })
-            .child(h_stack().px_1p5().map(|this| {
-                if let Some(user) = current_user {
-                    this.when_some(user.avatar.clone(), |this, avatar| {
-                        // TODO: Finish implementing user menu popover
-                        //
-                        this.child(
-                            popover_menu("user-menu")
-                                .menu(|cx| ContextMenu::build(cx, |menu, _| menu.header("ADADA")))
-                                .trigger(
-                                    ButtonLike::new("user-menu")
-                                        .child(
-                                            h_stack().gap_0p5().child(Avatar::data(avatar)).child(
-                                                IconElement::new(Icon::ChevronDown)
-                                                    .color(Color::Muted),
-                                            ),
+                                        .trigger(
+                                            ButtonLike::new("user-menu")
+                                                .child(
+                                                    h_stack()
+                                                        .gap_0p5()
+                                                        .child(Avatar::data(avatar))
+                                                        .child(
+                                                            IconElement::new(Icon::ChevronDown)
+                                                                .color(Color::Muted),
+                                                        ),
+                                                )
+                                                .style(ButtonStyle::Subtle)
+                                                .tooltip(move |cx| {
+                                                    Tooltip::text("Toggle User Menu", cx)
+                                                }),
                                         )
-                                        .style(ButtonStyle::Subtle)
-                                        .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)),
+                                        .anchor(gpui::AnchorCorner::TopRight),
                                 )
-                                .anchor(gpui::AnchorCorner::TopRight),
-                        )
-                        // this.child(
-                        //     ButtonLike::new("user-menu")
-                        //         .child(
-                        //             h_stack().gap_0p5().child(Avatar::data(avatar)).child(
-                        //                 IconElement::new(Icon::ChevronDown).color(Color::Muted),
-                        //             ),
-                        //         )
-                        //         .style(ButtonStyle::Subtle)
-                        //         .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)),
-                        // )
-                    })
-                } else {
-                    this.child(Button::new("sign_in", "Sign in").on_click(move |_, cx| {
-                        let client = client.clone();
-                        cx.spawn(move |mut cx| async move {
-                            client
-                                .authenticate_and_connect(true, &cx)
-                                .await
-                                .notify_async_err(&mut cx);
-                        })
-                        .detach();
-                    }))
-                }
-            }))
+                                // this.child(
+                                //     ButtonLike::new("user-menu")
+                                //         .child(
+                                //             h_stack().gap_0p5().child(Avatar::data(avatar)).child(
+                                //                 IconElement::new(Icon::ChevronDown).color(Color::Muted),
+                                //             ),
+                                //         )
+                                //         .style(ButtonStyle::Subtle)
+                                //         .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)),
+                                // )
+                            })
+                        } else {
+                            this.child(Button::new("sign_in", "Sign in").on_click(move |_, cx| {
+                                let client = client.clone();
+                                cx.spawn(move |mut cx| async move {
+                                    client
+                                        .authenticate_and_connect(true, &cx)
+                                        .await
+                                        .notify_async_err(&mut cx);
+                                })
+                                .detach();
+                            }))
+                        }
+                    })),
+            )
     }
 }
 
-// impl Entity for CollabTitlebarItem {
-//     type Event = ();
-// }
-
-// impl View for CollabTitlebarItem {
-//     fn ui_name() -> &'static str {
-//         "CollabTitlebarItem"
-//     }
-
-//     fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
-//         let workspace = if let Some(workspace) = self.workspace.upgrade(cx) {
-//             workspace
-//         } else {
-//             return Empty::new().into_any();
-//         };
-
-//         let theme = theme::current(cx).clone();
-//         let mut left_container = Flex::row();
-//         let mut right_container = Flex::row().align_children_center();
-
-//         left_container.add_child(self.collect_title_root_names(theme.clone(), cx));
-
-//         let user = self.user_store.read(cx).current_user();
-//         let peer_id = self.client.peer_id();
-//         if let Some(((user, peer_id), room)) = user
-//             .as_ref()
-//             .zip(peer_id)
-//             .zip(ActiveCall::global(cx).read(cx).room().cloned())
-//         {
-//             if room.read(cx).can_publish() {
-//                 right_container
-//                     .add_children(self.render_in_call_share_unshare_button(&workspace, &theme, cx));
-//             }
-//             right_container.add_child(self.render_leave_call(&theme, cx));
-//             let muted = room.read(cx).is_muted(cx);
-//             let speaking = room.read(cx).is_speaking();
-//             left_container.add_child(
-//                 self.render_current_user(&workspace, &theme, &user, peer_id, muted, speaking, cx),
-//             );
-//             left_container.add_children(self.render_collaborators(&workspace, &theme, &room, cx));
-//             if room.read(cx).can_publish() {
-//                 right_container.add_child(self.render_toggle_mute(&theme, &room, cx));
-//             }
-//             right_container.add_child(self.render_toggle_deafen(&theme, &room, cx));
-//             if room.read(cx).can_publish() {
-//                 right_container
-//                     .add_child(self.render_toggle_screen_sharing_button(&theme, &room, cx));
-//             }
-//         }
-
-//         let status = workspace.read(cx).client().status();
-//         let status = &*status.borrow();
-//         if matches!(status, client::Status::Connected { .. }) {
-//             let avatar = user.as_ref().and_then(|user| user.avatar.clone());
-//             right_container.add_child(self.render_user_menu_button(&theme, avatar, cx));
-//         } else {
-//             right_container.add_children(self.render_connection_status(status, cx));
-//             right_container.add_child(self.render_sign_in_button(&theme, cx));
-//             right_container.add_child(self.render_user_menu_button(&theme, None, cx));
-//         }
-
-//         Stack::new()
-//             .with_child(left_container)
-//             .with_child(
-//                 Flex::row()
-//                     .with_child(
-//                         right_container.contained().with_background_color(
-//                             theme
-//                                 .titlebar
-//                                 .container
-//                                 .background_color
-//                                 .unwrap_or_else(|| Color::transparent_black()),
-//                         ),
-//                     )
-//                     .aligned()
-//                     .right(),
-//             )
-//             .into_any()
-//     }
-// }
+fn render_color_ribbon(participant_index: ParticipantIndex, colors: &PlayerColors) -> gpui::Canvas {
+    let color = colors.color_for_participant(participant_index.0).cursor;
+    canvas(move |bounds, cx| {
+        let mut path = Path::new(bounds.lower_left());
+        let height = bounds.size.height;
+        path.curve_to(bounds.origin + point(height, px(0.)), bounds.origin);
+        path.line_to(bounds.upper_right() - point(height, px(0.)));
+        path.curve_to(bounds.lower_right(), bounds.upper_right());
+        path.line_to(bounds.lower_left());
+        cx.paint_path(path, color);
+    })
+    .h_1()
+    .w_full()
+}
 
 impl CollabTitlebarItem {
     pub fn new(workspace: &Workspace, cx: &mut ViewContext<Self>) -> Self {
@@ -435,7 +338,7 @@ impl CollabTitlebarItem {
     // resolve if you are in a room -> render_project_owner
     // render_project_owner -> resolve if you are in a room -> Option<foo>
 
-    pub fn render_project_owner(&self, cx: &mut ViewContext<Self>) -> Option<impl Element> {
+    pub fn render_project_host(&self, cx: &mut ViewContext<Self>) -> Option<impl Element> {
         let host = self.project.read(cx).host()?;
         let host = self.user_store.read(cx).get_cached_user(host.user_id)?;
         let participant_index = self
@@ -509,169 +412,56 @@ impl CollabTitlebarItem {
         )
     }
 
-    // fn collect_title_root_names(
-    //     &self,
-    //     theme: Arc<Theme>,
-    //     cx: &mut ViewContext<Self>,
-    // ) -> AnyElement<Self> {
-    //     let project = self.project.read(cx);
-
-    //     let (name, entry) = {
-    //         let mut names_and_branches = project.visible_worktrees(cx).map(|worktree| {
-    //             let worktree = worktree.read(cx);
-    //             (worktree.root_name(), worktree.root_git_entry())
-    //         });
-
-    //         names_and_branches.next().unwrap_or(("", None))
-    //     };
-
-    //     let name = util::truncate_and_trailoff(name, MAX_PROJECT_NAME_LENGTH);
-    //     let branch_prepended = entry
-    //         .as_ref()
-    //         .and_then(RepositoryEntry::branch)
-    //         .map(|branch| util::truncate_and_trailoff(&branch, MAX_BRANCH_NAME_LENGTH));
-    //     let project_style = theme.titlebar.project_menu_button.clone();
-    //     let git_style = theme.titlebar.git_menu_button.clone();
-    //     let item_spacing = theme.titlebar.item_spacing;
-
-    //     let mut ret = Flex::row();
-
-    //     if let Some(project_host) = self.collect_project_host(theme.clone(), cx) {
-    //         ret = ret.with_child(project_host)
-    //     }
-
-    //     ret = ret.with_child(
-    //         Stack::new()
-    //             .with_child(
-    //                 MouseEventHandler::new::<ToggleProjectMenu, _>(0, cx, |mouse_state, cx| {
-    //                     let style = project_style
-    //                         .in_state(self.project_popover.is_some())
-    //                         .style_for(mouse_state);
-    //                     enum RecentProjectsTooltip {}
-    //                     Label::new(name, style.text.clone())
-    //                         .contained()
-    //                         .with_style(style.container)
-    //                         .aligned()
-    //                         .left()
-    //                         .with_tooltip::<RecentProjectsTooltip>(
-    //                             0,
-    //                             "Recent projects",
-    //                             Some(Box::new(recent_projects::OpenRecent)),
-    //                             theme.tooltip.clone(),
-    //                             cx,
-    //                         )
-    //                         .into_any_named("title-project-name")
-    //                 })
-    //                 .with_cursor_style(CursorStyle::PointingHand)
-    //                 .on_down(MouseButton::Left, move |_, this, cx| {
-    //                     this.toggle_project_menu(&Default::default(), cx)
-    //                 })
-    //                 .on_click(MouseButton::Left, move |_, _, _| {}),
-    //             )
-    //             .with_children(self.render_project_popover_host(&theme.titlebar, cx)),
-    //     );
-    //     if let Some(git_branch) = branch_prepended {
-    //         ret = ret.with_child(
-    //             Flex::row().with_child(
-    //                 Stack::new()
-    //                     .with_child(
-    //                         MouseEventHandler::new::<ToggleVcsMenu, _>(0, cx, |mouse_state, cx| {
-    //                             enum BranchPopoverTooltip {}
-    //                             let style = git_style
-    //                                 .in_state(self.branch_popover.is_some())
-    //                                 .style_for(mouse_state);
-    //                             Label::new(git_branch, style.text.clone())
-    //                                 .contained()
-    //                                 .with_style(style.container.clone())
-    //                                 .with_margin_right(item_spacing)
-    //                                 .aligned()
-    //                                 .left()
-    //                                 .with_tooltip::<BranchPopoverTooltip>(
-    //                                     0,
-    //                                     "Recent branches",
-    //                                     Some(Box::new(ToggleVcsMenu)),
-    //                                     theme.tooltip.clone(),
-    //                                     cx,
-    //                                 )
-    //                                 .into_any_named("title-project-branch")
-    //                         })
-    //                         .with_cursor_style(CursorStyle::PointingHand)
-    //                         .on_down(MouseButton::Left, move |_, this, cx| {
-    //                             this.toggle_vcs_menu(&Default::default(), cx)
-    //                         })
-    //                         .on_click(MouseButton::Left, move |_, _, _| {}),
-    //                     )
-    //                     .with_children(self.render_branches_popover_host(&theme.titlebar, cx)),
-    //             ),
-    //         )
-    //     }
-    //     ret.into_any()
-    // }
-
-    // fn collect_project_host(
-    //     &self,
-    //     theme: Arc<Theme>,
-    //     cx: &mut ViewContext<Self>,
-    // ) -> Option<AnyElement<Self>> {
-    //     if ActiveCall::global(cx).read(cx).room().is_none() {
-    //         return None;
-    //     }
-    //     let project = self.project.read(cx);
-    //     let user_store = self.user_store.read(cx);
-
-    //     if project.is_local() {
-    //         return None;
-    //     }
-
-    //     let Some(host) = project.host() else {
-    //         return None;
-    //     };
-    //     let (Some(host_user), Some(participant_index)) = (
-    //         user_store.get_cached_user(host.user_id),
-    //         user_store.participant_indices().get(&host.user_id),
-    //     ) else {
-    //         return None;
-    //     };
-
-    //     enum ProjectHost {}
-    //     enum ProjectHostTooltip {}
-
-    //     let host_style = theme.titlebar.project_host.clone();
-    //     let selection_style = theme
-    //         .editor
-    //         .selection_style_for_room_participant(participant_index.0);
-    //     let peer_id = host.peer_id.clone();
-
-    //     Some(
-    //         MouseEventHandler::new::<ProjectHost, _>(0, cx, |mouse_state, _| {
-    //             let mut host_style = host_style.style_for(mouse_state).clone();
-    //             host_style.text.color = selection_style.cursor;
-    //             Label::new(host_user.github_login.clone(), host_style.text)
-    //                 .contained()
-    //                 .with_style(host_style.container)
-    //                 .aligned()
-    //                 .left()
-    //         })
-    //         .with_cursor_style(CursorStyle::PointingHand)
-    //         .on_click(MouseButton::Left, move |_, this, cx| {
-    //             if let Some(workspace) = this.workspace.upgrade(cx) {
-    //                 if let Some(task) =
-    //                     workspace.update(cx, |workspace, cx| workspace.follow(peer_id, cx))
-    //                 {
-    //                     task.detach_and_log_err(cx);
-    //                 }
-    //             }
-    //         })
-    //         .with_tooltip::<ProjectHostTooltip>(
-    //             0,
-    //             host_user.github_login.clone() + " is sharing this project. Click to follow.",
-    //             None,
-    //             theme.tooltip.clone(),
-    //             cx,
-    //         )
-    //         .into_any_named("project-host"),
-    //     )
-    // }
+    fn render_collaborator(
+        &self,
+        user: &Arc<User>,
+        peer_id: PeerId,
+        is_present: bool,
+        is_speaking: bool,
+        is_muted: bool,
+        room: &Room,
+        project_id: Option<u64>,
+        current_user: &Arc<User>,
+    ) -> Option<FacePile> {
+        let followers = project_id.map_or(&[] as &[_], |id| room.followers_for(peer_id, id));
+        let mut pile = FacePile::default();
+        pile.extend(
+            user.avatar
+                .clone()
+                .map(|avatar| {
+                    div()
+                        .child(
+                            Avatar::data(avatar.clone())
+                                .grayscale(!is_present)
+                                .border_color(if is_speaking {
+                                    gpui::blue()
+                                } else if is_muted {
+                                    gpui::red()
+                                } else {
+                                    Hsla::default()
+                                }),
+                        )
+                        .into_any_element()
+                })
+                .into_iter()
+                .chain(followers.iter().filter_map(|follower_peer_id| {
+                    let follower = room
+                        .remote_participants()
+                        .values()
+                        .find_map(|p| (p.peer_id == *follower_peer_id).then_some(&p.user))
+                        .or_else(|| {
+                            (self.client.peer_id() == Some(*follower_peer_id))
+                                .then_some(current_user)
+                        })?
+                        .clone();
+                    follower
+                        .avatar
+                        .clone()
+                        .map(|avatar| div().child(Avatar::data(avatar.clone())).into_any_element())
+                })),
+        );
+        Some(pile)
+    }
 
     fn window_activation_changed(&mut self, cx: &mut ViewContext<Self>) {
         let project = if cx.is_window_active() {
@@ -868,245 +658,6 @@ impl CollabTitlebarItem {
     //     cx.notify();
     // }
 
-    // fn render_toggle_screen_sharing_button(
-    //     &self,
-    //     theme: &Theme,
-    //     room: &ModelHandle<Room>,
-    //     cx: &mut ViewContext<Self>,
-    // ) -> AnyElement<Self> {
-    //     let icon;
-    //     let tooltip;
-    //     if room.read(cx).is_screen_sharing() {
-    //         icon = "icons/desktop.svg";
-    //         tooltip = "Stop Sharing Screen"
-    //     } else {
-    //         icon = "icons/desktop.svg";
-    //         tooltip = "Share Screen";
-    //     }
-
-    //     let active = room.read(cx).is_screen_sharing();
-    //     let titlebar = &theme.titlebar;
-    //     MouseEventHandler::new::<ToggleScreenSharing, _>(0, cx, |state, _| {
-    //         let style = titlebar
-    //             .screen_share_button
-    //             .in_state(active)
-    //             .style_for(state);
-
-    //         Svg::new(icon)
-    //             .with_color(style.color)
-    //             .constrained()
-    //             .with_width(style.icon_width)
-    //             .aligned()
-    //             .constrained()
-    //             .with_width(style.button_width)
-    //             .with_height(style.button_width)
-    //             .contained()
-    //             .with_style(style.container)
-    //     })
-    //     .with_cursor_style(CursorStyle::PointingHand)
-    //     .on_click(MouseButton::Left, move |_, _, cx| {
-    //         toggle_screen_sharing(&Default::default(), cx)
-    //     })
-    //     .with_tooltip::<ToggleScreenSharing>(
-    //         0,
-    //         tooltip,
-    //         Some(Box::new(ToggleScreenSharing)),
-    //         theme.tooltip.clone(),
-    //         cx,
-    //     )
-    //     .aligned()
-    //     .into_any()
-    // }
-    // fn render_toggle_mute(
-    //     &self,
-    //     theme: &Theme,
-    //     room: &ModelHandle<Room>,
-    //     cx: &mut ViewContext<Self>,
-    // ) -> AnyElement<Self> {
-    //     let icon;
-    //     let tooltip;
-    //     let is_muted = room.read(cx).is_muted(cx);
-    //     if is_muted {
-    //         icon = "icons/mic-mute.svg";
-    //         tooltip = "Unmute microphone";
-    //     } else {
-    //         icon = "icons/mic.svg";
-    //         tooltip = "Mute microphone";
-    //     }
-
-    //     let titlebar = &theme.titlebar;
-    //     MouseEventHandler::new::<ToggleMute, _>(0, cx, |state, _| {
-    //         let style = titlebar
-    //             .toggle_microphone_button
-    //             .in_state(is_muted)
-    //             .style_for(state);
-    //         let image = Svg::new(icon)
-    //             .with_color(style.color)
-    //             .constrained()
-    //             .with_width(style.icon_width)
-    //             .aligned()
-    //             .constrained()
-    //             .with_width(style.button_width)
-    //             .with_height(style.button_width)
-    //             .contained()
-    //             .with_style(style.container);
-    //         if let Some(color) = style.container.background_color {
-    //             image.with_background_color(color)
-    //         } else {
-    //             image
-    //         }
-    //     })
-    //     .with_cursor_style(CursorStyle::PointingHand)
-    //     .on_click(MouseButton::Left, move |_, _, cx| {
-    //         toggle_mute(&Default::default(), cx)
-    //     })
-    //     .with_tooltip::<ToggleMute>(
-    //         0,
-    //         tooltip,
-    //         Some(Box::new(ToggleMute)),
-    //         theme.tooltip.clone(),
-    //         cx,
-    //     )
-    //     .aligned()
-    //     .into_any()
-    // }
-    // fn render_toggle_deafen(
-    //     &self,
-    //     theme: &Theme,
-    //     room: &ModelHandle<Room>,
-    //     cx: &mut ViewContext<Self>,
-    // ) -> AnyElement<Self> {
-    //     let icon;
-    //     let tooltip;
-    //     let is_deafened = room.read(cx).is_deafened().unwrap_or(false);
-    //     if is_deafened {
-    //         icon = "icons/speaker-off.svg";
-    //         tooltip = "Unmute speakers";
-    //     } else {
-    //         icon = "icons/speaker-loud.svg";
-    //         tooltip = "Mute speakers";
-    //     }
-
-    //     let titlebar = &theme.titlebar;
-    //     MouseEventHandler::new::<ToggleDeafen, _>(0, cx, |state, _| {
-    //         let style = titlebar
-    //             .toggle_speakers_button
-    //             .in_state(is_deafened)
-    //             .style_for(state);
-    //         Svg::new(icon)
-    //             .with_color(style.color)
-    //             .constrained()
-    //             .with_width(style.icon_width)
-    //             .aligned()
-    //             .constrained()
-    //             .with_width(style.button_width)
-    //             .with_height(style.button_width)
-    //             .contained()
-    //             .with_style(style.container)
-    //     })
-    //     .with_cursor_style(CursorStyle::PointingHand)
-    //     .on_click(MouseButton::Left, move |_, _, cx| {
-    //         toggle_deafen(&Default::default(), cx)
-    //     })
-    //     .with_tooltip::<ToggleDeafen>(
-    //         0,
-    //         tooltip,
-    //         Some(Box::new(ToggleDeafen)),
-    //         theme.tooltip.clone(),
-    //         cx,
-    //     )
-    //     .aligned()
-    //     .into_any()
-    // }
-    // fn render_leave_call(&self, theme: &Theme, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
-    //     let icon = "icons/exit.svg";
-    //     let tooltip = "Leave call";
-
-    //     let titlebar = &theme.titlebar;
-    //     MouseEventHandler::new::<LeaveCall, _>(0, cx, |state, _| {
-    //         let style = titlebar.leave_call_button.style_for(state);
-    //         Svg::new(icon)
-    //             .with_color(style.color)
-    //             .constrained()
-    //             .with_width(style.icon_width)
-    //             .aligned()
-    //             .constrained()
-    //             .with_width(style.button_width)
-    //             .with_height(style.button_width)
-    //             .contained()
-    //             .with_style(style.container)
-    //     })
-    //     .with_cursor_style(CursorStyle::PointingHand)
-    //     .on_click(MouseButton::Left, move |_, _, cx| {
-    //         ActiveCall::global(cx)
-    //             .update(cx, |call, cx| call.hang_up(cx))
-    //             .detach_and_log_err(cx);
-    //     })
-    //     .with_tooltip::<LeaveCall>(
-    //         0,
-    //         tooltip,
-    //         Some(Box::new(LeaveCall)),
-    //         theme.tooltip.clone(),
-    //         cx,
-    //     )
-    //     .aligned()
-    //     .into_any()
-    // }
-    // fn render_in_call_share_unshare_button(
-    //     &self,
-    //     workspace: &ViewHandle<Workspace>,
-    //     theme: &Theme,
-    //     cx: &mut ViewContext<Self>,
-    // ) -> Option<AnyElement<Self>> {
-    //     let project = workspace.read(cx).project();
-    //     if project.read(cx).is_remote() {
-    //         return None;
-    //     }
-
-    //     let is_shared = project.read(cx).is_shared();
-    //     let label = if is_shared { "Stop Sharing" } else { "Share" };
-    //     let tooltip = if is_shared {
-    //         "Stop sharing project with call participants"
-    //     } else {
-    //         "Share project with call participants"
-    //     };
-
-    //     let titlebar = &theme.titlebar;
-
-    //     enum ShareUnshare {}
-    //     Some(
-    //         Stack::new()
-    //             .with_child(
-    //                 MouseEventHandler::new::<ShareUnshare, _>(0, cx, |state, _| {
-    //                     //TODO: Ensure this button has consistent width for both text variations
-    //                     let style = titlebar.share_button.inactive_state().style_for(state);
-    //                     Label::new(label, style.text.clone())
-    //                         .contained()
-    //                         .with_style(style.container)
-    //                 })
-    //                 .with_cursor_style(CursorStyle::PointingHand)
-    //                 .on_click(MouseButton::Left, move |_, this, cx| {
-    //                     if is_shared {
-    //                         this.unshare_project(&Default::default(), cx);
-    //                     } else {
-    //                         this.share_project(&Default::default(), cx);
-    //                     }
-    //                 })
-    //                 .with_tooltip::<ShareUnshare>(
-    //                     0,
-    //                     tooltip.to_owned(),
-    //                     None,
-    //                     theme.tooltip.clone(),
-    //                     cx,
-    //                 ),
-    //             )
-    //             .aligned()
-    //             .contained()
-    //             .with_margin_left(theme.titlebar.item_spacing)
-    //             .into_any(),
-    //     )
-    // }
-
     // fn render_user_menu_button(
     //     &self,
     //     theme: &Theme,

crates/collab_ui2/src/collab_ui.rs 🔗

@@ -12,6 +12,7 @@ use std::{rc::Rc, sync::Arc};
 use call::{report_call_event_for_room, ActiveCall, Room};
 pub use collab_panel::CollabPanel;
 pub use collab_titlebar_item::CollabTitlebarItem;
+use feature_flags::{ChannelsAlpha, FeatureFlagAppExt};
 use gpui::{
     actions, point, AppContext, GlobalPixels, Pixels, PlatformDisplay, Size, Task, WindowBounds,
     WindowKind, WindowOptions,
@@ -23,7 +24,10 @@ use settings::Settings;
 use util::ResultExt;
 use workspace::AppState;
 
-actions!(ToggleScreenSharing, ToggleMute, ToggleDeafen, LeaveCall);
+actions!(
+    collab,
+    [ToggleScreenSharing, ToggleMute, ToggleDeafen, LeaveCall]
+);
 
 pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
     CollaborationPanelSettings::register(cx);
@@ -34,7 +38,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
     collab_titlebar_item::init(cx);
     collab_panel::init(cx);
     channel_view::init(cx);
-    // chat_panel::init(cx);
+    chat_panel::init(cx);
     notifications::init(&app_state, cx);
 
     // cx.add_global_action(toggle_screen_sharing);
@@ -157,6 +161,6 @@ fn notification_window_options(
 //         .into_any()
 // }
 
-// fn is_channels_feature_enabled(cx: &gpui::WindowContext<'_>) -> bool {
-//     cx.is_staff() || cx.has_flag::<ChannelsAlpha>()
-// }
+fn is_channels_feature_enabled(cx: &gpui::WindowContext<'_>) -> bool {
+    cx.is_staff() || cx.has_flag::<ChannelsAlpha>()
+}

crates/collab_ui2/src/face_pile.rs 🔗

@@ -1,8 +1,9 @@
 use gpui::{
-    div, AnyElement, Div, IntoElement as _, ParentElement as _, RenderOnce, Styled, WindowContext,
+    div, AnyElement, Div, ElementId, IntoElement, ParentElement as _, RenderOnce, Styled,
+    WindowContext,
 };
 
-#[derive(Default)]
+#[derive(Default, IntoElement)]
 pub struct FacePile {
     pub faces: Vec<AnyElement>,
 }
@@ -15,64 +16,15 @@ impl RenderOnce for FacePile {
         let player_list = self.faces.into_iter().enumerate().map(|(ix, player)| {
             let isnt_last = ix < player_count - 1;
 
-            div().when(isnt_last, |div| div.neg_mr_1()).child(player)
+            div()
+                .z_index((player_count - ix) as u32)
+                .when(isnt_last, |div| div.neg_mr_1())
+                .child(player)
         });
         div().p_1().flex().items_center().children(player_list)
     }
 }
 
-// impl Element for FacePile {
-//     type State = ();
-//     fn layout(
-//         &mut self,
-//         state: Option<Self::State>,
-//         cx: &mut WindowContext,
-//     ) -> (LayoutId, Self::State) {
-//         let mut width = 0.;
-//         let mut max_height = 0.;
-//         let mut faces = Vec::with_capacity(self.faces.len());
-//         for face in &mut self.faces {
-//             let layout = face.layout(cx);
-//             width += layout.x();
-//             max_height = f32::max(max_height, layout.y());
-//             faces.push(layout);
-//         }
-//         width -= self.overlap * self.faces.len().saturating_sub(1) as f32;
-//         (cx.request_layout(&Style::default(), faces), ())
-//         // (
-//         //     Vector2F::new(width, max_height.clamp(1., constraint.max.y())),
-//         //     (),
-//         // ))
-//     }
-
-//     fn paint(
-//         &mut self,
-//         bounds: RectF,
-//         visible_bounds: RectF,
-//         _layout: &mut Self::LayoutState,
-//         view: &mut V,
-//         cx: &mut ViewContext<V>,
-//     ) -> Self::PaintState {
-//         let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
-
-//         let origin_y = bounds.upper_right().y();
-//         let mut origin_x = bounds.upper_right().x();
-
-//         for face in self.faces.iter_mut().rev() {
-//             let size = face.size();
-//             origin_x -= size.x();
-//             let origin_y = origin_y + (bounds.height() - size.y()) / 2.0;
-
-//             cx.scene().push_layer(None);
-//             face.paint(vec2f(origin_x, origin_y), visible_bounds, view, cx);
-//             cx.scene().pop_layer();
-//             origin_x += self.overlap;
-//         }
-
-//         ()
-//     }
-// }
-
 impl Extend<AnyElement> for FacePile {
     fn extend<T: IntoIterator<Item = AnyElement>>(&mut self, children: T) {
         self.faces.extend(children);

crates/collab_ui2/src/notifications.rs 🔗

@@ -3,9 +3,9 @@ use std::sync::Arc;
 use workspace::AppState;
 
 pub mod incoming_call_notification;
-// pub mod project_shared_notification;
+pub mod project_shared_notification;
 
 pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
     incoming_call_notification::init(app_state, cx);
-    //project_shared_notification::init(app_state, cx);
+    project_shared_notification::init(app_state, cx);
 }

crates/collab_ui2/src/notifications/incoming_call_notification.rs 🔗

@@ -33,8 +33,8 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
                     height: px(64.),
                 };
 
-                for window in unique_screens {
-                    let options = notification_window_options(window, window_size);
+                for screen in unique_screens {
+                    let options = notification_window_options(screen, window_size);
                     let window = cx
                         .open_window(options, |cx| {
                             cx.build_view(|_| {
@@ -47,15 +47,6 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
                         .unwrap();
                     notification_windows.push(window);
                 }
-
-                // for screen in cx.platform().screens() {
-                //     let window = cx
-                //         .add_window(notification_window_options(screen, window_size), |_| {
-                //             IncomingCallNotification::new(incoming_call.clone(), app_state.clone())
-                //         });
-
-                //     notification_windows.push(window);
-                // }
             }
         }
     })
@@ -84,21 +75,22 @@ impl IncomingCallNotificationState {
         let active_call = ActiveCall::global(cx);
         if accept {
             let join = active_call.update(cx, |active_call, cx| active_call.accept_incoming(cx));
+            let caller_user_id = self.call.calling_user.id;
             let initial_project_id = self.call.initial_project.as_ref().map(|project| project.id);
             let app_state = self.app_state.clone();
             let cx: &mut AppContext = cx;
             cx.spawn(|cx| async move {
                 join.await?;
-                if let Some(_project_id) = initial_project_id {
-                    cx.update(|_cx| {
-                        if let Some(_app_state) = app_state.upgrade() {
-                            // workspace::join_remote_project(
-                            //     project_id,
-                            //     caller_user_id,
-                            //     app_state,
-                            //     cx,
-                            // )
-                            // .detach_and_log_err(cx);
+                if let Some(project_id) = initial_project_id {
+                    cx.update(|cx| {
+                        if let Some(app_state) = app_state.upgrade() {
+                            workspace::join_remote_project(
+                                project_id,
+                                caller_user_id,
+                                app_state,
+                                cx,
+                            )
+                            .detach_and_log_err(cx);
                         }
                     })
                     .log_err();
@@ -138,135 +130,25 @@ impl IncomingCallNotification {
                     )))
                     .child(self.render_buttons(cx)),
             )
-        // let theme = &theme::current(cx).incoming_call_notification;
-        // let default_project = proto::ParticipantProject::default();
-        // let initial_project = self
-        //     .call
-        //     .initial_project
-        //     .as_ref()
-        //     .unwrap_or(&default_project);
-        // Flex::row()
-        //     .with_children(self.call.calling_user.avatar.clone().map(|avatar| {
-        //         Image::from_data(avatar)
-        //             .with_style(theme.caller_avatar)
-        //             .aligned()
-        //     }))
-        //     .with_child(
-        //         Flex::column()
-        //             .with_child(
-        //                 Label::new(
-        //                     self.call.calling_user.github_login.clone(),
-        //                     theme.caller_username.text.clone(),
-        //                 )
-        //                 .contained()
-        //                 .with_style(theme.caller_username.container),
-        //             )
-        //             .with_child(
-        //                 Label::new(
-        //                     format!(
-        //                         "is sharing a project in Zed{}",
-        //                         if initial_project.worktree_root_names.is_empty() {
-        //                             ""
-        //                         } else {
-        //                             ":"
-        //                         }
-        //                     ),
-        //                     theme.caller_message.text.clone(),
-        //                 )
-        //                 .contained()
-        //                 .with_style(theme.caller_message.container),
-        //             )
-        //             .with_children(if initial_project.worktree_root_names.is_empty() {
-        //                 None
-        //             } else {
-        //                 Some(
-        //                     Label::new(
-        //                         initial_project.worktree_root_names.join(", "),
-        //                         theme.worktree_roots.text.clone(),
-        //                     )
-        //                     .contained()
-        //                     .with_style(theme.worktree_roots.container),
-        //                 )
-        //             })
-        //             .contained()
-        //             .with_style(theme.caller_metadata)
-        //             .aligned(),
-        //     )
-        //     .contained()
-        //     .with_style(theme.caller_container)
-        //     .flex(1., true)
-        //     .into_any()
     }
 
     fn render_buttons(&self, cx: &mut ViewContext<Self>) -> impl Element {
         h_stack()
-            .child(
-                Button::new("accept", "Accept")
-                    .render(cx)
-                    // .bg(green())
-                    .on_click({
-                        let state = self.state.clone();
-                        move |_, cx| state.respond(true, cx)
-                    }),
-            )
-            .child(
-                Button::new("decline", "Decline")
-                    .render(cx)
-                    // .bg(red())
-                    .on_click({
-                        let state = self.state.clone();
-                        move |_, cx| state.respond(false, cx)
-                    }),
-            )
-
-        // enum Accept {}
-        // enum Decline {}
-
-        // let theme = theme::current(cx);
-        // Flex::column()
-        //     .with_child(
-        //         MouseEventHandler::new::<Accept, _>(0, cx, |_, _| {
-        //             let theme = &theme.incoming_call_notification;
-        //             Label::new("Accept", theme.accept_button.text.clone())
-        //                 .aligned()
-        //                 .contained()
-        //                 .with_style(theme.accept_button.container)
-        //         })
-        //         .with_cursor_style(CursorStyle::PointingHand)
-        //         .on_click(MouseButton::Left, |_, this, cx| {
-        //             this.respond(true, cx);
-        //         })
-        //         .flex(1., true),
-        //     )
-        //     .with_child(
-        //         MouseEventHandler::new::<Decline, _>(0, cx, |_, _| {
-        //             let theme = &theme.incoming_call_notification;
-        //             Label::new("Decline", theme.decline_button.text.clone())
-        //                 .aligned()
-        //                 .contained()
-        //                 .with_style(theme.decline_button.container)
-        //         })
-        //         .with_cursor_style(CursorStyle::PointingHand)
-        //         .on_click(MouseButton::Left, |_, this, cx| {
-        //             this.respond(false, cx);
-        //         })
-        //         .flex(1., true),
-        //     )
-        //     .constrained()
-        //     .with_width(theme.incoming_call_notification.button_width)
-        //     .into_any()
+            .child(Button::new("accept", "Accept").render(cx).on_click({
+                let state = self.state.clone();
+                move |_, cx| state.respond(true, cx)
+            }))
+            .child(Button::new("decline", "Decline").render(cx).on_click({
+                let state = self.state.clone();
+                move |_, cx| state.respond(false, cx)
+            }))
     }
 }
+
 impl Render for IncomingCallNotification {
     type Element = Div;
+
     fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
         div().bg(red()).flex_none().child(self.render_caller(cx))
-        // Flex::row()
-        //     .with_child()
-        //     .with_child(self.render_buttons(cx))
-        //     .contained()
-        //     .with_background_color(background)
-        //     .expanded()
-        //     .into_any()
     }
 }

crates/collab_ui2/src/notifications/project_shared_notification.rs 🔗

@@ -3,12 +3,11 @@ use call::{room, ActiveCall};
 use client::User;
 use collections::HashMap;
 use gpui::{
-    elements::*,
-    geometry::vector::vec2f,
-    platform::{CursorStyle, MouseButton},
-    AppContext, Entity, View, ViewContext,
+    px, AppContext, Div, Element, ParentElement, Render, RenderOnce, Size, Styled, ViewContext,
+    VisualContext,
 };
 use std::sync::{Arc, Weak};
+use ui::{h_stack, v_stack, Avatar, Button, Clickable, Label};
 use workspace::AppState;
 
 pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
@@ -21,38 +20,54 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
             project_id,
             worktree_root_names,
         } => {
-            let theme = &theme::current(cx).project_shared_notification;
-            let window_size = vec2f(theme.window_width, theme.window_height);
+            let window_size = Size {
+                width: px(380.),
+                height: px(64.),
+            };
 
-            for screen in cx.platform().screens() {
-                let window =
-                    cx.add_window(notification_window_options(screen, window_size), |_| {
+            for screen in cx.displays() {
+                let options = notification_window_options(screen, window_size);
+                let window = cx.open_window(options, |cx| {
+                    cx.build_view(|_| {
                         ProjectSharedNotification::new(
                             owner.clone(),
                             *project_id,
                             worktree_root_names.clone(),
                             app_state.clone(),
                         )
-                    });
+                    })
+                });
                 notification_windows
                     .entry(*project_id)
                     .or_insert(Vec::new())
                     .push(window);
             }
         }
+
         room::Event::RemoteProjectUnshared { project_id }
         | room::Event::RemoteProjectJoined { project_id }
         | room::Event::RemoteProjectInvitationDiscarded { project_id } => {
             if let Some(windows) = notification_windows.remove(&project_id) {
                 for window in windows {
-                    window.remove(cx);
+                    window
+                        .update(cx, |_, cx| {
+                            // todo!()
+                            cx.remove_window();
+                        })
+                        .ok();
                 }
             }
         }
+
         room::Event::Left => {
             for (_, windows) in notification_windows.drain() {
                 for window in windows {
-                    window.remove(cx);
+                    window
+                        .update(cx, |_, cx| {
+                            // todo!()
+                            cx.remove_window();
+                        })
+                        .ok();
                 }
             }
         }
@@ -102,116 +117,60 @@ impl ProjectSharedNotification {
         }
     }
 
-    fn render_owner(&self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
-        let theme = &theme::current(cx).project_shared_notification;
-        Flex::row()
-            .with_children(self.owner.avatar.clone().map(|avatar| {
-                Image::from_data(avatar)
-                    .with_style(theme.owner_avatar)
-                    .aligned()
-            }))
-            .with_child(
-                Flex::column()
-                    .with_child(
-                        Label::new(
-                            self.owner.github_login.clone(),
-                            theme.owner_username.text.clone(),
-                        )
-                        .contained()
-                        .with_style(theme.owner_username.container),
-                    )
-                    .with_child(
-                        Label::new(
-                            format!(
-                                "is sharing a project in Zed{}",
-                                if self.worktree_root_names.is_empty() {
-                                    ""
-                                } else {
-                                    ":"
-                                }
-                            ),
-                            theme.message.text.clone(),
-                        )
-                        .contained()
-                        .with_style(theme.message.container),
-                    )
-                    .with_children(if self.worktree_root_names.is_empty() {
+    fn render_owner(&self) -> impl Element {
+        h_stack()
+            .children(
+                self.owner
+                    .avatar
+                    .clone()
+                    .map(|avatar| Avatar::data(avatar.clone())),
+            )
+            .child(
+                v_stack()
+                    .child(Label::new(self.owner.github_login.clone()))
+                    .child(Label::new(format!(
+                        "is sharing a project in Zed{}",
+                        if self.worktree_root_names.is_empty() {
+                            ""
+                        } else {
+                            ":"
+                        }
+                    )))
+                    .children(if self.worktree_root_names.is_empty() {
                         None
                     } else {
-                        Some(
-                            Label::new(
-                                self.worktree_root_names.join(", "),
-                                theme.worktree_roots.text.clone(),
-                            )
-                            .contained()
-                            .with_style(theme.worktree_roots.container),
-                        )
-                    })
-                    .contained()
-                    .with_style(theme.owner_metadata)
-                    .aligned(),
+                        Some(Label::new(self.worktree_root_names.join(", ")))
+                    }),
             )
-            .contained()
-            .with_style(theme.owner_container)
-            .flex(1., true)
-            .into_any()
     }
 
-    fn render_buttons(&self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
-        enum Open {}
-        enum Dismiss {}
-
-        let theme = theme::current(cx);
-        Flex::column()
-            .with_child(
-                MouseEventHandler::new::<Open, _>(0, cx, |_, _| {
-                    let theme = &theme.project_shared_notification;
-                    Label::new("Open", theme.open_button.text.clone())
-                        .aligned()
-                        .contained()
-                        .with_style(theme.open_button.container)
-                })
-                .with_cursor_style(CursorStyle::PointingHand)
-                .on_click(MouseButton::Left, move |_, this, cx| this.join(cx))
-                .flex(1., true),
-            )
-            .with_child(
-                MouseEventHandler::new::<Dismiss, _>(0, cx, |_, _| {
-                    let theme = &theme.project_shared_notification;
-                    Label::new("Dismiss", theme.dismiss_button.text.clone())
-                        .aligned()
-                        .contained()
-                        .with_style(theme.dismiss_button.container)
-                })
-                .with_cursor_style(CursorStyle::PointingHand)
-                .on_click(MouseButton::Left, |_, this, cx| {
-                    this.dismiss(cx);
-                })
-                .flex(1., true),
+    fn render_buttons(&self, cx: &mut ViewContext<Self>) -> impl Element {
+        let this = cx.view().clone();
+        v_stack()
+            .child(Button::new("open", "Open").render(cx).on_click({
+                let this = this.clone();
+                move |_, cx| {
+                    this.update(cx, |this, cx| this.join(cx));
+                }
+            }))
+            .child(
+                Button::new("dismiss", "Dismiss")
+                    .render(cx)
+                    .on_click(move |_, cx| {
+                        this.update(cx, |this, cx| this.dismiss(cx));
+                    }),
             )
-            .constrained()
-            .with_width(theme.project_shared_notification.button_width)
-            .into_any()
     }
 }
 
-impl Entity for ProjectSharedNotification {
-    type Event = ();
-}
-
-impl View for ProjectSharedNotification {
-    fn ui_name() -> &'static str {
-        "ProjectSharedNotification"
-    }
+impl Render for ProjectSharedNotification {
+    type Element = Div;
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::AnyElement<Self> {
-        let background = theme::current(cx).project_shared_notification.background;
-        Flex::row()
-            .with_child(self.render_owner(cx))
-            .with_child(self.render_buttons(cx))
-            .contained()
-            .with_background_color(background)
-            .expanded()
-            .into_any()
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+        h_stack()
+            .size_full()
+            .bg(gpui::red())
+            .child(self.render_owner())
+            .child(self.render_buttons(cx))
     }
 }

crates/command_palette2/src/command_palette.rs 🔗

@@ -7,7 +7,7 @@ use collections::{CommandPaletteFilter, HashMap};
 use fuzzy::{StringMatch, StringMatchCandidate};
 use gpui::{
     actions, Action, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView,
-    Keystroke, ParentElement, Render, Styled, View, ViewContext, VisualContext, WeakView,
+    ParentElement, Render, Styled, View, ViewContext, VisualContext, WeakView,
 };
 use picker::{Picker, PickerDelegate};
 
@@ -16,16 +16,18 @@ use util::{
     channel::{parse_zed_link, ReleaseChannel, RELEASE_CHANNEL},
     ResultExt,
 };
-use workspace::Workspace;
+use workspace::{ModalView, Workspace};
 use zed_actions::OpenZedURL;
 
-actions!(Toggle);
+actions!(command_palette, [Toggle]);
 
 pub fn init(cx: &mut AppContext) {
     cx.set_global(HitCounts::default());
     cx.observe_new_views(CommandPalette::register).detach();
 }
 
+impl ModalView for CommandPalette {}
+
 pub struct CommandPalette {
     picker: View<Picker<CommandPaletteDelegate>>,
 }
@@ -47,7 +49,7 @@ impl CommandPalette {
             .available_actions()
             .into_iter()
             .filter_map(|action| {
-                let name = gpui::remove_the_2(action.name());
+                let name = action.name();
                 let namespace = name.split("::").next().unwrap_or("malformed action name");
                 if filter.is_some_and(|f| {
                     f.hidden_namespaces.contains(namespace)
@@ -59,7 +61,6 @@ impl CommandPalette {
                 Some(Command {
                     name: humanize_action_name(&name),
                     action,
-                    keystrokes: vec![], // todo!()
                 })
             })
             .collect();
@@ -108,7 +109,6 @@ pub struct CommandPaletteDelegate {
 struct Command {
     name: String,
     action: Box<dyn Action>,
-    keystrokes: Vec<Keystroke>,
 }
 
 impl Clone for Command {
@@ -116,7 +116,6 @@ impl Clone for Command {
         Self {
             name: self.name.clone(),
             action: self.action.boxed_clone(),
-            keystrokes: self.keystrokes.clone(),
         }
     }
 }
@@ -227,6 +226,7 @@ impl PickerDelegate for CommandPaletteDelegate {
                     })
                 }
             }
+
             if let Some(CommandInterceptResult {
                 action,
                 string,
@@ -242,7 +242,6 @@ impl PickerDelegate for CommandPaletteDelegate {
                 commands.push(Command {
                     name: string.clone(),
                     action,
-                    keystrokes: vec![],
                 });
                 matches.insert(
                     0,
@@ -254,6 +253,7 @@ impl PickerDelegate for CommandPaletteDelegate {
                     },
                 )
             }
+
             picker
                 .update(&mut cx, |picker, _| {
                     let delegate = &mut picker.delegate;
@@ -283,6 +283,8 @@ impl PickerDelegate for CommandPaletteDelegate {
         }
         let action_ix = self.matches[self.selected_ix].candidate_id;
         let command = self.commands.swap_remove(action_ix);
+        self.matches.clear();
+        self.commands.clear();
         cx.update_global(|hit_counts: &mut HitCounts, _| {
             *hit_counts.0.entry(command.name).or_default() += 1;
         });
@@ -298,13 +300,8 @@ impl PickerDelegate for CommandPaletteDelegate {
         selected: bool,
         cx: &mut ViewContext<Picker<Self>>,
     ) -> Option<Self::ListItem> {
-        let Some(r#match) = self.matches.get(ix) else {
-            return None;
-        };
-        let Some(command) = self.commands.get(r#match.candidate_id) else {
-            return None;
-        };
-
+        let r#match = self.matches.get(ix)?;
+        let command = self.commands.get(r#match.candidate_id)?;
         Some(
             ListItem::new(ix).inset(true).selected(selected).child(
                 h_stack()
@@ -352,8 +349,7 @@ impl std::fmt::Debug for Command {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("Command")
             .field("name", &self.name)
-            .field("keystrokes", &self.keystrokes)
-            .finish()
+            .finish_non_exhaustive()
     }
 }
 

crates/copilot2/src/copilot2.rs 🔗

@@ -34,12 +34,15 @@ use util::{
 };
 
 actions!(
-    Suggest,
-    NextSuggestion,
-    PreviousSuggestion,
-    Reinstall,
-    SignIn,
-    SignOut
+    copilot,
+    [
+        Suggest,
+        NextSuggestion,
+        PreviousSuggestion,
+        Reinstall,
+        SignIn,
+        SignOut
+    ]
 );
 
 pub fn init(

crates/diagnostics2/src/diagnostics.rs 🔗

@@ -43,7 +43,7 @@ use workspace::{
     ItemNavHistory, Pane, ToolbarItemLocation, Workspace,
 };
 
-actions!(Deploy, ToggleWarnings);
+actions!(diagnostics, [Deploy, ToggleWarnings]);
 
 const CONTEXT_LINE_COUNT: u32 = 1;
 

crates/editor/src/editor.rs 🔗

@@ -12,6 +12,7 @@ mod link_go_to_definition;
 mod mouse_context_menu;
 pub mod movement;
 mod persistence;
+mod rust_analyzer_ext;
 pub mod scroll;
 pub mod selections_collection;
 
@@ -300,6 +301,7 @@ actions!(
         DeleteToEndOfLine,
         CutToEndOfLine,
         DuplicateLine,
+        ExpandMacroRecursively,
         MoveLineUp,
         MoveLineDown,
         JoinLines,
@@ -425,6 +427,8 @@ pub fn init_settings(cx: &mut AppContext) {
 
 pub fn init(cx: &mut AppContext) {
     init_settings(cx);
+
+    rust_analyzer_ext::apply_related_actions(cx);
     cx.add_action(Editor::new_file);
     cx.add_action(Editor::new_file_in_direction);
     cx.add_action(Editor::cancel);

crates/editor/src/rust_analyzer_ext.rs 🔗

@@ -0,0 +1,98 @@
+use std::sync::Arc;
+
+use anyhow::Context as _;
+use gpui::{AppContext, Task, ViewContext};
+use language::Language;
+use multi_buffer::MultiBuffer;
+use project::lsp_ext_command::ExpandMacro;
+use text::ToPointUtf16;
+
+use crate::{Editor, ExpandMacroRecursively};
+
+pub fn apply_related_actions(cx: &mut AppContext) {
+    cx.add_async_action(expand_macro_recursively);
+}
+
+pub fn expand_macro_recursively(
+    editor: &mut Editor,
+    _: &ExpandMacroRecursively,
+    cx: &mut ViewContext<'_, '_, Editor>,
+) -> Option<Task<anyhow::Result<()>>> {
+    if editor.selections.count() == 0 {
+        return None;
+    }
+    let project = editor.project.as_ref()?;
+    let workspace = editor.workspace(cx)?;
+    let multibuffer = editor.buffer().read(cx);
+
+    let (trigger_anchor, rust_language, server_to_query, buffer) = editor
+        .selections
+        .disjoint_anchors()
+        .into_iter()
+        .filter(|selection| selection.start == selection.end)
+        .filter_map(|selection| Some((selection.start.buffer_id?, selection.start)))
+        .filter_map(|(buffer_id, trigger_anchor)| {
+            let buffer = multibuffer.buffer(buffer_id)?;
+            let rust_language = buffer.read(cx).language_at(trigger_anchor.text_anchor)?;
+            if !is_rust_language(&rust_language) {
+                return None;
+            }
+            Some((trigger_anchor, rust_language, buffer))
+        })
+        .find_map(|(trigger_anchor, rust_language, buffer)| {
+            project
+                .read(cx)
+                .language_servers_for_buffer(buffer.read(cx), cx)
+                .into_iter()
+                .find_map(|(adapter, server)| {
+                    if adapter.name.0.as_ref() == "rust-analyzer" {
+                        Some((
+                            trigger_anchor,
+                            Arc::clone(&rust_language),
+                            server.server_id(),
+                            buffer.clone(),
+                        ))
+                    } else {
+                        None
+                    }
+                })
+        })?;
+
+    let project = project.clone();
+    let buffer_snapshot = buffer.read(cx).snapshot();
+    let position = trigger_anchor.text_anchor.to_point_utf16(&buffer_snapshot);
+    let expand_macro_task = project.update(cx, |project, cx| {
+        project.request_lsp(
+            buffer,
+            project::LanguageServerToQuery::Other(server_to_query),
+            ExpandMacro { position },
+            cx,
+        )
+    });
+    Some(cx.spawn(|_, mut cx| async move {
+        let macro_expansion = expand_macro_task.await.context("expand macro")?;
+        if macro_expansion.is_empty() {
+            log::info!("Empty macro expansion for position {position:?}");
+            return Ok(());
+        }
+
+        let buffer = project.update(&mut cx, |project, cx| {
+            project.create_buffer(&macro_expansion.expansion, Some(rust_language), cx)
+        })?;
+        workspace.update(&mut cx, |workspace, cx| {
+            let buffer = cx.add_model(|cx| {
+                MultiBuffer::singleton(buffer, cx).with_title(macro_expansion.name)
+            });
+            workspace.add_item(
+                Box::new(cx.add_view(|cx| Editor::for_multibuffer(buffer, Some(project), cx))),
+                cx,
+            );
+        });
+
+        anyhow::Ok(())
+    }))
+}
+
+fn is_rust_language(language: &Language) -> bool {
+    language.name().as_ref() == "Rust"
+}

crates/editor2/src/editor.rs 🔗

@@ -13,6 +13,7 @@ mod link_go_to_definition;
 mod mouse_context_menu;
 pub mod movement;
 mod persistence;
+mod rust_analyzer_ext;
 pub mod scroll;
 pub mod selections_collection;
 
@@ -39,8 +40,8 @@ use futures::FutureExt;
 use fuzzy::{StringMatch, StringMatchCandidate};
 use git::diff_hunk_to_display;
 use gpui::{
-    actions, div, point, prelude::*, px, relative, rems, size, uniform_list, Action, AnyElement,
-    AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Context,
+    actions, div, impl_actions, point, prelude::*, px, relative, rems, size, uniform_list, Action,
+    AnyElement, AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Context,
     DispatchPhase, Div, ElementId, EventEmitter, FocusHandle, FocusableView, FontFeatures,
     FontStyle, FontWeight, HighlightStyle, Hsla, InputHandler, InteractiveText, KeyContext, Model,
     MouseButton, ParentElement, Pixels, Render, RenderOnce, SharedString, Styled, StyledText,
@@ -107,7 +108,7 @@ use ui::{
 use ui::{prelude::*, IconSize};
 use util::{post_inc, RangeExt, ResultExt, TryFutureExt};
 use workspace::{
-    item::{ItemEvent, ItemHandle},
+    item::{Item, ItemEvent, ItemHandle},
     searchable::SearchEvent,
     ItemNavHistory, Pane, SplitDirection, ViewId, Workspace,
 };
@@ -185,82 +186,101 @@ pub fn render_parsed_markdown(
     })
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct SelectNext {
     #[serde(default)]
     pub replace_newest: bool,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct SelectPrevious {
     #[serde(default)]
     pub replace_newest: bool,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct SelectAllMatches {
     #[serde(default)]
     pub replace_newest: bool,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct SelectToBeginningOfLine {
     #[serde(default)]
     stop_at_soft_wraps: bool,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct MovePageUp {
     #[serde(default)]
     center_cursor: bool,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct MovePageDown {
     #[serde(default)]
     center_cursor: bool,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct SelectToEndOfLine {
     #[serde(default)]
     stop_at_soft_wraps: bool,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct ToggleCodeActions {
     #[serde(default)]
     pub deployed_from_indicator: bool,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct ConfirmCompletion {
     #[serde(default)]
     pub item_ix: Option<usize>,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct ConfirmCodeAction {
     #[serde(default)]
     pub item_ix: Option<usize>,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct ToggleComments {
     #[serde(default)]
     pub advance_downwards: bool,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct FoldAt {
     pub buffer_row: u32,
 }
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize, Default)]
 pub struct UnfoldAt {
     pub buffer_row: u32,
 }
 
+impl_actions!(
+    editor,
+    [
+        SelectNext,
+        SelectPrevious,
+        SelectAllMatches,
+        SelectToBeginningOfLine,
+        MovePageUp,
+        MovePageDown,
+        SelectToEndOfLine,
+        ToggleCodeActions,
+        ConfirmCompletion,
+        ConfirmCodeAction,
+        ToggleComments,
+        FoldAt,
+        UnfoldAt
+    ]
+);
+
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum InlayId {
     Suggestion(usize),
@@ -277,121 +297,125 @@ impl InlayId {
 }
 
 actions!(
-    AddSelectionAbove,
-    AddSelectionBelow,
-    Backspace,
-    Cancel,
-    ConfirmRename,
-    ContextMenuFirst,
-    ContextMenuLast,
-    ContextMenuNext,
-    ContextMenuPrev,
-    ConvertToKebabCase,
-    ConvertToLowerCamelCase,
-    ConvertToLowerCase,
-    ConvertToSnakeCase,
-    ConvertToTitleCase,
-    ConvertToUpperCamelCase,
-    ConvertToUpperCase,
-    Copy,
-    CopyHighlightJson,
-    CopyPath,
-    CopyRelativePath,
-    Cut,
-    CutToEndOfLine,
-    Delete,
-    DeleteLine,
-    DeleteToBeginningOfLine,
-    DeleteToEndOfLine,
-    DeleteToNextSubwordEnd,
-    DeleteToNextWordEnd,
-    DeleteToPreviousSubwordStart,
-    DeleteToPreviousWordStart,
-    DuplicateLine,
-    FindAllReferences,
-    Fold,
-    FoldSelectedRanges,
-    Format,
-    GoToDefinition,
-    GoToDefinitionSplit,
-    GoToDiagnostic,
-    GoToHunk,
-    GoToPrevDiagnostic,
-    GoToPrevHunk,
-    GoToTypeDefinition,
-    GoToTypeDefinitionSplit,
-    HalfPageDown,
-    HalfPageUp,
-    Hover,
-    Indent,
-    JoinLines,
-    LineDown,
-    LineUp,
-    MoveDown,
-    MoveLeft,
-    MoveLineDown,
-    MoveLineUp,
-    MoveRight,
-    MoveToBeginning,
-    MoveToBeginningOfLine,
-    MoveToEnclosingBracket,
-    MoveToEnd,
-    MoveToEndOfLine,
-    MoveToEndOfParagraph,
-    MoveToNextSubwordEnd,
-    MoveToNextWordEnd,
-    MoveToPreviousSubwordStart,
-    MoveToPreviousWordStart,
-    MoveToStartOfParagraph,
-    MoveUp,
-    Newline,
-    NewlineAbove,
-    NewlineBelow,
-    NextScreen,
-    OpenExcerpts,
-    Outdent,
-    PageDown,
-    PageUp,
-    Paste,
-    Redo,
-    RedoSelection,
-    Rename,
-    RestartLanguageServer,
-    RevealInFinder,
-    ReverseLines,
-    ScrollCursorBottom,
-    ScrollCursorCenter,
-    ScrollCursorTop,
-    SelectAll,
-    SelectDown,
-    SelectLargerSyntaxNode,
-    SelectLeft,
-    SelectLine,
-    SelectRight,
-    SelectSmallerSyntaxNode,
-    SelectToBeginning,
-    SelectToEnd,
-    SelectToEndOfParagraph,
-    SelectToNextSubwordEnd,
-    SelectToNextWordEnd,
-    SelectToPreviousSubwordStart,
-    SelectToPreviousWordStart,
-    SelectToStartOfParagraph,
-    SelectUp,
-    ShowCharacterPalette,
-    ShowCompletions,
-    ShuffleLines,
-    SortLinesCaseInsensitive,
-    SortLinesCaseSensitive,
-    SplitSelectionIntoLines,
-    Tab,
-    TabPrev,
-    ToggleInlayHints,
-    ToggleSoftWrap,
-    Transpose,
-    Undo,
-    UndoSelection,
-    UnfoldLines,
+    editor,
+    [
+        AddSelectionAbove,
+        AddSelectionBelow,
+        Backspace,
+        Cancel,
+        ConfirmRename,
+        ContextMenuFirst,
+        ContextMenuLast,
+        ContextMenuNext,
+        ContextMenuPrev,
+        ConvertToKebabCase,
+        ConvertToLowerCamelCase,
+        ConvertToLowerCase,
+        ConvertToSnakeCase,
+        ConvertToTitleCase,
+        ConvertToUpperCamelCase,
+        ConvertToUpperCase,
+        Copy,
+        CopyHighlightJson,
+        CopyPath,
+        CopyRelativePath,
+        Cut,
+        CutToEndOfLine,
+        Delete,
+        DeleteLine,
+        DeleteToBeginningOfLine,
+        DeleteToEndOfLine,
+        DeleteToNextSubwordEnd,
+        DeleteToNextWordEnd,
+        DeleteToPreviousSubwordStart,
+        DeleteToPreviousWordStart,
+        DuplicateLine,
+        ExpandMacroRecursively,
+        FindAllReferences,
+        Fold,
+        FoldSelectedRanges,
+        Format,
+        GoToDefinition,
+        GoToDefinitionSplit,
+        GoToDiagnostic,
+        GoToHunk,
+        GoToPrevDiagnostic,
+        GoToPrevHunk,
+        GoToTypeDefinition,
+        GoToTypeDefinitionSplit,
+        HalfPageDown,
+        HalfPageUp,
+        Hover,
+        Indent,
+        JoinLines,
+        LineDown,
+        LineUp,
+        MoveDown,
+        MoveLeft,
+        MoveLineDown,
+        MoveLineUp,
+        MoveRight,
+        MoveToBeginning,
+        MoveToBeginningOfLine,
+        MoveToEnclosingBracket,
+        MoveToEnd,
+        MoveToEndOfLine,
+        MoveToEndOfParagraph,
+        MoveToNextSubwordEnd,
+        MoveToNextWordEnd,
+        MoveToPreviousSubwordStart,
+        MoveToPreviousWordStart,
+        MoveToStartOfParagraph,
+        MoveUp,
+        Newline,
+        NewlineAbove,
+        NewlineBelow,
+        NextScreen,
+        OpenExcerpts,
+        Outdent,
+        PageDown,
+        PageUp,
+        Paste,
+        Redo,
+        RedoSelection,
+        Rename,
+        RestartLanguageServer,
+        RevealInFinder,
+        ReverseLines,
+        ScrollCursorBottom,
+        ScrollCursorCenter,
+        ScrollCursorTop,
+        SelectAll,
+        SelectDown,
+        SelectLargerSyntaxNode,
+        SelectLeft,
+        SelectLine,
+        SelectRight,
+        SelectSmallerSyntaxNode,
+        SelectToBeginning,
+        SelectToEnd,
+        SelectToEndOfParagraph,
+        SelectToNextSubwordEnd,
+        SelectToNextWordEnd,
+        SelectToPreviousSubwordStart,
+        SelectToPreviousWordStart,
+        SelectToStartOfParagraph,
+        SelectUp,
+        ShowCharacterPalette,
+        ShowCompletions,
+        ShuffleLines,
+        SortLinesCaseInsensitive,
+        SortLinesCaseSensitive,
+        SplitSelectionIntoLines,
+        Tab,
+        TabPrev,
+        ToggleInlayHints,
+        ToggleSoftWrap,
+        Transpose,
+        Undo,
+        UndoSelection,
+        UnfoldLines,
+    ]
 );
 
 enum DocumentHighlightRead {}
@@ -9319,7 +9343,6 @@ impl Render for Editor {
                 scrollbar_width: px(12.),
                 syntax: cx.theme().syntax().clone(),
                 diagnostic_style: cx.theme().diagnostic_style(),
-                // TODO kb find `HighlightStyle` usages
                 // todo!("what about the rest of the highlight style parts?")
                 inlays_style: HighlightStyle {
                     color: Some(cx.theme().status().hint),

crates/editor2/src/element.rs 🔗

@@ -32,7 +32,7 @@ use gpui::{
     Style, Styled, TextRun, TextStyle, View, ViewContext, WeakView, WindowContext, WrappedLine,
 };
 use itertools::Itertools;
-use language::language_settings::ShowWhitespaceSetting;
+use language::{language_settings::ShowWhitespaceSetting, Language};
 use multi_buffer::Anchor;
 use project::{
     project_settings::{GitGutterSetting, ProjectSettings},
@@ -135,11 +135,13 @@ impl EditorElement {
 
     fn register_actions(&self, cx: &mut WindowContext) {
         let view = &self.editor;
-        self.editor.update(cx, |editor, cx| {
+        view.update(cx, |editor, cx| {
             for action in editor.editor_actions.iter() {
                 (action)(cx)
             }
         });
+
+        crate::rust_analyzer_ext::apply_related_actions(view, cx);
         register_action(view, cx, Editor::move_left);
         register_action(view, cx, Editor::move_right);
         register_action(view, cx, Editor::move_down);
@@ -385,17 +387,17 @@ impl EditorElement {
         gutter_bounds: Bounds<Pixels>,
         stacking_order: &StackingOrder,
         cx: &mut ViewContext<Editor>,
-    ) -> bool {
+    ) {
         let mut click_count = event.click_count;
         let modifiers = event.modifiers;
 
         if gutter_bounds.contains_point(&event.position) {
             click_count = 3; // Simulate triple-click when clicking the gutter to select lines
         } else if !text_bounds.contains_point(&event.position) {
-            return false;
+            return;
         }
         if !cx.was_top_layer(&event.position, stacking_order) {
-            return false;
+            return;
         }
 
         let point_for_position = position_map.point_for_position(text_bounds, event.position);
@@ -427,7 +429,7 @@ impl EditorElement {
             );
         }
 
-        true
+        cx.stop_propagation();
     }
 
     fn mouse_right_down(
@@ -436,9 +438,9 @@ impl EditorElement {
         position_map: &PositionMap,
         text_bounds: Bounds<Pixels>,
         cx: &mut ViewContext<Editor>,
-    ) -> bool {
+    ) {
         if !text_bounds.contains_point(&event.position) {
-            return false;
+            return;
         }
         let point_for_position = position_map.point_for_position(text_bounds, event.position);
         mouse_context_menu::deploy_context_menu(
@@ -447,7 +449,7 @@ impl EditorElement {
             point_for_position.previous_valid,
             cx,
         );
-        true
+        cx.stop_propagation();
     }
 
     fn mouse_up(
@@ -457,7 +459,7 @@ impl EditorElement {
         text_bounds: Bounds<Pixels>,
         stacking_order: &StackingOrder,
         cx: &mut ViewContext<Editor>,
-    ) -> bool {
+    ) {
         let end_selection = editor.has_pending_selection();
         let pending_nonempty_selections = editor.has_pending_nonempty_selection();
 
@@ -479,10 +481,10 @@ impl EditorElement {
                 go_to_fetched_definition(editor, point, split, cx);
             }
 
-            return true;
+            cx.stop_propagation();
+        } else if end_selection {
+            cx.stop_propagation();
         }
-
-        end_selection
     }
 
     fn mouse_moved(
@@ -493,7 +495,7 @@ impl EditorElement {
         gutter_bounds: Bounds<Pixels>,
         stacking_order: &StackingOrder,
         cx: &mut ViewContext<Editor>,
-    ) -> bool {
+    ) {
         let modifiers = event.modifiers;
         if editor.has_pending_selection() && event.pressed_button == Some(MouseButton::Left) {
             let point_for_position = position_map.point_for_position(text_bounds, event.position);
@@ -562,11 +564,13 @@ impl EditorElement {
                 }
             }
 
-            true
+            cx.stop_propagation();
         } else {
             update_go_to_definition_link(editor, None, modifiers.command, modifiers.shift, cx);
             hover_at(editor, None, cx);
-            gutter_hovered && was_top
+            if gutter_hovered && was_top {
+                cx.stop_propagation();
+            }
         }
     }
 
@@ -576,9 +580,9 @@ impl EditorElement {
         position_map: &PositionMap,
         bounds: &InteractiveBounds,
         cx: &mut ViewContext<Editor>,
-    ) -> bool {
+    ) {
         if !bounds.visibly_contains(&event.position, cx) {
-            return false;
+            return;
         }
 
         let line_height = position_map.line_height;
@@ -602,8 +606,7 @@ impl EditorElement {
         let y = f32::from((scroll_position.y * line_height - delta.y) / line_height);
         let scroll_position = point(x, y).clamp(&point(0., 0.), &position_map.scroll_max);
         editor.scroll(scroll_position, axis, cx);
-
-        true
+        cx.stop_propagation();
     }
 
     fn paint_background(
@@ -749,44 +752,47 @@ impl EditorElement {
             }
         }
 
-        for (ix, fold_indicator) in layout.fold_indicators.drain(..).enumerate() {
-            if let Some(mut fold_indicator) = fold_indicator {
-                let mut fold_indicator = fold_indicator.into_any_element();
-                let available_space = size(
-                    AvailableSpace::MinContent,
-                    AvailableSpace::Definite(line_height * 0.55),
-                );
-                let fold_indicator_size = fold_indicator.measure(available_space, cx);
+        cx.with_z_index(1, |cx| {
+            for (ix, fold_indicator) in layout.fold_indicators.drain(..).enumerate() {
+                if let Some(mut fold_indicator) = fold_indicator {
+                    let mut fold_indicator = fold_indicator.into_any_element();
+                    let available_space = size(
+                        AvailableSpace::MinContent,
+                        AvailableSpace::Definite(line_height * 0.55),
+                    );
+                    let fold_indicator_size = fold_indicator.measure(available_space, cx);
 
-                let position = point(
-                    bounds.size.width - layout.gutter_padding,
-                    ix as f32 * line_height - (scroll_top % line_height),
-                );
-                let centering_offset = point(
-                    (layout.gutter_padding + layout.gutter_margin - fold_indicator_size.width) / 2.,
-                    (line_height - fold_indicator_size.height) / 2.,
-                );
-                let origin = bounds.origin + position + centering_offset;
-                fold_indicator.draw(origin, available_space, cx);
+                    let position = point(
+                        bounds.size.width - layout.gutter_padding,
+                        ix as f32 * line_height - (scroll_top % line_height),
+                    );
+                    let centering_offset = point(
+                        (layout.gutter_padding + layout.gutter_margin - fold_indicator_size.width)
+                            / 2.,
+                        (line_height - fold_indicator_size.height) / 2.,
+                    );
+                    let origin = bounds.origin + position + centering_offset;
+                    fold_indicator.draw(origin, available_space, cx);
+                }
             }
-        }
 
-        if let Some(indicator) = layout.code_actions_indicator.take() {
-            let mut button = indicator.button.into_any_element();
-            let available_space = size(
-                AvailableSpace::MinContent,
-                AvailableSpace::Definite(line_height),
-            );
-            let indicator_size = button.measure(available_space, cx);
+            if let Some(indicator) = layout.code_actions_indicator.take() {
+                let mut button = indicator.button.into_any_element();
+                let available_space = size(
+                    AvailableSpace::MinContent,
+                    AvailableSpace::Definite(line_height),
+                );
+                let indicator_size = button.measure(available_space, cx);
 
-            let mut x = Pixels::ZERO;
-            let mut y = indicator.row as f32 * line_height - scroll_top;
-            // Center indicator.
-            x += ((layout.gutter_padding + layout.gutter_margin) - indicator_size.width) / 2.;
-            y += (line_height - indicator_size.height) / 2.;
+                let mut x = Pixels::ZERO;
+                let mut y = indicator.row as f32 * line_height - scroll_top;
+                // Center indicator.
+                x += ((layout.gutter_padding + layout.gutter_margin) - indicator_size.width) / 2.;
+                y += (line_height - indicator_size.height) / 2.;
 
-            button.draw(bounds.origin + point(x, y), available_space, cx);
-        }
+                button.draw(bounds.origin + point(x, y), available_space, cx);
+            }
+        });
     }
 
     fn paint_diff_hunks(bounds: Bounds<Pixels>, layout: &LayoutState, cx: &mut WindowContext) {
@@ -824,8 +830,8 @@ impl EditorElement {
             };
 
             let color = match status {
-                DiffHunkStatus::Added => gpui::green(), // todo!("use the appropriate color")
-                DiffHunkStatus::Modified => gpui::yellow(), // todo!("use the appropriate color")
+                DiffHunkStatus::Added => cx.theme().status().created,
+                DiffHunkStatus::Modified => cx.theme().status().modified,
 
                 //TODO: This rendering is entirely a horrible hack
                 DiffHunkStatus::Removed => {
@@ -842,7 +848,7 @@ impl EditorElement {
                     cx.paint_quad(
                         highlight_bounds,
                         Corners::all(1. * line_height),
-                        gpui::red(), // todo!("use the right color")
+                        cx.theme().status().deleted,
                         Edges::default(),
                         transparent_black(),
                     );
@@ -1230,203 +1236,216 @@ impl EditorElement {
         bounds.upper_right().x - self.style.scrollbar_width
     }
 
-    // fn paint_scrollbar(
-    //     &mut self,
-    //     bounds: Bounds<Pixels>,
-    //     layout: &mut LayoutState,
-    //     editor: &Editor,
-    //     cx: &mut ViewContext<Editor>,
-    // ) {
-    //     enum ScrollbarMouseHandlers {}
-    //     if layout.mode != EditorMode::Full {
-    //         return;
-    //     }
-
-    //     let style = &self.style.theme.scrollbar;
-
-    //     let top = bounds.min_y;
-    //     let bottom = bounds.max_y;
-    //     let right = bounds.max_x;
-    //     let left = self.scrollbar_left(&bounds);
-    //     let row_range = &layout.scrollbar_row_range;
-    //     let max_row = layout.max_row as f32 + (row_range.end - row_range.start);
-
-    //     let mut height = bounds.height();
-    //     let mut first_row_y_offset = 0.0;
-
-    //     // Impose a minimum height on the scrollbar thumb
-    //     let row_height = height / max_row;
-    //     let min_thumb_height =
-    //         style.min_height_factor * cx.font_cache.line_height(self.style.text.font_size);
-    //     let thumb_height = (row_range.end - row_range.start) * row_height;
-    //     if thumb_height < min_thumb_height {
-    //         first_row_y_offset = (min_thumb_height - thumb_height) / 2.0;
-    //         height -= min_thumb_height - thumb_height;
-    //     }
-
-    //     let y_for_row = |row: f32| -> f32 { top + first_row_y_offset + row * row_height };
-
-    //     let thumb_top = y_for_row(row_range.start) - first_row_y_offset;
-    //     let thumb_bottom = y_for_row(row_range.end) + first_row_y_offset;
-    //     let track_bounds = Bounds::<Pixels>::from_points(point(left, top), point(right, bottom));
-    //     let thumb_bounds = Bounds::<Pixels>::from_points(point(left, thumb_top), point(right, thumb_bottom));
-
-    //     if layout.show_scrollbars {
-    //         cx.paint_quad(Quad {
-    //             bounds: track_bounds,
-    //             border: style.track.border.into(),
-    //             background: style.track.background_color,
-    //             ..Default::default()
-    //         });
-    //         let scrollbar_settings = settings::get::<EditorSettings>(cx).scrollbar;
-    //         let theme = theme::current(cx);
-    //         let scrollbar_theme = &theme.editor.scrollbar;
-    //         if layout.is_singleton && scrollbar_settings.selections {
-    //             let start_anchor = Anchor::min();
-    //             let end_anchor = Anchor::max;
-    //             let color = scrollbar_theme.selections;
-    //             let border = Border {
-    //                 width: 1.,
-    //                 color: style.thumb.border.color,
-    //                 overlay: false,
-    //                 top: false,
-    //                 right: true,
-    //                 bottom: false,
-    //                 left: true,
-    //             };
-    //             let mut push_region = |start: DisplayPoint, end: DisplayPoint| {
-    //                 let start_y = y_for_row(start.row() as f32);
-    //                 let mut end_y = y_for_row(end.row() as f32);
-    //                 if end_y - start_y < 1. {
-    //                     end_y = start_y + 1.;
-    //                 }
-    //                 let bounds = Bounds::<Pixels>::from_points(point(left, start_y), point(right, end_y));
-
-    //                 cx.paint_quad(Quad {
-    //                     bounds,
-    //                     background: Some(color),
-    //                     border: border.into(),
-    //                     corner_radii: style.thumb.corner_radii.into(),
-    //                 })
-    //             };
-    //             let background_ranges = editor
-    //                 .background_highlight_row_ranges::<crate::items::BufferSearchHighlights>(
-    //                     start_anchor..end_anchor,
-    //                     &layout.position_map.snapshot,
-    //                     50000,
-    //                 );
-    //             for row in background_ranges {
-    //                 let start = row.start();
-    //                 let end = row.end();
-    //                 push_region(*start, *end);
-    //             }
-    //         }
-
-    //         if layout.is_singleton && scrollbar_settings.git_diff {
-    //             let diff_style = scrollbar_theme.git.clone();
-    //             for hunk in layout
-    //                 .position_map
-    //                 .snapshot
-    //                 .buffer_snapshot
-    //                 .git_diff_hunks_in_range(0..(max_row.floor() as u32))
-    //             {
-    //                 let start_display = Point::new(hunk.buffer_range.start, 0)
-    //                     .to_display_point(&layout.position_map.snapshot.display_snapshot);
-    //                 let end_display = Point::new(hunk.buffer_range.end, 0)
-    //                     .to_display_point(&layout.position_map.snapshot.display_snapshot);
-    //                 let start_y = y_for_row(start_display.row() as f32);
-    //                 let mut end_y = if hunk.buffer_range.start == hunk.buffer_range.end {
-    //                     y_for_row((end_display.row() + 1) as f32)
-    //                 } else {
-    //                     y_for_row((end_display.row()) as f32)
-    //                 };
-
-    //                 if end_y - start_y < 1. {
-    //                     end_y = start_y + 1.;
-    //                 }
-    //                 let bounds = Bounds::<Pixels>::from_points(point(left, start_y), point(right, end_y));
-
-    //                 let color = match hunk.status() {
-    //                     DiffHunkStatus::Added => diff_style.inserted,
-    //                     DiffHunkStatus::Modified => diff_style.modified,
-    //                     DiffHunkStatus::Removed => diff_style.deleted,
-    //                 };
-
-    //                 let border = Border {
-    //                     width: 1.,
-    //                     color: style.thumb.border.color,
-    //                     overlay: false,
-    //                     top: false,
-    //                     right: true,
-    //                     bottom: false,
-    //                     left: true,
-    //                 };
-
-    //                 cx.paint_quad(Quad {
-    //                     bounds,
-    //                     background: Some(color),
-    //                     border: border.into(),
-    //                     corner_radii: style.thumb.corner_radii.into(),
-    //                 })
-    //             }
-    //         }
-
-    //         cx.paint_quad(Quad {
-    //             bounds: thumb_bounds,
-    //             border: style.thumb.border.into(),
-    //             background: style.thumb.background_color,
-    //             corner_radii: style.thumb.corner_radii.into(),
-    //         });
-    //     }
-
-    //     cx.scene().push_cursor_region(CursorRegion {
-    //         bounds: track_bounds,
-    //         style: CursorStyle::Arrow,
-    //     });
-    //     let region_id = cx.view_id();
-    //     cx.scene().push_mouse_region(
-    //         MouseRegion::new::<ScrollbarMouseHandlers>(region_id, region_id, track_bounds)
-    //             .on_move(move |event, editor: &mut Editor, cx| {
-    //                 if event.pressed_button.is_none() {
-    //                     editor.scroll_manager.show_scrollbar(cx);
-    //                 }
-    //             })
-    //             .on_down(MouseButton::Left, {
-    //                 let row_range = row_range.clone();
-    //                 move |event, editor: &mut Editor, cx| {
-    //                     let y = event.position.y;
-    //                     if y < thumb_top || thumb_bottom < y {
-    //                         let center_row = ((y - top) * max_row as f32 / height).round() as u32;
-    //                         let top_row = center_row
-    //                             .saturating_sub((row_range.end - row_range.start) as u32 / 2);
-    //                         let mut position = editor.scroll_position(cx);
-    //                         position.set_y(top_row as f32);
-    //                         editor.set_scroll_position(position, cx);
-    //                     } else {
-    //                         editor.scroll_manager.show_scrollbar(cx);
-    //                     }
-    //                 }
-    //             })
-    //             .on_drag(MouseButton::Left, {
-    //                 move |event, editor: &mut Editor, cx| {
-    //                     if event.end {
-    //                         return;
-    //                     }
-
-    //                     let y = event.prev_mouse_position.y;
-    //                     let new_y = event.position.y;
-    //                     if thumb_top < y && y < thumb_bottom {
-    //                         let mut position = editor.scroll_position(cx);
-    //                         position.set_y(position.y + (new_y - y) * (max_row as f32) / height);
-    //                         if position.y < 0.0 {
-    //                             position.set_y(0.);
-    //                         }
-    //                         editor.set_scroll_position(position, cx);
-    //                     }
-    //                 }
-    //             }),
-    //     );
-    // }
+    fn paint_scrollbar(
+        &mut self,
+        bounds: Bounds<Pixels>,
+        layout: &mut LayoutState,
+        cx: &mut WindowContext,
+    ) {
+        if layout.mode != EditorMode::Full {
+            return;
+        }
+
+        let top = bounds.origin.y;
+        let bottom = bounds.lower_left().y;
+        let right = bounds.lower_right().x;
+        let left = self.scrollbar_left(&bounds);
+        let row_range = layout.scrollbar_row_range.clone();
+        let max_row = layout.max_row as f32 + (row_range.end - row_range.start);
+
+        let mut height = bounds.size.height;
+        let mut first_row_y_offset = px(0.0);
+
+        // Impose a minimum height on the scrollbar thumb
+        let row_height = height / max_row;
+        let min_thumb_height = layout.position_map.line_height;
+        let thumb_height = (row_range.end - row_range.start) * row_height;
+        if thumb_height < min_thumb_height {
+            first_row_y_offset = (min_thumb_height - thumb_height) / 2.0;
+            height -= min_thumb_height - thumb_height;
+        }
+
+        let y_for_row = |row: f32| -> Pixels { top + first_row_y_offset + row * row_height };
+
+        let thumb_top = y_for_row(row_range.start) - first_row_y_offset;
+        let thumb_bottom = y_for_row(row_range.end) + first_row_y_offset;
+        let track_bounds = Bounds::from_corners(point(left, top), point(right, bottom));
+        let thumb_bounds = Bounds::from_corners(point(left, thumb_top), point(right, thumb_bottom));
+
+        if layout.show_scrollbars {
+            cx.paint_quad(
+                track_bounds,
+                Corners::default(),
+                gpui::blue(),        // todo!("style.track.background_color")
+                Edges::default(),    // todo!("style.track.border")
+                transparent_black(), // todo!("style.track.border")
+            );
+            let scrollbar_settings = EditorSettings::get_global(cx).scrollbar;
+            if layout.is_singleton && scrollbar_settings.selections {
+                let start_anchor = Anchor::min();
+                let end_anchor = Anchor::max();
+                let background_ranges = self
+                    .editor
+                    .read(cx)
+                    .background_highlight_row_ranges::<crate::items::BufferSearchHighlights>(
+                        start_anchor..end_anchor,
+                        &layout.position_map.snapshot,
+                        50000,
+                    );
+                for range in background_ranges {
+                    let start_y = y_for_row(range.start().row() as f32);
+                    let mut end_y = y_for_row(range.end().row() as f32);
+                    if end_y - start_y < px(1.) {
+                        end_y = start_y + px(1.);
+                    }
+                    let bounds = Bounds::from_corners(point(left, start_y), point(right, end_y));
+                    cx.paint_quad(
+                        bounds,
+                        Corners::default(),
+                        gpui::yellow(), // todo!("theme.editor.scrollbar")
+                        Edges {
+                            top: Pixels::ZERO,
+                            right: px(1.),
+                            bottom: Pixels::ZERO,
+                            left: px(1.),
+                        },
+                        gpui::green(), // todo!("style.thumb.border.color")
+                    );
+                }
+            }
+
+            if layout.is_singleton && scrollbar_settings.git_diff {
+                for hunk in layout
+                    .position_map
+                    .snapshot
+                    .buffer_snapshot
+                    .git_diff_hunks_in_range(0..(max_row.floor() as u32))
+                {
+                    let start_display = Point::new(hunk.buffer_range.start, 0)
+                        .to_display_point(&layout.position_map.snapshot.display_snapshot);
+                    let end_display = Point::new(hunk.buffer_range.end, 0)
+                        .to_display_point(&layout.position_map.snapshot.display_snapshot);
+                    let start_y = y_for_row(start_display.row() as f32);
+                    let mut end_y = if hunk.buffer_range.start == hunk.buffer_range.end {
+                        y_for_row((end_display.row() + 1) as f32)
+                    } else {
+                        y_for_row((end_display.row()) as f32)
+                    };
+
+                    if end_y - start_y < px(1.) {
+                        end_y = start_y + px(1.);
+                    }
+                    let bounds = Bounds::from_corners(point(left, start_y), point(right, end_y));
+
+                    let color = match hunk.status() {
+                        DiffHunkStatus::Added => gpui::green(), // todo!("use the right color")
+                        DiffHunkStatus::Modified => gpui::yellow(), // todo!("use the right color")
+                        DiffHunkStatus::Removed => gpui::red(), // todo!("use the right color")
+                    };
+                    cx.paint_quad(
+                        bounds,
+                        Corners::default(),
+                        color,
+                        Edges {
+                            top: Pixels::ZERO,
+                            right: px(1.),
+                            bottom: Pixels::ZERO,
+                            left: px(1.),
+                        },
+                        gpui::green(), // todo!("style.thumb.border.color")
+                    );
+                }
+            }
+
+            cx.paint_quad(
+                thumb_bounds,
+                Corners::default(),
+                gpui::black(), // todo!("style.thumb.background_color")
+                Edges {
+                    top: Pixels::ZERO,
+                    right: px(1.),
+                    bottom: Pixels::ZERO,
+                    left: px(1.),
+                },
+                gpui::green(), // todo!("style.thumb.border.color")
+            );
+        }
+
+        let mouse_position = cx.mouse_position();
+        if track_bounds.contains_point(&mouse_position) {
+            cx.set_cursor_style(CursorStyle::Arrow);
+        }
+
+        cx.on_mouse_event({
+            let editor = self.editor.clone();
+            move |event: &MouseMoveEvent, phase, cx| {
+                if phase == DispatchPhase::Capture {
+                    return;
+                }
+
+                editor.update(cx, |editor, cx| {
+                    if event.pressed_button == Some(MouseButton::Left)
+                        && editor.scroll_manager.is_dragging_scrollbar()
+                    {
+                        let y = mouse_position.y;
+                        let new_y = event.position.y;
+                        if thumb_top < y && y < thumb_bottom {
+                            let mut position = editor.scroll_position(cx);
+                            position.y += (new_y - y) * (max_row as f32) / height;
+                            if position.y < 0.0 {
+                                position.y = 0.0;
+                            }
+                            editor.set_scroll_position(position, cx);
+                        }
+                        cx.stop_propagation();
+                    } else {
+                        editor.scroll_manager.set_is_dragging_scrollbar(false, cx);
+                        if track_bounds.contains_point(&event.position) {
+                            editor.scroll_manager.show_scrollbar(cx);
+                        }
+                    }
+                })
+            }
+        });
+
+        if self.editor.read(cx).scroll_manager.is_dragging_scrollbar() {
+            cx.on_mouse_event({
+                let editor = self.editor.clone();
+                move |event: &MouseUpEvent, phase, cx| {
+                    editor.update(cx, |editor, cx| {
+                        editor.scroll_manager.set_is_dragging_scrollbar(false, cx);
+                        cx.stop_propagation();
+                    });
+                }
+            });
+        } else {
+            cx.on_mouse_event({
+                let editor = self.editor.clone();
+                move |event: &MouseDownEvent, phase, cx| {
+                    editor.update(cx, |editor, cx| {
+                        if track_bounds.contains_point(&event.position) {
+                            editor.scroll_manager.set_is_dragging_scrollbar(true, cx);
+
+                            let y = event.position.y;
+                            if y < thumb_top || thumb_bottom < y {
+                                let center_row =
+                                    ((y - top) * max_row as f32 / height).round() as u32;
+                                let top_row = center_row
+                                    .saturating_sub((row_range.end - row_range.start) as u32 / 2);
+                                let mut position = editor.scroll_position(cx);
+                                position.y = top_row as f32;
+                                editor.set_scroll_position(position, cx);
+                            } else {
+                                editor.scroll_manager.show_scrollbar(cx);
+                            }
+
+                            cx.stop_propagation();
+                        }
+                    });
+                }
+            });
+        }
+    }
 
     #[allow(clippy::too_many_arguments)]
     fn paint_highlighted_range(
@@ -2452,12 +2471,9 @@ impl EditorElement {
                     return;
                 }
 
-                let handled = editor.update(cx, |editor, cx| {
+                editor.update(cx, |editor, cx| {
                     Self::scroll(editor, event, &position_map, &interactive_bounds, cx)
                 });
-                if handled {
-                    cx.stop_propagation();
-                }
             }
         });
 
@@ -2471,7 +2487,7 @@ impl EditorElement {
                     return;
                 }
 
-                let handled = match event.button {
+                match event.button {
                     MouseButton::Left => editor.update(cx, |editor, cx| {
                         Self::mouse_left_down(
                             editor,
@@ -2486,12 +2502,8 @@ impl EditorElement {
                     MouseButton::Right => editor.update(cx, |editor, cx| {
                         Self::mouse_right_down(editor, event, &position_map, text_bounds, cx)
                     }),
-                    _ => false,
+                    _ => {}
                 };
-
-                if handled {
-                    cx.stop_propagation()
-                }
             }
         });
 
@@ -2501,7 +2513,7 @@ impl EditorElement {
             let stacking_order = cx.stacking_order().clone();
 
             move |event: &MouseUpEvent, phase, cx| {
-                let handled = editor.update(cx, |editor, cx| {
+                editor.update(cx, |editor, cx| {
                     Self::mouse_up(
                         editor,
                         event,
@@ -2511,10 +2523,6 @@ impl EditorElement {
                         cx,
                     )
                 });
-
-                if handled {
-                    cx.stop_propagation()
-                }
             }
         });
         cx.on_mouse_event({
@@ -2527,7 +2535,7 @@ impl EditorElement {
                     return;
                 }
 
-                let stop_propogating = editor.update(cx, |editor, cx| {
+                editor.update(cx, |editor, cx| {
                     Self::mouse_moved(
                         editor,
                         event,
@@ -2538,10 +2546,6 @@ impl EditorElement {
                         cx,
                     )
                 });
-
-                if stop_propogating {
-                    cx.stop_propagation()
-                }
             }
         });
     }
@@ -2840,9 +2844,11 @@ impl Element for EditorElement {
                         cx.with_z_index(1, |cx| {
                             cx.with_element_id(Some("editor_blocks"), |cx| {
                                 self.paint_blocks(bounds, &mut layout, cx);
-                            })
+                            });
                         })
                     }
+
+                    cx.with_z_index(2, |cx| self.paint_scrollbar(bounds, &mut layout, cx));
                 });
             });
         })
@@ -2944,7 +2950,7 @@ impl PositionMap {
     ) -> PointForPosition {
         let scroll_position = self.snapshot.scroll_position();
         let position = position - text_bounds.origin;
-        let y = position.y.max(px(0.)).min(self.size.width);
+        let y = position.y.max(px(0.)).min(self.size.height);
         let x = position.x + (scroll_position.x * self.em_width);
         let row = (f32::from(y / self.line_height) + scroll_position.y) as u32;
 

crates/editor2/src/hover_popover.rs 🔗

@@ -26,7 +26,7 @@ pub const MIN_POPOVER_CHARACTER_WIDTH: f32 = 20.;
 pub const MIN_POPOVER_LINE_HEIGHT: Pixels = px(4.);
 pub const HOVER_POPOVER_GAP: Pixels = px(10.);
 
-actions!(Hover);
+actions!(editor, [Hover]);
 
 /// Bindable action which uses the most recent selection head to trigger a hover
 pub fn hover(editor: &mut Editor, _: &Hover, cx: &mut ViewContext<Editor>) {

crates/editor2/src/rust_analyzer_ext.rs 🔗

@@ -0,0 +1,119 @@
+use std::sync::Arc;
+
+use anyhow::Context as _;
+use gpui::{Context, Model, View, ViewContext, VisualContext, WindowContext};
+use language::Language;
+use multi_buffer::MultiBuffer;
+use project::lsp_ext_command::ExpandMacro;
+use text::ToPointUtf16;
+
+use crate::{element::register_action, Editor, ExpandMacroRecursively};
+
+pub fn apply_related_actions(editor: &View<Editor>, cx: &mut WindowContext) {
+    let is_rust_related = editor.update(cx, |editor, cx| {
+        editor
+            .buffer()
+            .read(cx)
+            .all_buffers()
+            .iter()
+            .any(|b| match b.read(cx).language() {
+                Some(l) => is_rust_language(l),
+                None => false,
+            })
+    });
+
+    if is_rust_related {
+        register_action(editor, cx, expand_macro_recursively);
+    }
+}
+
+pub fn expand_macro_recursively(
+    editor: &mut Editor,
+    _: &ExpandMacroRecursively,
+    cx: &mut ViewContext<'_, Editor>,
+) {
+    if editor.selections.count() == 0 {
+        return;
+    }
+    let Some(project) = &editor.project else {
+        return;
+    };
+    let Some(workspace) = editor.workspace() else {
+        return;
+    };
+
+    let multibuffer = editor.buffer().read(cx);
+
+    let Some((trigger_anchor, rust_language, server_to_query, buffer)) = editor
+        .selections
+        .disjoint_anchors()
+        .into_iter()
+        .filter(|selection| selection.start == selection.end)
+        .filter_map(|selection| Some((selection.start.buffer_id?, selection.start)))
+        .filter_map(|(buffer_id, trigger_anchor)| {
+            let buffer = multibuffer.buffer(buffer_id)?;
+            let rust_language = buffer.read(cx).language_at(trigger_anchor.text_anchor)?;
+            if !is_rust_language(&rust_language) {
+                return None;
+            }
+            Some((trigger_anchor, rust_language, buffer))
+        })
+        .find_map(|(trigger_anchor, rust_language, buffer)| {
+            project
+                .read(cx)
+                .language_servers_for_buffer(buffer.read(cx), cx)
+                .into_iter()
+                .find_map(|(adapter, server)| {
+                    if adapter.name.0.as_ref() == "rust-analyzer" {
+                        Some((
+                            trigger_anchor,
+                            Arc::clone(&rust_language),
+                            server.server_id(),
+                            buffer.clone(),
+                        ))
+                    } else {
+                        None
+                    }
+                })
+        })
+    else {
+        return;
+    };
+
+    let project = project.clone();
+    let buffer_snapshot = buffer.read(cx).snapshot();
+    let position = trigger_anchor.text_anchor.to_point_utf16(&buffer_snapshot);
+    let expand_macro_task = project.update(cx, |project, cx| {
+        project.request_lsp(
+            buffer,
+            project::LanguageServerToQuery::Other(server_to_query),
+            ExpandMacro { position },
+            cx,
+        )
+    });
+    cx.spawn(|editor, mut cx| async move {
+        let macro_expansion = expand_macro_task.await.context("expand macro")?;
+        if macro_expansion.is_empty() {
+            log::info!("Empty macro expansion for position {position:?}");
+            return Ok(());
+        }
+
+        let buffer = project.update(&mut cx, |project, cx| {
+            project.create_buffer(&macro_expansion.expansion, Some(rust_language), cx)
+        })??;
+        workspace.update(&mut cx, |workspace, cx| {
+            let buffer = cx.build_model(|cx| {
+                MultiBuffer::singleton(buffer, cx).with_title(macro_expansion.name)
+            });
+            workspace.add_item(
+                Box::new(cx.build_view(|cx| Editor::for_multibuffer(buffer, Some(project), cx))),
+                cx,
+            );
+        })
+    })
+    .detach_and_log_err(cx);
+}
+
+fn is_rust_language(language: &Language) -> bool {
+    language.name().as_ref() == "Rust"
+}

crates/editor2/src/scroll.rs 🔗

@@ -136,6 +136,7 @@ pub struct ScrollManager {
     last_autoscroll: Option<(gpui::Point<f32>, f32, f32, AutoscrollStrategy)>,
     show_scrollbars: bool,
     hide_scrollbar_task: Option<Task<()>>,
+    dragging_scrollbar: bool,
     visible_line_count: Option<f32>,
 }
 
@@ -148,6 +149,7 @@ impl ScrollManager {
             autoscroll_request: None,
             show_scrollbars: true,
             hide_scrollbar_task: None,
+            dragging_scrollbar: false,
             last_autoscroll: None,
             visible_line_count: None,
         }
@@ -278,6 +280,17 @@ impl ScrollManager {
         self.autoscroll_request.is_some()
     }
 
+    pub fn is_dragging_scrollbar(&self) -> bool {
+        self.dragging_scrollbar
+    }
+
+    pub fn set_is_dragging_scrollbar(&mut self, dragging: bool, cx: &mut ViewContext<Editor>) {
+        if dragging != self.dragging_scrollbar {
+            self.dragging_scrollbar = dragging;
+            cx.notify();
+        }
+    }
+
     pub fn clamp_scroll_left(&mut self, max: f32) -> bool {
         if max < self.anchor.offset.x {
             self.anchor.offset.x = max;

crates/feedback2/src/deploy_feedback_button.rs 🔗

@@ -32,7 +32,7 @@ impl Render for DeployFeedbackButton {
         IconButton::new("give-feedback", Icon::Envelope)
             .style(ui::ButtonStyle::Subtle)
             .selected(is_open)
-            .tooltip(|cx| Tooltip::text("Give Feedback", cx))
+            .tooltip(|cx| Tooltip::text("Share Feedback", cx))
             .on_click(|_, cx| {
                 cx.dispatch_action(Box::new(GiveFeedback));
             })

crates/feedback2/src/feedback2.rs 🔗

@@ -5,15 +5,18 @@ use workspace::Workspace;
 pub mod deploy_feedback_button;
 pub mod feedback_modal;
 
-actions!(GiveFeedback, SubmitFeedback);
+actions!(feedback, [GiveFeedback, SubmitFeedback]);
 
 mod system_specs;
 
 actions!(
-    CopySystemSpecsIntoClipboard,
-    FileBugReport,
-    RequestFeature,
-    OpenZedCommunityRepo
+    zed,
+    [
+        CopySystemSpecsIntoClipboard,
+        FileBugReport,
+        RequestFeature,
+        OpenZedCommunityRepo
+    ]
 );
 
 pub fn init(cx: &mut AppContext) {

crates/feedback2/src/feedback_modal.rs 🔗

@@ -1,28 +1,38 @@
 use std::{ops::RangeInclusive, sync::Arc};
 
-use anyhow::bail;
+use anyhow::{anyhow, bail};
 use client::{Client, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
 use db::kvp::KEY_VALUE_STORE;
 use editor::{Editor, EditorEvent};
 use futures::AsyncReadExt;
 use gpui::{
-    div, red, rems, serde_json, AppContext, DismissEvent, Div, EventEmitter, FocusHandle,
-    FocusableView, Model, PromptLevel, Render, Task, View, ViewContext,
+    div, rems, serde_json, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView,
+    Model, PromptLevel, Render, Task, View, ViewContext,
 };
 use isahc::Request;
 use language::Buffer;
 use project::Project;
 use regex::Regex;
 use serde_derive::Serialize;
-use ui::{prelude::*, Button, ButtonStyle, Label, Tooltip};
+use ui::{prelude::*, Button, ButtonStyle, IconPosition, Tooltip};
 use util::ResultExt;
-use workspace::Workspace;
+use workspace::{ModalView, Workspace};
 
 use crate::{system_specs::SystemSpecs, GiveFeedback, OpenZedCommunityRepo};
 
+// For UI testing purposes
+const SEND_SUCCESS_IN_DEV_MODE: bool = true;
+
+// Temporary, until tests are in place
+#[cfg(debug_assertions)]
+const DEV_MODE: bool = true;
+
+#[cfg(not(debug_assertions))]
+const DEV_MODE: bool = false;
+
 const DATABASE_KEY_NAME: &str = "email_address";
 const EMAIL_REGEX: &str = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b";
-const FEEDBACK_CHAR_LIMIT: RangeInclusive<usize> = 10..=5000;
+const FEEDBACK_CHAR_LIMIT: RangeInclusive<i32> = 10..=5000;
 const FEEDBACK_SUBMISSION_ERROR_TEXT: &str =
     "Feedback failed to submit, see error log for details.";
 
@@ -41,8 +51,9 @@ pub struct FeedbackModal {
     system_specs: SystemSpecs,
     feedback_editor: View<Editor>,
     email_address_editor: View<Editor>,
-    character_count: usize,
-    pending_submission: bool,
+    awaiting_submission: bool,
+    user_submitted: bool,
+    character_count: i32,
 }
 
 impl FocusableView for FeedbackModal {
@@ -52,6 +63,25 @@ impl FocusableView for FeedbackModal {
 }
 impl EventEmitter<DismissEvent> for FeedbackModal {}
 
+impl ModalView for FeedbackModal {
+    fn dismiss(&mut self, cx: &mut ViewContext<Self>) -> Task<bool> {
+        if self.user_submitted {
+            self.set_user_submitted(false, cx);
+            return cx.spawn(|_, _| async { true });
+        }
+
+        let has_feedback = self.feedback_editor.read(cx).text_option(cx).is_some();
+
+        if !has_feedback {
+            return cx.spawn(|_, _| async { true });
+        }
+
+        let answer = cx.prompt(PromptLevel::Info, "Discard feedback?", &["Yes", "No"]);
+
+        cx.spawn(|_, _| async { answer.await.ok() == Some(0) })
+    }
+}
+
 impl FeedbackModal {
     pub fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
         let _handle = cx.view().downgrade();
@@ -104,6 +134,11 @@ impl FeedbackModal {
 
         let feedback_editor = cx.build_view(|cx| {
             let mut editor = Editor::for_buffer(buffer, Some(project.clone()), cx);
+            editor.set_placeholder_text(
+                "You can use markdown to organize your feedback wiht add code and links, or organize feedback.",
+                cx,
+            );
+            // editor.set_show_gutter(false, cx);
             editor.set_vertical_scroll_margin(5, cx);
             editor
         });
@@ -119,7 +154,7 @@ impl FeedbackModal {
                         .as_singleton()
                         .expect("Feedback editor is never a multi-buffer")
                         .read(cx)
-                        .len();
+                        .len() as i32;
                     cx.notify();
                 }
                 _ => {}
@@ -131,7 +166,8 @@ impl FeedbackModal {
             system_specs: system_specs.clone(),
             feedback_editor,
             email_address_editor,
-            pending_submission: false,
+            awaiting_submission: false,
+            user_submitted: false,
             character_count: 0,
         }
     }
@@ -163,37 +199,53 @@ impl FeedbackModal {
                     }
                 };
 
-                this.update(&mut cx, |feedback_editor, cx| {
-                    feedback_editor.set_pending_submission(true, cx);
+                this.update(&mut cx, |this, cx| {
+                    this.set_awaiting_submission(true, cx);
                 })
                 .log_err();
 
-                if let Err(error) =
-                    FeedbackModal::submit_feedback(&feedback_text, email, client, specs).await
-                {
-                    log::error!("{}", error);
-                    this.update(&mut cx, |feedback_editor, cx| {
-                        let prompt = cx.prompt(
-                            PromptLevel::Critical,
-                            FEEDBACK_SUBMISSION_ERROR_TEXT,
-                            &["OK"],
-                        );
-                        cx.spawn(|_, _cx| async move {
-                            prompt.await.ok();
+                let res =
+                    FeedbackModal::submit_feedback(&feedback_text, email, client, specs).await;
+
+                match res {
+                    Ok(_) => {
+                        this.update(&mut cx, |this, cx| {
+                            this.set_user_submitted(true, cx);
+                            cx.emit(DismissEvent)
+                        })
+                        .ok();
+                    }
+                    Err(error) => {
+                        log::error!("{}", error);
+                        this.update(&mut cx, |this, cx| {
+                            let prompt = cx.prompt(
+                                PromptLevel::Critical,
+                                FEEDBACK_SUBMISSION_ERROR_TEXT,
+                                &["OK"],
+                            );
+                            cx.spawn(|_, _cx| async move {
+                                prompt.await.ok();
+                            })
+                            .detach();
+                            this.set_awaiting_submission(false, cx);
                         })
-                        .detach();
-                        feedback_editor.set_pending_submission(false, cx);
-                    })
-                    .log_err();
+                        .log_err();
+                    }
                 }
             }
         })
         .detach();
+
         Task::ready(Ok(()))
     }
 
-    fn set_pending_submission(&mut self, pending_submission: bool, cx: &mut ViewContext<Self>) {
-        self.pending_submission = pending_submission;
+    fn set_awaiting_submission(&mut self, awaiting_submission: bool, cx: &mut ViewContext<Self>) {
+        self.awaiting_submission = awaiting_submission;
+        cx.notify();
+    }
+
+    fn set_user_submitted(&mut self, user_submitted: bool, cx: &mut ViewContext<Self>) {
+        self.user_submitted = user_submitted;
         cx.notify();
     }
 
@@ -203,6 +255,14 @@ impl FeedbackModal {
         zed_client: Arc<Client>,
         system_specs: SystemSpecs,
     ) -> anyhow::Result<()> {
+        if DEV_MODE {
+            if SEND_SUCCESS_IN_DEV_MODE {
+                return Ok(());
+            } else {
+                return Err(anyhow!("Error submitting feedback"));
+            }
+        }
+
         let feedback_endpoint = format!("{}/api/feedback", *ZED_SERVER_URL);
         let telemetry = zed_client.telemetry();
         let metrics_id = telemetry.metrics_id();
@@ -233,11 +293,8 @@ impl FeedbackModal {
     }
 
     // TODO: Escape button calls dismiss
-    // TODO: Should do same as hitting cancel / clicking outside of modal
-    //     Close immediately if no text in field
-    //     Ask to close if text in the field
     fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
-        cx.emit(DismissEvent);
+        cx.emit(DismissEvent)
     }
 }
 
@@ -251,132 +308,128 @@ impl Render for FeedbackModal {
         };
 
         let valid_character_count = FEEDBACK_CHAR_LIMIT.contains(&self.character_count);
-        let characters_remaining =
-            if valid_character_count || self.character_count > *FEEDBACK_CHAR_LIMIT.end() {
-                *FEEDBACK_CHAR_LIMIT.end() as i32 - self.character_count as i32
-            } else {
-                self.character_count as i32 - *FEEDBACK_CHAR_LIMIT.start() as i32
-            };
 
         let allow_submission =
-            valid_character_count && valid_email_address && !self.pending_submission;
+            valid_character_count && valid_email_address && !self.awaiting_submission;
 
-        let has_feedback = self.feedback_editor.read(cx).text_option(cx).is_some();
-
-        let submit_button_text = if self.pending_submission {
-            "Sending..."
+        let submit_button_text = if self.awaiting_submission {
+            "Submitting..."
         } else {
-            "Send Feedback"
+            "Submit"
         };
-        let dismiss = cx.listener(|_, _, cx| {
-            cx.emit(DismissEvent);
-        });
-        // TODO: get the "are you sure you want to dismiss?" prompt here working
-        let dismiss_prompt = cx.listener(|_, _, _| {
-            // let answer = cx.prompt(PromptLevel::Info, "Exit feedback?", &["Yes", "No"]);
-            // cx.spawn(|_, _| async move {
-            //     let answer = answer.await.ok();
-            //     if answer == Some(0) {
-            //         cx.emit(DismissEvent);
-            //     }
-            // })
-            // .detach();
-        });
+
         let open_community_repo =
             cx.listener(|_, _, cx| cx.dispatch_action(Box::new(OpenZedCommunityRepo)));
 
-        // TODO: Nate UI pass
+        // Moved this here because providing it inline breaks rustfmt
+        let provide_an_email_address =
+            "Provide an email address if you want us to be able to reply.";
+
         v_stack()
             .elevation_3(cx)
             .key_context("GiveFeedback")
             .on_action(cx.listener(Self::cancel))
             .min_w(rems(40.))
             .max_w(rems(96.))
-            .border()
-            .border_color(red())
-            .h(rems(40.))
-            .p_2()
-            .gap_2()
+            .h(rems(32.))
+            .p_4()
+            .gap_4()
+            .child(v_stack().child(
+                // TODO: Add Headline component to `ui2`
+                div().text_xl().child("Share Feedback"),
+            ))
             .child(
-                v_stack().child(
-                    div()
-                        .size_full()
-                        .child(Label::new("Give Feedback").color(Color::Default))
-                        .child(Label::new("This editor supports markdown").color(Color::Muted)),
-                ),
+                Label::new(if self.character_count < *FEEDBACK_CHAR_LIMIT.start() {
+                    format!(
+                        "Feedback must be at least {} characters.",
+                        FEEDBACK_CHAR_LIMIT.start()
+                    )
+                } else {
+                    format!(
+                        "Characters: {}",
+                        *FEEDBACK_CHAR_LIMIT.end() - self.character_count
+                    )
+                })
+                .color(if valid_character_count {
+                    Color::Success
+                } else {
+                    Color::Error
+                }),
             )
             .child(
                 div()
                     .flex_1()
                     .bg(cx.theme().colors().editor_background)
+                    .p_2()
                     .border()
+                    .rounded_md()
                     .border_color(cx.theme().colors().border)
                     .child(self.feedback_editor.clone()),
             )
-            .child(
-                div().child(
-                    Label::new(format!(
-                        "Characters: {}",
-                        characters_remaining
-                    ))
-                    .when_else(
-                        valid_character_count,
-                        |this| this.color(Color::Success),
-                        |this| this.color(Color::Error)
-                    )
-                ),
-            )
             .child(
                 div()
-                .bg(cx.theme().colors().editor_background)
-                .border()
-                .border_color(cx.theme().colors().border)
-                .child(self.email_address_editor.clone())
-            )
-            .child(
-                h_stack()
-                    .justify_between()
-                    .gap_1()
-                    .child(Button::new("community_repo", "Community Repo")
-                        .style(ButtonStyle::Filled)
-                        .color(Color::Muted)
-                        .on_click(open_community_repo)
+                    .child(
+                        h_stack()
+                            .bg(cx.theme().colors().editor_background)
+                            .p_2()
+                            .border()
+                            .rounded_md()
+                            .border_color(cx.theme().colors().border)
+                            .child(self.email_address_editor.clone()),
                     )
-                    .child(h_stack().justify_between().gap_1()
-                        .child(
-                            Button::new("cancel_feedback", "Cancel")
-                                .style(ButtonStyle::Subtle)
-                                .color(Color::Muted)
-                                // TODO: replicate this logic when clicking outside the modal
-                                // TODO: Will require somehow overriding the modal dismal default behavior
-                                .when_else(
-                                    has_feedback,
-                                    |this| this.on_click(dismiss_prompt),
-                                    |this| this.on_click(dismiss)
-                                )
-                        )
-                        .child(
-                            Button::new("send_feedback", submit_button_text)
-                                .color(Color::Accent)
-                                .style(ButtonStyle::Filled)
-                                // TODO: Ensure that while submitting, "Sending..." is shown and disable the button
-                                // TODO: If submit errors: show popup with error, don't close modal, set text back to "Send Feedback", and re-enable button
-                                // TODO: If submit is successful, close the modal
-                                .on_click(cx.listener(|this, _, cx| {
-                                    let _ = this.submit(cx);
-                                }))
-                                .tooltip(|cx| {
-                                    Tooltip::with_meta(
-                                        "Submit feedback to the Zed team.",
-                                        None,
-                                        "Provide an email address if you want us to be able to reply.",
-                                        cx,
+                    .child(
+                        h_stack()
+                            .justify_between()
+                            .gap_1()
+                            .child(
+                                Button::new("community_repo", "Community Repo")
+                                    .style(ButtonStyle::Transparent)
+                                    .icon(Icon::ExternalLink)
+                                    .icon_position(IconPosition::End)
+                                    .icon_size(IconSize::Small)
+                                    .on_click(open_community_repo),
+                            )
+                            .child(
+                                h_stack()
+                                    .gap_1()
+                                    .child(
+                                        Button::new("cancel_feedback", "Cancel")
+                                            .style(ButtonStyle::Subtle)
+                                            .color(Color::Muted)
+                                            .on_click(cx.listener(move |_, _, cx| {
+                                                cx.spawn(|this, mut cx| async move {
+                                                    this.update(&mut cx, |_, cx| {
+                                                        cx.emit(DismissEvent)
+                                                    })
+                                                    .ok();
+                                                })
+                                                .detach();
+                                            })),
                                     )
-                                })
-                                .when(!allow_submission, |this| this.disabled(true))
-                        ),
-                    )
-
+                                    .child(
+                                        Button::new("send_feedback", submit_button_text)
+                                            .color(Color::Accent)
+                                            .style(ButtonStyle::Filled)
+                                            // TODO: Ensure that while submitting, "Sending..." is shown and disable the button
+                                            // TODO: If submit errors: show popup with error, don't close modal, set text back to "Submit", and re-enable button
+                                            .on_click(cx.listener(|this, _, cx| {
+                                                this.submit(cx).detach();
+                                            }))
+                                            .tooltip(move |cx| {
+                                                Tooltip::with_meta(
+                                                    "Submit feedback to the Zed team.",
+                                                    None,
+                                                    provide_an_email_address,
+                                                    cx,
+                                                )
+                                            })
+                                            .when(!allow_submission, |this| this.disabled(true)),
+                                    ),
+                            ),
+                    ),
             )
     }
 }
+
+// TODO: Maybe store email address whenever the modal is closed, versus just on submit, so users can remove it if they want without submitting
+// TODO: Testing of various button states, dismissal prompts, etc.

crates/file_finder2/src/file_finder.rs 🔗

@@ -17,9 +17,11 @@ use std::{
 use text::Point;
 use ui::{prelude::*, HighlightedLabel, ListItem};
 use util::{paths::PathLikeWithPosition, post_inc, ResultExt};
-use workspace::Workspace;
+use workspace::{ModalView, Workspace};
 
-actions!(Toggle);
+actions!(file_finder, [Toggle]);
+
+impl ModalView for FileFinder {}
 
 pub struct FileFinder {
     picker: View<Picker<FileFinderDelegate>>,

crates/go_to_line2/src/go_to_line.rs 🔗

@@ -8,8 +8,9 @@ use text::{Bias, Point};
 use theme::ActiveTheme;
 use ui::{h_stack, prelude::*, v_stack, Label};
 use util::paths::FILE_ROW_COLUMN_DELIMITER;
+use workspace::ModalView;
 
-actions!(Toggle);
+actions!(go_to_line, [Toggle]);
 
 pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(GoToLine::register).detach();
@@ -23,6 +24,8 @@ pub struct GoToLine {
     _subscriptions: Vec<Subscription>,
 }
 
+impl ModalView for GoToLine {}
+
 impl FocusableView for GoToLine {
     fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
         self.line_editor.focus_handle(cx)

crates/gpui2/docs/key_dispatch.md 🔗

@@ -22,7 +22,7 @@ Actions are frequently unit structs, for which we have a macro. The above could
 
 ```rust
 mod menu {
-    actions!(MoveUp, MoveDown);
+    actions!(gpui, [MoveUp, MoveDown]);
 }
 ```
 

crates/gpui2/src/action.rs 🔗

@@ -3,34 +3,33 @@ use anyhow::{anyhow, Context, Result};
 use collections::HashMap;
 pub use no_action::NoAction;
 use serde_json::json;
-use std::{
-    any::{Any, TypeId},
-    ops::Deref,
-};
+use std::any::{Any, TypeId};
 
 /// Actions are used to implement keyboard-driven UI.
 /// When you declare an action, you can bind keys to the action in the keymap and
 /// listeners for that action in the element tree.
 ///
 /// To declare a list of simple actions, you can use the actions! macro, which defines a simple unit struct
-/// action for each listed action name.
+/// action for each listed action name in the given namespace.
 /// ```rust
-/// actions!(MoveUp, MoveDown, MoveLeft, MoveRight, Newline);
+/// actions!(editor, [MoveUp, MoveDown, MoveLeft, MoveRight, Newline]);
 /// ```
-/// More complex data types can also be actions. If you annotate your type with the action derive macro
-/// it will be implemented and registered automatically.
+/// More complex data types can also be actions, providing they implement Clone, PartialEq,
+/// and serde_derive::Deserialize.
+/// Use `impl_actions!` to automatically implement the action in the given namespace.
 /// ```
-/// #[derive(Clone, PartialEq, serde_derive::Deserialize, Action)]
+/// #[derive(Clone, PartialEq, serde_derive::Deserialize)]
 /// pub struct SelectNext {
 ///     pub replace_newest: bool,
 /// }
+/// impl_actions!(editor, [SelectNext]);
+/// ```
 ///
 /// If you want to control the behavior of the action trait manually, you can use the lower-level `#[register_action]`
 /// macro, which only generates the code needed to register your action before `main`.
 ///
 /// ```
-/// #[gpui::register_action]
-/// #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::fmt::Debug)]
+/// #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone)]
 /// pub struct Paste {
 ///     pub content: SharedString,
 /// }
@@ -38,6 +37,7 @@ use std::{
 /// impl gpui::Action for Paste {
 ///      ///...
 /// }
+/// register_action!(Paste);
 /// ```
 pub trait Action: 'static {
     fn boxed_clone(&self) -> Box<dyn Action>;
@@ -56,7 +56,7 @@ pub trait Action: 'static {
 impl std::fmt::Debug for dyn Action {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("dyn Action")
-            .field("type_name", &self.name())
+            .field("name", &self.name())
             .finish()
     }
 }
@@ -115,7 +115,7 @@ impl ActionRegistry {
         for builder in __GPUI_ACTIONS {
             let action = builder();
             //todo(remove)
-            let name: SharedString = remove_the_2(action.name).into();
+            let name: SharedString = action.name.into();
             self.builders_by_name.insert(name.clone(), action.build);
             self.names_by_type_id.insert(action.type_id, name.clone());
             self.all_names.push(name);
@@ -139,11 +139,9 @@ impl ActionRegistry {
         name: &str,
         params: Option<serde_json::Value>,
     ) -> Result<Box<dyn Action>> {
-        //todo(remove)
-        let name = remove_the_2(name);
         let build_action = self
             .builders_by_name
-            .get(name.deref())
+            .get(name)
             .ok_or_else(|| anyhow!("no action type registered for {}", name))?;
         (build_action)(params.unwrap_or_else(|| json!({})))
             .with_context(|| format!("Attempting to build action {}", name))
@@ -155,36 +153,88 @@ impl ActionRegistry {
 }
 
 /// Defines unit structs that can be used as actions.
-/// To use more complex data types as actions, annotate your type with the #[action] macro.
+/// To use more complex data types as actions, use `impl_actions!`
 #[macro_export]
 macro_rules! actions {
-    () => {};
-
-    ( $name:ident ) => {
-        #[derive(::std::cmp::PartialEq, ::std::clone::Clone, ::std::default::Default, gpui::serde_derive::Deserialize, gpui::Action)]
-        #[serde(crate = "gpui::serde")]
-        pub struct $name;
+    ($namespace:path, [ $($name:ident),* $(,)? ]) => {
+        $(
+            #[derive(::std::cmp::PartialEq, ::std::clone::Clone, ::std::default::Default, gpui::serde_derive::Deserialize)]
+            #[serde(crate = "gpui::serde")]
+            pub struct $name;
+
+            gpui::__impl_action!($namespace, $name,
+                fn build(_: gpui::serde_json::Value) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
+                    Ok(Box::new(Self))
+                }
+            );
+
+            gpui::register_action!($name);
+        )*
     };
+}
 
-    ( $name:ident, $($rest:tt)* ) => {
-        actions!($name);
-        actions!($($rest)*);
+/// Implements the Action trait for any struct that implements Clone, Default, PartialEq, and serde_deserialize::Deserialize
+#[macro_export]
+macro_rules! impl_actions {
+    ($namespace:path, [ $($name:ident),* $(,)? ]) => {
+        $(
+            gpui::__impl_action!($namespace, $name,
+                fn build(value: gpui::serde_json::Value) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>> {
+                    Ok(std::boxed::Box::new(gpui::serde_json::from_value::<Self>(value)?))
+                }
+            );
+        )*
     };
 }
 
-//todo!(remove)
-pub fn remove_the_2(action_name: &str) -> String {
-    let mut separator_matches = action_name.rmatch_indices("::");
-    separator_matches.next().unwrap();
-    let name_start_ix = separator_matches.next().map_or(0, |(ix, _)| ix + 2);
-    // todo!() remove the 2 replacement when migration is done
-    action_name[name_start_ix..]
-        .replace("2::", "::")
-        .to_string()
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __impl_action {
+    ($namespace:path, $name:ident, $build:item) => {
+        impl gpui::Action for $name {
+            fn name(&self) -> &'static str
+            {
+                concat!(
+                    stringify!($namespace),
+                    "::",
+                    stringify!($name),
+                )
+            }
+
+            // todo!() why is this needed in addition to name?
+            fn debug_name() -> &'static str
+            where
+                Self: ::std::marker::Sized
+            {
+                concat!(
+                    stringify!($namespace),
+                    "::",
+                    stringify!($name),
+                )
+            }
+
+            $build
+
+            fn partial_eq(&self, action: &dyn gpui::Action) -> bool {
+                action
+                    .as_any()
+                    .downcast_ref::<Self>()
+                    .map_or(false, |a| self == a)
+            }
+
+            fn boxed_clone(&self) ->  std::boxed::Box<dyn gpui::Action> {
+                ::std::boxed::Box::new(self.clone())
+            }
+
+            fn as_any(&self) -> &dyn ::std::any::Any {
+                self
+            }
+        }
+    };
 }
 
 mod no_action {
     use crate as gpui;
 
-    actions!(NoAction);
+    actions!(zed, [NoAction]);
 }

crates/gpui2/src/app.rs 🔗

@@ -13,6 +13,7 @@ use smallvec::SmallVec;
 use smol::future::FutureExt;
 #[cfg(any(test, feature = "test-support"))]
 pub use test_context::*;
+use time::UtcOffset;
 
 use crate::{
     current_platform, image_cache::ImageCache, init_app_menus, Action, ActionRegistry, Any,
@@ -536,6 +537,10 @@ impl AppContext {
         self.platform.restart()
     }
 
+    pub fn local_timezone(&self) -> UtcOffset {
+        self.platform.local_timezone()
+    }
+
     pub(crate) fn push_effect(&mut self, effect: Effect) {
         match &effect {
             Effect::Notify { emitter } => {
@@ -1110,6 +1115,10 @@ impl AppContext {
             }
         }
     }
+
+    pub fn has_active_drag(&self) -> bool {
+        self.active_drag.is_some()
+    }
 }
 
 impl Context for AppContext {

crates/gpui2/src/element.rs 🔗

@@ -69,24 +69,6 @@ pub trait IntoElement: Sized {
         self.map(|this| if condition { then(this) } else { this })
     }
 
-    fn when_else(
-        self,
-        condition: bool,
-        then: impl FnOnce(Self) -> Self,
-        otherwise: impl FnOnce(Self) -> Self,
-    ) -> Self
-    where
-        Self: Sized,
-    {
-        self.map(|this| {
-            if condition {
-                then(this)
-            } else {
-                otherwise(this)
-            }
-        })
-    }
-
     fn when_some<T>(self, option: Option<T>, then: impl FnOnce(Self, T) -> Self) -> Self
     where
         Self: Sized,

crates/gpui2/src/elements/list.rs 🔗

@@ -0,0 +1,496 @@
+use crate::{
+    px, AnyElement, AvailableSpace, BorrowAppContext, DispatchPhase, Element, IntoElement, Pixels,
+    Point, ScrollWheelEvent, Size, Style, StyleRefinement, Styled, WindowContext,
+};
+use collections::VecDeque;
+use refineable::Refineable as _;
+use std::{cell::RefCell, ops::Range, rc::Rc};
+use sum_tree::{Bias, SumTree};
+
+pub fn list(state: ListState) -> List {
+    List {
+        state,
+        style: StyleRefinement::default(),
+    }
+}
+
+pub struct List {
+    state: ListState,
+    style: StyleRefinement,
+}
+
+#[derive(Clone)]
+pub struct ListState(Rc<RefCell<StateInner>>);
+
+struct StateInner {
+    last_layout_width: Option<Pixels>,
+    render_item: Box<dyn FnMut(usize, &mut WindowContext) -> AnyElement>,
+    items: SumTree<ListItem>,
+    logical_scroll_top: Option<ListOffset>,
+    alignment: ListAlignment,
+    overdraw: Pixels,
+    #[allow(clippy::type_complexity)]
+    scroll_handler: Option<Box<dyn FnMut(&ListScrollEvent, &mut WindowContext)>>,
+}
+
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum ListAlignment {
+    Top,
+    Bottom,
+}
+
+pub struct ListScrollEvent {
+    pub visible_range: Range<usize>,
+    pub count: usize,
+}
+
+#[derive(Clone)]
+enum ListItem {
+    Unrendered,
+    Rendered { height: Pixels },
+}
+
+#[derive(Clone, Debug, Default, PartialEq)]
+struct ListItemSummary {
+    count: usize,
+    rendered_count: usize,
+    unrendered_count: usize,
+    height: Pixels,
+}
+
+#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
+struct Count(usize);
+
+#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
+struct RenderedCount(usize);
+
+#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
+struct UnrenderedCount(usize);
+
+#[derive(Clone, Debug, Default)]
+struct Height(Pixels);
+
+impl ListState {
+    pub fn new<F>(
+        element_count: usize,
+        orientation: ListAlignment,
+        overdraw: Pixels,
+        render_item: F,
+    ) -> Self
+    where
+        F: 'static + FnMut(usize, &mut WindowContext) -> AnyElement,
+    {
+        let mut items = SumTree::new();
+        items.extend((0..element_count).map(|_| ListItem::Unrendered), &());
+        Self(Rc::new(RefCell::new(StateInner {
+            last_layout_width: None,
+            render_item: Box::new(render_item),
+            items,
+            logical_scroll_top: None,
+            alignment: orientation,
+            overdraw,
+            scroll_handler: None,
+        })))
+    }
+
+    pub fn reset(&self, element_count: usize) {
+        let state = &mut *self.0.borrow_mut();
+        state.logical_scroll_top = None;
+        state.items = SumTree::new();
+        state
+            .items
+            .extend((0..element_count).map(|_| ListItem::Unrendered), &());
+    }
+
+    pub fn item_count(&self) -> usize {
+        self.0.borrow().items.summary().count
+    }
+
+    pub fn splice(&self, old_range: Range<usize>, count: usize) {
+        let state = &mut *self.0.borrow_mut();
+
+        if let Some(ListOffset {
+            item_ix,
+            offset_in_item,
+        }) = state.logical_scroll_top.as_mut()
+        {
+            if old_range.contains(item_ix) {
+                *item_ix = old_range.start;
+                *offset_in_item = px(0.);
+            } else if old_range.end <= *item_ix {
+                *item_ix = *item_ix - (old_range.end - old_range.start) + count;
+            }
+        }
+
+        let mut old_heights = state.items.cursor::<Count>();
+        let mut new_heights = old_heights.slice(&Count(old_range.start), Bias::Right, &());
+        old_heights.seek_forward(&Count(old_range.end), Bias::Right, &());
+
+        new_heights.extend((0..count).map(|_| ListItem::Unrendered), &());
+        new_heights.append(old_heights.suffix(&()), &());
+        drop(old_heights);
+        state.items = new_heights;
+    }
+
+    pub fn set_scroll_handler(
+        &self,
+        handler: impl FnMut(&ListScrollEvent, &mut WindowContext) + 'static,
+    ) {
+        self.0.borrow_mut().scroll_handler = Some(Box::new(handler))
+    }
+
+    pub fn logical_scroll_top(&self) -> ListOffset {
+        self.0.borrow().logical_scroll_top()
+    }
+
+    pub fn scroll_to(&self, mut scroll_top: ListOffset) {
+        let state = &mut *self.0.borrow_mut();
+        let item_count = state.items.summary().count;
+        if scroll_top.item_ix >= item_count {
+            scroll_top.item_ix = item_count;
+            scroll_top.offset_in_item = px(0.);
+        }
+        state.logical_scroll_top = Some(scroll_top);
+    }
+}
+
+impl StateInner {
+    fn visible_range(&self, height: Pixels, scroll_top: &ListOffset) -> Range<usize> {
+        let mut cursor = self.items.cursor::<ListItemSummary>();
+        cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
+        let start_y = cursor.start().height + scroll_top.offset_in_item;
+        cursor.seek_forward(&Height(start_y + height), Bias::Left, &());
+        scroll_top.item_ix..cursor.start().count + 1
+    }
+
+    fn scroll(
+        &mut self,
+        scroll_top: &ListOffset,
+        height: Pixels,
+        delta: Point<Pixels>,
+        cx: &mut WindowContext,
+    ) {
+        let scroll_max = (self.items.summary().height - height).max(px(0.));
+        let new_scroll_top = (self.scroll_top(scroll_top) - delta.y)
+            .max(px(0.))
+            .min(scroll_max);
+
+        if self.alignment == ListAlignment::Bottom && new_scroll_top == scroll_max {
+            self.logical_scroll_top = None;
+        } else {
+            let mut cursor = self.items.cursor::<ListItemSummary>();
+            cursor.seek(&Height(new_scroll_top), Bias::Right, &());
+            let item_ix = cursor.start().count;
+            let offset_in_item = new_scroll_top - cursor.start().height;
+            self.logical_scroll_top = Some(ListOffset {
+                item_ix,
+                offset_in_item,
+            });
+        }
+
+        if self.scroll_handler.is_some() {
+            let visible_range = self.visible_range(height, scroll_top);
+            self.scroll_handler.as_mut().unwrap()(
+                &ListScrollEvent {
+                    visible_range,
+                    count: self.items.summary().count,
+                },
+                cx,
+            );
+        }
+
+        cx.notify();
+    }
+
+    fn logical_scroll_top(&self) -> ListOffset {
+        self.logical_scroll_top
+            .unwrap_or_else(|| match self.alignment {
+                ListAlignment::Top => ListOffset {
+                    item_ix: 0,
+                    offset_in_item: px(0.),
+                },
+                ListAlignment::Bottom => ListOffset {
+                    item_ix: self.items.summary().count,
+                    offset_in_item: px(0.),
+                },
+            })
+    }
+
+    fn scroll_top(&self, logical_scroll_top: &ListOffset) -> Pixels {
+        let mut cursor = self.items.cursor::<ListItemSummary>();
+        cursor.seek(&Count(logical_scroll_top.item_ix), Bias::Right, &());
+        cursor.start().height + logical_scroll_top.offset_in_item
+    }
+}
+
+impl std::fmt::Debug for ListItem {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Self::Unrendered => write!(f, "Unrendered"),
+            Self::Rendered { height, .. } => {
+                f.debug_struct("Rendered").field("height", height).finish()
+            }
+        }
+    }
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct ListOffset {
+    pub item_ix: usize,
+    pub offset_in_item: Pixels,
+}
+
+impl Element for List {
+    type State = ();
+
+    fn layout(
+        &mut self,
+        _state: Option<Self::State>,
+        cx: &mut crate::WindowContext,
+    ) -> (crate::LayoutId, Self::State) {
+        let mut style = Style::default();
+        style.refine(&self.style);
+        let layout_id = cx.with_text_style(style.text_style().cloned(), |cx| {
+            cx.request_layout(&style, None)
+        });
+        (layout_id, ())
+    }
+
+    fn paint(
+        self,
+        bounds: crate::Bounds<crate::Pixels>,
+        _state: &mut Self::State,
+        cx: &mut crate::WindowContext,
+    ) {
+        let state = &mut *self.state.0.borrow_mut();
+
+        // If the width of the list has changed, invalidate all cached item heights
+        if state.last_layout_width != Some(bounds.size.width) {
+            state.items = SumTree::from_iter(
+                (0..state.items.summary().count).map(|_| ListItem::Unrendered),
+                &(),
+            )
+        }
+
+        let old_items = state.items.clone();
+        let mut measured_items = VecDeque::new();
+        let mut item_elements = VecDeque::new();
+        let mut rendered_height = px(0.);
+        let mut scroll_top = state.logical_scroll_top();
+
+        let available_item_space = Size {
+            width: AvailableSpace::Definite(bounds.size.width),
+            height: AvailableSpace::MinContent,
+        };
+
+        // Render items after the scroll top, including those in the trailing overdraw
+        let mut cursor = old_items.cursor::<Count>();
+        cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
+        for (ix, item) in cursor.by_ref().enumerate() {
+            let visible_height = rendered_height - scroll_top.offset_in_item;
+            if visible_height >= bounds.size.height + state.overdraw {
+                break;
+            }
+
+            // Use the previously cached height if available
+            let mut height = if let ListItem::Rendered { height } = item {
+                Some(*height)
+            } else {
+                None
+            };
+
+            // If we're within the visible area or the height wasn't cached, render and measure the item's element
+            if visible_height < bounds.size.height || height.is_none() {
+                let mut element = (state.render_item)(scroll_top.item_ix + ix, cx);
+                let element_size = element.measure(available_item_space, cx);
+                height = Some(element_size.height);
+                if visible_height < bounds.size.height {
+                    item_elements.push_back(element);
+                }
+            }
+
+            let height = height.unwrap();
+            rendered_height += height;
+            measured_items.push_back(ListItem::Rendered { height });
+        }
+
+        // Prepare to start walking upward from the item at the scroll top.
+        cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
+
+        // If the rendered items do not fill the visible region, then adjust
+        // the scroll top upward.
+        if rendered_height - scroll_top.offset_in_item < bounds.size.height {
+            while rendered_height < bounds.size.height {
+                cursor.prev(&());
+                if cursor.item().is_some() {
+                    let mut element = (state.render_item)(cursor.start().0, cx);
+                    let element_size = element.measure(available_item_space, cx);
+
+                    rendered_height += element_size.height;
+                    measured_items.push_front(ListItem::Rendered {
+                        height: element_size.height,
+                    });
+                    item_elements.push_front(element)
+                } else {
+                    break;
+                }
+            }
+
+            scroll_top = ListOffset {
+                item_ix: cursor.start().0,
+                offset_in_item: rendered_height - bounds.size.height,
+            };
+
+            match state.alignment {
+                ListAlignment::Top => {
+                    scroll_top.offset_in_item = scroll_top.offset_in_item.max(px(0.));
+                    state.logical_scroll_top = Some(scroll_top);
+                }
+                ListAlignment::Bottom => {
+                    scroll_top = ListOffset {
+                        item_ix: cursor.start().0,
+                        offset_in_item: rendered_height - bounds.size.height,
+                    };
+                    state.logical_scroll_top = None;
+                }
+            };
+        }
+
+        // Measure items in the leading overdraw
+        let mut leading_overdraw = scroll_top.offset_in_item;
+        while leading_overdraw < state.overdraw {
+            cursor.prev(&());
+            if let Some(item) = cursor.item() {
+                let height = if let ListItem::Rendered { height } = item {
+                    *height
+                } else {
+                    let mut element = (state.render_item)(cursor.start().0, cx);
+                    element.measure(available_item_space, cx).height
+                };
+
+                leading_overdraw += height;
+                measured_items.push_front(ListItem::Rendered { height });
+            } else {
+                break;
+            }
+        }
+
+        let measured_range = cursor.start().0..(cursor.start().0 + measured_items.len());
+        let mut cursor = old_items.cursor::<Count>();
+        let mut new_items = cursor.slice(&Count(measured_range.start), Bias::Right, &());
+        new_items.extend(measured_items, &());
+        cursor.seek(&Count(measured_range.end), Bias::Right, &());
+        new_items.append(cursor.suffix(&()), &());
+
+        // Paint the visible items
+        let mut item_origin = bounds.origin;
+        item_origin.y -= scroll_top.offset_in_item;
+        for mut item_element in item_elements {
+            let item_height = item_element.measure(available_item_space, cx).height;
+            item_element.draw(item_origin, available_item_space, cx);
+            item_origin.y += item_height;
+        }
+
+        state.items = new_items;
+        state.last_layout_width = Some(bounds.size.width);
+
+        let list_state = self.state.clone();
+        let height = bounds.size.height;
+        cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| {
+            if phase == DispatchPhase::Bubble {
+                list_state.0.borrow_mut().scroll(
+                    &scroll_top,
+                    height,
+                    event.delta.pixel_delta(px(20.)),
+                    cx,
+                )
+            }
+        });
+    }
+}
+
+impl IntoElement for List {
+    type Element = Self;
+
+    fn element_id(&self) -> Option<crate::ElementId> {
+        None
+    }
+
+    fn into_element(self) -> Self::Element {
+        self
+    }
+}
+
+impl Styled for List {
+    fn style(&mut self) -> &mut StyleRefinement {
+        &mut self.style
+    }
+}
+
+impl sum_tree::Item for ListItem {
+    type Summary = ListItemSummary;
+
+    fn summary(&self) -> Self::Summary {
+        match self {
+            ListItem::Unrendered => ListItemSummary {
+                count: 1,
+                rendered_count: 0,
+                unrendered_count: 1,
+                height: px(0.),
+            },
+            ListItem::Rendered { height } => ListItemSummary {
+                count: 1,
+                rendered_count: 1,
+                unrendered_count: 0,
+                height: *height,
+            },
+        }
+    }
+}
+
+impl sum_tree::Summary for ListItemSummary {
+    type Context = ();
+
+    fn add_summary(&mut self, summary: &Self, _: &()) {
+        self.count += summary.count;
+        self.rendered_count += summary.rendered_count;
+        self.unrendered_count += summary.unrendered_count;
+        self.height += summary.height;
+    }
+}
+
+impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Count {
+    fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) {
+        self.0 += summary.count;
+    }
+}
+
+impl<'a> sum_tree::Dimension<'a, ListItemSummary> for RenderedCount {
+    fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) {
+        self.0 += summary.rendered_count;
+    }
+}
+
+impl<'a> sum_tree::Dimension<'a, ListItemSummary> for UnrenderedCount {
+    fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) {
+        self.0 += summary.unrendered_count;
+    }
+}
+
+impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Height {
+    fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) {
+        self.0 += summary.height;
+    }
+}
+
+impl<'a> sum_tree::SeekTarget<'a, ListItemSummary, ListItemSummary> for Count {
+    fn cmp(&self, other: &ListItemSummary, _: &()) -> std::cmp::Ordering {
+        self.0.partial_cmp(&other.count).unwrap()
+    }
+}
+
+impl<'a> sum_tree::SeekTarget<'a, ListItemSummary, ListItemSummary> for Height {
+    fn cmp(&self, other: &ListItemSummary, _: &()) -> std::cmp::Ordering {
+        self.0.partial_cmp(&other.height).unwrap()
+    }
+}

crates/gpui2/src/elements/mod.rs 🔗

@@ -1,6 +1,7 @@
 mod canvas;
 mod div;
 mod img;
+mod list;
 mod overlay;
 mod svg;
 mod text;
@@ -9,6 +10,7 @@ mod uniform_list;
 pub use canvas::*;
 pub use div::*;
 pub use img::*;
+pub use list::*;
 pub use overlay::*;
 pub use svg::*;
 pub use text::*;

crates/gpui2/src/elements/uniform_list.rs 🔗

@@ -131,7 +131,7 @@ impl Element for UniformList {
                                         }
                                     });
                             let height = match available_space.height {
-                                AvailableSpace::Definite(x) => desired_height.min(x),
+                                AvailableSpace::Definite(height) => desired_height.min(height),
                                 AvailableSpace::MinContent | AvailableSpace::MaxContent => {
                                     desired_height
                                 }

crates/gpui2/src/gpui2.rs 🔗

@@ -1,6 +1,7 @@
 #[macro_use]
 mod action;
 mod app;
+
 mod assets;
 mod color;
 mod element;
@@ -15,6 +16,7 @@ mod keymap;
 mod platform;
 pub mod prelude;
 mod scene;
+mod shared_string;
 mod style;
 mod styled;
 mod subscription;
@@ -57,6 +59,7 @@ pub use scene::*;
 pub use serde;
 pub use serde_derive;
 pub use serde_json;
+pub use shared_string::*;
 pub use smallvec;
 pub use smol::Timer;
 pub use style::*;
@@ -71,10 +74,9 @@ pub use util::arc_cow::ArcCow;
 pub use view::*;
 pub use window::*;
 
-use derive_more::{Deref, DerefMut};
 use std::{
     any::{Any, TypeId},
-    borrow::{Borrow, BorrowMut},
+    borrow::BorrowMut,
 };
 use taffy::TaffyLayoutEngine;
 
@@ -209,42 +211,3 @@ impl<T> Flatten<T> for Result<T> {
         self
     }
 }
-
-#[derive(Deref, DerefMut, Eq, PartialEq, Hash, Clone)]
-pub struct SharedString(ArcCow<'static, str>);
-
-impl Default for SharedString {
-    fn default() -> Self {
-        Self(ArcCow::Owned("".into()))
-    }
-}
-
-impl AsRef<str> for SharedString {
-    fn as_ref(&self) -> &str {
-        &self.0
-    }
-}
-
-impl Borrow<str> for SharedString {
-    fn borrow(&self) -> &str {
-        self.as_ref()
-    }
-}
-
-impl std::fmt::Debug for SharedString {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-impl std::fmt::Display for SharedString {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.0.as_ref())
-    }
-}
-
-impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
-    fn from(value: T) -> Self {
-        Self(value.into())
-    }
-}

crates/gpui2/src/interactive.rs 🔗

@@ -193,6 +193,12 @@ impl Deref for MouseExitEvent {
 #[derive(Debug, Clone, Default)]
 pub struct ExternalPaths(pub(crate) SmallVec<[PathBuf; 2]>);
 
+impl ExternalPaths {
+    pub fn paths(&self) -> &[PathBuf] {
+        &self.0
+    }
+}
+
 impl Render for ExternalPaths {
     type Element = Div;
 
@@ -296,7 +302,7 @@ mod test {
         focus_handle: FocusHandle,
     }
 
-    actions!(TestAction);
+    actions!(test, [TestAction]);
 
     impl Render for TestView {
         type Element = Stateful<Div>;

crates/gpui2/src/key_dispatch.rs 🔗

@@ -149,13 +149,19 @@ impl DispatchTree {
     }
 
     pub fn available_actions(&self, target: DispatchNodeId) -> Vec<Box<dyn Action>> {
-        let mut actions = Vec::new();
+        let mut actions = Vec::<Box<dyn Action>>::new();
         for node_id in self.dispatch_path(target) {
             let node = &self.nodes[node_id.0];
             for DispatchActionListener { action_type, .. } in &node.action_listeners {
-                // Intentionally silence these errors without logging.
-                // If an action cannot be built by default, it's not available.
-                actions.extend(self.action_registry.build_action_type(action_type).ok());
+                if let Err(ix) = actions.binary_search_by_key(action_type, |a| a.as_any().type_id())
+                {
+                    // Intentionally silence these errors without logging.
+                    // If an action cannot be built by default, it's not available.
+                    let action = self.action_registry.build_action_type(action_type).ok();
+                    if let Some(action) = action {
+                        actions.insert(ix, action);
+                    }
+                }
             }
         }
         actions

crates/gpui2/src/keymap/context.rs 🔗

@@ -293,11 +293,13 @@ mod tests {
     #[test]
     fn test_actions_definition() {
         {
-            actions!(A, B, C, D, E, F, G);
+            actions!(test, [A, B, C, D, E, F, G]);
         }
 
         {
             actions!(
+                test,
+                [
                 A,
                 B,
                 C,
@@ -305,6 +307,7 @@ mod tests {
                 E,
                 F,
                 G, // Don't wrap, test the trailing comma
+            ]
             );
         }
     }

crates/gpui2/src/platform/mac/metal_renderer.rs 🔗

@@ -325,7 +325,7 @@ impl MetalRenderer {
                 .entry(tile.texture_id)
                 .or_insert(Vec::new())
                 .extend(path.vertices.iter().map(|vertex| PathVertex {
-                    xy_position: vertex.xy_position - path.bounds.origin
+                    xy_position: vertex.xy_position - clipped_bounds.origin
                         + tile.bounds.origin.map(Into::into),
                     st_position: vertex.st_position,
                     content_mask: ContentMask {
@@ -544,9 +544,10 @@ impl MetalRenderer {
             if let Some((path, tile)) = paths_and_tiles.peek() {
                 if prev_texture_id.map_or(true, |texture_id| texture_id == tile.texture_id) {
                     prev_texture_id = Some(tile.texture_id);
+                    let origin = path.bounds.intersect(&path.content_mask.bounds).origin;
                     sprites.push(PathSprite {
                         bounds: Bounds {
-                            origin: path.bounds.origin.map(|p| p.floor()),
+                            origin: origin.map(|p| p.floor()),
                             size: tile.bounds.size.map(Into::into),
                         },
                         color: path.color,

crates/gpui2/src/shared_string.rs 🔗

@@ -0,0 +1,101 @@
+use derive_more::{Deref, DerefMut};
+use serde::{Deserialize, Serialize};
+use std::{borrow::Borrow, sync::Arc};
+use util::arc_cow::ArcCow;
+
+#[derive(Deref, DerefMut, Eq, PartialEq, Hash, Clone)]
+pub struct SharedString(ArcCow<'static, str>);
+
+impl Default for SharedString {
+    fn default() -> Self {
+        Self(ArcCow::Owned("".into()))
+    }
+}
+
+impl AsRef<str> for SharedString {
+    fn as_ref(&self) -> &str {
+        &self.0
+    }
+}
+
+impl Borrow<str> for SharedString {
+    fn borrow(&self) -> &str {
+        self.as_ref()
+    }
+}
+
+impl std::fmt::Debug for SharedString {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+impl std::fmt::Display for SharedString {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.0.as_ref())
+    }
+}
+
+impl PartialEq<String> for SharedString {
+    fn eq(&self, other: &String) -> bool {
+        self.as_ref() == other
+    }
+}
+
+impl PartialEq<SharedString> for String {
+    fn eq(&self, other: &SharedString) -> bool {
+        self == other.as_ref()
+    }
+}
+
+impl PartialEq<str> for SharedString {
+    fn eq(&self, other: &str) -> bool {
+        self.as_ref() == other
+    }
+}
+
+impl<'a> PartialEq<&'a str> for SharedString {
+    fn eq(&self, other: &&'a str) -> bool {
+        self.as_ref() == *other
+    }
+}
+
+impl Into<Arc<str>> for SharedString {
+    fn into(self) -> Arc<str> {
+        match self.0 {
+            ArcCow::Borrowed(borrowed) => Arc::from(borrowed),
+            ArcCow::Owned(owned) => owned.clone(),
+        }
+    }
+}
+
+impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
+    fn from(value: T) -> Self {
+        Self(value.into())
+    }
+}
+
+impl Into<String> for SharedString {
+    fn into(self) -> String {
+        self.0.to_string()
+    }
+}
+
+impl Serialize for SharedString {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: serde::Serializer,
+    {
+        serializer.serialize_str(self.as_ref())
+    }
+}
+
+impl<'de> Deserialize<'de> for SharedString {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: serde::Deserializer<'de>,
+    {
+        let s = String::deserialize(deserializer)?;
+        Ok(SharedString::from(s))
+    }
+}

crates/gpui2/src/styled.rs 🔗

@@ -245,6 +245,13 @@ pub trait Styled: Sized {
         self
     }
 
+    /// Sets the flex direction of the element to `column-reverse`.
+    /// [Docs](https://tailwindcss.com/docs/flex-direction#column-reverse)
+    fn flex_col_reverse(mut self) -> Self {
+        self.style().flex_direction = Some(FlexDirection::ColumnReverse);
+        self
+    }
+
     /// Sets the flex direction of the element to `row`.
     /// [Docs](https://tailwindcss.com/docs/flex-direction#row)
     fn flex_row(mut self) -> Self {
@@ -252,6 +259,13 @@ pub trait Styled: Sized {
         self
     }
 
+    /// Sets the flex direction of the element to `row-reverse`.
+    /// [Docs](https://tailwindcss.com/docs/flex-direction#row-reverse)
+    fn flex_row_reverse(mut self) -> Self {
+        self.style().flex_direction = Some(FlexDirection::RowReverse);
+        self
+    }
+
     /// Sets the element to allow a flex item to grow and shrink as needed, ignoring its initial size.
     /// [Docs](https://tailwindcss.com/docs/flex#flex-1)
     fn flex_1(mut self) -> Self {

crates/gpui2/src/window.rs 🔗

@@ -4,12 +4,12 @@ use crate::{
     DevicePixels, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity, EntityId,
     EventEmitter, FileDropEvent, Flatten, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
     ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, LayoutId, Model,
-    ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent,
-    MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler,
-    PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams,
-    RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size,
-    Style, SubscriberSet, Subscription, Surface, TaffyLayoutEngine, Task, Underline,
-    UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
+    ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent, Path,
+    Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
+    PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
+    RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet,
+    Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext,
+    WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
 };
 use anyhow::{anyhow, Context as _, Result};
 use collections::HashMap;
@@ -1269,10 +1269,9 @@ impl<'a> WindowContext<'a> {
                             cursor_offset: position,
                         });
                     }
-                    InputEvent::MouseDown(MouseDownEvent {
+                    InputEvent::MouseMove(MouseMoveEvent {
                         position,
-                        button: MouseButton::Left,
-                        click_count: 1,
+                        pressed_button: Some(MouseButton::Left),
                         modifiers: Modifiers::default(),
                     })
                 }
@@ -1285,6 +1284,7 @@ impl<'a> WindowContext<'a> {
                     })
                 }
                 FileDropEvent::Submit { position } => {
+                    self.activate(true);
                     self.window.mouse_position = position;
                     InputEvent::MouseUp(MouseUpEvent {
                         button: MouseButton::Left,
@@ -2839,3 +2839,9 @@ impl From<(&'static str, usize)> for ElementId {
         ElementId::NamedInteger(name.into(), id)
     }
 }
+
+impl From<(&'static str, u64)> for ElementId {
+    fn from((name, id): (&'static str, u64)) -> Self {
+        ElementId::NamedInteger(name.into(), id as usize)
+    }
+}

crates/gpui2/tests/action_macros.rs 🔗

@@ -1,16 +1,23 @@
+use gpui2::{actions, impl_actions};
+use gpui2_macros::register_action;
 use serde_derive::Deserialize;
 
 #[test]
-fn test_derive() {
+fn test_action_macros() {
     use gpui2 as gpui;
 
-    #[derive(PartialEq, Clone, Deserialize, gpui2_macros::Action)]
+    actions!(test, [TestAction]);
+
+    #[derive(PartialEq, Clone, Deserialize)]
     struct AnotherTestAction;
 
-    #[gpui2_macros::register_action]
+    impl_actions!(test, [AnotherTestAction]);
+
     #[derive(PartialEq, Clone, gpui::serde_derive::Deserialize)]
     struct RegisterableAction {}
 
+    register_action!(RegisterableAction);
+
     impl gpui::Action for RegisterableAction {
         fn boxed_clone(&self) -> Box<dyn gpui::Action> {
             todo!()

crates/gpui2_macros/src/action.rs 🔗

@@ -1,96 +0,0 @@
-// Input:
-//
-// #[action]
-// struct Foo {
-//   bar: String,
-// }
-
-// Output:
-//
-// #[gpui::register_action]
-// #[derive(gpui::serde::Deserialize, std::cmp::PartialEq, std::clone::Clone, std::default::Default, std::fmt::Debug)]
-// struct Foo {
-//   bar: String,
-// }
-
-use proc_macro::TokenStream;
-use quote::quote;
-use syn::{parse_macro_input, DeriveInput, Error};
-
-use crate::register_action::register_action;
-
-pub fn action(input: TokenStream) -> TokenStream {
-    let input = parse_macro_input!(input as DeriveInput);
-
-    let name = &input.ident;
-
-    if input.generics.lt_token.is_some() {
-        return Error::new(name.span(), "Actions must be a concrete type")
-            .into_compile_error()
-            .into();
-    }
-
-    let is_unit_struct = match input.data {
-        syn::Data::Struct(struct_data) => struct_data.fields.is_empty(),
-        syn::Data::Enum(_) => false,
-        syn::Data::Union(_) => false,
-    };
-
-    let build_impl = if is_unit_struct {
-        quote! {
-            Ok(std::boxed::Box::new(Self {}))
-        }
-    } else {
-        quote! {
-            Ok(std::boxed::Box::new(gpui::serde_json::from_value::<Self>(value)?))
-        }
-    };
-
-    let register_action = register_action(&name);
-
-    let output = quote! {
-        const _: fn() = || {
-            fn assert_impl<T: ?Sized + for<'a> gpui::serde::Deserialize<'a> +  ::std::cmp::PartialEq + ::std::clone::Clone>() {}
-            assert_impl::<#name>();
-        };
-
-        impl gpui::Action for #name {
-            fn name(&self) -> &'static str
-            {
-                ::std::any::type_name::<#name>()
-            }
-
-            fn debug_name() -> &'static str
-            where
-                Self: ::std::marker::Sized
-            {
-                ::std::any::type_name::<#name>()
-            }
-
-            fn build(value: gpui::serde_json::Value) -> gpui::Result<::std::boxed::Box<dyn gpui::Action>>
-            where
-                Self: ::std::marker::Sized {
-                    #build_impl
-            }
-
-            fn partial_eq(&self, action: &dyn gpui::Action) -> bool {
-                action
-                    .as_any()
-                    .downcast_ref::<Self>()
-                    .map_or(false, |a| self == a)
-            }
-
-            fn boxed_clone(&self) ->  std::boxed::Box<dyn gpui::Action> {
-                ::std::boxed::Box::new(self.clone())
-            }
-
-            fn as_any(&self) -> &dyn ::std::any::Any {
-                self
-            }
-        }
-
-        #register_action
-    };
-
-    TokenStream::from(output)
-}

crates/gpui2_macros/src/gpui2_macros.rs 🔗

@@ -1,4 +1,3 @@
-mod action;
 mod derive_into_element;
 mod register_action;
 mod style_helpers;
@@ -6,14 +5,9 @@ mod test;
 
 use proc_macro::TokenStream;
 
-#[proc_macro_derive(Action)]
-pub fn action(input: TokenStream) -> TokenStream {
-    action::action(input)
-}
-
-#[proc_macro_attribute]
-pub fn register_action(attr: TokenStream, item: TokenStream) -> TokenStream {
-    register_action::register_action_macro(attr, item)
+#[proc_macro]
+pub fn register_action(ident: TokenStream) -> TokenStream {
+    register_action::register_action_macro(ident)
 }
 
 #[proc_macro_derive(IntoElement)]

crates/gpui2_macros/src/register_action.rs 🔗

@@ -14,47 +14,13 @@
 use proc_macro::TokenStream;
 use proc_macro2::Ident;
 use quote::{format_ident, quote};
-use syn::{parse_macro_input, DeriveInput, Error};
+use syn::parse_macro_input;
 
-pub fn register_action_macro(_attr: TokenStream, item: TokenStream) -> TokenStream {
-    let input = parse_macro_input!(item as DeriveInput);
-    let registration = register_action(&input.ident);
-
-    let has_action_derive = input
-        .attrs
-        .iter()
-        .find(|attr| {
-            (|| {
-                let meta = attr.parse_meta().ok()?;
-                meta.path().is_ident("derive").then(|| match meta {
-                    syn::Meta::Path(_) => None,
-                    syn::Meta::NameValue(_) => None,
-                    syn::Meta::List(list) => list
-                        .nested
-                        .iter()
-                        .find(|list| match list {
-                            syn::NestedMeta::Meta(meta) => meta.path().is_ident("Action"),
-                            syn::NestedMeta::Lit(_) => false,
-                        })
-                        .map(|_| true),
-                })?
-            })()
-            .unwrap_or(false)
-        })
-        .is_some();
-
-    if has_action_derive {
-        return Error::new(
-            input.ident.span(),
-            "The Action derive macro has already registered this action",
-        )
-        .into_compile_error()
-        .into();
-    }
+pub fn register_action_macro(ident: TokenStream) -> TokenStream {
+    let name = parse_macro_input!(ident as Ident);
+    let registration = register_action(&name);
 
     TokenStream::from(quote! {
-        #input
-
         #registration
     })
 }
@@ -78,7 +44,7 @@ pub(crate) fn register_action(type_name: &Ident) -> proc_macro2::TokenStream {
         #[doc(hidden)]
         fn #action_builder_fn_name() -> gpui::ActionData {
             gpui::ActionData {
-                name: ::std::any::type_name::<#type_name>(),
+                name: <#type_name as gpui::Action>::debug_name(),
                 type_id: ::std::any::TypeId::of::<#type_name>(),
                 build: <#type_name as gpui::Action>::build,
             }

crates/install_cli2/src/install_cli2.rs 🔗

@@ -3,7 +3,7 @@ use gpui::{actions, AsyncAppContext};
 use std::path::Path;
 use util::ResultExt;
 
-actions!(Install);
+actions!(cli, [Install]);
 
 pub async fn install_cli(cx: &AsyncAppContext) -> Result<()> {
     let cli_path = cx.update(|cx| cx.path_for_auxiliary_executable("cli"))??;

crates/language_selector2/src/language_selector.rs 🔗

@@ -14,9 +14,9 @@ use project::Project;
 use std::sync::Arc;
 use ui::{prelude::*, HighlightedLabel, ListItem};
 use util::ResultExt;
-use workspace::Workspace;
+use workspace::{ModalView, Workspace};
 
-actions!(Toggle);
+actions!(language_selector, [Toggle]);
 
 pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(LanguageSelector::register).detach();
@@ -81,6 +81,7 @@ impl FocusableView for LanguageSelector {
 }
 
 impl EventEmitter<DismissEvent> for LanguageSelector {}
+impl ModalView for LanguageSelector {}
 
 pub struct LanguageSelectorDelegate {
     language_selector: WeakView<LanguageSelector>,

crates/live_kit_client2/examples/test_app2.rs 🔗

@@ -1,17 +1,15 @@
 use std::{sync::Arc, time::Duration};
 
 use futures::StreamExt;
-use gpui::{Action, KeyBinding};
+use gpui::{actions, KeyBinding};
 use live_kit_client2::{
     LocalAudioTrack, LocalVideoTrack, RemoteAudioTrackUpdate, RemoteVideoTrackUpdate, Room,
 };
 use live_kit_server::token::{self, VideoGrant};
 use log::LevelFilter;
-use serde_derive::Deserialize;
 use simplelog::SimpleLogger;
 
-#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Action)]
-struct Quit;
+actions!(live_kit_client, [Quit]);
 
 fn main() {
     SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");

crates/menu2/src/menu2.rs 🔗

@@ -10,12 +10,15 @@ use gpui::actions;
 pub fn init() {}
 
 actions!(
-    Cancel,
-    Confirm,
-    SecondaryConfirm,
-    SelectPrev,
-    SelectNext,
-    SelectFirst,
-    SelectLast,
-    ShowContextMenu
+    menu,
+    [
+        Cancel,
+        Confirm,
+        SecondaryConfirm,
+        SelectPrev,
+        SelectNext,
+        SelectFirst,
+        SelectLast,
+        ShowContextMenu
+    ]
 );

crates/outline2/src/outline.rs 🔗

@@ -1,6 +1,6 @@
 use editor::{
     display_map::ToDisplayPoint, scroll::autoscroll::Autoscroll, Anchor, AnchorRangeExt,
-    DisplayPoint, Editor, ToPoint,
+    DisplayPoint, Editor, EditorMode, ToPoint,
 };
 use fuzzy::StringMatch;
 use gpui::{
@@ -20,29 +20,26 @@ use std::{
 use theme::{color_alpha, ActiveTheme, ThemeSettings};
 use ui::{prelude::*, ListItem};
 use util::ResultExt;
-use workspace::Workspace;
+use workspace::ModalView;
 
-actions!(Toggle);
+actions!(outline, [Toggle]);
 
 pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(OutlineView::register).detach();
 }
 
-pub fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Workspace>) {
-    if let Some(editor) = workspace
-        .active_item(cx)
-        .and_then(|item| item.downcast::<Editor>())
-    {
-        let outline = editor
-            .read(cx)
-            .buffer()
-            .read(cx)
-            .snapshot(cx)
-            .outline(Some(&cx.theme().syntax()));
-
-        if let Some(outline) = outline {
+pub fn toggle(editor: View<Editor>, _: &Toggle, cx: &mut WindowContext) {
+    let outline = editor
+        .read(cx)
+        .buffer()
+        .read(cx)
+        .snapshot(cx)
+        .outline(Some(&cx.theme().syntax()));
+
+    if let Some((workspace, outline)) = editor.read(cx).workspace().zip(outline) {
+        workspace.update(cx, |workspace, cx| {
             workspace.toggle_modal(cx, |cx| OutlineView::new(outline, editor, cx));
-        }
+        })
     }
 }
 
@@ -57,6 +54,7 @@ impl FocusableView for OutlineView {
 }
 
 impl EventEmitter<DismissEvent> for OutlineView {}
+impl ModalView for OutlineView {}
 
 impl Render for OutlineView {
     type Element = Div;
@@ -67,8 +65,15 @@ impl Render for OutlineView {
 }
 
 impl OutlineView {
-    fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
-        workspace.register_action(toggle);
+    fn register(editor: &mut Editor, cx: &mut ViewContext<Editor>) {
+        if editor.mode() == EditorMode::Full {
+            let handle = cx.view().downgrade();
+            editor.register_action(move |action, cx| {
+                if let Some(editor) = handle.upgrade() {
+                    toggle(editor, action, cx);
+                }
+            });
+        }
     }
 
     fn new(
@@ -238,6 +243,7 @@ impl PickerDelegate for OutlineViewDelegate {
                     s.select_ranges([position..position])
                 });
                 active_editor.highlight_rows(None);
+                active_editor.focus(cx);
             }
         });
 

crates/project/src/lsp_command.rs 🔗

@@ -33,7 +33,7 @@ pub fn lsp_formatting_options(tab_size: u32) -> lsp::FormattingOptions {
 }
 
 #[async_trait(?Send)]
-pub(crate) trait LspCommand: 'static + Sized {
+pub trait LspCommand: 'static + Sized {
     type Response: 'static + Default + Send;
     type LspRequest: 'static + Send + lsp::request::Request;
     type ProtoRequest: 'static + Send + proto::RequestMessage;

crates/project/src/lsp_ext_command.rs 🔗

@@ -0,0 +1,137 @@
+use std::{path::Path, sync::Arc};
+
+use anyhow::Context;
+use async_trait::async_trait;
+use gpui::{AppContext, AsyncAppContext, ModelHandle};
+use language::{point_to_lsp, proto::deserialize_anchor, Buffer};
+use lsp::{LanguageServer, LanguageServerId};
+use rpc::proto::{self, PeerId};
+use serde::{Deserialize, Serialize};
+use text::{PointUtf16, ToPointUtf16};
+
+use crate::{lsp_command::LspCommand, Project};
+
+pub enum LspExpandMacro {}
+
+impl lsp::request::Request for LspExpandMacro {
+    type Params = ExpandMacroParams;
+    type Result = Option<ExpandedMacro>;
+    const METHOD: &'static str = "rust-analyzer/expandMacro";
+}
+
+#[derive(Deserialize, Serialize, Debug)]
+#[serde(rename_all = "camelCase")]
+pub struct ExpandMacroParams {
+    pub text_document: lsp::TextDocumentIdentifier,
+    pub position: lsp::Position,
+}
+
+#[derive(Default, Deserialize, Serialize, Debug)]
+#[serde(rename_all = "camelCase")]
+pub struct ExpandedMacro {
+    pub name: String,
+    pub expansion: String,
+}
+
+impl ExpandedMacro {
+    pub fn is_empty(&self) -> bool {
+        self.name.is_empty() && self.expansion.is_empty()
+    }
+}
+
+pub struct ExpandMacro {
+    pub position: PointUtf16,
+}
+
+#[async_trait(?Send)]
+impl LspCommand for ExpandMacro {
+    type Response = ExpandedMacro;
+    type LspRequest = LspExpandMacro;
+    type ProtoRequest = proto::LspExtExpandMacro;
+
+    fn to_lsp(
+        &self,
+        path: &Path,
+        _: &Buffer,
+        _: &Arc<LanguageServer>,
+        _: &AppContext,
+    ) -> ExpandMacroParams {
+        ExpandMacroParams {
+            text_document: lsp::TextDocumentIdentifier {
+                uri: lsp::Url::from_file_path(path).unwrap(),
+            },
+            position: point_to_lsp(self.position),
+        }
+    }
+
+    async fn response_from_lsp(
+        self,
+        message: Option<ExpandedMacro>,
+        _: ModelHandle<Project>,
+        _: ModelHandle<Buffer>,
+        _: LanguageServerId,
+        _: AsyncAppContext,
+    ) -> anyhow::Result<ExpandedMacro> {
+        Ok(message
+            .map(|message| ExpandedMacro {
+                name: message.name,
+                expansion: message.expansion,
+            })
+            .unwrap_or_default())
+    }
+
+    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::LspExtExpandMacro {
+        proto::LspExtExpandMacro {
+            project_id,
+            buffer_id: buffer.remote_id(),
+            position: Some(language::proto::serialize_anchor(
+                &buffer.anchor_before(self.position),
+            )),
+        }
+    }
+
+    async fn from_proto(
+        message: Self::ProtoRequest,
+        _: ModelHandle<Project>,
+        buffer: ModelHandle<Buffer>,
+        mut cx: AsyncAppContext,
+    ) -> anyhow::Result<Self> {
+        let position = message
+            .position
+            .and_then(deserialize_anchor)
+            .context("invalid position")?;
+        Ok(Self {
+            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer)),
+        })
+    }
+
+    fn response_to_proto(
+        response: ExpandedMacro,
+        _: &mut Project,
+        _: PeerId,
+        _: &clock::Global,
+        _: &mut AppContext,
+    ) -> proto::LspExtExpandMacroResponse {
+        proto::LspExtExpandMacroResponse {
+            name: response.name,
+            expansion: response.expansion,
+        }
+    }
+
+    async fn response_from_proto(
+        self,
+        message: proto::LspExtExpandMacroResponse,
+        _: ModelHandle<Project>,
+        _: ModelHandle<Buffer>,
+        _: AsyncAppContext,
+    ) -> anyhow::Result<ExpandedMacro> {
+        Ok(ExpandedMacro {
+            name: message.name,
+            expansion: message.expansion,
+        })
+    }
+
+    fn buffer_id_from_proto(message: &proto::LspExtExpandMacro) -> u64 {
+        message.buffer_id
+    }
+}

crates/project/src/project.rs 🔗

@@ -1,5 +1,6 @@
 mod ignore;
-mod lsp_command;
+pub mod lsp_command;
+pub mod lsp_ext_command;
 mod prettier_support;
 pub mod project_settings;
 pub mod search;
@@ -174,7 +175,7 @@ struct DelayedDebounced {
     cancel_channel: Option<oneshot::Sender<()>>,
 }
 
-enum LanguageServerToQuery {
+pub enum LanguageServerToQuery {
     Primary,
     Other(LanguageServerId),
 }
@@ -626,6 +627,7 @@ impl Project {
         client.add_model_request_handler(Self::handle_open_buffer_by_path);
         client.add_model_request_handler(Self::handle_save_buffer);
         client.add_model_message_handler(Self::handle_update_diff_base);
+        client.add_model_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
     }
 
     pub fn local(
@@ -5863,7 +5865,7 @@ impl Project {
             .await;
     }
 
-    fn request_lsp<R: LspCommand>(
+    pub fn request_lsp<R: LspCommand>(
         &self,
         buffer_handle: ModelHandle<Buffer>,
         server: LanguageServerToQuery,

crates/project2/src/lsp_command.rs 🔗

@@ -33,7 +33,7 @@ pub fn lsp_formatting_options(tab_size: u32) -> lsp::FormattingOptions {
 }
 
 #[async_trait(?Send)]
-pub(crate) trait LspCommand: 'static + Sized + Send {
+pub trait LspCommand: 'static + Sized + Send {
     type Response: 'static + Default + Send;
     type LspRequest: 'static + Send + lsp::request::Request;
     type ProtoRequest: 'static + Send + proto::RequestMessage;

crates/project2/src/lsp_ext_command.rs 🔗

@@ -0,0 +1,137 @@
+use std::{path::Path, sync::Arc};
+
+use anyhow::Context;
+use async_trait::async_trait;
+use gpui::{AppContext, AsyncAppContext, Model};
+use language::{point_to_lsp, proto::deserialize_anchor, Buffer};
+use lsp::{LanguageServer, LanguageServerId};
+use rpc::proto::{self, PeerId};
+use serde::{Deserialize, Serialize};
+use text::{PointUtf16, ToPointUtf16};
+
+use crate::{lsp_command::LspCommand, Project};
+
+pub enum LspExpandMacro {}
+
+impl lsp::request::Request for LspExpandMacro {
+    type Params = ExpandMacroParams;
+    type Result = Option<ExpandedMacro>;
+    const METHOD: &'static str = "rust-analyzer/expandMacro";
+}
+
+#[derive(Deserialize, Serialize, Debug)]
+#[serde(rename_all = "camelCase")]
+pub struct ExpandMacroParams {
+    pub text_document: lsp::TextDocumentIdentifier,
+    pub position: lsp::Position,
+}
+
+#[derive(Default, Deserialize, Serialize, Debug)]
+#[serde(rename_all = "camelCase")]
+pub struct ExpandedMacro {
+    pub name: String,
+    pub expansion: String,
+}
+
+impl ExpandedMacro {
+    pub fn is_empty(&self) -> bool {
+        self.name.is_empty() && self.expansion.is_empty()
+    }
+}
+
+pub struct ExpandMacro {
+    pub position: PointUtf16,
+}
+
+#[async_trait(?Send)]
+impl LspCommand for ExpandMacro {
+    type Response = ExpandedMacro;
+    type LspRequest = LspExpandMacro;
+    type ProtoRequest = proto::LspExtExpandMacro;
+
+    fn to_lsp(
+        &self,
+        path: &Path,
+        _: &Buffer,
+        _: &Arc<LanguageServer>,
+        _: &AppContext,
+    ) -> ExpandMacroParams {
+        ExpandMacroParams {
+            text_document: lsp::TextDocumentIdentifier {
+                uri: lsp::Url::from_file_path(path).unwrap(),
+            },
+            position: point_to_lsp(self.position),
+        }
+    }
+
+    async fn response_from_lsp(
+        self,
+        message: Option<ExpandedMacro>,
+        _: Model<Project>,
+        _: Model<Buffer>,
+        _: LanguageServerId,
+        _: AsyncAppContext,
+    ) -> anyhow::Result<ExpandedMacro> {
+        Ok(message
+            .map(|message| ExpandedMacro {
+                name: message.name,
+                expansion: message.expansion,
+            })
+            .unwrap_or_default())
+    }
+
+    fn to_proto(&self, project_id: u64, buffer: &Buffer) -> proto::LspExtExpandMacro {
+        proto::LspExtExpandMacro {
+            project_id,
+            buffer_id: buffer.remote_id(),
+            position: Some(language::proto::serialize_anchor(
+                &buffer.anchor_before(self.position),
+            )),
+        }
+    }
+
+    async fn from_proto(
+        message: Self::ProtoRequest,
+        _: Model<Project>,
+        buffer: Model<Buffer>,
+        mut cx: AsyncAppContext,
+    ) -> anyhow::Result<Self> {
+        let position = message
+            .position
+            .and_then(deserialize_anchor)
+            .context("invalid position")?;
+        Ok(Self {
+            position: buffer.update(&mut cx, |buffer, _| position.to_point_utf16(buffer))?,
+        })
+    }
+
+    fn response_to_proto(
+        response: ExpandedMacro,
+        _: &mut Project,
+        _: PeerId,
+        _: &clock::Global,
+        _: &mut AppContext,
+    ) -> proto::LspExtExpandMacroResponse {
+        proto::LspExtExpandMacroResponse {
+            name: response.name,
+            expansion: response.expansion,
+        }
+    }
+
+    async fn response_from_proto(
+        self,
+        message: proto::LspExtExpandMacroResponse,
+        _: Model<Project>,
+        _: Model<Buffer>,
+        _: AsyncAppContext,
+    ) -> anyhow::Result<ExpandedMacro> {
+        Ok(ExpandedMacro {
+            name: message.name,
+            expansion: message.expansion,
+        })
+    }
+
+    fn buffer_id_from_proto(message: &proto::LspExtExpandMacro) -> u64 {
+        message.buffer_id
+    }
+}

crates/project2/src/project2.rs 🔗

@@ -1,5 +1,6 @@
 mod ignore;
-mod lsp_command;
+pub mod lsp_command;
+pub mod lsp_ext_command;
 mod prettier_support;
 pub mod project_settings;
 pub mod search;
@@ -172,7 +173,7 @@ struct DelayedDebounced {
     cancel_channel: Option<oneshot::Sender<()>>,
 }
 
-enum LanguageServerToQuery {
+pub enum LanguageServerToQuery {
     Primary,
     Other(LanguageServerId),
 }
@@ -623,6 +624,7 @@ impl Project {
         client.add_model_request_handler(Self::handle_open_buffer_by_path);
         client.add_model_request_handler(Self::handle_save_buffer);
         client.add_model_message_handler(Self::handle_update_diff_base);
+        client.add_model_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
     }
 
     pub fn local(
@@ -5933,7 +5935,7 @@ impl Project {
             .await;
     }
 
-    fn request_lsp<R: LspCommand>(
+    pub fn request_lsp<R: LspCommand>(
         &self,
         buffer_handle: Model<Buffer>,
         server: LanguageServerToQuery,

crates/project_panel2/src/project_panel.rs 🔗

@@ -103,23 +103,26 @@ pub struct EntryDetails {
 }
 
 actions!(
-    ExpandSelectedEntry,
-    CollapseSelectedEntry,
-    CollapseAllEntries,
-    NewDirectory,
-    NewFile,
-    Copy,
-    CopyPath,
-    CopyRelativePath,
-    RevealInFinder,
-    OpenInTerminal,
-    Cut,
-    Paste,
-    Delete,
-    Rename,
-    Open,
-    ToggleFocus,
-    NewSearchInDirectory,
+    project_panel,
+    [
+        ExpandSelectedEntry,
+        CollapseSelectedEntry,
+        CollapseAllEntries,
+        NewDirectory,
+        NewFile,
+        Copy,
+        CopyPath,
+        CopyRelativePath,
+        RevealInFinder,
+        OpenInTerminal,
+        Cut,
+        Paste,
+        Delete,
+        Rename,
+        Open,
+        ToggleFocus,
+        NewSearchInDirectory,
+    ]
 );
 
 pub fn init_settings(cx: &mut AppContext) {

crates/recent_projects2/src/recent_projects.rs 🔗

@@ -1,9 +1,10 @@
 mod highlighted_workspace_location;
+mod projects;
 
 use fuzzy::{StringMatch, StringMatchCandidate};
 use gpui::{
-    actions, AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Result, Task,
-    View, ViewContext, WeakView,
+    AppContext, DismissEvent, Div, EventEmitter, FocusHandle, FocusableView, Result, Task, View,
+    ViewContext, WeakView,
 };
 use highlighted_workspace_location::HighlightedWorkspaceLocation;
 use ordered_float::OrderedFloat;
@@ -12,11 +13,11 @@ use std::sync::Arc;
 use ui::{prelude::*, ListItem};
 use util::paths::PathExt;
 use workspace::{
-    notifications::simple_message_notification::MessageNotification, Workspace, WorkspaceLocation,
-    WORKSPACE_DB,
+    notifications::simple_message_notification::MessageNotification, ModalView, Workspace,
+    WorkspaceLocation, WORKSPACE_DB,
 };
 
-actions!(OpenRecent);
+pub use projects::OpenRecent;
 
 pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(RecentProjects::register).detach();
@@ -26,6 +27,8 @@ pub struct RecentProjects {
     picker: View<Picker<RecentProjectsDelegate>>,
 }
 
+impl ModalView for RecentProjects {}
+
 impl RecentProjects {
     fn new(delegate: RecentProjectsDelegate, cx: &mut ViewContext<Self>) -> Self {
         Self {

crates/rich_text2/src/rich_text.rs 🔗

@@ -1,13 +1,16 @@
-use std::{ops::Range, sync::Arc};
-
-use anyhow::bail;
 use futures::FutureExt;
-use gpui::{AnyElement, FontStyle, FontWeight, HighlightStyle, UnderlineStyle};
+use gpui::{
+    AnyElement, ElementId, FontStyle, FontWeight, HighlightStyle, InteractiveText, IntoElement,
+    SharedString, StyledText, UnderlineStyle, WindowContext,
+};
 use language::{HighlightId, Language, LanguageRegistry};
+use std::{ops::Range, sync::Arc};
+use theme::ActiveTheme;
 use util::RangeExt;
 
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum Highlight {
+    Code,
     Id(HighlightId),
     Highlight(HighlightStyle),
     Mention,
@@ -28,24 +31,10 @@ impl From<HighlightId> for Highlight {
 
 #[derive(Debug, Clone)]
 pub struct RichText {
-    pub text: String,
+    pub text: SharedString,
     pub highlights: Vec<(Range<usize>, Highlight)>,
-    pub region_ranges: Vec<Range<usize>>,
-    pub regions: Vec<RenderedRegion>,
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum BackgroundKind {
-    Code,
-    /// A mention background for non-self user.
-    Mention,
-    SelfMention,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct RenderedRegion {
-    pub background_kind: Option<BackgroundKind>,
-    pub link_url: Option<String>,
+    pub link_ranges: Vec<Range<usize>>,
+    pub link_urls: Arc<[String]>,
 }
 
 /// Allows one to specify extra links to the rendered markdown, which can be used
@@ -56,94 +45,71 @@ pub struct Mention {
 }
 
 impl RichText {
-    pub fn element(
-        &self,
-        // syntax: Arc<SyntaxTheme>,
-        //  style: RichTextStyle,
-        // cx: &mut ViewContext<V>,
-    ) -> AnyElement {
-        todo!();
+    pub fn element(&self, id: ElementId, cx: &mut WindowContext) -> AnyElement {
+        let theme = cx.theme();
+        let code_background = theme.colors().surface_background;
 
-        // let mut region_id = 0;
-        // let view_id = cx.view_id();
-
-        // let regions = self.regions.clone();
-
-        // enum Markdown {}
-        // Text::new(self.text.clone(), style.text.clone())
-        //     .with_highlights(
-        //         self.highlights
-        //             .iter()
-        //             .filter_map(|(range, highlight)| {
-        //                 let style = match highlight {
-        //                     Highlight::Id(id) => id.style(&syntax)?,
-        //                     Highlight::Highlight(style) => style.clone(),
-        //                     Highlight::Mention => style.mention_highlight,
-        //                     Highlight::SelfMention => style.self_mention_highlight,
-        //                 };
-        //                 Some((range.clone(), style))
-        //             })
-        //             .collect::<Vec<_>>(),
-        //     )
-        //     .with_custom_runs(self.region_ranges.clone(), move |ix, bounds, cx| {
-        //         region_id += 1;
-        //         let region = regions[ix].clone();
-        //         if let Some(url) = region.link_url {
-        //             cx.scene().push_cursor_region(CursorRegion {
-        //                 bounds,
-        //                 style: CursorStyle::PointingHand,
-        //             });
-        //             cx.scene().push_mouse_region(
-        //                 MouseRegion::new::<Markdown>(view_id, region_id, bounds)
-        //                     .on_click::<V, _>(MouseButton::Left, move |_, _, cx| {
-        //                         cx.platform().open_url(&url)
-        //                     }),
-        //             );
-        //         }
-        //         if let Some(region_kind) = &region.background_kind {
-        //             let background = match region_kind {
-        //                 BackgroundKind::Code => style.code_background,
-        //                 BackgroundKind::Mention => style.mention_background,
-        //                 BackgroundKind::SelfMention => style.self_mention_background,
-        //             };
-        //             if background.is_some() {
-        //                 cx.scene().push_quad(gpui::Quad {
-        //                     bounds,
-        //                     background,
-        //                     border: Default::default(),
-        //                     corner_radii: (2.0).into(),
-        //                 });
-        //             }
-        //         }
-        //     })
-        //     .with_soft_wrap(true)
-        //     .into_any()
+        InteractiveText::new(
+            id,
+            StyledText::new(self.text.clone()).with_highlights(
+                &cx.text_style(),
+                self.highlights.iter().map(|(range, highlight)| {
+                    (
+                        range.clone(),
+                        match highlight {
+                            Highlight::Code => HighlightStyle {
+                                background_color: Some(code_background),
+                                ..Default::default()
+                            },
+                            Highlight::Id(id) => HighlightStyle {
+                                background_color: Some(code_background),
+                                ..id.style(&theme.syntax()).unwrap_or_default()
+                            },
+                            Highlight::Highlight(highlight) => *highlight,
+                            Highlight::Mention => HighlightStyle {
+                                font_weight: Some(FontWeight::BOLD),
+                                ..Default::default()
+                            },
+                            Highlight::SelfMention => HighlightStyle {
+                                font_weight: Some(FontWeight::BOLD),
+                                ..Default::default()
+                            },
+                        },
+                    )
+                }),
+            ),
+        )
+        .on_click(self.link_ranges.clone(), {
+            let link_urls = self.link_urls.clone();
+            move |ix, cx| cx.open_url(&link_urls[ix])
+        })
+        .into_any_element()
     }
 
-    pub fn add_mention(
-        &mut self,
-        range: Range<usize>,
-        is_current_user: bool,
-        mention_style: HighlightStyle,
-    ) -> anyhow::Result<()> {
-        if range.end > self.text.len() {
-            bail!(
-                "Mention in range {range:?} is outside of bounds for a message of length {}",
-                self.text.len()
-            );
-        }
+    // pub fn add_mention(
+    //     &mut self,
+    //     range: Range<usize>,
+    //     is_current_user: bool,
+    //     mention_style: HighlightStyle,
+    // ) -> anyhow::Result<()> {
+    //     if range.end > self.text.len() {
+    //         bail!(
+    //             "Mention in range {range:?} is outside of bounds for a message of length {}",
+    //             self.text.len()
+    //         );
+    //     }
 
-        if is_current_user {
-            self.region_ranges.push(range.clone());
-            self.regions.push(RenderedRegion {
-                background_kind: Some(BackgroundKind::Mention),
-                link_url: None,
-            });
-        }
-        self.highlights
-            .push((range, Highlight::Highlight(mention_style)));
-        Ok(())
-    }
+    //     if is_current_user {
+    //         self.region_ranges.push(range.clone());
+    //         self.regions.push(RenderedRegion {
+    //             background_kind: Some(BackgroundKind::Mention),
+    //             link_url: None,
+    //         });
+    //     }
+    //     self.highlights
+    //         .push((range, Highlight::Highlight(mention_style)));
+    //     Ok(())
+    // }
 }
 
 pub fn render_markdown_mut(
@@ -151,7 +117,10 @@ pub fn render_markdown_mut(
     mut mentions: &[Mention],
     language_registry: &Arc<LanguageRegistry>,
     language: Option<&Arc<Language>>,
-    data: &mut RichText,
+    text: &mut String,
+    highlights: &mut Vec<(Range<usize>, Highlight)>,
+    link_ranges: &mut Vec<Range<usize>>,
+    link_urls: &mut Vec<String>,
 ) {
     use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag};
 
@@ -163,18 +132,18 @@ pub fn render_markdown_mut(
 
     let options = Options::all();
     for (event, source_range) in Parser::new_ext(&block, options).into_offset_iter() {
-        let prev_len = data.text.len();
+        let prev_len = text.len();
         match event {
             Event::Text(t) => {
                 if let Some(language) = &current_language {
-                    render_code(&mut data.text, &mut data.highlights, t.as_ref(), language);
+                    render_code(text, highlights, t.as_ref(), language);
                 } else {
                     if let Some(mention) = mentions.first() {
                         if source_range.contains_inclusive(&mention.range) {
                             mentions = &mentions[1..];
                             let range = (prev_len + mention.range.start - source_range.start)
                                 ..(prev_len + mention.range.end - source_range.start);
-                            data.highlights.push((
+                            highlights.push((
                                 range.clone(),
                                 if mention.is_self_mention {
                                     Highlight::SelfMention
@@ -182,19 +151,10 @@ pub fn render_markdown_mut(
                                     Highlight::Mention
                                 },
                             ));
-                            data.region_ranges.push(range);
-                            data.regions.push(RenderedRegion {
-                                background_kind: Some(if mention.is_self_mention {
-                                    BackgroundKind::SelfMention
-                                } else {
-                                    BackgroundKind::Mention
-                                }),
-                                link_url: None,
-                            });
                         }
                     }
 
-                    data.text.push_str(t.as_ref());
+                    text.push_str(t.as_ref());
                     let mut style = HighlightStyle::default();
                     if bold_depth > 0 {
                         style.font_weight = Some(FontWeight::BOLD);
@@ -203,11 +163,8 @@ pub fn render_markdown_mut(
                         style.font_style = Some(FontStyle::Italic);
                     }
                     if let Some(link_url) = link_url.clone() {
-                        data.region_ranges.push(prev_len..data.text.len());
-                        data.regions.push(RenderedRegion {
-                            link_url: Some(link_url),
-                            background_kind: None,
-                        });
+                        link_ranges.push(prev_len..text.len());
+                        link_urls.push(link_url);
                         style.underline = Some(UnderlineStyle {
                             thickness: 1.0.into(),
                             ..Default::default()
@@ -216,27 +173,25 @@ pub fn render_markdown_mut(
 
                     if style != HighlightStyle::default() {
                         let mut new_highlight = true;
-                        if let Some((last_range, last_style)) = data.highlights.last_mut() {
+                        if let Some((last_range, last_style)) = highlights.last_mut() {
                             if last_range.end == prev_len
                                 && last_style == &Highlight::Highlight(style)
                             {
-                                last_range.end = data.text.len();
+                                last_range.end = text.len();
                                 new_highlight = false;
                             }
                         }
                         if new_highlight {
-                            data.highlights
-                                .push((prev_len..data.text.len(), Highlight::Highlight(style)));
+                            highlights.push((prev_len..text.len(), Highlight::Highlight(style)));
                         }
                     }
                 }
             }
             Event::Code(t) => {
-                data.text.push_str(t.as_ref());
-                data.region_ranges.push(prev_len..data.text.len());
+                text.push_str(t.as_ref());
                 if link_url.is_some() {
-                    data.highlights.push((
-                        prev_len..data.text.len(),
+                    highlights.push((
+                        prev_len..text.len(),
                         Highlight::Highlight(HighlightStyle {
                             underline: Some(UnderlineStyle {
                                 thickness: 1.0.into(),
@@ -246,19 +201,19 @@ pub fn render_markdown_mut(
                         }),
                     ));
                 }
-                data.regions.push(RenderedRegion {
-                    background_kind: Some(BackgroundKind::Code),
-                    link_url: link_url.clone(),
-                });
+                if let Some(link_url) = link_url.clone() {
+                    link_ranges.push(prev_len..text.len());
+                    link_urls.push(link_url);
+                }
             }
             Event::Start(tag) => match tag {
-                Tag::Paragraph => new_paragraph(&mut data.text, &mut list_stack),
+                Tag::Paragraph => new_paragraph(text, &mut list_stack),
                 Tag::Heading(_, _, _) => {
-                    new_paragraph(&mut data.text, &mut list_stack);
+                    new_paragraph(text, &mut list_stack);
                     bold_depth += 1;
                 }
                 Tag::CodeBlock(kind) => {
-                    new_paragraph(&mut data.text, &mut list_stack);
+                    new_paragraph(text, &mut list_stack);
                     current_language = if let CodeBlockKind::Fenced(language) = kind {
                         language_registry
                             .language_for_name(language.as_ref())
@@ -278,18 +233,18 @@ pub fn render_markdown_mut(
                     let len = list_stack.len();
                     if let Some((list_number, has_content)) = list_stack.last_mut() {
                         *has_content = false;
-                        if !data.text.is_empty() && !data.text.ends_with('\n') {
-                            data.text.push('\n');
+                        if !text.is_empty() && !text.ends_with('\n') {
+                            text.push('\n');
                         }
                         for _ in 0..len - 1 {
-                            data.text.push_str("  ");
+                            text.push_str("  ");
                         }
                         if let Some(number) = list_number {
-                            data.text.push_str(&format!("{}. ", number));
+                            text.push_str(&format!("{}. ", number));
                             *number += 1;
                             *has_content = false;
                         } else {
-                            data.text.push_str("- ");
+                            text.push_str("- ");
                         }
                     }
                 }
@@ -304,8 +259,8 @@ pub fn render_markdown_mut(
                 Tag::List(_) => drop(list_stack.pop()),
                 _ => {}
             },
-            Event::HardBreak => data.text.push('\n'),
-            Event::SoftBreak => data.text.push(' '),
+            Event::HardBreak => text.push('\n'),
+            Event::SoftBreak => text.push(' '),
             _ => {}
         }
     }
@@ -317,18 +272,35 @@ pub fn render_markdown(
     language_registry: &Arc<LanguageRegistry>,
     language: Option<&Arc<Language>>,
 ) -> RichText {
-    let mut data = RichText {
-        text: Default::default(),
-        highlights: Default::default(),
-        region_ranges: Default::default(),
-        regions: Default::default(),
-    };
-
-    render_markdown_mut(&block, mentions, language_registry, language, &mut data);
+    // let mut data = RichText {
+    //     text: Default::default(),
+    //     highlights: Default::default(),
+    //     region_ranges: Default::default(),
+    //     regions: Default::default(),
+    // };
 
-    data.text = data.text.trim().to_string();
+    let mut text = String::new();
+    let mut highlights = Vec::new();
+    let mut link_ranges = Vec::new();
+    let mut link_urls = Vec::new();
+    render_markdown_mut(
+        &block,
+        mentions,
+        language_registry,
+        language,
+        &mut text,
+        &mut highlights,
+        &mut link_ranges,
+        &mut link_urls,
+    );
+    text.truncate(text.trim_end().len());
 
-    data
+    RichText {
+        text: SharedString::from(text),
+        link_urls: link_urls.into(),
+        link_ranges,
+        highlights,
+    }
 }
 
 pub fn render_code(
@@ -339,11 +311,19 @@ pub fn render_code(
 ) {
     let prev_len = text.len();
     text.push_str(content);
+    let mut offset = 0;
     for (range, highlight_id) in language.highlight_text(&content.into(), 0..content.len()) {
+        if range.start > offset {
+            highlights.push((prev_len + offset..prev_len + range.start, Highlight::Code));
+        }
         highlights.push((
             prev_len + range.start..prev_len + range.end,
             Highlight::Id(highlight_id),
         ));
+        offset = range.end;
+    }
+    if offset < content.len() {
+        highlights.push((prev_len + offset..prev_len + content.len(), Highlight::Code));
     }
 }
 

crates/rpc/proto/zed.proto 🔗

@@ -178,7 +178,9 @@ message Envelope {
         GetNotifications get_notifications = 150;
         GetNotificationsResponse get_notifications_response = 151;
         DeleteNotification delete_notification = 152;
-        MarkNotificationRead mark_notification_read = 153; // Current max
+        MarkNotificationRead mark_notification_read = 153;
+        LspExtExpandMacro lsp_ext_expand_macro = 154;
+        LspExtExpandMacroResponse lsp_ext_expand_macro_response = 155; // Current max
     }
 }
 
@@ -1619,3 +1621,14 @@ message Notification {
     bool is_read = 6;
     optional bool response = 7;
 }
+
+message LspExtExpandMacro {
+    uint64 project_id = 1;
+    uint64 buffer_id = 2;
+    Anchor position = 3;
+}
+
+message LspExtExpandMacroResponse {
+    string name = 1;
+    string expansion = 2;
+}

crates/rpc/src/proto.rs 🔗

@@ -280,6 +280,8 @@ messages!(
     (UpdateWorktree, Foreground),
     (UpdateWorktreeSettings, Foreground),
     (UsersResponse, Foreground),
+    (LspExtExpandMacro, Background),
+    (LspExtExpandMacroResponse, Background),
 );
 
 request_messages!(
@@ -363,6 +365,7 @@ request_messages!(
     (UpdateParticipantLocation, Ack),
     (UpdateProject, Ack),
     (UpdateWorktree, Ack),
+    (LspExtExpandMacro, LspExtExpandMacroResponse),
 );
 
 entity_messages!(
@@ -415,6 +418,7 @@ entity_messages!(
     UpdateProjectCollaborator,
     UpdateWorktree,
     UpdateWorktreeSettings,
+    LspExtExpandMacro,
 );
 
 entity_messages!(

crates/rpc2/proto/zed.proto 🔗

@@ -178,7 +178,9 @@ message Envelope {
         GetNotifications get_notifications = 150;
         GetNotificationsResponse get_notifications_response = 151;
         DeleteNotification delete_notification = 152;
-        MarkNotificationRead mark_notification_read = 153; // Current max
+        MarkNotificationRead mark_notification_read = 153;
+        LspExtExpandMacro lsp_ext_expand_macro = 154;
+        LspExtExpandMacroResponse lsp_ext_expand_macro_response = 155; // Current max
     }
 }
 
@@ -1619,3 +1621,14 @@ message Notification {
     bool is_read = 6;
     optional bool response = 7;
 }
+
+message LspExtExpandMacro {
+    uint64 project_id = 1;
+    uint64 buffer_id = 2;
+    Anchor position = 3;
+}
+
+message LspExtExpandMacroResponse {
+    string name = 1;
+    string expansion = 2;
+}

crates/rpc2/src/proto.rs 🔗

@@ -280,6 +280,8 @@ messages!(
     (UpdateWorktree, Foreground),
     (UpdateWorktreeSettings, Foreground),
     (UsersResponse, Foreground),
+    (LspExtExpandMacro, Background),
+    (LspExtExpandMacroResponse, Background),
 );
 
 request_messages!(
@@ -363,6 +365,7 @@ request_messages!(
     (UpdateParticipantLocation, Ack),
     (UpdateProject, Ack),
     (UpdateWorktree, Ack),
+    (LspExtExpandMacro, LspExtExpandMacroResponse),
 );
 
 entity_messages!(
@@ -415,6 +418,7 @@ entity_messages!(
     UpdateProjectCollaborator,
     UpdateWorktree,
     UpdateWorktreeSettings,
+    LspExtExpandMacro,
 );
 
 entity_messages!(

crates/search/src/project_search.rs 🔗

@@ -1075,8 +1075,7 @@ impl ProjectSearchView {
         });
     }
 
-    // Re-activate the most recently activated search or the most recent if it has been closed.
-    // If no search exists in the workspace, create a new one.
+    // Add another search tab to the workspace.
     fn deploy(
         workspace: &mut Workspace,
         _: &workspace::NewSearch,
@@ -1087,19 +1086,6 @@ impl ProjectSearchView {
             state.0.retain(|project, _| project.is_upgradable(cx))
         });
 
-        let active_search = cx
-            .global::<ActiveSearches>()
-            .0
-            .get(&workspace.project().downgrade());
-
-        let existing = active_search
-            .and_then(|active_search| {
-                workspace
-                    .items_of_type::<ProjectSearchView>(cx)
-                    .find(|search| search == active_search)
-            })
-            .or_else(|| workspace.item_of_type::<ProjectSearchView>(cx));
-
         let query = workspace.active_item(cx).and_then(|item| {
             let editor = item.act_as::<Editor>(cx)?;
             let query = editor.query_suggestion(cx);
@@ -1110,27 +1096,21 @@ impl ProjectSearchView {
             }
         });
 
-        let search = if let Some(existing) = existing {
-            workspace.activate_item(&existing, cx);
-            existing
-        } else {
-            let settings = cx
-                .global::<ActiveSettings>()
-                .0
-                .get(&workspace.project().downgrade());
+        let settings = cx
+            .global::<ActiveSettings>()
+            .0
+            .get(&workspace.project().downgrade());
 
-            let settings = if let Some(settings) = settings {
-                Some(settings.clone())
-            } else {
-                None
-            };
+        let settings = if let Some(settings) = settings {
+            Some(settings.clone())
+        } else {
+            None
+        };
 
-            let model = cx.add_model(|cx| ProjectSearch::new(workspace.project().clone(), cx));
-            let view = cx.add_view(|cx| ProjectSearchView::new(model, cx, settings));
+        let model = cx.add_model(|cx| ProjectSearch::new(workspace.project().clone(), cx));
+        let search = cx.add_view(|cx| ProjectSearchView::new(model, cx, settings));
 
-            workspace.add_item(Box::new(view.clone()), cx);
-            view
-        };
+        workspace.add_item(Box::new(search.clone()), cx);
 
         search.update(cx, |search, cx| {
             if let Some(query) = query {
@@ -2306,29 +2286,86 @@ pub mod tests {
         workspace.update(cx, |workspace, cx| {
             ProjectSearchView::deploy(workspace, &workspace::NewSearch, cx)
         });
+        deterministic.run_until_parked();
+        let Some(search_view_2) = cx.read(|cx| {
+            workspace
+                .read(cx)
+                .active_pane()
+                .read(cx)
+                .active_item()
+                .and_then(|item| item.downcast::<ProjectSearchView>())
+        }) else {
+            panic!("Search view expected to appear after new search event trigger")
+        };
+        let search_view_id_2 = search_view_2.id();
+        assert_ne!(
+            search_view_2, search_view,
+            "New search view should be open after `workspace::NewSearch` event"
+        );
+
         search_view.update(cx, |search_view, cx| {
-            assert_eq!(search_view.query_editor.read(cx).text(cx), "two", "Query should be updated to first search result after search view 2nd open in a row");
+            assert_eq!(search_view.query_editor.read(cx).text(cx), "TWO", "First search view should not have an updated query");
             assert_eq!(
                 search_view
                     .results_editor
                     .update(cx, |editor, cx| editor.display_text(cx)),
                 "\n\nconst THREE: usize = one::ONE + two::TWO;\n\n\nconst TWO: usize = one::ONE + one::ONE;",
-                "Results should be unchanged after search view 2nd open in a row"
+                "Results of the first search view should not update too"
             );
             assert!(
-                search_view.query_editor.is_focused(cx),
-                "Focus should be moved into query editor again after search view 2nd open in a row"
+                !search_view.query_editor.is_focused(cx),
+                "Focus should be moved away from the first search view"
+            );
+        });
+
+        search_view_2.update(cx, |search_view_2, cx| {
+            assert_eq!(
+                search_view_2.query_editor.read(cx).text(cx),
+                "two",
+                "New search view should get the query from the text cursor was at during the event spawn (first search view's first result)"
+            );
+            assert_eq!(
+                search_view_2
+                    .results_editor
+                    .update(cx, |editor, cx| editor.display_text(cx)),
+                "",
+                "No search results should be in the 2nd view yet, as we did not spawn a search for it"
+            );
+            assert!(
+                search_view_2.query_editor.is_focused(cx),
+                "Focus should be moved into query editor fo the new window"
+            );
+        });
+
+        search_view_2.update(cx, |search_view_2, cx| {
+            search_view_2
+                .query_editor
+                .update(cx, |query_editor, cx| query_editor.set_text("FOUR", cx));
+            search_view_2.search(cx);
+        });
+        deterministic.run_until_parked();
+        search_view_2.update(cx, |search_view_2, cx| {
+            assert_eq!(
+                search_view_2
+                    .results_editor
+                    .update(cx, |editor, cx| editor.display_text(cx)),
+                "\n\nconst FOUR: usize = one::ONE + three::THREE;",
+                "New search view with the updated query should have new search results"
+            );
+            assert!(
+                search_view_2.results_editor.is_focused(cx),
+                "Search view with mismatching query should be focused after search results are available",
             );
         });
 
         cx.spawn(|mut cx| async move {
-            window.dispatch_action(search_view_id, &ToggleFocus, &mut cx);
+            window.dispatch_action(search_view_id_2, &ToggleFocus, &mut cx);
         })
         .detach();
         deterministic.run_until_parked();
-        search_view.update(cx, |search_view, cx| {
+        search_view_2.update(cx, |search_view_2, cx| {
             assert!(
-                search_view.results_editor.is_focused(cx),
+                search_view_2.results_editor.is_focused(cx),
                 "Search view with matching query should switch focus to the results editor after the toggle focus event",
             );
         });

crates/search2/src/buffer_search.rs 🔗

@@ -10,15 +10,15 @@ use collections::HashMap;
 use editor::{Editor, EditorMode};
 use futures::channel::oneshot;
 use gpui::{
-    actions, div, red, Action, AppContext, Div, EventEmitter, FocusableView,
-    InteractiveElement as _, IntoElement, ParentElement as _, Render, Styled, Subscription, Task,
-    View, ViewContext, VisualContext as _, WeakView, WindowContext,
+    actions, div, impl_actions, red, Action, AppContext, Div, EventEmitter, FocusableView,
+    InteractiveElement as _, IntoElement, KeyContext, ParentElement as _, Render, Styled,
+    Subscription, Task, View, ViewContext, VisualContext as _, WeakView, WindowContext,
 };
 use project::search::SearchQuery;
 use serde::Deserialize;
 use std::{any::Any, sync::Arc};
 
-use ui::{h_stack, Clickable, Icon, IconButton, IconElement};
+use ui::{h_stack, ButtonCommon, Clickable, Icon, IconButton, IconElement, Tooltip};
 use util::ResultExt;
 use workspace::{
     item::ItemHandle,
@@ -26,12 +26,14 @@ use workspace::{
     ToolbarItemLocation, ToolbarItemView,
 };
 
-#[derive(PartialEq, Clone, Deserialize, Default, Action)]
+#[derive(PartialEq, Clone, Deserialize)]
 pub struct Deploy {
     pub focus: bool,
 }
 
-actions!(Dismiss, FocusEditor);
+impl_actions!(buffer_search, [Deploy]);
+
+actions!(buffer_search, [Dismiss, FocusEditor]);
 
 pub enum Event {
     UpdateLocation,
@@ -131,13 +133,7 @@ impl Render for BufferSearchBar {
         let search_button_for_mode = |mode| {
             let is_active = self.current_mode == mode;
 
-            render_search_mode_button(
-                mode,
-                is_active,
-                cx.listener(move |this, _, cx| {
-                    this.activate_search_mode(mode, cx);
-                }),
-            )
+            render_search_mode_button(mode, is_active)
         };
         let search_option_button = |option| {
             let is_active = self.search_options.contains(option);
@@ -163,23 +159,35 @@ impl Render for BufferSearchBar {
             });
         let should_show_replace_input = self.replace_enabled && supported_options.replacement;
         let replace_all = should_show_replace_input
-            .then(|| super::render_replace_button(ReplaceAll, ui::Icon::ReplaceAll));
-        let replace_next = should_show_replace_input
-            .then(|| super::render_replace_button(ReplaceNext, ui::Icon::ReplaceNext));
+            .then(|| super::render_replace_button(ReplaceAll, ui::Icon::ReplaceAll, "Replace all"));
+        let replace_next = should_show_replace_input.then(|| {
+            super::render_replace_button(ReplaceNext, ui::Icon::ReplaceNext, "Replace next")
+        });
         let in_replace = self.replacement_editor.focus_handle(cx).is_focused(cx);
 
+        let mut key_context = KeyContext::default();
+        key_context.add("BufferSearchBar");
+        if in_replace {
+            key_context.add("in_replace");
+        }
+
         h_stack()
-            .key_context("BufferSearchBar")
+            .key_context(key_context)
             .on_action(cx.listener(Self::previous_history_query))
             .on_action(cx.listener(Self::next_history_query))
             .on_action(cx.listener(Self::dismiss))
             .on_action(cx.listener(Self::select_next_match))
             .on_action(cx.listener(Self::select_prev_match))
+            .on_action(cx.listener(|this, _: &ActivateRegexMode, cx| {
+                this.activate_search_mode(SearchMode::Regex, cx);
+            }))
+            .on_action(cx.listener(|this, _: &ActivateTextMode, cx| {
+                this.activate_search_mode(SearchMode::Text, cx);
+            }))
             .when(self.supported_options().replacement, |this| {
                 this.on_action(cx.listener(Self::toggle_replace))
                     .when(in_replace, |this| {
-                        this.key_context("in_replace")
-                            .on_action(cx.listener(Self::replace_next))
+                        this.on_action(cx.listener(Self::replace_next))
                             .on_action(cx.listener(Self::replace_all))
                     })
             })
@@ -238,21 +246,19 @@ impl Render for BufferSearchBar {
                 h_stack()
                     .gap_0p5()
                     .flex_none()
-                    .child(self.render_action_button(cx))
+                    .child(self.render_action_button())
                     .children(match_count)
                     .child(render_nav_button(
                         ui::Icon::ChevronLeft,
                         self.active_match_index.is_some(),
-                        cx.listener(move |this, _, cx| {
-                            this.select_prev_match(&Default::default(), cx);
-                        }),
+                        "Select previous match",
+                        &SelectPrevMatch,
                     ))
                     .child(render_nav_button(
                         ui::Icon::ChevronRight,
                         self.active_match_index.is_some(),
-                        cx.listener(move |this, _, cx| {
-                            this.select_next_match(&Default::default(), cx);
-                        }),
+                        "Select next match",
+                        &SelectNextMatch,
                     )),
             )
     }
@@ -597,14 +603,10 @@ impl BufferSearchBar {
         self.update_matches(cx)
     }
 
-    fn render_action_button(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
-        // let tooltip_style = theme.tooltip.clone();
-
-        // let style = theme.search.action_button.clone();
-
-        IconButton::new("select-all", ui::Icon::SelectAll).on_click(cx.listener(|this, _, cx| {
-            this.select_all_matches(&SelectAllMatches, cx);
-        }))
+    fn render_action_button(&self) -> impl IntoElement {
+        IconButton::new("select-all", ui::Icon::SelectAll)
+            .on_click(|_, cx| cx.dispatch_action(SelectAllMatches.boxed_clone()))
+            .tooltip(|cx| Tooltip::for_action("Select all matches", &SelectAllMatches, cx))
     }
 
     pub fn activate_search_mode(&mut self, mode: SearchMode, cx: &mut ViewContext<Self>) {

crates/search2/src/mode.rs 🔗

@@ -1,3 +1,7 @@
+use gpui::{Action, SharedString};
+
+use crate::{ActivateRegexMode, ActivateSemanticMode, ActivateTextMode};
+
 // TODO: Update the default search mode to get from config
 #[derive(Copy, Clone, Debug, Default, PartialEq)]
 pub enum SearchMode {
@@ -15,6 +19,16 @@ impl SearchMode {
             SearchMode::Regex => "Regex",
         }
     }
+    pub(crate) fn tooltip(&self) -> SharedString {
+        format!("Activate {} Mode", self.label()).into()
+    }
+    pub(crate) fn action(&self) -> Box<dyn Action> {
+        match self {
+            SearchMode::Text => ActivateTextMode.boxed_clone(),
+            SearchMode::Semantic => ActivateSemanticMode.boxed_clone(),
+            SearchMode::Regex => ActivateRegexMode.boxed_clone(),
+        }
+    }
 }
 
 pub(crate) fn next_mode(mode: &SearchMode, semantic_enabled: bool) -> SearchMode {

crates/search2/src/project_search.rs 🔗

@@ -1,8 +1,7 @@
 use crate::{
-    history::SearchHistory, mode::SearchMode, ActivateRegexMode, ActivateSemanticMode,
-    ActivateTextMode, CycleMode, NextHistoryQuery, PreviousHistoryQuery, ReplaceAll, ReplaceNext,
-    SearchOptions, SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleReplace,
-    ToggleWholeWord,
+    history::SearchHistory, mode::SearchMode, ActivateRegexMode, ActivateTextMode, CycleMode,
+    NextHistoryQuery, PreviousHistoryQuery, ReplaceAll, ReplaceNext, SearchOptions,
+    SelectNextMatch, SelectPrevMatch, ToggleCaseSensitive, ToggleReplace, ToggleWholeWord,
 };
 use anyhow::{Context as _, Result};
 use collections::HashMap;
@@ -45,7 +44,10 @@ use workspace::{
     WorkspaceId,
 };
 
-actions!(SearchInNew, ToggleFocus, NextField, ToggleFilters,);
+actions!(
+    project_search,
+    [SearchInNew, ToggleFocus, NextField, ToggleFilters]
+);
 
 #[derive(Default)]
 struct ActiveSearches(HashMap<WeakModel<Project>, WeakView<ProjectSearchView>>);
@@ -58,7 +60,9 @@ pub fn init(cx: &mut AppContext) {
     cx.set_global(ActiveSearches::default());
     cx.set_global(ActiveSettings::default());
     cx.observe_new_views(|workspace: &mut Workspace, _cx| {
-        workspace.register_action(ProjectSearchView::deploy);
+        workspace
+            .register_action(ProjectSearchView::deploy)
+            .register_action(ProjectSearchBar::search_in_new);
     })
     .detach();
 }
@@ -1007,8 +1011,7 @@ impl ProjectSearchView {
         });
     }
 
-    // Re-activate the most recently activated search or the most recent if it has been closed.
-    // If no search exists in the workspace, create a new one.
+    // Add another search tab to the workspace.
     fn deploy(
         workspace: &mut Workspace,
         _: &workspace::NewSearch,
@@ -1019,20 +1022,6 @@ impl ProjectSearchView {
             state.0.retain(|project, _| project.is_upgradable())
         });
 
-        let active_search = cx
-            .global::<ActiveSearches>()
-            .0
-            .get(&workspace.project().downgrade())
-            .and_then(WeakView::upgrade);
-
-        let existing = active_search
-            .and_then(|active_search| {
-                workspace
-                    .items_of_type::<ProjectSearchView>(cx)
-                    .find(|search| search == &active_search)
-            })
-            .or_else(|| workspace.item_of_type::<ProjectSearchView>(cx));
-
         let query = workspace.active_item(cx).and_then(|item| {
             let editor = item.act_as::<Editor>(cx)?;
             let query = editor.query_suggestion(cx);
@@ -1043,27 +1032,21 @@ impl ProjectSearchView {
             }
         });
 
-        let search = if let Some(existing) = existing {
-            workspace.activate_item(&existing, cx);
-            existing
-        } else {
-            let settings = cx
-                .global::<ActiveSettings>()
-                .0
-                .get(&workspace.project().downgrade());
+        let settings = cx
+            .global::<ActiveSettings>()
+            .0
+            .get(&workspace.project().downgrade());
 
-            let settings = if let Some(settings) = settings {
-                Some(settings.clone())
-            } else {
-                None
-            };
+        let settings = if let Some(settings) = settings {
+            Some(settings.clone())
+        } else {
+            None
+        };
 
-            let model = cx.build_model(|cx| ProjectSearch::new(workspace.project().clone(), cx));
-            let view = cx.build_view(|cx| ProjectSearchView::new(model, cx, settings));
+        let model = cx.build_model(|cx| ProjectSearch::new(workspace.project().clone(), cx));
+        let search = cx.build_view(|cx| ProjectSearchView::new(model, cx, settings));
 
-            workspace.add_item(Box::new(view.clone()), cx);
-            view
-        };
+        workspace.add_item(Box::new(search.clone()), cx);
 
         search.update(cx, |search, cx| {
             if let Some(query) = query {
@@ -2436,29 +2419,86 @@ pub mod tests {
         workspace.update(cx, |workspace, cx| {
             ProjectSearchView::deploy(workspace, &workspace::NewSearch, cx)
         });
+        deterministic.run_until_parked();
+        let Some(search_view_2) = cx.read(|cx| {
+            workspace
+                .read(cx)
+                .active_pane()
+                .read(cx)
+                .active_item()
+                .and_then(|item| item.downcast::<ProjectSearchView>())
+        }) else {
+            panic!("Search view expected to appear after new search event trigger")
+        };
+        let search_view_id_2 = search_view_2.id();
+        assert_ne!(
+            search_view_2, search_view,
+            "New search view should be open after `workspace::NewSearch` event"
+        );
+
         search_view.update(cx, |search_view, cx| {
-            assert_eq!(search_view.query_editor.read(cx).text(cx), "two", "Query should be updated to first search result after search view 2nd open in a row");
+            assert_eq!(search_view.query_editor.read(cx).text(cx), "TWO", "First search view should not have an updated query");
             assert_eq!(
                 search_view
                     .results_editor
                     .update(cx, |editor, cx| editor.display_text(cx)),
                 "\n\nconst THREE: usize = one::ONE + two::TWO;\n\n\nconst TWO: usize = one::ONE + one::ONE;",
-                "Results should be unchanged after search view 2nd open in a row"
+                "Results of the first search view should not update too"
             );
             assert!(
-                search_view.query_editor.is_focused(cx),
-                "Focus should be moved into query editor again after search view 2nd open in a row"
+                !search_view.query_editor.is_focused(cx),
+                "Focus should be moved away from the first search view"
+            );
+        });
+
+        search_view_2.update(cx, |search_view_2, cx| {
+            assert_eq!(
+                search_view_2.query_editor.read(cx).text(cx),
+                "two",
+                "New search view should get the query from the text cursor was at during the event spawn (first search view's first result)"
+            );
+            assert_eq!(
+                search_view_2
+                    .results_editor
+                    .update(cx, |editor, cx| editor.display_text(cx)),
+                "",
+                "No search results should be in the 2nd view yet, as we did not spawn a search for it"
+            );
+            assert!(
+                search_view_2.query_editor.is_focused(cx),
+                "Focus should be moved into query editor fo the new window"
+            );
+        });
+
+        search_view_2.update(cx, |search_view_2, cx| {
+            search_view_2
+                .query_editor
+                .update(cx, |query_editor, cx| query_editor.set_text("FOUR", cx));
+            search_view_2.search(cx);
+        });
+        deterministic.run_until_parked();
+        search_view_2.update(cx, |search_view_2, cx| {
+            assert_eq!(
+                search_view_2
+                    .results_editor
+                    .update(cx, |editor, cx| editor.display_text(cx)),
+                "\n\nconst FOUR: usize = one::ONE + three::THREE;",
+                "New search view with the updated query should have new search results"
+            );
+            assert!(
+                search_view_2.results_editor.is_focused(cx),
+                "Search view with mismatching query should be focused after search results are available",
             );
         });
 
         cx.spawn(|mut cx| async move {
-            window.dispatch_action(search_view_id, &ToggleFocus, &mut cx);
+            window.dispatch_action(search_view_id_2, &ToggleFocus, &mut cx);
         })
         .detach();
         deterministic.run_until_parked();
-        search_view.update(cx, |search_view, cx| {
+        search_view_id_2.update(cx, |search_view_2, cx| {
             assert!(
-                search_view.results_editor.is_focused(cx),
+                search_view_2.results_editor.is_focused(cx),
                 "Search view with matching query should switch focus to the results editor after the toggle focus event",
             );
         });

crates/search2/src/search.rs 🔗

@@ -3,7 +3,7 @@ pub use buffer_search::BufferSearchBar;
 use gpui::{actions, Action, AppContext, IntoElement};
 pub use mode::SearchMode;
 use project::search::SearchQuery;
-use ui::prelude::*;
+use ui::{prelude::*, Tooltip};
 use ui::{ButtonStyle, Icon, IconButton};
 //pub use project_search::{ProjectSearchBar, ProjectSearchView};
 // use theme::components::{
@@ -22,20 +22,23 @@ pub fn init(cx: &mut AppContext) {
 }
 
 actions!(
-    CycleMode,
-    ToggleWholeWord,
-    ToggleCaseSensitive,
-    ToggleReplace,
-    SelectNextMatch,
-    SelectPrevMatch,
-    SelectAllMatches,
-    NextHistoryQuery,
-    PreviousHistoryQuery,
-    ActivateTextMode,
-    ActivateSemanticMode,
-    ActivateRegexMode,
-    ReplaceAll,
-    ReplaceNext,
+    search,
+    [
+        CycleMode,
+        ToggleWholeWord,
+        ToggleCaseSensitive,
+        ToggleReplace,
+        SelectNextMatch,
+        SelectPrevMatch,
+        SelectAllMatches,
+        NextHistoryQuery,
+        PreviousHistoryQuery,
+        ActivateTextMode,
+        ActivateSemanticMode,
+        ActivateRegexMode,
+        ReplaceAll,
+        ReplaceNext,
+    ]
 );
 
 bitflags! {
@@ -85,7 +88,7 @@ impl SearchOptions {
     }
 
     pub fn as_button(&self, active: bool) -> impl IntoElement {
-        IconButton::new(0, self.icon())
+        IconButton::new(self.label(), self.icon())
             .on_click({
                 let action = self.to_toggle_action();
                 move |_, cx| {
@@ -94,26 +97,38 @@ impl SearchOptions {
             })
             .style(ButtonStyle::Subtle)
             .when(active, |button| button.style(ButtonStyle::Filled))
+            .tooltip({
+                let action = self.to_toggle_action();
+                let label: SharedString = format!("Toggle {}", self.label()).into();
+                move |cx| Tooltip::for_action(label.clone(), &*action, cx)
+            })
     }
 }
 
 fn toggle_replace_button(active: bool) -> impl IntoElement {
     // todo: add toggle_replace button
-    IconButton::new(0, Icon::Replace)
+    IconButton::new("buffer-search-bar-toggle-replace-button", Icon::Replace)
         .on_click(|_, cx| {
             cx.dispatch_action(Box::new(ToggleReplace));
             cx.notify();
         })
         .style(ButtonStyle::Subtle)
         .when(active, |button| button.style(ButtonStyle::Filled))
+        .tooltip(|cx| Tooltip::for_action("Toggle replace", &ToggleReplace, cx))
 }
 
 fn render_replace_button(
     action: impl Action + 'static + Send + Sync,
     icon: Icon,
+    tooltip: &'static str,
 ) -> impl IntoElement {
-    // todo: add tooltip
-    IconButton::new(0, icon).on_click(move |_, cx| {
-        cx.dispatch_action(action.boxed_clone());
-    })
+    let id: SharedString = format!("search-replace-{}", action.name()).into();
+    IconButton::new(id, icon)
+        .tooltip({
+            let action = action.boxed_clone();
+            move |cx| Tooltip::for_action(tooltip, &*action, cx)
+        })
+        .on_click(move |_, cx| {
+            cx.dispatch_action(action.boxed_clone());
+        })
 }

crates/search2/src/search_bar.rs 🔗

@@ -1,30 +1,36 @@
-use gpui::{ClickEvent, IntoElement, WindowContext};
-use ui::prelude::*;
+use gpui::{Action, IntoElement};
+use ui::{prelude::*, Tooltip};
 use ui::{Button, IconButton};
 
 use crate::mode::SearchMode;
 
 pub(super) fn render_nav_button(
     icon: ui::Icon,
-    _active: bool,
-    on_click: impl Fn(&ClickEvent, &mut WindowContext) + 'static,
+    active: bool,
+    tooltip: &'static str,
+    action: &'static dyn Action,
 ) -> impl IntoElement {
-    // let tooltip_style = cx.theme().tooltip.clone();
-    // let cursor_style = if active {
-    //     CursorStyle::PointingHand
-    // } else {
-    //     CursorStyle::default()
-    // };
-    // enum NavButton {}
-    IconButton::new("search-nav-button", icon).on_click(on_click)
+    IconButton::new(
+        SharedString::from(format!("search-nav-button-{}", action.name())),
+        icon,
+    )
+    .on_click(|_, cx| cx.dispatch_action(action.boxed_clone()))
+    .tooltip(move |cx| Tooltip::for_action(tooltip, action, cx))
+    .disabled(!active)
 }
 
-pub(crate) fn render_search_mode_button(
-    mode: SearchMode,
-    is_active: bool,
-    on_click: impl Fn(&ClickEvent, &mut WindowContext) + 'static,
-) -> Button {
+pub(crate) fn render_search_mode_button(mode: SearchMode, is_active: bool) -> Button {
     Button::new(mode.label(), mode.label())
         .selected(is_active)
-        .on_click(on_click)
+        .on_click({
+            let action = mode.action();
+            move |_, cx| {
+                cx.dispatch_action(action.boxed_clone());
+            }
+        })
+        .tooltip({
+            let action = mode.action();
+            let tooltip_text = mode.tooltip();
+            move |cx| Tooltip::for_action(tooltip_text.clone(), &*action, cx)
+        })
 }

crates/settings2/src/keymap_file.rs 🔗

@@ -1,7 +1,7 @@
 use crate::{settings_store::parse_json_with_comments, SettingsAssets};
 use anyhow::{anyhow, Context, Result};
 use collections::BTreeMap;
-use gpui::{actions, Action, AppContext, KeyBinding, SharedString};
+use gpui::{Action, AppContext, KeyBinding, SharedString};
 use schemars::{
     gen::{SchemaGenerator, SchemaSettings},
     schema::{InstanceType, Schema, SchemaObject, SingleOrVec, SubschemaValidation},
@@ -137,10 +137,8 @@ impl KeymapFile {
     }
 }
 
-actions!(NoAction);
-
 fn no_action() -> Box<dyn gpui::Action> {
-    NoAction.boxed_clone()
+    gpui::NoAction.boxed_clone()
 }
 
 #[cfg(test)]

crates/storybook2/src/stories/focus.rs 🔗

@@ -4,7 +4,7 @@ use gpui::{
 };
 use ui::prelude::*;
 
-actions!(ActionA, ActionB, ActionC);
+actions!(focus, [ActionA, ActionB, ActionC]);
 
 pub struct FocusStory {
     child_1_focus: FocusHandle,

crates/storybook2/src/story_selector.rs 🔗

@@ -28,6 +28,7 @@ pub enum ComponentStory {
     ListHeader,
     ListItem,
     Scroll,
+    Tab,
     Text,
     ZIndex,
     Picker,
@@ -53,6 +54,7 @@ impl ComponentStory {
             Self::ListItem => cx.build_view(|_| ui::ListItemStory).into(),
             Self::Scroll => ScrollStory::view(cx).into(),
             Self::Text => TextStory::view(cx).into(),
+            Self::Tab => cx.build_view(|_| ui::TabStory).into(),
             Self::ZIndex => cx.build_view(|_| ZIndexStory).into(),
             Self::Picker => PickerStory::new(cx).into(),
         }

crates/terminal2/src/terminal2.rs 🔗

@@ -50,7 +50,7 @@ use std::{
 use thiserror::Error;
 
 use gpui::{
-    px, AnyWindowHandle, AppContext, Bounds, ClipboardItem, EventEmitter, Hsla, Keystroke,
+    actions, px, AnyWindowHandle, AppContext, Bounds, ClipboardItem, EventEmitter, Hsla, Keystroke,
     ModelContext, Modifiers, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels,
     Point, ScrollWheelEvent, Size, Task, TouchPhase,
 };
@@ -58,6 +58,19 @@ use gpui::{
 use crate::mappings::{colors::to_alac_rgb, keys::to_esc_str};
 use lazy_static::lazy_static;
 
+actions!(
+    terminal,
+    [
+        Clear,
+        Copy,
+        Paste,
+        ShowCharacterPalette,
+        SearchTest,
+        SendText,
+        SendKeystroke,
+    ]
+);
+
 ///Scrolling is unbearably sluggish by default. Alacritty supports a configurable
 ///Scroll multiplier that is set to 3 by default. This will be removed when I
 ///Implement scroll bars.

crates/terminal_view2/src/terminal_element.rs 🔗

@@ -1,11 +1,11 @@
 use editor::{Cursor, HighlightedRange, HighlightedRangeLine};
 use gpui::{
     black, div, point, px, red, relative, transparent_black, AnyElement, AsyncWindowContext,
-    AvailableSpace, Bounds, DispatchPhase, Element, ElementId, FocusHandle, Font, FontStyle,
-    FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState, IntoElement,
-    LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
+    AvailableSpace, Bounds, DispatchPhase, Element, ElementId, ExternalPaths, FocusHandle, Font,
+    FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState,
+    IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
     PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled,
-    TextRun, TextStyle, TextSystem, UnderlineStyle, View, WhiteSpace, WindowContext,
+    TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext,
 };
 use itertools::Itertools;
 use language::CursorShape;
@@ -27,8 +27,6 @@ use ui::Tooltip;
 use std::mem;
 use std::{fmt::Debug, ops::RangeInclusive};
 
-use crate::TerminalView;
-
 ///The information generated during layout that is necessary for painting
 pub struct LayoutState {
     cells: Vec<LayoutCell>,
@@ -149,7 +147,6 @@ impl LayoutRect {
 ///We need to keep a reference to the view for mouse events, do we need it for any other terminal stuff, or can we move that to connection?
 pub struct TerminalElement {
     terminal: Model<Terminal>,
-    terminal_view: View<TerminalView>,
     focus: FocusHandle,
     focused: bool,
     cursor_visible: bool,
@@ -168,7 +165,6 @@ impl StatefulInteractiveElement for TerminalElement {}
 impl TerminalElement {
     pub fn new(
         terminal: Model<Terminal>,
-        terminal_view: View<TerminalView>,
         focus: FocusHandle,
         focused: bool,
         cursor_visible: bool,
@@ -176,7 +172,6 @@ impl TerminalElement {
     ) -> TerminalElement {
         TerminalElement {
             terminal,
-            terminal_view,
             focused,
             focus: focus.clone(),
             cursor_visible,
@@ -474,6 +469,7 @@ impl TerminalElement {
                 .size_full()
                 .id("terminal-element")
                 .tooltip(move |cx| Tooltip::text(hovered_word.word.clone(), cx))
+                .into_any_element()
         });
 
         let TerminalContent {
@@ -575,7 +571,7 @@ impl TerminalElement {
             relative_highlighted_ranges,
             mode: *mode,
             display_offset: *display_offset,
-            hyperlink_tooltip: None, // todo!(tooltips)
+            hyperlink_tooltip,
             gutter,
         }
     }
@@ -643,13 +639,11 @@ impl TerminalElement {
                 let connection = connection.clone();
                 let focus = focus.clone();
                 move |e, cx| {
-                    if e.pressed_button.is_some() {
-                        if focus.is_focused(cx) {
-                            connection.update(cx, |terminal, cx| {
-                                terminal.mouse_drag(e, origin, bounds);
-                                cx.notify();
-                            })
-                        }
+                    if e.pressed_button.is_some() && focus.is_focused(cx) && !cx.has_active_drag() {
+                        connection.update(cx, |terminal, cx| {
+                            terminal.mouse_drag(e, origin, bounds);
+                            cx.notify();
+                        })
                     }
                 }
             })
@@ -776,18 +770,11 @@ impl Element for TerminalElement {
         (layout_id, interactive_state)
     }
 
-    fn paint(
-        mut self,
-        bounds: Bounds<Pixels>,
-        state: &mut Self::State,
-        cx: &mut WindowContext<'_>,
-    ) {
+    fn paint(self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext<'_>) {
         let mut layout = self.compute_layout(bounds, cx);
 
         let theme = cx.theme();
 
-        let dispatch_context = self.terminal_view.read(cx).dispatch_context(cx);
-        self.interactivity().key_context = Some(dispatch_context);
         cx.paint_quad(
             bounds,
             Default::default(),
@@ -806,7 +793,28 @@ impl Element for TerminalElement {
                 .map(|cursor| cursor.bounding_rect(origin)),
         };
 
-        let mut this = self.register_mouse_listeners(origin, layout.mode, bounds, cx);
+        let terminal_focus_handle = self.focus.clone();
+        let terminal_handle = self.terminal.clone();
+        let mut this: TerminalElement = self
+            .register_mouse_listeners(origin, layout.mode, bounds, cx)
+            .drag_over::<ExternalPaths>(|style| {
+                // todo!() why does not it work? z-index of elements?
+                style.bg(cx.theme().colors().ghost_element_hover)
+            })
+            .on_drop::<ExternalPaths>(move |external_paths, cx| {
+                cx.focus(&terminal_focus_handle);
+                let mut new_text = external_paths
+                    .read(cx)
+                    .paths()
+                    .iter()
+                    .map(|path| format!(" {path:?}"))
+                    .join("");
+                new_text.push(' ');
+                terminal_handle.update(cx, |terminal, _| {
+                    // todo!() long paths are not displayed properly albeit the text is there
+                    terminal.paste(&new_text);
+                });
+            });
 
         let interactivity = mem::take(&mut this.interactivity);
 

crates/terminal_view2/src/terminal_panel.rs 🔗

@@ -24,7 +24,7 @@ use anyhow::Result;
 
 const TERMINAL_PANEL_KEY: &'static str = "TerminalPanel";
 
-actions!(ToggleFocus);
+actions!(terminal_view, [ToggleFocus]);
 
 pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(

crates/terminal_view2/src/terminal_view.rs 🔗

@@ -9,9 +9,10 @@ pub mod terminal_panel;
 // use crate::terminal_element::TerminalElement;
 use editor::{scroll::autoscroll::Autoscroll, Editor};
 use gpui::{
-    actions, div, Action, AnyElement, AppContext, Div, EventEmitter, FocusEvent, FocusHandle,
-    Focusable, FocusableElement, FocusableView, KeyContext, KeyDownEvent, Keystroke, Model,
-    MouseButton, MouseDownEvent, Pixels, Render, Subscription, Task, View, VisualContext, WeakView,
+    div, impl_actions, overlay, AnyElement, AppContext, DismissEvent, Div, EventEmitter,
+    FocusEvent, FocusHandle, Focusable, FocusableElement, FocusableView, KeyContext, KeyDownEvent,
+    Keystroke, Model, MouseButton, MouseDownEvent, Pixels, Render, Styled, Subscription, Task,
+    View, VisualContext, WeakView,
 };
 use language::Bias;
 use persistence::TERMINAL_DB;
@@ -22,7 +23,7 @@ use terminal::{
         term::{search::RegexSearch, TermMode},
     },
     terminal_settings::{TerminalBlink, TerminalSettings, WorkingDirectory},
-    Event, MaybeNavigationTarget, Terminal,
+    Clear, Copy, Event, MaybeNavigationTarget, Paste, ShowCharacterPalette, Terminal,
 };
 use terminal_element::TerminalElement;
 use ui::{h_stack, prelude::*, ContextMenu, Icon, IconElement, Label};
@@ -54,13 +55,13 @@ const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
 #[derive(Clone, Debug, PartialEq)]
 pub struct ScrollTerminal(pub i32);
 
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Action)]
+#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
 pub struct SendText(String);
 
-#[derive(Clone, Debug, Default, Deserialize, PartialEq, Action)]
+#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
 pub struct SendKeystroke(String);
 
-actions!(Clear, Copy, Paste, ShowCharacterPalette, SearchTest);
+impl_actions!(terminal_view, [SendText, SendKeystroke]);
 
 pub fn init(cx: &mut AppContext) {
     terminal_panel::init(cx);
@@ -83,7 +84,7 @@ pub struct TerminalView {
     has_new_content: bool,
     //Currently using iTerm bell, show bell emoji in tab until input is received
     has_bell: bool,
-    context_menu: Option<View<ContextMenu>>,
+    context_menu: Option<(View<ContextMenu>, gpui::Point<Pixels>, Subscription)>,
     blink_state: bool,
     blinking_on: bool,
     blinking_paused: bool,
@@ -314,14 +315,24 @@ impl TerminalView {
         position: gpui::Point<Pixels>,
         cx: &mut ViewContext<Self>,
     ) {
-        self.context_menu = Some(ContextMenu::build(cx, |menu, cx| {
+        let context_menu = ContextMenu::build(cx, |menu, cx| {
             menu.action("Clear", Box::new(Clear))
                 .action("Close", Box::new(CloseActiveItem { save_intent: None }))
-        }));
-        // todo!(context menus)
-        //     self.context_menu
-        //         .show(position, AnchorCorner::TopLeft, menu_entries, cx);
-        //     cx.notify();
+        });
+
+        cx.focus_view(&context_menu);
+        let subscription =
+            cx.subscribe(&context_menu, |this, _, _: &DismissEvent, cx| {
+                if this.context_menu.as_ref().is_some_and(|context_menu| {
+                    context_menu.0.focus_handle(cx).contains_focused(cx)
+                }) {
+                    cx.focus_self();
+                }
+                this.context_menu.take();
+                cx.notify();
+            });
+
+        self.context_menu = Some((context_menu, position, subscription));
     }
 
     fn show_character_palette(&mut self, _: &ShowCharacterPalette, cx: &mut ViewContext<Self>) {
@@ -623,7 +634,6 @@ impl Render for TerminalView {
 
     fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
         let terminal_handle = self.terminal.clone();
-        let this_view = cx.view().clone();
 
         let self_id = cx.entity_id();
         let focused = self.focus_handle.is_focused(cx);
@@ -631,43 +641,41 @@ impl Render for TerminalView {
         div()
             .size_full()
             .relative()
-            .child(
-                div()
-                    .z_index(0)
-                    .absolute()
-                    .size_full()
-                    .on_key_down(cx.listener(Self::key_down))
-                    .on_action(cx.listener(TerminalView::send_text))
-                    .on_action(cx.listener(TerminalView::send_keystroke))
-                    .on_action(cx.listener(TerminalView::copy))
-                    .on_action(cx.listener(TerminalView::paste))
-                    .on_action(cx.listener(TerminalView::clear))
-                    .on_action(cx.listener(TerminalView::show_character_palette))
-                    .on_action(cx.listener(TerminalView::select_all))
-                    .child(TerminalElement::new(
-                        terminal_handle,
-                        this_view,
-                        self.focus_handle.clone(),
-                        focused,
-                        self.should_show_cursor(focused, cx),
-                        self.can_navigate_to_selected_word,
-                    ))
-                    .on_mouse_down(
-                        MouseButton::Right,
-                        cx.listener(|this, event: &MouseDownEvent, cx| {
-                            this.deploy_context_menu(event.position, cx);
-                            cx.notify();
-                        }),
-                    ),
-            )
-            .children(
-                self.context_menu
-                    .clone()
-                    .map(|context_menu| div().z_index(1).absolute().child(context_menu)),
-            )
             .track_focus(&self.focus_handle)
+            .key_context(self.dispatch_context(cx))
+            .on_action(cx.listener(TerminalView::send_text))
+            .on_action(cx.listener(TerminalView::send_keystroke))
+            .on_action(cx.listener(TerminalView::copy))
+            .on_action(cx.listener(TerminalView::paste))
+            .on_action(cx.listener(TerminalView::clear))
+            .on_action(cx.listener(TerminalView::show_character_palette))
+            .on_action(cx.listener(TerminalView::select_all))
             .on_focus_in(cx.listener(Self::focus_in))
             .on_focus_out(cx.listener(Self::focus_out))
+            .on_key_down(cx.listener(Self::key_down))
+            .on_mouse_down(
+                MouseButton::Right,
+                cx.listener(|this, event: &MouseDownEvent, cx| {
+                    this.deploy_context_menu(event.position, cx);
+                    cx.notify();
+                }),
+            )
+            .child(
+                // TODO: Oddly this wrapper div is needed for TerminalElement to not steal events from the context menu
+                div().size_full().child(TerminalElement::new(
+                    terminal_handle,
+                    self.focus_handle.clone(),
+                    focused,
+                    self.should_show_cursor(focused, cx),
+                    self.can_navigate_to_selected_word,
+                )),
+            )
+            .children(self.context_menu.as_ref().map(|(menu, positon, _)| {
+                overlay()
+                    .position(*positon)
+                    .anchor(gpui::AnchorCorner::TopLeft)
+                    .child(menu.clone())
+            }))
     }
 }
 

crates/theme2/src/registry.rs 🔗

@@ -10,6 +10,12 @@ use crate::{
     SystemColors, Theme, ThemeColors, ThemeFamily, ThemeStyles, UserTheme, UserThemeFamily,
 };
 
+#[derive(Debug, Clone)]
+pub struct ThemeMeta {
+    pub name: SharedString,
+    pub appearance: Appearance,
+}
+
 pub struct ThemeRegistry {
     themes: HashMap<SharedString, Arc<Theme>>,
 }
@@ -94,8 +100,11 @@ impl ThemeRegistry {
         self.themes.keys().cloned()
     }
 
-    pub fn list(&self, _staff: bool) -> impl Iterator<Item = SharedString> + '_ {
-        self.themes.values().map(|theme| theme.name.clone())
+    pub fn list(&self, _staff: bool) -> impl Iterator<Item = ThemeMeta> + '_ {
+        self.themes.values().map(|theme| ThemeMeta {
+            name: theme.name.clone(),
+            appearance: theme.appearance(),
+        })
     }
 
     pub fn get(&self, name: &str) -> Result<Arc<Theme>> {

crates/theme2/src/theme2.rs 🔗

@@ -31,6 +31,15 @@ pub enum Appearance {
     Dark,
 }
 
+impl Appearance {
+    pub fn is_light(&self) -> bool {
+        match self {
+            Self::Light => true,
+            Self::Dark => false,
+        }
+    }
+}
+
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
 pub enum LoadThemes {
     /// Only load the base theme.

crates/theme2/src/themes/andromeda.rs 🔗

@@ -25,7 +25,7 @@ pub fn andromeda() -> UserThemeFamily {
                         border_selected: Some(rgba(0x1b1d23ff).into()),
                         border_transparent: Some(rgba(0x1b1d23ff).into()),
                         border_disabled: Some(rgba(0x1b1d23ff).into()),
-                        elevated_surface_background: Some(rgba(0x23262eff).into()),
+                        elevated_surface_background: Some(rgba(0x2b303bff).into()),
                         surface_background: Some(rgba(0x23262eff).into()),
                         background: Some(rgba(0x23262eff).into()),
                         element_background: Some(rgba(0x00e8c5cc).into()),
@@ -33,31 +33,40 @@ pub fn andromeda() -> UserThemeFamily {
                         element_selected: Some(rgba(0x23262eff).into()),
                         drop_target_background: Some(rgba(0x3a404eff).into()),
                         ghost_element_hover: Some(rgba(0x23262eff).into()),
-                        text: Some(rgba(0xd4cdd8ff).into()),
+                        ghost_element_selected: Some(rgba(0x23262eff).into()),
+                        text: Some(rgba(0xd5ced9ff).into()),
+                        status_bar_background: Some(rgba(0x23262eff).into()),
+                        title_bar_background: Some(rgba(0x23262eff).into()),
+                        toolbar_background: Some(rgba(0x23262eff).into()),
+                        tab_bar_background: Some(rgba(0x23262eff).into()),
                         tab_inactive_background: Some(rgba(0x23262eff).into()),
                         tab_active_background: Some(rgba(0x23262eff).into()),
                         editor_background: Some(rgba(0x23262eff).into()),
                         editor_gutter_background: Some(rgba(0x23262eff).into()),
                         editor_line_number: Some(rgba(0x746f77ff).into()),
-                        editor_active_line_number: Some(rgba(0xd4cdd8ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xee5d42ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0x95e072ff).into()),
+                        editor_active_line_number: Some(rgba(0xd5ced9ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xee5d43ff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0x96e072ff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0xffe66dff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x7bb7ffff).into()),
-                        terminal_ansi_bright_magenta: Some(rgba(0xff00a9ff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x7cb7ffff).into()),
+                        terminal_ansi_bright_magenta: Some(rgba(0xff00aaff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0x00e8c6ff).into()),
-                        terminal_ansi_red: Some(rgba(0xee5d42ff).into()),
-                        terminal_ansi_green: Some(rgba(0x95e072ff).into()),
+                        terminal_ansi_red: Some(rgba(0xee5d43ff).into()),
+                        terminal_ansi_green: Some(rgba(0x96e072ff).into()),
                         terminal_ansi_yellow: Some(rgba(0xffe66dff).into()),
-                        terminal_ansi_blue: Some(rgba(0x7bb7ffff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xff00a9ff).into()),
+                        terminal_ansi_blue: Some(rgba(0x7cb7ffff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xff00aaff).into()),
                         terminal_ansi_cyan: Some(rgba(0x00e8c6ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xfc634cff).into()),
-                        error: Some(rgba(0xfc634cff).into()),
+                        created: Some(rgba(0x9bc53dbb).into()),
+                        deleted: Some(rgba(0xfc644dbb).into()),
+                        error: Some(rgba(0xfc644dff).into()),
                         hidden: Some(rgba(0x746f77ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x555555ff).into()),
+                        modified: Some(rgba(0x5bc0ebbb).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -65,28 +74,49 @@ pub fn andromeda() -> UserThemeFamily {
                             (
                                 "attribute".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf39c11ff).into()),
+                                    color: Some(rgba(0xffe66dff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "comment".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x9fa0a6cc).into()),
+                                    color: Some(rgba(0xa0a1a7cc).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa0a1a7cc).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constant".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xee5d43ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xf92672ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "emphasis".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xc64dedff).into()),
+                                    color: Some(rgba(0xc74dedff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf39c11ff).into()),
+                                    color: Some(rgba(0xf39c12ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -100,42 +130,70 @@ pub fn andromeda() -> UserThemeFamily {
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xc64dedff).into()),
+                                    color: Some(rgba(0xc74dedff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf39c11ff).into()),
+                                    color: Some(rgba(0xf39c12ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "operator".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xee5d42ff).into()),
+                                    color: Some(rgba(0xee5d43ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x95e072ff).into()),
+                                    color: Some(rgba(0x96e072ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.escape".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x96e072ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x96e072ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x96e072ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x96e072ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf92571ff).into()),
+                                    color: Some(rgba(0xf92672ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x95e072ff).into()),
+                                    color: Some(rgba(0x96e072ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -153,6 +211,13 @@ pub fn andromeda() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "variable.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x00e8c6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                         ],
                     }),
                 },
@@ -168,39 +233,48 @@ pub fn andromeda() -> UserThemeFamily {
                         border_selected: Some(rgba(0x1b1d23ff).into()),
                         border_transparent: Some(rgba(0x1b1d23ff).into()),
                         border_disabled: Some(rgba(0x1b1d23ff).into()),
-                        elevated_surface_background: Some(rgba(0x23262eff).into()),
+                        elevated_surface_background: Some(rgba(0x2b303bff).into()),
                         surface_background: Some(rgba(0x23262eff).into()),
-                        background: Some(rgba(0x262933ff).into()),
+                        background: Some(rgba(0x262a33ff).into()),
                         element_background: Some(rgba(0x00e8c5cc).into()),
                         element_hover: Some(rgba(0x23262eff).into()),
                         element_selected: Some(rgba(0x23262eff).into()),
                         drop_target_background: Some(rgba(0x3a404eff).into()),
                         ghost_element_hover: Some(rgba(0x23262eff).into()),
-                        text: Some(rgba(0xd4cdd8ff).into()),
+                        ghost_element_selected: Some(rgba(0x23262eff).into()),
+                        text: Some(rgba(0xd5ced9ff).into()),
+                        status_bar_background: Some(rgba(0x23262eff).into()),
+                        title_bar_background: Some(rgba(0x23262eff).into()),
+                        toolbar_background: Some(rgba(0x262a33ff).into()),
+                        tab_bar_background: Some(rgba(0x23262eff).into()),
                         tab_inactive_background: Some(rgba(0x23262eff).into()),
-                        tab_active_background: Some(rgba(0x262933ff).into()),
-                        editor_background: Some(rgba(0x262933ff).into()),
-                        editor_gutter_background: Some(rgba(0x262933ff).into()),
+                        tab_active_background: Some(rgba(0x262a33ff).into()),
+                        editor_background: Some(rgba(0x262a33ff).into()),
+                        editor_gutter_background: Some(rgba(0x262a33ff).into()),
                         editor_line_number: Some(rgba(0x746f77ff).into()),
-                        editor_active_line_number: Some(rgba(0xd4cdd8ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xee5d42ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0x95e072ff).into()),
+                        editor_active_line_number: Some(rgba(0xd5ced9ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xee5d43ff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0x96e072ff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0xffe66dff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x7bb7ffff).into()),
-                        terminal_ansi_bright_magenta: Some(rgba(0xff00a9ff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x7cb7ffff).into()),
+                        terminal_ansi_bright_magenta: Some(rgba(0xff00aaff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0x00e8c6ff).into()),
-                        terminal_ansi_red: Some(rgba(0xee5d42ff).into()),
-                        terminal_ansi_green: Some(rgba(0x95e072ff).into()),
+                        terminal_ansi_red: Some(rgba(0xee5d43ff).into()),
+                        terminal_ansi_green: Some(rgba(0x96e072ff).into()),
                         terminal_ansi_yellow: Some(rgba(0xffe66dff).into()),
-                        terminal_ansi_blue: Some(rgba(0x7bb7ffff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xff00a9ff).into()),
+                        terminal_ansi_blue: Some(rgba(0x7cb7ffff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xff00aaff).into()),
                         terminal_ansi_cyan: Some(rgba(0x00e8c6ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xfc634cff).into()),
-                        error: Some(rgba(0xfc634cff).into()),
+                        created: Some(rgba(0x9bc53dbb).into()),
+                        deleted: Some(rgba(0xfc644dbb).into()),
+                        error: Some(rgba(0xfc644dff).into()),
                         hidden: Some(rgba(0x746f77ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x555555ff).into()),
+                        modified: Some(rgba(0x5bc0ebbb).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -208,28 +282,49 @@ pub fn andromeda() -> UserThemeFamily {
                             (
                                 "attribute".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf39c11ff).into()),
+                                    color: Some(rgba(0xffe66dff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "comment".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x9fa0a6cc).into()),
+                                    color: Some(rgba(0xa0a1a7cc).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa0a1a7cc).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constant".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xee5d43ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xf92672ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "emphasis".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xc64dedff).into()),
+                                    color: Some(rgba(0xc74dedff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf39c11ff).into()),
+                                    color: Some(rgba(0xf39c12ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -243,42 +338,70 @@ pub fn andromeda() -> UserThemeFamily {
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xc64dedff).into()),
+                                    color: Some(rgba(0xc74dedff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf39c11ff).into()),
+                                    color: Some(rgba(0xf39c12ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "operator".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xee5d42ff).into()),
+                                    color: Some(rgba(0xee5d43ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x95e072ff).into()),
+                                    color: Some(rgba(0x96e072ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.escape".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x96e072ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x96e072ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x96e072ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x96e072ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf92571ff).into()),
+                                    color: Some(rgba(0xf92672ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x95e072ff).into()),
+                                    color: Some(rgba(0x96e072ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -296,6 +419,13 @@ pub fn andromeda() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "variable.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x00e8c6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                         ],
                     }),
                 },

crates/theme2/src/themes/ayu.rs 🔗

@@ -21,18 +21,23 @@ pub fn ayu() -> UserThemeFamily {
                     colors: ThemeColorsRefinement {
                         border: Some(rgba(0x6b7d8f1f).into()),
                         border_variant: Some(rgba(0x6b7d8f1f).into()),
-                        border_focused: Some(rgba(0xffaa32b3).into()),
+                        border_focused: Some(rgba(0xffaa33b3).into()),
                         border_selected: Some(rgba(0x6b7d8f1f).into()),
                         border_transparent: Some(rgba(0x6b7d8f1f).into()),
                         border_disabled: Some(rgba(0x6b7d8f1f).into()),
-                        elevated_surface_background: Some(rgba(0xf8f9faff).into()),
+                        elevated_surface_background: Some(rgba(0xfcfcfcff).into()),
                         surface_background: Some(rgba(0xf8f9faff).into()),
                         background: Some(rgba(0xf8f9faff).into()),
-                        element_background: Some(rgba(0xffaa32ff).into()),
-                        element_hover: Some(rgba(0x55728f1f).into()),
-                        element_selected: Some(rgba(0x55728f1f).into()),
-                        ghost_element_hover: Some(rgba(0x55728f1f).into()),
+                        element_background: Some(rgba(0xffaa33ff).into()),
+                        element_hover: Some(rgba(0x56728f1f).into()),
+                        element_selected: Some(rgba(0x56728f1f).into()),
+                        ghost_element_hover: Some(rgba(0x56728f1f).into()),
+                        ghost_element_selected: Some(rgba(0x56728f1f).into()),
                         text: Some(rgba(0x8a9199ff).into()),
+                        status_bar_background: Some(rgba(0xf8f9faff).into()),
+                        title_bar_background: Some(rgba(0xf8f9faff).into()),
+                        toolbar_background: Some(rgba(0xf8f9faff).into()),
+                        tab_bar_background: Some(rgba(0xf8f9faff).into()),
                         tab_inactive_background: Some(rgba(0xf8f9faff).into()),
                         tab_active_background: Some(rgba(0xf8f9faff).into()),
                         editor_background: Some(rgba(0xf8f9faff).into()),
@@ -41,27 +46,31 @@ pub fn ayu() -> UserThemeFamily {
                         editor_active_line_number: Some(rgba(0x5c6166ff).into()),
                         terminal_background: Some(rgba(0xf8f9faff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x686868ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xef7070ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xf07171ff).into()),
                         terminal_ansi_bright_green: Some(rgba(0x86b300ff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xf2ad48ff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x389ee6ff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xf2ae49ff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x399ee6ff).into()),
                         terminal_ansi_bright_magenta: Some(rgba(0xa37accff).into()),
-                        terminal_ansi_bright_cyan: Some(rgba(0x4bbf98ff).into()),
+                        terminal_ansi_bright_cyan: Some(rgba(0x4cbf99ff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xd1d1d1ff).into()),
                         terminal_ansi_black: Some(rgba(0x000000ff).into()),
                         terminal_ansi_red: Some(rgba(0xea6c6dff).into()),
                         terminal_ansi_green: Some(rgba(0x6cbf43ff).into()),
                         terminal_ansi_yellow: Some(rgba(0xeca944ff).into()),
-                        terminal_ansi_blue: Some(rgba(0x3198e1ff).into()),
+                        terminal_ansi_blue: Some(rgba(0x3199e1ff).into()),
                         terminal_ansi_magenta: Some(rgba(0x9e75c7ff).into()),
                         terminal_ansi_cyan: Some(rgba(0x46ba94ff).into()),
                         terminal_ansi_white: Some(rgba(0xc7c7c7ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xe65050ff).into()),
+                        created: Some(rgba(0x6cbf43cc).into()),
+                        deleted: Some(rgba(0xff7383cc).into()),
                         error: Some(rgba(0xe65050ff).into()),
                         hidden: Some(rgba(0x8a9199ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x8a919980).into()),
+                        modified: Some(rgba(0x478acccc).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -69,7 +78,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "attribute".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf2ad48ff).into()),
+                                    color: Some(rgba(0xf2ae49ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -88,10 +97,25 @@ pub fn ayu() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x787b8099).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "constant".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x4bbf98ff).into()),
+                                    color: Some(rgba(0xa37accff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x55b4d4ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -105,7 +129,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "emphasis".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xef7070ff).into()),
+                                    color: Some(rgba(0xf07171ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -113,7 +137,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xef7070ff).into()),
+                                    color: Some(rgba(0xf07171ff).into()),
                                     font_weight: Some(UserFontWeight(700.0)),
                                     ..Default::default()
                                 },
@@ -121,7 +145,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf2ad48ff).into()),
+                                    color: Some(rgba(0xf2ae49ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -142,14 +166,14 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "link_text".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x55b4d3ff).into()),
+                                    color: Some(rgba(0x55b4d4ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_uri".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x55b4d3ff).into()),
+                                    color: Some(rgba(0x55b4d4ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -163,28 +187,28 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "operator".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xed9365ff).into()),
+                                    color: Some(rgba(0xed9366ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xef7070ff).into()),
+                                    color: Some(rgba(0xf07171ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "punctuation".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x5c6166b3).into()),
+                                    color: Some(rgba(0x5c6166ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "punctuation.bracket".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x55b4d380).into()),
+                                    color: Some(rgba(0x55b4d480).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -198,7 +222,14 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "punctuation.list_marker".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf2ad48ff).into()),
+                                    color: Some(rgba(0xf2ae49ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x5c6166ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -212,7 +243,14 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "string.escape".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x4bbf98ff).into()),
+                                    color: Some(rgba(0x4cbf99ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x86b300ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -233,7 +271,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x55b4d3ff).into()),
+                                    color: Some(rgba(0x55b4d4ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -247,14 +285,14 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "title".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x389ee6ff).into()),
+                                    color: Some(rgba(0x399ee6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x55b4d3ff).into()),
+                                    color: Some(rgba(0x55b4d4ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -268,7 +306,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xef7070ff).into()),
+                                    color: Some(rgba(0xf07171ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -281,20 +319,25 @@ pub fn ayu() -> UserThemeFamily {
                 appearance: Appearance::Dark,
                 styles: UserThemeStylesRefinement {
                     colors: ThemeColorsRefinement {
-                        border: Some(rgba(0x171a24ff).into()),
-                        border_variant: Some(rgba(0x171a24ff).into()),
-                        border_focused: Some(rgba(0xffcb65b3).into()),
-                        border_selected: Some(rgba(0x171a24ff).into()),
-                        border_transparent: Some(rgba(0x171a24ff).into()),
-                        border_disabled: Some(rgba(0x171a24ff).into()),
-                        elevated_surface_background: Some(rgba(0x1f2430ff).into()),
+                        border: Some(rgba(0x171b24ff).into()),
+                        border_variant: Some(rgba(0x171b24ff).into()),
+                        border_focused: Some(rgba(0xffcc66b3).into()),
+                        border_selected: Some(rgba(0x171b24ff).into()),
+                        border_transparent: Some(rgba(0x171b24ff).into()),
+                        border_disabled: Some(rgba(0x171b24ff).into()),
+                        elevated_surface_background: Some(rgba(0x242936ff).into()),
                         surface_background: Some(rgba(0x1f2430ff).into()),
                         background: Some(rgba(0x1f2430ff).into()),
-                        element_background: Some(rgba(0xffcb65ff).into()),
+                        element_background: Some(rgba(0xffcc66ff).into()),
                         element_hover: Some(rgba(0x63759926).into()),
                         element_selected: Some(rgba(0x63759926).into()),
                         ghost_element_hover: Some(rgba(0x63759926).into()),
+                        ghost_element_selected: Some(rgba(0x63759926).into()),
                         text: Some(rgba(0x707a8cff).into()),
+                        status_bar_background: Some(rgba(0x1f2430ff).into()),
+                        title_bar_background: Some(rgba(0x1f2430ff).into()),
+                        toolbar_background: Some(rgba(0x1f2430ff).into()),
+                        tab_bar_background: Some(rgba(0x1f2430ff).into()),
                         tab_inactive_background: Some(rgba(0x1f2430ff).into()),
                         tab_active_background: Some(rgba(0x1f2430ff).into()),
                         editor_background: Some(rgba(0x1f2430ff).into()),
@@ -303,27 +346,31 @@ pub fn ayu() -> UserThemeFamily {
                         editor_active_line_number: Some(rgba(0xcccac2ff).into()),
                         terminal_background: Some(rgba(0x1f2430ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x686868ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xf18678ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0xd4fe7fff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xf28779ff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0xd5ff80ff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0xffd173ff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x73cfffff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x73d0ffff).into()),
                         terminal_ansi_bright_magenta: Some(rgba(0xdfbfffff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0x95e6cbff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xffffffff).into()),
-                        terminal_ansi_black: Some(rgba(0x171a24ff).into()),
-                        terminal_ansi_red: Some(rgba(0xed8173ff).into()),
-                        terminal_ansi_green: Some(rgba(0x86d96bff).into()),
+                        terminal_ansi_black: Some(rgba(0x171b24ff).into()),
+                        terminal_ansi_red: Some(rgba(0xed8274ff).into()),
+                        terminal_ansi_green: Some(rgba(0x87d96cff).into()),
                         terminal_ansi_yellow: Some(rgba(0xfacc6eff).into()),
-                        terminal_ansi_blue: Some(rgba(0x6ccafaff).into()),
+                        terminal_ansi_blue: Some(rgba(0x6dcbfaff).into()),
                         terminal_ansi_magenta: Some(rgba(0xdabafaff).into()),
                         terminal_ansi_cyan: Some(rgba(0x90e1c6ff).into()),
                         terminal_ansi_white: Some(rgba(0xc7c7c7ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xff6565ff).into()),
-                        error: Some(rgba(0xff6565ff).into()),
+                        created: Some(rgba(0x87d96ccc).into()),
+                        deleted: Some(rgba(0xf27983cc).into()),
+                        error: Some(rgba(0xff6666ff).into()),
                         hidden: Some(rgba(0x707a8cff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x707a8c80).into()),
+                        modified: Some(rgba(0x80bfffcc).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -350,10 +397,25 @@ pub fn ayu() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb8cfe680).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "constant".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x95e6cbff).into()),
+                                    color: Some(rgba(0xdfbfffff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x5ccfe6ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -367,7 +429,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "emphasis".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf18678ff).into()),
+                                    color: Some(rgba(0xf28779ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -375,7 +437,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf18678ff).into()),
+                                    color: Some(rgba(0xf28779ff).into()),
                                     font_weight: Some(UserFontWeight(700.0)),
                                     ..Default::default()
                                 },
@@ -390,14 +452,14 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xffad65ff).into()),
+                                    color: Some(rgba(0xffad66ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "label".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd4fe7fff).into()),
+                                    color: Some(rgba(0xd5ff80ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -432,14 +494,14 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf18678ff).into()),
+                                    color: Some(rgba(0xf28779ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "punctuation".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xcccac2b3).into()),
+                                    color: Some(rgba(0xcccac2ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -464,10 +526,17 @@ pub fn ayu() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xcccac2ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd4fe7fff).into()),
+                                    color: Some(rgba(0xd5ff80ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -478,17 +547,24 @@ pub fn ayu() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xd5ff80ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd4fe7fff).into()),
+                                    color: Some(rgba(0xd5ff80ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "string.special.symbol".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd4fe7fff).into()),
+                                    color: Some(rgba(0xd5ff80ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -502,14 +578,14 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd4fe7fff).into()),
+                                    color: Some(rgba(0xd5ff80ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "title".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x73cfffff).into()),
+                                    color: Some(rgba(0x73d0ffff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -530,7 +606,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf18678ff).into()),
+                                    color: Some(rgba(0xf28779ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -549,14 +625,19 @@ pub fn ayu() -> UserThemeFamily {
                         border_selected: Some(rgba(0x1e232bff).into()),
                         border_transparent: Some(rgba(0x1e232bff).into()),
                         border_disabled: Some(rgba(0x1e232bff).into()),
-                        elevated_surface_background: Some(rgba(0x0b0e14ff).into()),
+                        elevated_surface_background: Some(rgba(0x0d1017ff).into()),
                         surface_background: Some(rgba(0x0b0e14ff).into()),
                         background: Some(rgba(0x0b0e14ff).into()),
                         element_background: Some(rgba(0xe6b450ff).into()),
                         element_hover: Some(rgba(0x47526640).into()),
                         element_selected: Some(rgba(0x47526640).into()),
                         ghost_element_hover: Some(rgba(0x47526640).into()),
+                        ghost_element_selected: Some(rgba(0x47526640).into()),
                         text: Some(rgba(0x565b66ff).into()),
+                        status_bar_background: Some(rgba(0x0b0e14ff).into()),
+                        title_bar_background: Some(rgba(0x0b0e14ff).into()),
+                        toolbar_background: Some(rgba(0x0b0e14ff).into()),
+                        tab_bar_background: Some(rgba(0x0b0e14ff).into()),
                         tab_inactive_background: Some(rgba(0x0b0e14ff).into()),
                         tab_active_background: Some(rgba(0x0b0e14ff).into()),
                         editor_background: Some(rgba(0x0b0e14ff).into()),
@@ -565,27 +646,31 @@ pub fn ayu() -> UserThemeFamily {
                         editor_active_line_number: Some(rgba(0xbfbdb6ff).into()),
                         terminal_background: Some(rgba(0x0b0e14ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x686868ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xef7077ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0xa9d94bff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xffb353ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xf07178ff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0xaad94cff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xffb454ff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x59c2ffff).into()),
                         terminal_ansi_bright_magenta: Some(rgba(0xd2a6ffff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0x95e6cbff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xffffffff).into()),
                         terminal_ansi_black: Some(rgba(0x1e232bff).into()),
-                        terminal_ansi_red: Some(rgba(0xea6c72ff).into()),
-                        terminal_ansi_green: Some(rgba(0x7ed962ff).into()),
+                        terminal_ansi_red: Some(rgba(0xea6c73ff).into()),
+                        terminal_ansi_green: Some(rgba(0x7fd962ff).into()),
                         terminal_ansi_yellow: Some(rgba(0xf9af4fff).into()),
-                        terminal_ansi_blue: Some(rgba(0x52bdfaff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xcca1faff).into()),
+                        terminal_ansi_blue: Some(rgba(0x53bdfaff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xcda1faff).into()),
                         terminal_ansi_cyan: Some(rgba(0x90e1c6ff).into()),
                         terminal_ansi_white: Some(rgba(0xc7c7c7ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xd95757ff).into()),
+                        created: Some(rgba(0x7fd962cc).into()),
+                        deleted: Some(rgba(0xf26d78cc).into()),
                         error: Some(rgba(0xd95757ff).into()),
                         hidden: Some(rgba(0x565b66ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x565b6680).into()),
+                        modified: Some(rgba(0x73b8ffcc).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -593,7 +678,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "attribute".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xffb353ff).into()),
+                                    color: Some(rgba(0xffb454ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -607,7 +692,15 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "comment".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xabb5be8c).into()),
+                                    color: Some(rgba(0xacb6bf8c).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xacb6bf8c).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -615,7 +708,14 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "constant".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x95e6cbff).into()),
+                                    color: Some(rgba(0xd2a6ffff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x39bae6ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -629,7 +729,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "emphasis".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xef7077ff).into()),
+                                    color: Some(rgba(0xf07178ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -637,7 +737,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xef7077ff).into()),
+                                    color: Some(rgba(0xf07178ff).into()),
                                     font_weight: Some(UserFontWeight(700.0)),
                                     ..Default::default()
                                 },
@@ -645,35 +745,35 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xffb353ff).into()),
+                                    color: Some(rgba(0xffb454ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xff8f3fff).into()),
+                                    color: Some(rgba(0xff8f40ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "label".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xa9d94bff).into()),
+                                    color: Some(rgba(0xaad94cff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_text".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x38b9e6ff).into()),
+                                    color: Some(rgba(0x39bae6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_uri".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x38b9e6ff).into()),
+                                    color: Some(rgba(0x39bae6ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -694,21 +794,21 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xef7077ff).into()),
+                                    color: Some(rgba(0xf07178ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "punctuation".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xbfbdb6b3).into()),
+                                    color: Some(rgba(0xbfbdb6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "punctuation.bracket".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x38b9e680).into()),
+                                    color: Some(rgba(0x39bae680).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -722,14 +822,21 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "punctuation.list_marker".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xffb353ff).into()),
+                                    color: Some(rgba(0xffb454ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xbfbdb6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xa9d94bff).into()),
+                                    color: Some(rgba(0xaad94cff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -740,31 +847,38 @@ pub fn ayu() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xaad94cff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xa9d94bff).into()),
+                                    color: Some(rgba(0xaad94cff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "string.special.symbol".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xa9d94bff).into()),
+                                    color: Some(rgba(0xaad94cff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x38b9e6ff).into()),
+                                    color: Some(rgba(0x39bae6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xa9d94bff).into()),
+                                    color: Some(rgba(0xaad94cff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -778,7 +892,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x38b9e6ff).into()),
+                                    color: Some(rgba(0x39bae6ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -792,7 +906,7 @@ pub fn ayu() -> UserThemeFamily {
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xef7077ff).into()),
+                                    color: Some(rgba(0xf07178ff).into()),
                                     ..Default::default()
                                 },
                             ),

crates/theme2/src/themes/dracula.rs 🔗

@@ -24,29 +24,34 @@ pub fn dracula() -> UserThemeFamily {
                     border_selected: Some(rgba(0xbd93f9ff).into()),
                     border_transparent: Some(rgba(0xbd93f9ff).into()),
                     border_disabled: Some(rgba(0xbd93f9ff).into()),
-                    elevated_surface_background: Some(rgba(0x282a35ff).into()),
-                    surface_background: Some(rgba(0x282a35ff).into()),
-                    background: Some(rgba(0x282a35ff).into()),
+                    elevated_surface_background: Some(rgba(0x343746ff).into()),
+                    surface_background: Some(rgba(0x282a36ff).into()),
+                    background: Some(rgba(0x282a36ff).into()),
                     element_background: Some(rgba(0x44475aff).into()),
                     element_hover: Some(rgba(0x44475a75).into()),
                     element_selected: Some(rgba(0x44475aff).into()),
                     drop_target_background: Some(rgba(0x44475aff).into()),
                     ghost_element_hover: Some(rgba(0x44475a75).into()),
+                    ghost_element_selected: Some(rgba(0x44475aff).into()),
                     text: Some(rgba(0xf8f8f2ff).into()),
+                    status_bar_background: Some(rgba(0x191a21ff).into()),
+                    title_bar_background: Some(rgba(0x21222cff).into()),
+                    toolbar_background: Some(rgba(0x282a36ff).into()),
+                    tab_bar_background: Some(rgba(0x191a21ff).into()),
                     tab_inactive_background: Some(rgba(0x21222cff).into()),
-                    tab_active_background: Some(rgba(0x282a35ff).into()),
-                    editor_background: Some(rgba(0x282a35ff).into()),
-                    editor_gutter_background: Some(rgba(0x282a35ff).into()),
+                    tab_active_background: Some(rgba(0x282a36ff).into()),
+                    editor_background: Some(rgba(0x282a36ff).into()),
+                    editor_gutter_background: Some(rgba(0x282a36ff).into()),
                     editor_line_number: Some(rgba(0x6272a4ff).into()),
                     editor_active_line_number: Some(rgba(0xf8f8f2ff).into()),
-                    terminal_background: Some(rgba(0x282a35ff).into()),
+                    terminal_background: Some(rgba(0x282a36ff).into()),
                     terminal_ansi_bright_black: Some(rgba(0x6272a4ff).into()),
-                    terminal_ansi_bright_red: Some(rgba(0xff6d6dff).into()),
+                    terminal_ansi_bright_red: Some(rgba(0xff6e6eff).into()),
                     terminal_ansi_bright_green: Some(rgba(0x69ff94ff).into()),
                     terminal_ansi_bright_yellow: Some(rgba(0xffffa5ff).into()),
-                    terminal_ansi_bright_blue: Some(rgba(0xd6abfeff).into()),
+                    terminal_ansi_bright_blue: Some(rgba(0xd6acffff).into()),
                     terminal_ansi_bright_magenta: Some(rgba(0xff92dfff).into()),
-                    terminal_ansi_bright_cyan: Some(rgba(0xa3fefeff).into()),
+                    terminal_ansi_bright_cyan: Some(rgba(0xa4ffffff).into()),
                     terminal_ansi_bright_white: Some(rgba(0xffffffff).into()),
                     terminal_ansi_black: Some(rgba(0x21222cff).into()),
                     terminal_ansi_red: Some(rgba(0xff5555ff).into()),
@@ -59,10 +64,15 @@ pub fn dracula() -> UserThemeFamily {
                     ..Default::default()
                 },
                 status: StatusColorsRefinement {
-                    deleted: Some(rgba(0xff5555ff).into()),
+                    conflict: Some(rgba(0xffb86cff).into()),
+                    created: Some(rgba(0x50fa7b80).into()),
+                    deleted: Some(rgba(0xff555580).into()),
                     error: Some(rgba(0xff5555ff).into()),
                     hidden: Some(rgba(0x6272a4ff).into()),
-                    warning: Some(rgba(0xffb76bff).into()),
+                    hint: Some(rgba(0x969696ff).into()),
+                    ignored: Some(rgba(0x6272a4ff).into()),
+                    modified: Some(rgba(0x8be9fd80).into()),
+                    warning: Some(rgba(0xffb86cff).into()),
                     ..Default::default()
                 },
                 syntax: Some(UserSyntaxTheme {
@@ -82,6 +92,27 @@ pub fn dracula() -> UserThemeFamily {
                                 ..Default::default()
                             },
                         ),
+                        (
+                            "comment.doc".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0x6272a4ff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "constant".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xbd93f9ff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "constructor".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xff79c6ff).into()),
+                                ..Default::default()
+                            },
+                        ),
                         (
                             "emphasis".into(),
                             UserHighlightStyle {
@@ -93,7 +124,7 @@ pub fn dracula() -> UserThemeFamily {
                         (
                             "emphasis.strong".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xffb76bff).into()),
+                                color: Some(rgba(0xffb86cff).into()),
                                 font_weight: Some(UserFontWeight(700.0)),
                                 ..Default::default()
                             },
@@ -126,6 +157,13 @@ pub fn dracula() -> UserThemeFamily {
                                 ..Default::default()
                             },
                         ),
+                        (
+                            "number".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xbd93f9ff).into()),
+                                ..Default::default()
+                            },
+                        ),
                         (
                             "string".into(),
                             UserHighlightStyle {
@@ -133,6 +171,34 @@ pub fn dracula() -> UserThemeFamily {
                                 ..Default::default()
                             },
                         ),
+                        (
+                            "string.escape".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xf1fa8cff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "string.regex".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xf1fa8cff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "string.special".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xf1fa8cff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "string.special.symbol".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xf1fa8cff).into()),
+                                ..Default::default()
+                            },
+                        ),
                         (
                             "tag".into(),
                             UserHighlightStyle {
@@ -158,8 +224,7 @@ pub fn dracula() -> UserThemeFamily {
                         (
                             "variable".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xbd93f9ff).into()),
-                                font_style: Some(UserFontStyle::Italic),
+                                color: Some(rgba(0xf8f8f2ff).into()),
                                 ..Default::default()
                             },
                         ),

crates/theme2/src/themes/gruvbox.rs 🔗

@@ -25,13 +25,19 @@ pub fn gruvbox() -> UserThemeFamily {
                         border_selected: Some(rgba(0x3c3836ff).into()),
                         border_transparent: Some(rgba(0x3c3836ff).into()),
                         border_disabled: Some(rgba(0x3c3836ff).into()),
+                        elevated_surface_background: Some(rgba(0x1d2021ff).into()),
                         background: Some(rgba(0x1d2021ff).into()),
-                        element_background: Some(rgba(0x44858780).into()),
+                        element_background: Some(rgba(0x45858880).into()),
                         element_hover: Some(rgba(0x3c383680).into()),
                         element_selected: Some(rgba(0x3c383680).into()),
                         drop_target_background: Some(rgba(0x3c3836ff).into()),
                         ghost_element_hover: Some(rgba(0x3c383680).into()),
+                        ghost_element_selected: Some(rgba(0x3c383680).into()),
                         text: Some(rgba(0xebdbb2ff).into()),
+                        status_bar_background: Some(rgba(0x1d2021ff).into()),
+                        title_bar_background: Some(rgba(0x1d2021ff).into()),
+                        toolbar_background: Some(rgba(0x1d2021ff).into()),
+                        tab_bar_background: Some(rgba(0x1d2021ff).into()),
                         tab_inactive_background: Some(rgba(0x1d2021ff).into()),
                         tab_active_background: Some(rgba(0x32302fff).into()),
                         editor_background: Some(rgba(0x1d2021ff).into()),
@@ -40,27 +46,32 @@ pub fn gruvbox() -> UserThemeFamily {
                         editor_active_line_number: Some(rgba(0xebdbb2ff).into()),
                         terminal_background: Some(rgba(0x1d2021ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x928374ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xfb4833ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0xb8bb25ff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xfabd2eff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xfb4934ff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0xb8bb26ff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xfabd2fff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x83a598ff).into()),
                         terminal_ansi_bright_magenta: Some(rgba(0xd3869bff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0x8ec07cff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xebdbb2ff).into()),
                         terminal_ansi_black: Some(rgba(0x3c3836ff).into()),
-                        terminal_ansi_red: Some(rgba(0xcc241cff).into()),
-                        terminal_ansi_green: Some(rgba(0x989719ff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xd79920ff).into()),
-                        terminal_ansi_blue: Some(rgba(0x448587ff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xb16185ff).into()),
-                        terminal_ansi_cyan: Some(rgba(0x679d6aff).into()),
+                        terminal_ansi_red: Some(rgba(0xcc241dff).into()),
+                        terminal_ansi_green: Some(rgba(0x98971aff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xd79921ff).into()),
+                        terminal_ansi_blue: Some(rgba(0x458588ff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xb16286ff).into()),
+                        terminal_ansi_cyan: Some(rgba(0x689d6aff).into()),
                         terminal_ansi_white: Some(rgba(0xa89984ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xfb4833ff).into()),
-                        error: Some(rgba(0xfb4833ff).into()),
+                        conflict: Some(rgba(0xb16286ff).into()),
+                        created: Some(rgba(0xb8bb26ff).into()),
+                        deleted: Some(rgba(0xfb4934ff).into()),
+                        error: Some(rgba(0xfb4934ff).into()),
                         hidden: Some(rgba(0xa89984ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x7c6f64ff).into()),
+                        modified: Some(rgba(0x83a598ff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -68,7 +79,7 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "attribute".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -81,16 +92,31 @@ pub fn gruvbox() -> UserThemeFamily {
                                 },
                             ),
                             (
-                                "emphasis".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
+                                    color: Some(rgba(0x928374ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constant".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xd3869bff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x8ec07cff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfe7f18ff).into()),
+                                    color: Some(rgba(0xfe8019ff).into()),
                                     font_weight: Some(UserFontWeight(700.0)),
                                     ..Default::default()
                                 },
@@ -98,21 +124,21 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0x8ec07cff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfb4833ff).into()),
+                                    color: Some(rgba(0xfb4934ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "label".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -130,6 +156,13 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "number".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xd3869bff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "operator".into(),
                                 UserHighlightStyle {
@@ -137,10 +170,17 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "preproc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xfe8019ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x679d6aff).into()),
+                                    color: Some(rgba(0x689d6aff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -151,17 +191,66 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb8bb25ff).into()),
+                                    color: Some(rgba(0xb8bb26ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "string.escape".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfb4833ff).into()),
+                                    color: Some(rgba(0xfb4934ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb8bb26ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb8bb26ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb8bb26ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -175,21 +264,21 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb8bb25ff).into()),
+                                    color: Some(rgba(0xb8bb26ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "title".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -200,6 +289,13 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "variable.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x83a598ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                         ],
                     }),
                 },
@@ -215,13 +311,19 @@ pub fn gruvbox() -> UserThemeFamily {
                         border_selected: Some(rgba(0x3c3836ff).into()),
                         border_transparent: Some(rgba(0x3c3836ff).into()),
                         border_disabled: Some(rgba(0x3c3836ff).into()),
+                        elevated_surface_background: Some(rgba(0x282828ff).into()),
                         background: Some(rgba(0x282828ff).into()),
-                        element_background: Some(rgba(0x44858780).into()),
+                        element_background: Some(rgba(0x45858880).into()),
                         element_hover: Some(rgba(0x3c383680).into()),
                         element_selected: Some(rgba(0x3c383680).into()),
                         drop_target_background: Some(rgba(0x3c3836ff).into()),
                         ghost_element_hover: Some(rgba(0x3c383680).into()),
+                        ghost_element_selected: Some(rgba(0x3c383680).into()),
                         text: Some(rgba(0xebdbb2ff).into()),
+                        status_bar_background: Some(rgba(0x282828ff).into()),
+                        title_bar_background: Some(rgba(0x282828ff).into()),
+                        toolbar_background: Some(rgba(0x282828ff).into()),
+                        tab_bar_background: Some(rgba(0x282828ff).into()),
                         tab_inactive_background: Some(rgba(0x282828ff).into()),
                         tab_active_background: Some(rgba(0x3c3836ff).into()),
                         editor_background: Some(rgba(0x282828ff).into()),
@@ -230,27 +332,32 @@ pub fn gruvbox() -> UserThemeFamily {
                         editor_active_line_number: Some(rgba(0xebdbb2ff).into()),
                         terminal_background: Some(rgba(0x282828ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x928374ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xfb4833ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0xb8bb25ff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xfabd2eff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xfb4934ff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0xb8bb26ff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xfabd2fff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x83a598ff).into()),
                         terminal_ansi_bright_magenta: Some(rgba(0xd3869bff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0x8ec07cff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xebdbb2ff).into()),
                         terminal_ansi_black: Some(rgba(0x3c3836ff).into()),
-                        terminal_ansi_red: Some(rgba(0xcc241cff).into()),
-                        terminal_ansi_green: Some(rgba(0x989719ff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xd79920ff).into()),
-                        terminal_ansi_blue: Some(rgba(0x448587ff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xb16185ff).into()),
-                        terminal_ansi_cyan: Some(rgba(0x679d6aff).into()),
+                        terminal_ansi_red: Some(rgba(0xcc241dff).into()),
+                        terminal_ansi_green: Some(rgba(0x98971aff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xd79921ff).into()),
+                        terminal_ansi_blue: Some(rgba(0x458588ff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xb16286ff).into()),
+                        terminal_ansi_cyan: Some(rgba(0x689d6aff).into()),
                         terminal_ansi_white: Some(rgba(0xa89984ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xfb4833ff).into()),
-                        error: Some(rgba(0xfb4833ff).into()),
+                        conflict: Some(rgba(0xb16286ff).into()),
+                        created: Some(rgba(0xb8bb26ff).into()),
+                        deleted: Some(rgba(0xfb4934ff).into()),
+                        error: Some(rgba(0xfb4934ff).into()),
                         hidden: Some(rgba(0xa89984ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x7c6f64ff).into()),
+                        modified: Some(rgba(0x83a598ff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -258,7 +365,7 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "attribute".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -271,16 +378,31 @@ pub fn gruvbox() -> UserThemeFamily {
                                 },
                             ),
                             (
-                                "emphasis".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
+                                    color: Some(rgba(0x928374ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constant".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xd3869bff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x8ec07cff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfe7f18ff).into()),
+                                    color: Some(rgba(0xfe8019ff).into()),
                                     font_weight: Some(UserFontWeight(700.0)),
                                     ..Default::default()
                                 },
@@ -288,21 +410,21 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0x8ec07cff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfb4833ff).into()),
+                                    color: Some(rgba(0xfb4934ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "label".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -320,6 +442,13 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "number".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xd3869bff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "operator".into(),
                                 UserHighlightStyle {
@@ -327,10 +456,17 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "preproc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xfe8019ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x679d6aff).into()),
+                                    color: Some(rgba(0x689d6aff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -341,17 +477,66 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb8bb25ff).into()),
+                                    color: Some(rgba(0xb8bb26ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "string.escape".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfb4833ff).into()),
+                                    color: Some(rgba(0xfb4934ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb8bb26ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb8bb26ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb8bb26ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -365,21 +550,21 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb8bb25ff).into()),
+                                    color: Some(rgba(0xb8bb26ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "title".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -390,6 +575,13 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "variable.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x83a598ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                         ],
                     }),
                 },
@@ -405,13 +597,19 @@ pub fn gruvbox() -> UserThemeFamily {
                         border_selected: Some(rgba(0x3c3836ff).into()),
                         border_transparent: Some(rgba(0x3c3836ff).into()),
                         border_disabled: Some(rgba(0x3c3836ff).into()),
+                        elevated_surface_background: Some(rgba(0x32302fff).into()),
                         background: Some(rgba(0x32302fff).into()),
-                        element_background: Some(rgba(0x44858780).into()),
+                        element_background: Some(rgba(0x45858880).into()),
                         element_hover: Some(rgba(0x3c383680).into()),
                         element_selected: Some(rgba(0x3c383680).into()),
                         drop_target_background: Some(rgba(0x3c3836ff).into()),
                         ghost_element_hover: Some(rgba(0x3c383680).into()),
+                        ghost_element_selected: Some(rgba(0x3c383680).into()),
                         text: Some(rgba(0xebdbb2ff).into()),
+                        status_bar_background: Some(rgba(0x32302fff).into()),
+                        title_bar_background: Some(rgba(0x32302fff).into()),
+                        toolbar_background: Some(rgba(0x32302fff).into()),
+                        tab_bar_background: Some(rgba(0x32302fff).into()),
                         tab_inactive_background: Some(rgba(0x32302fff).into()),
                         tab_active_background: Some(rgba(0x504945ff).into()),
                         editor_background: Some(rgba(0x32302fff).into()),
@@ -420,27 +618,32 @@ pub fn gruvbox() -> UserThemeFamily {
                         editor_active_line_number: Some(rgba(0xebdbb2ff).into()),
                         terminal_background: Some(rgba(0x32302fff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x928374ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xfb4833ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0xb8bb25ff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xfabd2eff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xfb4934ff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0xb8bb26ff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xfabd2fff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x83a598ff).into()),
                         terminal_ansi_bright_magenta: Some(rgba(0xd3869bff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0x8ec07cff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xebdbb2ff).into()),
                         terminal_ansi_black: Some(rgba(0x3c3836ff).into()),
-                        terminal_ansi_red: Some(rgba(0xcc241cff).into()),
-                        terminal_ansi_green: Some(rgba(0x989719ff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xd79920ff).into()),
-                        terminal_ansi_blue: Some(rgba(0x448587ff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xb16185ff).into()),
-                        terminal_ansi_cyan: Some(rgba(0x679d6aff).into()),
+                        terminal_ansi_red: Some(rgba(0xcc241dff).into()),
+                        terminal_ansi_green: Some(rgba(0x98971aff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xd79921ff).into()),
+                        terminal_ansi_blue: Some(rgba(0x458588ff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xb16286ff).into()),
+                        terminal_ansi_cyan: Some(rgba(0x689d6aff).into()),
                         terminal_ansi_white: Some(rgba(0xa89984ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xfb4833ff).into()),
-                        error: Some(rgba(0xfb4833ff).into()),
+                        conflict: Some(rgba(0xb16286ff).into()),
+                        created: Some(rgba(0xb8bb26ff).into()),
+                        deleted: Some(rgba(0xfb4934ff).into()),
+                        error: Some(rgba(0xfb4934ff).into()),
                         hidden: Some(rgba(0xa89984ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x7c6f64ff).into()),
+                        modified: Some(rgba(0x83a598ff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -448,7 +651,7 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "attribute".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -461,16 +664,31 @@ pub fn gruvbox() -> UserThemeFamily {
                                 },
                             ),
                             (
-                                "emphasis".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
+                                    color: Some(rgba(0x928374ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constant".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xd3869bff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x8ec07cff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfe7f18ff).into()),
+                                    color: Some(rgba(0xfe8019ff).into()),
                                     font_weight: Some(UserFontWeight(700.0)),
                                     ..Default::default()
                                 },
@@ -478,21 +696,21 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0x8ec07cff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfb4833ff).into()),
+                                    color: Some(rgba(0xfb4934ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "label".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -510,6 +728,13 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "number".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xd3869bff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "operator".into(),
                                 UserHighlightStyle {
@@ -517,10 +742,17 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "preproc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xfe8019ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x679d6aff).into()),
+                                    color: Some(rgba(0x689d6aff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -531,17 +763,66 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xa89984ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb8bb25ff).into()),
+                                    color: Some(rgba(0xb8bb26ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "string.escape".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfb4833ff).into()),
+                                    color: Some(rgba(0xfb4934ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb8bb26ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb8bb26ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb8bb26ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -555,21 +836,21 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb8bb25ff).into()),
+                                    color: Some(rgba(0xb8bb26ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "title".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xfabd2eff).into()),
+                                    color: Some(rgba(0xfabd2fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -580,6 +861,13 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "variable.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x83a598ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                         ],
                     }),
                 },
@@ -595,13 +883,19 @@ pub fn gruvbox() -> UserThemeFamily {
                         border_selected: Some(rgba(0xebdbb2ff).into()),
                         border_transparent: Some(rgba(0xebdbb2ff).into()),
                         border_disabled: Some(rgba(0xebdbb2ff).into()),
+                        elevated_surface_background: Some(rgba(0xf9f5d7ff).into()),
                         background: Some(rgba(0xf9f5d7ff).into()),
-                        element_background: Some(rgba(0x44858780).into()),
+                        element_background: Some(rgba(0x45858880).into()),
                         element_hover: Some(rgba(0xebdbb280).into()),
                         element_selected: Some(rgba(0xebdbb280).into()),
                         drop_target_background: Some(rgba(0xebdbb2ff).into()),
                         ghost_element_hover: Some(rgba(0xebdbb280).into()),
+                        ghost_element_selected: Some(rgba(0xebdbb280).into()),
                         text: Some(rgba(0x3c3836ff).into()),
+                        status_bar_background: Some(rgba(0xf9f5d7ff).into()),
+                        title_bar_background: Some(rgba(0xf9f5d7ff).into()),
+                        toolbar_background: Some(rgba(0xf9f5d7ff).into()),
+                        tab_bar_background: Some(rgba(0xf9f5d7ff).into()),
                         tab_inactive_background: Some(rgba(0xf9f5d7ff).into()),
                         tab_active_background: Some(rgba(0xf2e5bcff).into()),
                         editor_background: Some(rgba(0xf9f5d7ff).into()),
@@ -612,25 +906,30 @@ pub fn gruvbox() -> UserThemeFamily {
                         terminal_ansi_bright_black: Some(rgba(0x928374ff).into()),
                         terminal_ansi_bright_red: Some(rgba(0x9d0006ff).into()),
                         terminal_ansi_bright_green: Some(rgba(0x79740eff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xb57613ff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x066578ff).into()),
-                        terminal_ansi_bright_magenta: Some(rgba(0x8f3e71ff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xb57614ff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x076678ff).into()),
+                        terminal_ansi_bright_magenta: Some(rgba(0x8f3f71ff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0x427b58ff).into()),
                         terminal_ansi_bright_white: Some(rgba(0x3c3836ff).into()),
                         terminal_ansi_black: Some(rgba(0xebdbb2ff).into()),
-                        terminal_ansi_red: Some(rgba(0xcc241cff).into()),
-                        terminal_ansi_green: Some(rgba(0x989719ff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xd79920ff).into()),
-                        terminal_ansi_blue: Some(rgba(0x448587ff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xb16185ff).into()),
-                        terminal_ansi_cyan: Some(rgba(0x679d6aff).into()),
+                        terminal_ansi_red: Some(rgba(0xcc241dff).into()),
+                        terminal_ansi_green: Some(rgba(0x98971aff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xd79921ff).into()),
+                        terminal_ansi_blue: Some(rgba(0x458588ff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xb16286ff).into()),
+                        terminal_ansi_cyan: Some(rgba(0x689d6aff).into()),
                         terminal_ansi_white: Some(rgba(0x7c6f64ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
+                        conflict: Some(rgba(0xb16286ff).into()),
+                        created: Some(rgba(0x79740eff).into()),
                         deleted: Some(rgba(0x9d0006ff).into()),
                         error: Some(rgba(0x9d0006ff).into()),
                         hidden: Some(rgba(0x7c6f64ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0xa89984ff).into()),
+                        modified: Some(rgba(0x076678ff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -638,7 +937,7 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "attribute".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb57613ff).into()),
+                                    color: Some(rgba(0xb57614ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -651,16 +950,31 @@ pub fn gruvbox() -> UserThemeFamily {
                                 },
                             ),
                             (
-                                "emphasis".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
+                                    color: Some(rgba(0x928374ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constant".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x8f3f71ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x427b58ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xaf3a02ff).into()),
+                                    color: Some(rgba(0xaf3a03ff).into()),
                                     font_weight: Some(UserFontWeight(700.0)),
                                     ..Default::default()
                                 },
@@ -668,7 +982,7 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb57613ff).into()),
+                                    color: Some(rgba(0x427b58ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -682,21 +996,28 @@ pub fn gruvbox() -> UserThemeFamily {
                             (
                                 "label".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb57613ff).into()),
+                                    color: Some(rgba(0xb57614ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_text".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x8f3e71ff).into()),
+                                    color: Some(rgba(0x8f3f71ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_uri".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x8f3e71ff).into()),
+                                    color: Some(rgba(0x8f3f71ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "number".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x8f3f71ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -707,10 +1028,17 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "preproc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xaf3a03ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x679d6aff).into()),
+                                    color: Some(rgba(0x689d6aff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -721,6 +1049,34 @@ pub fn gruvbox() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x7c6f64ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x7c6f64ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x7c6f64ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x7c6f64ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {

crates/theme2/src/themes/night_owl.rs 🔗

@@ -25,43 +25,53 @@ pub fn night_owl() -> UserThemeFamily {
                         border_selected: Some(rgba(0x5f7e97ff).into()),
                         border_transparent: Some(rgba(0x5f7e97ff).into()),
                         border_disabled: Some(rgba(0x5f7e97ff).into()),
-                        elevated_surface_background: Some(rgba(0x011526ff).into()),
-                        surface_background: Some(rgba(0x011526ff).into()),
-                        background: Some(rgba(0x011526ff).into()),
-                        element_background: Some(rgba(0x7d56c1cc).into()),
-                        element_hover: Some(rgba(0x011526ff).into()),
-                        element_selected: Some(rgba(0x234c708c).into()),
-                        drop_target_background: Some(rgba(0x011526ff).into()),
-                        ghost_element_hover: Some(rgba(0x011526ff).into()),
+                        elevated_surface_background: Some(rgba(0x011627ff).into()),
+                        surface_background: Some(rgba(0x011627ff).into()),
+                        background: Some(rgba(0x011627ff).into()),
+                        element_background: Some(rgba(0x7e57c2cc).into()),
+                        element_hover: Some(rgba(0x011627ff).into()),
+                        element_selected: Some(rgba(0x234d708c).into()),
+                        drop_target_background: Some(rgba(0x011627ff).into()),
+                        ghost_element_hover: Some(rgba(0x011627ff).into()),
+                        ghost_element_selected: Some(rgba(0x234d708c).into()),
                         text: Some(rgba(0xd6deebff).into()),
-                        tab_inactive_background: Some(rgba(0x01101cff).into()),
-                        tab_active_background: Some(rgba(0x0a2842ff).into()),
-                        editor_background: Some(rgba(0x011526ff).into()),
-                        editor_gutter_background: Some(rgba(0x011526ff).into()),
+                        status_bar_background: Some(rgba(0x011627ff).into()),
+                        title_bar_background: Some(rgba(0x011627ff).into()),
+                        toolbar_background: Some(rgba(0x011627ff).into()),
+                        tab_bar_background: Some(rgba(0x011627ff).into()),
+                        tab_inactive_background: Some(rgba(0x01111dff).into()),
+                        tab_active_background: Some(rgba(0x0b2942ff).into()),
+                        editor_background: Some(rgba(0x011627ff).into()),
+                        editor_gutter_background: Some(rgba(0x011627ff).into()),
                         editor_line_number: Some(rgba(0x4b6479ff).into()),
                         editor_active_line_number: Some(rgba(0xd6deebff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x575656ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xef524fff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0x21da6eff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xef5350ff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0x22da6eff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0xffeb95ff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x82aaffff).into()),
                         terminal_ansi_bright_magenta: Some(rgba(0xc792eaff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0x7fdbcaff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xffffffff).into()),
-                        terminal_ansi_black: Some(rgba(0x011526ff).into()),
-                        terminal_ansi_red: Some(rgba(0xef524fff).into()),
-                        terminal_ansi_green: Some(rgba(0x21da6eff).into()),
+                        terminal_ansi_black: Some(rgba(0x011627ff).into()),
+                        terminal_ansi_red: Some(rgba(0xef5350ff).into()),
+                        terminal_ansi_green: Some(rgba(0x22da6eff).into()),
                         terminal_ansi_yellow: Some(rgba(0xc5e478ff).into()),
                         terminal_ansi_blue: Some(rgba(0x82aaffff).into()),
                         terminal_ansi_magenta: Some(rgba(0xc792eaff).into()),
-                        terminal_ansi_cyan: Some(rgba(0x20c7a7ff).into()),
+                        terminal_ansi_cyan: Some(rgba(0x21c7a8ff).into()),
                         terminal_ansi_white: Some(rgba(0xffffffff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xef524fff).into()),
-                        error: Some(rgba(0xef524fff).into()),
+                        conflict: Some(rgba(0xffeb95cc).into()),
+                        created: Some(rgba(0x9ccc65ff).into()),
+                        deleted: Some(rgba(0xef5350ff).into()),
+                        error: Some(rgba(0xef5350ff).into()),
                         hidden: Some(rgba(0x5f7e97ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x395a75ff).into()),
+                        modified: Some(rgba(0xe2b93dff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -89,6 +99,14 @@ pub fn night_owl() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x637777ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "constant".into(),
                                 UserHighlightStyle {
@@ -96,10 +114,17 @@ pub fn night_owl() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xcaece6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xc792eaff).into()),
+                                    color: Some(rgba(0x82aaffff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -115,7 +140,7 @@ pub fn night_owl() -> UserThemeFamily {
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf78b6bff).into()),
+                                    color: Some(rgba(0xf78c6cff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -129,7 +154,7 @@ pub fn night_owl() -> UserThemeFamily {
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x7fcac3ff).into()),
+                                    color: Some(rgba(0x80cbc4ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -141,6 +166,38 @@ pub fn night_owl() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
@@ -155,6 +212,27 @@ pub fn night_owl() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xecc48dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xecc48dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xecc48dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
@@ -208,11 +286,16 @@ pub fn night_owl() -> UserThemeFamily {
                         elevated_surface_background: Some(rgba(0xf0f0f0ff).into()),
                         surface_background: Some(rgba(0xf0f0f0ff).into()),
                         background: Some(rgba(0xfbfbfbff).into()),
-                        element_background: Some(rgba(0x29a298ff).into()),
-                        element_hover: Some(rgba(0xd3e7f8ff).into()),
-                        element_selected: Some(rgba(0xd3e7f8ff).into()),
-                        ghost_element_hover: Some(rgba(0xd3e7f8ff).into()),
+                        element_background: Some(rgba(0x2aa298ff).into()),
+                        element_hover: Some(rgba(0xd3e8f8ff).into()),
+                        element_selected: Some(rgba(0xd3e8f8ff).into()),
+                        ghost_element_hover: Some(rgba(0xd3e8f8ff).into()),
+                        ghost_element_selected: Some(rgba(0xd3e8f8ff).into()),
                         text: Some(rgba(0x403f53ff).into()),
+                        status_bar_background: Some(rgba(0xf0f0f0ff).into()),
+                        title_bar_background: Some(rgba(0xf0f0f0ff).into()),
+                        toolbar_background: Some(rgba(0xfbfbfbff).into()),
+                        tab_bar_background: Some(rgba(0xf0f0f0ff).into()),
                         tab_inactive_background: Some(rgba(0xf0f0f0ff).into()),
                         tab_active_background: Some(rgba(0xf6f6f6ff).into()),
                         editor_background: Some(rgba(0xfbfbfbff).into()),
@@ -221,28 +304,31 @@ pub fn night_owl() -> UserThemeFamily {
                         editor_active_line_number: Some(rgba(0x403f53ff).into()),
                         terminal_background: Some(rgba(0xf6f6f6ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x403f53ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xde3c3aff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0x07916aff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xdaa900ff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x278dd7ff).into()),
-                        terminal_ansi_bright_magenta: Some(rgba(0xd64289ff).into()),
-                        terminal_ansi_bright_cyan: Some(rgba(0x29a298ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xde3d3bff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0x08916aff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xdaaa01ff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x288ed7ff).into()),
+                        terminal_ansi_bright_magenta: Some(rgba(0xd6438aff).into()),
+                        terminal_ansi_bright_cyan: Some(rgba(0x2aa298ff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xf0f0f0ff).into()),
                         terminal_ansi_black: Some(rgba(0x403f53ff).into()),
-                        terminal_ansi_red: Some(rgba(0xde3c3aff).into()),
-                        terminal_ansi_green: Some(rgba(0x07916aff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xe0ae01ff).into()),
-                        terminal_ansi_blue: Some(rgba(0x278dd7ff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xd64289ff).into()),
-                        terminal_ansi_cyan: Some(rgba(0x29a298ff).into()),
+                        terminal_ansi_red: Some(rgba(0xde3d3bff).into()),
+                        terminal_ansi_green: Some(rgba(0x08916aff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xe0af02ff).into()),
+                        terminal_ansi_blue: Some(rgba(0x288ed7ff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xd6438aff).into()),
+                        terminal_ansi_cyan: Some(rgba(0x2aa298ff).into()),
                         terminal_ansi_white: Some(rgba(0xf0f0f0ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0x403f53ff).into()),
+                        created: Some(rgba(0x49d0c5ff).into()),
+                        deleted: Some(rgba(0xf76e6eff).into()),
                         error: Some(rgba(0x403f53ff).into()),
                         hidden: Some(rgba(0x403f53ff).into()),
-                        warning: Some(rgba(0xdaa900ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        modified: Some(rgba(0x6fbef6ff).into()),
+                        warning: Some(rgba(0xdaaa01ff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -270,6 +356,14 @@ pub fn night_owl() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x989fb1ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "constant".into(),
                                 UserHighlightStyle {
@@ -277,10 +371,17 @@ pub fn night_owl() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x994cc3ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x994bc3ff).into()),
+                                    color: Some(rgba(0x4876d6ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -288,7 +389,7 @@ pub fn night_owl() -> UserThemeFamily {
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x994bc3ff).into()),
+                                    color: Some(rgba(0x994cc3ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -296,28 +397,60 @@ pub fn night_owl() -> UserThemeFamily {
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xaa0881ff).into()),
+                                    color: Some(rgba(0xaa0982ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "operator".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0b969bff).into()),
+                                    color: Some(rgba(0x0c969bff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0b969bff).into()),
+                                    color: Some(rgba(0x0c969bff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "punctuation".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x994bc3ff).into()),
+                                    color: Some(rgba(0x994cc3ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x994cc3ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x994cc3ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x994cc3ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x994cc3ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -336,10 +469,31 @@ pub fn night_owl() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x4876d6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x4876d6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x4876d6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x994bc3ff).into()),
+                                    color: Some(rgba(0x994cc3ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -367,7 +521,7 @@ pub fn night_owl() -> UserThemeFamily {
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0b969bff).into()),
+                                    color: Some(rgba(0x0c969bff).into()),
                                     ..Default::default()
                                 },
                             ),

crates/theme2/src/themes/noctis.rs 🔗

@@ -19,50 +19,60 @@ pub fn noctis() -> UserThemeFamily {
                 appearance: Appearance::Dark,
                 styles: UserThemeStylesRefinement {
                     colors: ThemeColorsRefinement {
-                        border: Some(rgba(0x1579b6ff).into()),
-                        border_variant: Some(rgba(0x1579b6ff).into()),
-                        border_focused: Some(rgba(0x08324eff).into()),
-                        border_selected: Some(rgba(0x1579b6ff).into()),
-                        border_transparent: Some(rgba(0x1579b6ff).into()),
-                        border_disabled: Some(rgba(0x1579b6ff).into()),
-                        elevated_surface_background: Some(rgba(0x051b28ff).into()),
-                        surface_background: Some(rgba(0x051b28ff).into()),
-                        background: Some(rgba(0x07263aff).into()),
-                        element_background: Some(rgba(0x007e99ff).into()),
+                        border: Some(rgba(0x1679b6ff).into()),
+                        border_variant: Some(rgba(0x1679b6ff).into()),
+                        border_focused: Some(rgba(0x09334eff).into()),
+                        border_selected: Some(rgba(0x1679b6ff).into()),
+                        border_transparent: Some(rgba(0x1679b6ff).into()),
+                        border_disabled: Some(rgba(0x1679b6ff).into()),
+                        elevated_surface_background: Some(rgba(0x09334eff).into()),
+                        surface_background: Some(rgba(0x051b29ff).into()),
+                        background: Some(rgba(0x07273bff).into()),
+                        element_background: Some(rgba(0x007f99ff).into()),
                         element_hover: Some(rgba(0x00558a65).into()),
-                        element_selected: Some(rgba(0x0b3f5fff).into()),
-                        drop_target_background: Some(rgba(0x00294dff).into()),
+                        element_selected: Some(rgba(0x0c3f5fff).into()),
+                        drop_target_background: Some(rgba(0x002a4dff).into()),
                         ghost_element_hover: Some(rgba(0x00558a65).into()),
+                        ghost_element_selected: Some(rgba(0x0c3f5fff).into()),
                         text: Some(rgba(0xbecfdaff).into()),
-                        tab_inactive_background: Some(rgba(0x08324eff).into()),
-                        tab_active_background: Some(rgba(0x07263aff).into()),
-                        editor_background: Some(rgba(0x07263aff).into()),
-                        editor_gutter_background: Some(rgba(0x07263aff).into()),
-                        editor_line_number: Some(rgba(0x4c6b7fff).into()),
+                        status_bar_background: Some(rgba(0x07273bff).into()),
+                        title_bar_background: Some(rgba(0x07273bff).into()),
+                        toolbar_background: Some(rgba(0x07273bff).into()),
+                        tab_bar_background: Some(rgba(0x09334eff).into()),
+                        tab_inactive_background: Some(rgba(0x09334eff).into()),
+                        tab_active_background: Some(rgba(0x07273bff).into()),
+                        editor_background: Some(rgba(0x07273bff).into()),
+                        editor_gutter_background: Some(rgba(0x07273bff).into()),
+                        editor_line_number: Some(rgba(0x4d6c80ff).into()),
                         editor_active_line_number: Some(rgba(0xbecfdaff).into()),
-                        terminal_background: Some(rgba(0x051b28ff).into()),
+                        terminal_background: Some(rgba(0x051b29ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x475e6cff).into()),
                         terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0x5febb1ff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xe69532ff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x5fb5ebff).into()),
-                        terminal_ansi_bright_magenta: Some(rgba(0xe697b2ff).into()),
-                        terminal_ansi_bright_cyan: Some(rgba(0x5fdaebff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0x60ebb1ff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xe69533ff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x60b6ebff).into()),
+                        terminal_ansi_bright_magenta: Some(rgba(0xe798b3ff).into()),
+                        terminal_ansi_bright_cyan: Some(rgba(0x60dbebff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xbecfdaff).into()),
-                        terminal_ansi_black: Some(rgba(0x28343dff).into()),
-                        terminal_ansi_red: Some(rgba(0xe66432ff).into()),
+                        terminal_ansi_black: Some(rgba(0x28353eff).into()),
+                        terminal_ansi_red: Some(rgba(0xe66533ff).into()),
                         terminal_ansi_green: Some(rgba(0x49e9a6ff).into()),
                         terminal_ansi_yellow: Some(rgba(0xe4b781ff).into()),
                         terminal_ansi_blue: Some(rgba(0x49ace9ff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xdf759aff).into()),
-                        terminal_ansi_cyan: Some(rgba(0x49d5e9ff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xdf769bff).into()),
+                        terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()),
                         terminal_ansi_white: Some(rgba(0xaec3d0ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xe34d1bff).into()),
-                        error: Some(rgba(0xe34d1bff).into()),
+                        conflict: Some(rgba(0xffc180ff).into()),
+                        created: Some(rgba(0x8ce99aff).into()),
+                        deleted: Some(rgba(0xe34e1cff).into()),
+                        error: Some(rgba(0xe34e1cff).into()),
                         hidden: Some(rgba(0x9fb6c6ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x5b788bff).into()),
+                        modified: Some(rgba(0xffc180ff).into()),
                         warning: Some(rgba(0xffa857ff).into()),
                         ..Default::default()
                     },
@@ -71,98 +81,105 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "boolean".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x705febff).into()),
+                                    color: Some(rgba(0x7060ebff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "comment".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x5888a5ff).into()),
+                                    color: Some(rgba(0x5988a6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "constant".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xbecfdaff).into()),
+                                    color: Some(rgba(0x5988a6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "constructor".into(),
+                                "constant".into(),
                                 UserHighlightStyle {
-                                    font_weight: Some(UserFontWeight(700.0)),
+                                    color: Some(rgba(0xd5971aff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "emphasis".into(),
+                                "constructor".into(),
                                 UserHighlightStyle {
-                                    font_style: Some(UserFontStyle::Italic),
+                                    color: Some(rgba(0xe66533ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x15a2b6ff).into()),
+                                    color: Some(rgba(0x16a3b6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xdf759aff).into()),
+                                    color: Some(rgba(0xe66533ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "label".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x49d5e9ff).into()),
+                                    color: Some(rgba(0x49d6e9ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_text".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x15a2b6ff).into()),
+                                    color: Some(rgba(0x49d6e9ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_uri".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x15a2b6ff).into()),
+                                    color: Some(rgba(0x49d6e9ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x705febff).into()),
+                                    color: Some(rgba(0x7060ebff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "operator".into(),
+                                "preproc".into(),
                                 UserHighlightStyle {
-                                    font_weight: Some(UserFontWeight(700.0)),
+                                    color: Some(rgba(0xdf769bff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x15a2b6ff).into()),
+                                    color: Some(rgba(0x16a3b6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "punctuation".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x5888a5ff).into()),
+                                    color: Some(rgba(0xbecfdaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xbecfdaff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -173,6 +190,20 @@ pub fn noctis() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xbecfdaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xbecfdaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
@@ -187,10 +218,31 @@ pub fn noctis() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x49e9a6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x49e9a6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x49e9a6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xdf759aff).into()),
+                                    color: Some(rgba(0xe66533ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -204,14 +256,14 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "title".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x49d5e9ff).into()),
+                                    color: Some(rgba(0x49d6e9ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x49d5e9ff).into()),
+                                    color: Some(rgba(0xd67e5cff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -225,7 +277,7 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xe66432ff).into()),
+                                    color: Some(rgba(0xe66533ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -244,15 +296,20 @@ pub fn noctis() -> UserThemeFamily {
                         border_selected: Some(rgba(0x997582ff).into()),
                         border_transparent: Some(rgba(0x997582ff).into()),
                         border_disabled: Some(rgba(0x997582ff).into()),
-                        elevated_surface_background: Some(rgba(0x272022ff).into()),
+                        elevated_surface_background: Some(rgba(0x413036ff).into()),
                         surface_background: Some(rgba(0x272022ff).into()),
                         background: Some(rgba(0x322a2dff).into()),
-                        element_background: Some(rgba(0x007e99ff).into()),
+                        element_background: Some(rgba(0x007f99ff).into()),
                         element_hover: Some(rgba(0x533641ff).into()),
                         element_selected: Some(rgba(0x5c2e3e99).into()),
                         drop_target_background: Some(rgba(0x38292eff).into()),
                         ghost_element_hover: Some(rgba(0x533641ff).into()),
+                        ghost_element_selected: Some(rgba(0x5c2e3e99).into()),
                         text: Some(rgba(0xcbbec2ff).into()),
+                        status_bar_background: Some(rgba(0x322a2dff).into()),
+                        title_bar_background: Some(rgba(0x322a2dff).into()),
+                        toolbar_background: Some(rgba(0x322a2dff).into()),
+                        tab_bar_background: Some(rgba(0x413036ff).into()),
                         tab_inactive_background: Some(rgba(0x413036ff).into()),
                         tab_active_background: Some(rgba(0x322a2dff).into()),
                         editor_background: Some(rgba(0x322a2dff).into()),
@@ -262,26 +319,31 @@ pub fn noctis() -> UserThemeFamily {
                         terminal_background: Some(rgba(0x272022ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x69545bff).into()),
                         terminal_ansi_bright_red: Some(rgba(0xe97749ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0x5febb1ff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xe69532ff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x5fb5ebff).into()),
-                        terminal_ansi_bright_magenta: Some(rgba(0xe697b2ff).into()),
-                        terminal_ansi_bright_cyan: Some(rgba(0x5fdaebff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0x60ebb1ff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xe69533ff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x60b6ebff).into()),
+                        terminal_ansi_bright_magenta: Some(rgba(0xe798b3ff).into()),
+                        terminal_ansi_bright_cyan: Some(rgba(0x60dbebff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xcbbec2ff).into()),
                         terminal_ansi_black: Some(rgba(0x47393eff).into()),
-                        terminal_ansi_red: Some(rgba(0xe66432ff).into()),
+                        terminal_ansi_red: Some(rgba(0xe66533ff).into()),
                         terminal_ansi_green: Some(rgba(0x49e9a6ff).into()),
                         terminal_ansi_yellow: Some(rgba(0xe4b781ff).into()),
                         terminal_ansi_blue: Some(rgba(0x49ace9ff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xdf759aff).into()),
-                        terminal_ansi_cyan: Some(rgba(0x49d5e9ff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xdf769bff).into()),
+                        terminal_ansi_cyan: Some(rgba(0x49d6e9ff).into()),
                         terminal_ansi_white: Some(rgba(0xb9acb0ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xe34d1bff).into()),
-                        error: Some(rgba(0xe34d1bff).into()),
+                        conflict: Some(rgba(0xffc180ff).into()),
+                        created: Some(rgba(0x8ce99aff).into()),
+                        deleted: Some(rgba(0xe34e1cff).into()),
+                        error: Some(rgba(0xe34e1cff).into()),
                         hidden: Some(rgba(0xbbaab0ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x5b788bff).into()),
+                        modified: Some(rgba(0xffc180ff).into()),
                         warning: Some(rgba(0xffa857ff).into()),
                         ..Default::default()
                     },
@@ -290,98 +352,105 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "boolean".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x705febff).into()),
+                                    color: Some(rgba(0x7060ebff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "comment".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x8b737bff).into()),
+                                    color: Some(rgba(0x8b747cff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "constant".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xcbbec2ff).into()),
+                                    color: Some(rgba(0x8b747cff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "constructor".into(),
+                                "constant".into(),
                                 UserHighlightStyle {
-                                    font_weight: Some(UserFontWeight(700.0)),
+                                    color: Some(rgba(0xd5971aff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "emphasis".into(),
+                                "constructor".into(),
                                 UserHighlightStyle {
-                                    font_style: Some(UserFontStyle::Italic),
+                                    color: Some(rgba(0xe66533ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x15a2b6ff).into()),
+                                    color: Some(rgba(0x16a3b6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xdf759aff).into()),
+                                    color: Some(rgba(0xe66533ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "label".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x49d5e9ff).into()),
+                                    color: Some(rgba(0x49d6e9ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_text".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x15a2b6ff).into()),
+                                    color: Some(rgba(0x49d6e9ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_uri".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x15a2b6ff).into()),
+                                    color: Some(rgba(0x49d6e9ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x705febff).into()),
+                                    color: Some(rgba(0x7060ebff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "operator".into(),
+                                "preproc".into(),
                                 UserHighlightStyle {
-                                    font_weight: Some(UserFontWeight(700.0)),
+                                    color: Some(rgba(0xdf769bff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x15a2b6ff).into()),
+                                    color: Some(rgba(0x16a3b6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "punctuation".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x8b737bff).into()),
+                                    color: Some(rgba(0xcbbec2ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xcbbec2ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -392,6 +461,20 @@ pub fn noctis() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xcbbec2ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xcbbec2ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
@@ -406,10 +489,31 @@ pub fn noctis() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x49e9a6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x49e9a6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x49e9a6ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xdf759aff).into()),
+                                    color: Some(rgba(0xe66533ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -423,14 +527,14 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "title".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x49d5e9ff).into()),
+                                    color: Some(rgba(0x49d6e9ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x49d5e9ff).into()),
+                                    color: Some(rgba(0xd67e5cff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -444,7 +548,7 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xe66432ff).into()),
+                                    color: Some(rgba(0xe66533ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -463,15 +567,20 @@ pub fn noctis() -> UserThemeFamily {
                         border_selected: Some(rgba(0x00c6e0ff).into()),
                         border_transparent: Some(rgba(0x00c6e0ff).into()),
                         border_disabled: Some(rgba(0x00c6e0ff).into()),
-                        elevated_surface_background: Some(rgba(0xe1eeefff).into()),
+                        elevated_surface_background: Some(rgba(0xf4f6f6ff).into()),
                         surface_background: Some(rgba(0xe1eeefff).into()),
                         background: Some(rgba(0xf4f6f6ff).into()),
-                        element_background: Some(rgba(0x089099ff).into()),
+                        element_background: Some(rgba(0x099099ff).into()),
                         element_hover: Some(rgba(0xd1eafaff).into()),
                         element_selected: Some(rgba(0xb6e1e7ff).into()),
-                        drop_target_background: Some(rgba(0xb1c9ccff).into()),
+                        drop_target_background: Some(rgba(0xb2cacdff).into()),
                         ghost_element_hover: Some(rgba(0xd1eafaff).into()),
+                        ghost_element_selected: Some(rgba(0xb6e1e7ff).into()),
                         text: Some(rgba(0x005661ff).into()),
+                        status_bar_background: Some(rgba(0xcaedf2ff).into()),
+                        title_bar_background: Some(rgba(0xe7f2f3ff).into()),
+                        toolbar_background: Some(rgba(0xf4f6f6ff).into()),
+                        tab_bar_background: Some(rgba(0xcaedf2ff).into()),
                         tab_inactive_background: Some(rgba(0xcaedf2ff).into()),
                         tab_active_background: Some(rgba(0xf4f6f6ff).into()),
                         editor_background: Some(rgba(0xf4f6f6ff).into()),
@@ -480,17 +589,17 @@ pub fn noctis() -> UserThemeFamily {
                         editor_active_line_number: Some(rgba(0x005661ff).into()),
                         terminal_background: Some(rgba(0xe1eeefff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x004d57ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xff3f00ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xff4000ff).into()),
                         terminal_ansi_bright_green: Some(rgba(0x00d17aff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0xff8c00ff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x0ea3ffff).into()),
-                        terminal_ansi_bright_magenta: Some(rgba(0xff6b9eff).into()),
-                        terminal_ansi_bright_cyan: Some(rgba(0x00cae6ff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x0fa3ffff).into()),
+                        terminal_ansi_bright_magenta: Some(rgba(0xff6b9fff).into()),
+                        terminal_ansi_bright_cyan: Some(rgba(0x00cbe6ff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xbbc3c4ff).into()),
-                        terminal_ansi_black: Some(rgba(0x003b41ff).into()),
-                        terminal_ansi_red: Some(rgba(0xe34d1bff).into()),
+                        terminal_ansi_black: Some(rgba(0x003b42ff).into()),
+                        terminal_ansi_red: Some(rgba(0xe34e1cff).into()),
                         terminal_ansi_green: Some(rgba(0x00b368ff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xf49724ff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xf49725ff).into()),
                         terminal_ansi_blue: Some(rgba(0x0094f0ff).into()),
                         terminal_ansi_magenta: Some(rgba(0xff5792ff).into()),
                         terminal_ansi_cyan: Some(rgba(0x00bdd6ff).into()),
@@ -498,9 +607,14 @@ pub fn noctis() -> UserThemeFamily {
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xff3f00ff).into()),
-                        error: Some(rgba(0xff3f00ff).into()),
-                        hidden: Some(rgba(0x70838dff).into()),
+                        conflict: Some(rgba(0xe9a149ff).into()),
+                        created: Some(rgba(0x8ce99aff).into()),
+                        deleted: Some(rgba(0xff4000ff).into()),
+                        error: Some(rgba(0xff4000ff).into()),
+                        hidden: Some(rgba(0x71838eff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0xa8a28faa).into()),
+                        modified: Some(rgba(0xe9a149ff).into()),
                         warning: Some(rgba(0xe07a52ff).into()),
                         ..Default::default()
                     },
@@ -509,7 +623,7 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "boolean".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x5841ffff).into()),
+                                    color: Some(rgba(0x5842ffff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -521,37 +635,37 @@ pub fn noctis() -> UserThemeFamily {
                                 },
                             ),
                             (
-                                "constant".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x004d57ff).into()),
+                                    color: Some(rgba(0x8ca6a6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "constructor".into(),
+                                "constant".into(),
                                 UserHighlightStyle {
-                                    font_weight: Some(UserFontWeight(700.0)),
+                                    color: Some(rgba(0xa88c00ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "emphasis".into(),
+                                "constructor".into(),
                                 UserHighlightStyle {
-                                    font_style: Some(UserFontStyle::Italic),
+                                    color: Some(rgba(0xe64100ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0094a8ff).into()),
+                                    color: Some(rgba(0x0095a8ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xff5792ff).into()),
+                                    color: Some(rgba(0xe64100ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -565,42 +679,49 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "link_text".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0094a8ff).into()),
+                                    color: Some(rgba(0x00bdd6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_uri".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0094a8ff).into()),
+                                    color: Some(rgba(0x00bdd6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x5841ffff).into()),
+                                    color: Some(rgba(0x5842ffff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "operator".into(),
+                                "preproc".into(),
                                 UserHighlightStyle {
-                                    font_weight: Some(UserFontWeight(700.0)),
+                                    color: Some(rgba(0xff5792ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0094a8ff).into()),
+                                    color: Some(rgba(0x0095a8ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "punctuation".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x8ca6a6ff).into()),
+                                    color: Some(rgba(0x004d57ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x004d57ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -611,6 +732,20 @@ pub fn noctis() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x004d57ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x004d57ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
@@ -625,10 +760,31 @@ pub fn noctis() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x00b368ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x00b368ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x00b368ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xff5792ff).into()),
+                                    color: Some(rgba(0xe64100ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -649,7 +805,7 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x00bdd6ff).into()),
+                                    color: Some(rgba(0xb3694dff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -682,34 +838,39 @@ pub fn noctis() -> UserThemeFamily {
                         border_selected: Some(rgba(0xaea4f4ff).into()),
                         border_transparent: Some(rgba(0xaea4f4ff).into()),
                         border_disabled: Some(rgba(0xaea4f4ff).into()),
-                        elevated_surface_background: Some(rgba(0xe9e7f3ff).into()),
+                        elevated_surface_background: Some(rgba(0xf2f1f8ff).into()),
                         surface_background: Some(rgba(0xe9e7f3ff).into()),
                         background: Some(rgba(0xf2f1f8ff).into()),
-                        element_background: Some(rgba(0x8d7ffeff).into()),
-                        element_hover: Some(rgba(0xd1cbfeff).into()),
+                        element_background: Some(rgba(0x8e80ffff).into()),
+                        element_hover: Some(rgba(0xd2ccffff).into()),
                         element_selected: Some(rgba(0xbcb6e7ff).into()),
                         drop_target_background: Some(rgba(0xafaad4aa).into()),
-                        ghost_element_hover: Some(rgba(0xd1cbfeff).into()),
+                        ghost_element_hover: Some(rgba(0xd2ccffff).into()),
+                        ghost_element_selected: Some(rgba(0xbcb6e7ff).into()),
                         text: Some(rgba(0x0c006bff).into()),
+                        status_bar_background: Some(rgba(0xe2dff6ff).into()),
+                        title_bar_background: Some(rgba(0xedecf8ff).into()),
+                        toolbar_background: Some(rgba(0xf2f1f8ff).into()),
+                        tab_bar_background: Some(rgba(0xe2dff6ff).into()),
                         tab_inactive_background: Some(rgba(0xe2dff6ff).into()),
                         tab_active_background: Some(rgba(0xf2f1f8ff).into()),
                         editor_background: Some(rgba(0xf2f1f8ff).into()),
                         editor_gutter_background: Some(rgba(0xf2f1f8ff).into()),
-                        editor_line_number: Some(rgba(0x9c99b0ff).into()),
+                        editor_line_number: Some(rgba(0x9d9ab1ff).into()),
                         editor_active_line_number: Some(rgba(0x0c006bff).into()),
                         terminal_background: Some(rgba(0xe9e7f3ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x0f0080ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xff3f00ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xff4000ff).into()),
                         terminal_ansi_bright_green: Some(rgba(0x00d17aff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0xff8c00ff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x0ea3ffff).into()),
-                        terminal_ansi_bright_magenta: Some(rgba(0xff6b9eff).into()),
-                        terminal_ansi_bright_cyan: Some(rgba(0x00cae6ff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x0fa3ffff).into()),
+                        terminal_ansi_bright_magenta: Some(rgba(0xff6b9fff).into()),
+                        terminal_ansi_bright_cyan: Some(rgba(0x00cbe6ff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xbbc3c4ff).into()),
                         terminal_ansi_black: Some(rgba(0x0c006bff).into()),
-                        terminal_ansi_red: Some(rgba(0xe34d1bff).into()),
+                        terminal_ansi_red: Some(rgba(0xe34e1cff).into()),
                         terminal_ansi_green: Some(rgba(0x00b368ff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xf49724ff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xf49725ff).into()),
                         terminal_ansi_blue: Some(rgba(0x0094f0ff).into()),
                         terminal_ansi_magenta: Some(rgba(0xff5792ff).into()),
                         terminal_ansi_cyan: Some(rgba(0x00bdd6ff).into()),
@@ -717,9 +878,14 @@ pub fn noctis() -> UserThemeFamily {
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xff3f00ff).into()),
-                        error: Some(rgba(0xff3f00ff).into()),
-                        hidden: Some(rgba(0x74708dff).into()),
+                        conflict: Some(rgba(0xe9a149ff).into()),
+                        created: Some(rgba(0x8ce99aff).into()),
+                        deleted: Some(rgba(0xff4000ff).into()),
+                        error: Some(rgba(0xff4000ff).into()),
+                        hidden: Some(rgba(0x75718eff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0xa8a28faa).into()),
+                        modified: Some(rgba(0xe9a149ff).into()),
                         warning: Some(rgba(0xe07a52ff).into()),
                         ..Default::default()
                     },
@@ -728,7 +894,7 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "boolean".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x5841ffff).into()),
+                                    color: Some(rgba(0x5842ffff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -740,37 +906,37 @@ pub fn noctis() -> UserThemeFamily {
                                 },
                             ),
                             (
-                                "constant".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0c006bff).into()),
+                                    color: Some(rgba(0x9995b7ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "constructor".into(),
+                                "constant".into(),
                                 UserHighlightStyle {
-                                    font_weight: Some(UserFontWeight(700.0)),
+                                    color: Some(rgba(0xa88c00ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "emphasis".into(),
+                                "constructor".into(),
                                 UserHighlightStyle {
-                                    font_style: Some(UserFontStyle::Italic),
+                                    color: Some(rgba(0xe64100ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0094a8ff).into()),
+                                    color: Some(rgba(0x0095a8ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xff5792ff).into()),
+                                    color: Some(rgba(0xe64100ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -784,42 +950,49 @@ pub fn noctis() -> UserThemeFamily {
                             (
                                 "link_text".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0094a8ff).into()),
+                                    color: Some(rgba(0x00bdd6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "link_uri".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0094a8ff).into()),
+                                    color: Some(rgba(0x00bdd6ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x5841ffff).into()),
+                                    color: Some(rgba(0x5842ffff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
-                                "operator".into(),
+                                "preproc".into(),
                                 UserHighlightStyle {
-                                    font_weight: Some(UserFontWeight(700.0)),
+                                    color: Some(rgba(0xff5792ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x0094a8ff).into()),
+                                    color: Some(rgba(0x0095a8ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "punctuation".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x9995b7ff).into()),
+                                    color: Some(rgba(0x0c006bff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x0c006bff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -830,6 +1003,20 @@ pub fn noctis() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x0c006bff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x0c006bff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {

crates/theme2/src/themes/nord.rs 🔗

@@ -24,15 +24,20 @@ pub fn nord() -> UserThemeFamily {
                     border_selected: Some(rgba(0x3b4252ff).into()),
                     border_transparent: Some(rgba(0x3b4252ff).into()),
                     border_disabled: Some(rgba(0x3b4252ff).into()),
-                    elevated_surface_background: Some(rgba(0x2e3440ff).into()),
+                    elevated_surface_background: Some(rgba(0x3b4252ff).into()),
                     surface_background: Some(rgba(0x2e3440ff).into()),
                     background: Some(rgba(0x2e3440ff).into()),
-                    element_background: Some(rgba(0x88bfd0ee).into()),
+                    element_background: Some(rgba(0x88c0d0ee).into()),
                     element_hover: Some(rgba(0x3b4252ff).into()),
-                    element_selected: Some(rgba(0x88bfd0ff).into()),
-                    drop_target_background: Some(rgba(0x88bfd099).into()),
+                    element_selected: Some(rgba(0x88c0d0ff).into()),
+                    drop_target_background: Some(rgba(0x88c0d099).into()),
                     ghost_element_hover: Some(rgba(0x3b4252ff).into()),
+                    ghost_element_selected: Some(rgba(0x88c0d0ff).into()),
                     text: Some(rgba(0xd8dee9ff).into()),
+                    status_bar_background: Some(rgba(0x3b4252ff).into()),
+                    title_bar_background: Some(rgba(0x2e3440ff).into()),
+                    toolbar_background: Some(rgba(0x2e3440ff).into()),
+                    tab_bar_background: Some(rgba(0x2e3440ff).into()),
                     tab_inactive_background: Some(rgba(0x2e3440ff).into()),
                     tab_active_background: Some(rgba(0x3b4252ff).into()),
                     editor_background: Some(rgba(0x2e3440ff).into()),
@@ -45,7 +50,7 @@ pub fn nord() -> UserThemeFamily {
                     terminal_ansi_bright_green: Some(rgba(0xa3be8cff).into()),
                     terminal_ansi_bright_yellow: Some(rgba(0xebcb8bff).into()),
                     terminal_ansi_bright_blue: Some(rgba(0x81a1c1ff).into()),
-                    terminal_ansi_bright_magenta: Some(rgba(0xb48eacff).into()),
+                    terminal_ansi_bright_magenta: Some(rgba(0xb48eadff).into()),
                     terminal_ansi_bright_cyan: Some(rgba(0x8fbcbbff).into()),
                     terminal_ansi_bright_white: Some(rgba(0xeceff4ff).into()),
                     terminal_ansi_black: Some(rgba(0x3b4252ff).into()),
@@ -53,15 +58,20 @@ pub fn nord() -> UserThemeFamily {
                     terminal_ansi_green: Some(rgba(0xa3be8cff).into()),
                     terminal_ansi_yellow: Some(rgba(0xebcb8bff).into()),
                     terminal_ansi_blue: Some(rgba(0x81a1c1ff).into()),
-                    terminal_ansi_magenta: Some(rgba(0xb48eacff).into()),
-                    terminal_ansi_cyan: Some(rgba(0x88bfd0ff).into()),
+                    terminal_ansi_magenta: Some(rgba(0xb48eadff).into()),
+                    terminal_ansi_cyan: Some(rgba(0x88c0d0ff).into()),
                     terminal_ansi_white: Some(rgba(0xe5e9f0ff).into()),
                     ..Default::default()
                 },
                 status: StatusColorsRefinement {
+                    conflict: Some(rgba(0x5e81acff).into()),
+                    created: Some(rgba(0xa3be8cff).into()),
                     deleted: Some(rgba(0xbf616aff).into()),
                     error: Some(rgba(0xbf616aff).into()),
                     hidden: Some(rgba(0xd8dee966).into()),
+                    hint: Some(rgba(0xd8dee9ff).into()),
+                    ignored: Some(rgba(0xd8dee966).into()),
+                    modified: Some(rgba(0xebcb8bff).into()),
                     warning: Some(rgba(0xebcb8bff).into()),
                     ..Default::default()
                 },
@@ -84,28 +94,35 @@ pub fn nord() -> UserThemeFamily {
                         (
                             "comment".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0x606e87ff).into()),
+                                color: Some(rgba(0x616e88ff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "comment.doc".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0x616e88ff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "constant".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xebcb8bff).into()),
+                                color: Some(rgba(0x81a1c1ff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
-                            "emphasis.strong".into(),
+                            "constructor".into(),
                             UserHighlightStyle {
-                                font_weight: Some(UserFontWeight(700.0)),
+                                color: Some(rgba(0x81a1c1ff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "function".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0x88bfd0ff).into()),
+                                color: Some(rgba(0x88c0d0ff).into()),
                                 ..Default::default()
                             },
                         ),
@@ -119,7 +136,7 @@ pub fn nord() -> UserThemeFamily {
                         (
                             "number".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xb48eacff).into()),
+                                color: Some(rgba(0xb48eadff).into()),
                                 ..Default::default()
                             },
                         ),
@@ -130,6 +147,13 @@ pub fn nord() -> UserThemeFamily {
                                 ..Default::default()
                             },
                         ),
+                        (
+                            "preproc".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0x5e81acff).into()),
+                                ..Default::default()
+                            },
+                        ),
                         (
                             "punctuation".into(),
                             UserHighlightStyle {
@@ -137,6 +161,13 @@ pub fn nord() -> UserThemeFamily {
                                 ..Default::default()
                             },
                         ),
+                        (
+                            "punctuation.bracket".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xeceff4ff).into()),
+                                ..Default::default()
+                            },
+                        ),
                         (
                             "punctuation.delimiter".into(),
                             UserHighlightStyle {
@@ -144,6 +175,20 @@ pub fn nord() -> UserThemeFamily {
                                 ..Default::default()
                             },
                         ),
+                        (
+                            "punctuation.list_marker".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xeceff4ff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "punctuation.special".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xeceff4ff).into()),
+                                ..Default::default()
+                            },
+                        ),
                         (
                             "string".into(),
                             UserHighlightStyle {
@@ -158,6 +203,27 @@ pub fn nord() -> UserThemeFamily {
                                 ..Default::default()
                             },
                         ),
+                        (
+                            "string.regex".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xa3be8cff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "string.special".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xa3be8cff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "string.special.symbol".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xa3be8cff).into()),
+                                ..Default::default()
+                            },
+                        ),
                         (
                             "tag".into(),
                             UserHighlightStyle {

crates/theme2/src/themes/palenight.rs 🔗

@@ -19,29 +19,34 @@ pub fn palenight() -> UserThemeFamily {
                 appearance: Appearance::Dark,
                 styles: UserThemeStylesRefinement {
                     colors: ThemeColorsRefinement {
-                        border: Some(rgba(0x282b3bff).into()),
-                        border_variant: Some(rgba(0x282b3bff).into()),
-                        border_focused: Some(rgba(0x282b3bff).into()),
-                        border_selected: Some(rgba(0x282b3bff).into()),
-                        border_transparent: Some(rgba(0x282b3bff).into()),
-                        border_disabled: Some(rgba(0x282b3bff).into()),
-                        elevated_surface_background: Some(rgba(0x292c3eff).into()),
-                        surface_background: Some(rgba(0x292c3eff).into()),
-                        background: Some(rgba(0x292c3eff).into()),
-                        element_background: Some(rgba(0x7d56c1cc).into()),
+                        border: Some(rgba(0x282b3cff).into()),
+                        border_variant: Some(rgba(0x282b3cff).into()),
+                        border_focused: Some(rgba(0x282b3cff).into()),
+                        border_selected: Some(rgba(0x282b3cff).into()),
+                        border_transparent: Some(rgba(0x282b3cff).into()),
+                        border_disabled: Some(rgba(0x282b3cff).into()),
+                        elevated_surface_background: Some(rgba(0x292d3eff).into()),
+                        surface_background: Some(rgba(0x292d3eff).into()),
+                        background: Some(rgba(0x292d3eff).into()),
+                        element_background: Some(rgba(0x7e57c2cc).into()),
                         element_hover: Some(rgba(0x0000001a).into()),
-                        element_selected: Some(rgba(0x7d56c1ff).into()),
+                        element_selected: Some(rgba(0x7e57c2ff).into()),
                         drop_target_background: Some(rgba(0x2e3245ff).into()),
                         ghost_element_hover: Some(rgba(0x0000001a).into()),
+                        ghost_element_selected: Some(rgba(0x7e57c2ff).into()),
                         text: Some(rgba(0xffffffff).into()),
+                        status_bar_background: Some(rgba(0x282c3dff).into()),
+                        title_bar_background: Some(rgba(0x292d3eff).into()),
+                        toolbar_background: Some(rgba(0x292d3eff).into()),
+                        tab_bar_background: Some(rgba(0x31364aff).into()),
                         tab_inactive_background: Some(rgba(0x31364aff).into()),
-                        tab_active_background: Some(rgba(0x292c3eff).into()),
-                        editor_background: Some(rgba(0x292c3eff).into()),
-                        editor_gutter_background: Some(rgba(0x292c3eff).into()),
+                        tab_active_background: Some(rgba(0x292d3eff).into()),
+                        editor_background: Some(rgba(0x292d3eff).into()),
+                        editor_gutter_background: Some(rgba(0x292d3eff).into()),
                         editor_line_number: Some(rgba(0x4c5374ff).into()),
                         editor_active_line_number: Some(rgba(0xbfc7d5ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x676e95ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xff5571ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xff5572ff).into()),
                         terminal_ansi_bright_green: Some(rgba(0xc3e88dff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0xffcb6bff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x82aaffff).into()),
@@ -49,7 +54,7 @@ pub fn palenight() -> UserThemeFamily {
                         terminal_ansi_bright_cyan: Some(rgba(0x89ddffff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xffffffff).into()),
                         terminal_ansi_black: Some(rgba(0x676e95ff).into()),
-                        terminal_ansi_red: Some(rgba(0xff5571ff).into()),
+                        terminal_ansi_red: Some(rgba(0xff5572ff).into()),
                         terminal_ansi_green: Some(rgba(0xa9c77dff).into()),
                         terminal_ansi_yellow: Some(rgba(0xffcb6bff).into()),
                         terminal_ansi_blue: Some(rgba(0x82aaffff).into()),
@@ -59,9 +64,14 @@ pub fn palenight() -> UserThemeFamily {
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xef524fff).into()),
-                        error: Some(rgba(0xef524fff).into()),
-                        hidden: Some(rgba(0x9199c8ff).into()),
+                        conflict: Some(rgba(0xffeb95cc).into()),
+                        created: Some(rgba(0x9ccc65ff).into()),
+                        deleted: Some(rgba(0xef5350ff).into()),
+                        error: Some(rgba(0xef5350ff).into()),
+                        hidden: Some(rgba(0x929ac9ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x69709890).into()),
+                        modified: Some(rgba(0xe2b93dff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -83,7 +93,15 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "comment".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x687097ff).into()),
+                                    color: Some(rgba(0x697098ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x697098ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -95,6 +113,13 @@ pub fn palenight() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xff5572ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "emphasis".into(),
                                 UserHighlightStyle {
@@ -142,7 +167,7 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf78b6bff).into()),
+                                    color: Some(rgba(0xf78c6cff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -156,7 +181,7 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x7fcac3ff).into()),
+                                    color: Some(rgba(0x80cbc4ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -167,6 +192,34 @@ pub fn palenight() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
@@ -181,10 +234,31 @@ pub fn palenight() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc3e88dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc3e88dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc3e88dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xff5571ff).into()),
+                                    color: Some(rgba(0xff5572ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -212,7 +286,7 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xff5571ff).into()),
+                                    color: Some(rgba(0xff5572ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -225,29 +299,34 @@ pub fn palenight() -> UserThemeFamily {
                 appearance: Appearance::Dark,
                 styles: UserThemeStylesRefinement {
                     colors: ThemeColorsRefinement {
-                        border: Some(rgba(0x282b3bff).into()),
-                        border_variant: Some(rgba(0x282b3bff).into()),
-                        border_focused: Some(rgba(0x282b3bff).into()),
-                        border_selected: Some(rgba(0x282b3bff).into()),
-                        border_transparent: Some(rgba(0x282b3bff).into()),
-                        border_disabled: Some(rgba(0x282b3bff).into()),
-                        elevated_surface_background: Some(rgba(0x292c3eff).into()),
-                        surface_background: Some(rgba(0x292c3eff).into()),
-                        background: Some(rgba(0x292c3eff).into()),
-                        element_background: Some(rgba(0x7d56c1cc).into()),
+                        border: Some(rgba(0x282b3cff).into()),
+                        border_variant: Some(rgba(0x282b3cff).into()),
+                        border_focused: Some(rgba(0x282b3cff).into()),
+                        border_selected: Some(rgba(0x282b3cff).into()),
+                        border_transparent: Some(rgba(0x282b3cff).into()),
+                        border_disabled: Some(rgba(0x282b3cff).into()),
+                        elevated_surface_background: Some(rgba(0x292d3eff).into()),
+                        surface_background: Some(rgba(0x292d3eff).into()),
+                        background: Some(rgba(0x292d3eff).into()),
+                        element_background: Some(rgba(0x7e57c2cc).into()),
                         element_hover: Some(rgba(0x0000001a).into()),
-                        element_selected: Some(rgba(0x7d56c1ff).into()),
+                        element_selected: Some(rgba(0x7e57c2ff).into()),
                         drop_target_background: Some(rgba(0x2e3245ff).into()),
                         ghost_element_hover: Some(rgba(0x0000001a).into()),
+                        ghost_element_selected: Some(rgba(0x7e57c2ff).into()),
                         text: Some(rgba(0xffffffff).into()),
+                        status_bar_background: Some(rgba(0x282c3dff).into()),
+                        title_bar_background: Some(rgba(0x292d3eff).into()),
+                        toolbar_background: Some(rgba(0x292d3eff).into()),
+                        tab_bar_background: Some(rgba(0x31364aff).into()),
                         tab_inactive_background: Some(rgba(0x31364aff).into()),
-                        tab_active_background: Some(rgba(0x292c3eff).into()),
-                        editor_background: Some(rgba(0x292c3eff).into()),
-                        editor_gutter_background: Some(rgba(0x292c3eff).into()),
+                        tab_active_background: Some(rgba(0x292d3eff).into()),
+                        editor_background: Some(rgba(0x292d3eff).into()),
+                        editor_gutter_background: Some(rgba(0x292d3eff).into()),
                         editor_line_number: Some(rgba(0x4c5374ff).into()),
                         editor_active_line_number: Some(rgba(0xbfc7d5ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x676e95ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xff5571ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xff5572ff).into()),
                         terminal_ansi_bright_green: Some(rgba(0xc3e88dff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0xffcb6bff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x82aaffff).into()),
@@ -255,7 +334,7 @@ pub fn palenight() -> UserThemeFamily {
                         terminal_ansi_bright_cyan: Some(rgba(0x89ddffff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xffffffff).into()),
                         terminal_ansi_black: Some(rgba(0x676e95ff).into()),
-                        terminal_ansi_red: Some(rgba(0xff5571ff).into()),
+                        terminal_ansi_red: Some(rgba(0xff5572ff).into()),
                         terminal_ansi_green: Some(rgba(0xa9c77dff).into()),
                         terminal_ansi_yellow: Some(rgba(0xffcb6bff).into()),
                         terminal_ansi_blue: Some(rgba(0x82aaffff).into()),
@@ -265,9 +344,14 @@ pub fn palenight() -> UserThemeFamily {
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xef524fff).into()),
-                        error: Some(rgba(0xef524fff).into()),
-                        hidden: Some(rgba(0x9199c8ff).into()),
+                        conflict: Some(rgba(0xffeb95cc).into()),
+                        created: Some(rgba(0x9ccc65ff).into()),
+                        deleted: Some(rgba(0xef5350ff).into()),
+                        error: Some(rgba(0xef5350ff).into()),
+                        hidden: Some(rgba(0x929ac9ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x69709890).into()),
+                        modified: Some(rgba(0xe2b93dff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -289,7 +373,15 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "comment".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x687097ff).into()),
+                                    color: Some(rgba(0x697098ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x697098ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -301,6 +393,13 @@ pub fn palenight() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xff5572ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "emphasis".into(),
                                 UserHighlightStyle {
@@ -348,7 +447,7 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf78b6bff).into()),
+                                    color: Some(rgba(0xf78c6cff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -362,7 +461,7 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x7fcac3ff).into()),
+                                    color: Some(rgba(0x80cbc4ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -373,6 +472,34 @@ pub fn palenight() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
@@ -387,10 +514,31 @@ pub fn palenight() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc3e88dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc3e88dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc3e88dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xff5571ff).into()),
+                                    color: Some(rgba(0xff5572ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -418,7 +566,7 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xff5571ff).into()),
+                                    color: Some(rgba(0xff5572ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -437,23 +585,28 @@ pub fn palenight() -> UserThemeFamily {
                         border_selected: Some(rgba(0x2c2f40ff).into()),
                         border_transparent: Some(rgba(0x2c2f40ff).into()),
                         border_disabled: Some(rgba(0x2c2f40ff).into()),
-                        elevated_surface_background: Some(rgba(0x25283aff).into()),
-                        surface_background: Some(rgba(0x25283aff).into()),
-                        background: Some(rgba(0x292c3eff).into()),
-                        element_background: Some(rgba(0x7d56c1cc).into()),
+                        elevated_surface_background: Some(rgba(0x292d3eff).into()),
+                        surface_background: Some(rgba(0x25293aff).into()),
+                        background: Some(rgba(0x292d3eff).into()),
+                        element_background: Some(rgba(0x7e57c2cc).into()),
                         element_hover: Some(rgba(0x0000001a).into()),
-                        element_selected: Some(rgba(0x7d56c1ff).into()),
+                        element_selected: Some(rgba(0x7e57c2ff).into()),
                         drop_target_background: Some(rgba(0x2e3245ff).into()),
                         ghost_element_hover: Some(rgba(0x0000001a).into()),
+                        ghost_element_selected: Some(rgba(0x7e57c2ff).into()),
                         text: Some(rgba(0xffffffff).into()),
+                        status_bar_background: Some(rgba(0x25293aff).into()),
+                        title_bar_background: Some(rgba(0x25293aff).into()),
+                        toolbar_background: Some(rgba(0x292d3eff).into()),
+                        tab_bar_background: Some(rgba(0x31364aff).into()),
                         tab_inactive_background: Some(rgba(0x31364aff).into()),
-                        tab_active_background: Some(rgba(0x25283aff).into()),
-                        editor_background: Some(rgba(0x292c3eff).into()),
-                        editor_gutter_background: Some(rgba(0x292c3eff).into()),
+                        tab_active_background: Some(rgba(0x25293aff).into()),
+                        editor_background: Some(rgba(0x292d3eff).into()),
+                        editor_gutter_background: Some(rgba(0x292d3eff).into()),
                         editor_line_number: Some(rgba(0x4c5374ff).into()),
                         editor_active_line_number: Some(rgba(0xbfc7d5ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x676e95ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xff5571ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xff5572ff).into()),
                         terminal_ansi_bright_green: Some(rgba(0xc3e88dff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0xffcb6bff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x82aaffff).into()),
@@ -461,7 +614,7 @@ pub fn palenight() -> UserThemeFamily {
                         terminal_ansi_bright_cyan: Some(rgba(0x89ddffff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xffffffff).into()),
                         terminal_ansi_black: Some(rgba(0x676e95ff).into()),
-                        terminal_ansi_red: Some(rgba(0xff5571ff).into()),
+                        terminal_ansi_red: Some(rgba(0xff5572ff).into()),
                         terminal_ansi_green: Some(rgba(0xa9c77dff).into()),
                         terminal_ansi_yellow: Some(rgba(0xffcb6bff).into()),
                         terminal_ansi_blue: Some(rgba(0x82aaffff).into()),
@@ -471,9 +624,14 @@ pub fn palenight() -> UserThemeFamily {
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xef524fff).into()),
-                        error: Some(rgba(0xef524fff).into()),
-                        hidden: Some(rgba(0x9199c8ff).into()),
+                        conflict: Some(rgba(0xffeb95cc).into()),
+                        created: Some(rgba(0x9ccc65ff).into()),
+                        deleted: Some(rgba(0xef5350ff).into()),
+                        error: Some(rgba(0xef5350ff).into()),
+                        hidden: Some(rgba(0x929ac9ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
+                        ignored: Some(rgba(0x69709890).into()),
+                        modified: Some(rgba(0xe2b93dff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -495,7 +653,15 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "comment".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x687097ff).into()),
+                                    color: Some(rgba(0x697098ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x697098ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -507,6 +673,13 @@ pub fn palenight() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xff5572ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "emphasis".into(),
                                 UserHighlightStyle {
@@ -554,7 +727,7 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf78b6bff).into()),
+                                    color: Some(rgba(0xf78c6cff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -568,7 +741,7 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "property".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x7fcac3ff).into()),
+                                    color: Some(rgba(0x80cbc4ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -579,6 +752,34 @@ pub fn palenight() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc792eaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
@@ -593,10 +794,31 @@ pub fn palenight() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc3e88dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc3e88dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xc3e88dff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xff5571ff).into()),
+                                    color: Some(rgba(0xff5572ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -624,7 +846,7 @@ pub fn palenight() -> UserThemeFamily {
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xff5571ff).into()),
+                                    color: Some(rgba(0xff5572ff).into()),
                                     ..Default::default()
                                 },
                             ),

crates/theme2/src/themes/rose_pine.rs 🔗

@@ -19,12 +19,12 @@ pub fn rose_pine() -> UserThemeFamily {
                 appearance: Appearance::Dark,
                 styles: UserThemeStylesRefinement {
                     colors: ThemeColorsRefinement {
-                        border: Some(rgba(0x000000ff).into()),
-                        border_variant: Some(rgba(0x000000ff).into()),
+                        border: Some(rgba(0x00000000).into()),
+                        border_variant: Some(rgba(0x00000000).into()),
                         border_focused: Some(rgba(0x6e6a8633).into()),
-                        border_selected: Some(rgba(0x000000ff).into()),
-                        border_transparent: Some(rgba(0x000000ff).into()),
-                        border_disabled: Some(rgba(0x000000ff).into()),
+                        border_selected: Some(rgba(0x00000000).into()),
+                        border_transparent: Some(rgba(0x00000000).into()),
+                        border_disabled: Some(rgba(0x00000000).into()),
                         elevated_surface_background: Some(rgba(0x1f1d2eff).into()),
                         surface_background: Some(rgba(0x1f1d2eff).into()),
                         background: Some(rgba(0x191724ff).into()),
@@ -33,8 +33,13 @@ pub fn rose_pine() -> UserThemeFamily {
                         element_selected: Some(rgba(0x6e6a8633).into()),
                         drop_target_background: Some(rgba(0x1f1d2eff).into()),
                         ghost_element_hover: Some(rgba(0x6e6a861a).into()),
+                        ghost_element_selected: Some(rgba(0x6e6a8633).into()),
                         text: Some(rgba(0xe0def4ff).into()),
-                        tab_inactive_background: Some(rgba(0x000000ff).into()),
+                        status_bar_background: Some(rgba(0x191724ff).into()),
+                        title_bar_background: Some(rgba(0x191724ff).into()),
+                        toolbar_background: Some(rgba(0x191724ff).into()),
+                        tab_bar_background: Some(rgba(0x00000000).into()),
+                        tab_inactive_background: Some(rgba(0x00000000).into()),
                         tab_active_background: Some(rgba(0x6e6a861a).into()),
                         editor_background: Some(rgba(0x191724ff).into()),
                         editor_gutter_background: Some(rgba(0x191724ff).into()),
@@ -42,16 +47,16 @@ pub fn rose_pine() -> UserThemeFamily {
                         editor_active_line_number: Some(rgba(0xe0def4ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x908caaff).into()),
                         terminal_ansi_bright_red: Some(rgba(0xeb6f92ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0x30738fff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xf5c177ff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0x31748fff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xf6c177ff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x9ccfd8ff).into()),
                         terminal_ansi_bright_magenta: Some(rgba(0xc4a7e7ff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0xebbcbaff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xe0def4ff).into()),
                         terminal_ansi_black: Some(rgba(0x26233aff).into()),
                         terminal_ansi_red: Some(rgba(0xeb6f92ff).into()),
-                        terminal_ansi_green: Some(rgba(0x30738fff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xf5c177ff).into()),
+                        terminal_ansi_green: Some(rgba(0x31748fff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xf6c177ff).into()),
                         terminal_ansi_blue: Some(rgba(0x9ccfd8ff).into()),
                         terminal_ansi_magenta: Some(rgba(0xc4a7e7ff).into()),
                         terminal_ansi_cyan: Some(rgba(0xebbcbaff).into()),
@@ -59,10 +64,15 @@ pub fn rose_pine() -> UserThemeFamily {
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
+                        conflict: Some(rgba(0xeb6f92ff).into()),
+                        created: Some(rgba(0x9ccfd8ff).into()),
                         deleted: Some(rgba(0xeb6f92ff).into()),
                         error: Some(rgba(0xeb6f92ff).into()),
                         hidden: Some(rgba(0x908caaff).into()),
-                        warning: Some(rgba(0xf5c177ff).into()),
+                        hint: Some(rgba(0x908caaff).into()),
+                        ignored: Some(rgba(0x6e6a86ff).into()),
+                        modified: Some(rgba(0xebbcbaff).into()),
+                        warning: Some(rgba(0xf6c177ff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -91,17 +101,38 @@ pub fn rose_pine() -> UserThemeFamily {
                                 },
                             ),
                             (
-                                "function".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xeb6f92ff).into()),
+                                    color: Some(rgba(0x6e6a86ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constant".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x31748fff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x9ccfd8ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "function".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xebbcbaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x30738fff).into()),
+                                    color: Some(rgba(0x31748fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -126,10 +157,66 @@ pub fn rose_pine() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x908caaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x908caaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x908caaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x908caaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf5c177ff).into()),
+                                    color: Some(rgba(0xf6c177ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.escape".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xf6c177ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xf6c177ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xf6c177ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xf6c177ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -143,7 +230,7 @@ pub fn rose_pine() -> UserThemeFamily {
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf5c177ff).into()),
+                                    color: Some(rgba(0xf6c177ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -185,22 +272,27 @@ pub fn rose_pine() -> UserThemeFamily {
                 appearance: Appearance::Dark,
                 styles: UserThemeStylesRefinement {
                     colors: ThemeColorsRefinement {
-                        border: Some(rgba(0x000000ff).into()),
-                        border_variant: Some(rgba(0x000000ff).into()),
+                        border: Some(rgba(0x00000000).into()),
+                        border_variant: Some(rgba(0x00000000).into()),
                         border_focused: Some(rgba(0x817c9c26).into()),
-                        border_selected: Some(rgba(0x000000ff).into()),
-                        border_transparent: Some(rgba(0x000000ff).into()),
-                        border_disabled: Some(rgba(0x000000ff).into()),
-                        elevated_surface_background: Some(rgba(0x2a273eff).into()),
-                        surface_background: Some(rgba(0x2a273eff).into()),
+                        border_selected: Some(rgba(0x00000000).into()),
+                        border_transparent: Some(rgba(0x00000000).into()),
+                        border_disabled: Some(rgba(0x00000000).into()),
+                        elevated_surface_background: Some(rgba(0x2a273fff).into()),
+                        surface_background: Some(rgba(0x2a273fff).into()),
                         background: Some(rgba(0x232136ff).into()),
                         element_background: Some(rgba(0xea9a97ff).into()),
                         element_hover: Some(rgba(0x817c9c14).into()),
                         element_selected: Some(rgba(0x817c9c26).into()),
-                        drop_target_background: Some(rgba(0x2a273eff).into()),
+                        drop_target_background: Some(rgba(0x2a273fff).into()),
                         ghost_element_hover: Some(rgba(0x817c9c14).into()),
+                        ghost_element_selected: Some(rgba(0x817c9c26).into()),
                         text: Some(rgba(0xe0def4ff).into()),
-                        tab_inactive_background: Some(rgba(0x000000ff).into()),
+                        status_bar_background: Some(rgba(0x232136ff).into()),
+                        title_bar_background: Some(rgba(0x232136ff).into()),
+                        toolbar_background: Some(rgba(0x232136ff).into()),
+                        tab_bar_background: Some(rgba(0x00000000).into()),
+                        tab_inactive_background: Some(rgba(0x00000000).into()),
                         tab_active_background: Some(rgba(0x817c9c14).into()),
                         editor_background: Some(rgba(0x232136ff).into()),
                         editor_gutter_background: Some(rgba(0x232136ff).into()),
@@ -208,16 +300,16 @@ pub fn rose_pine() -> UserThemeFamily {
                         editor_active_line_number: Some(rgba(0xe0def4ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x908caaff).into()),
                         terminal_ansi_bright_red: Some(rgba(0xeb6f92ff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0x3d8fb0ff).into()),
-                        terminal_ansi_bright_yellow: Some(rgba(0xf5c177ff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0x3e8fb0ff).into()),
+                        terminal_ansi_bright_yellow: Some(rgba(0xf6c177ff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x9ccfd8ff).into()),
                         terminal_ansi_bright_magenta: Some(rgba(0xc4a7e7ff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0xea9a97ff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xe0def4ff).into()),
                         terminal_ansi_black: Some(rgba(0x393552ff).into()),
                         terminal_ansi_red: Some(rgba(0xeb6f92ff).into()),
-                        terminal_ansi_green: Some(rgba(0x3d8fb0ff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xf5c177ff).into()),
+                        terminal_ansi_green: Some(rgba(0x3e8fb0ff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xf6c177ff).into()),
                         terminal_ansi_blue: Some(rgba(0x9ccfd8ff).into()),
                         terminal_ansi_magenta: Some(rgba(0xc4a7e7ff).into()),
                         terminal_ansi_cyan: Some(rgba(0xea9a97ff).into()),
@@ -225,10 +317,15 @@ pub fn rose_pine() -> UserThemeFamily {
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
+                        conflict: Some(rgba(0xeb6f92ff).into()),
+                        created: Some(rgba(0x9ccfd8ff).into()),
                         deleted: Some(rgba(0xeb6f92ff).into()),
                         error: Some(rgba(0xeb6f92ff).into()),
                         hidden: Some(rgba(0x908caaff).into()),
-                        warning: Some(rgba(0xf5c177ff).into()),
+                        hint: Some(rgba(0x908caaff).into()),
+                        ignored: Some(rgba(0x6e6a86ff).into()),
+                        modified: Some(rgba(0xea9a97ff).into()),
+                        warning: Some(rgba(0xf6c177ff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -257,17 +354,38 @@ pub fn rose_pine() -> UserThemeFamily {
                                 },
                             ),
                             (
-                                "function".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xeb6f92ff).into()),
+                                    color: Some(rgba(0x6e6a86ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constant".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x3e8fb0ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x9ccfd8ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "function".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xea9a97ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x3d8fb0ff).into()),
+                                    color: Some(rgba(0x3e8fb0ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -292,10 +410,66 @@ pub fn rose_pine() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x908caaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x908caaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x908caaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x908caaff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf5c177ff).into()),
+                                    color: Some(rgba(0xf6c177ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.escape".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xf6c177ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xf6c177ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xf6c177ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xf6c177ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -309,7 +483,7 @@ pub fn rose_pine() -> UserThemeFamily {
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xf5c177ff).into()),
+                                    color: Some(rgba(0xf6c177ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -351,49 +525,59 @@ pub fn rose_pine() -> UserThemeFamily {
                 appearance: Appearance::Light,
                 styles: UserThemeStylesRefinement {
                     colors: ThemeColorsRefinement {
-                        border: Some(rgba(0x000000ff).into()),
-                        border_variant: Some(rgba(0x000000ff).into()),
+                        border: Some(rgba(0x00000000).into()),
+                        border_variant: Some(rgba(0x00000000).into()),
                         border_focused: Some(rgba(0x6e6a8614).into()),
-                        border_selected: Some(rgba(0x000000ff).into()),
-                        border_transparent: Some(rgba(0x000000ff).into()),
-                        border_disabled: Some(rgba(0x000000ff).into()),
+                        border_selected: Some(rgba(0x00000000).into()),
+                        border_transparent: Some(rgba(0x00000000).into()),
+                        border_disabled: Some(rgba(0x00000000).into()),
                         elevated_surface_background: Some(rgba(0xfffaf3ff).into()),
                         surface_background: Some(rgba(0xfffaf3ff).into()),
                         background: Some(rgba(0xfaf4edff).into()),
-                        element_background: Some(rgba(0xd7827dff).into()),
+                        element_background: Some(rgba(0xd7827eff).into()),
                         element_hover: Some(rgba(0x6e6a860d).into()),
                         element_selected: Some(rgba(0x6e6a8614).into()),
                         drop_target_background: Some(rgba(0xfffaf3ff).into()),
                         ghost_element_hover: Some(rgba(0x6e6a860d).into()),
+                        ghost_element_selected: Some(rgba(0x6e6a8614).into()),
                         text: Some(rgba(0x575279ff).into()),
-                        tab_inactive_background: Some(rgba(0x000000ff).into()),
+                        status_bar_background: Some(rgba(0xfaf4edff).into()),
+                        title_bar_background: Some(rgba(0xfaf4edff).into()),
+                        toolbar_background: Some(rgba(0xfaf4edff).into()),
+                        tab_bar_background: Some(rgba(0x00000000).into()),
+                        tab_inactive_background: Some(rgba(0x00000000).into()),
                         tab_active_background: Some(rgba(0x6e6a860d).into()),
                         editor_background: Some(rgba(0xfaf4edff).into()),
                         editor_gutter_background: Some(rgba(0xfaf4edff).into()),
                         editor_line_number: Some(rgba(0x797593ff).into()),
                         editor_active_line_number: Some(rgba(0x575279ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x797593ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xb3627aff).into()),
-                        terminal_ansi_bright_green: Some(rgba(0x276983ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xb4637aff).into()),
+                        terminal_ansi_bright_green: Some(rgba(0x286983ff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0xea9d34ff).into()),
-                        terminal_ansi_bright_blue: Some(rgba(0x55949fff).into()),
-                        terminal_ansi_bright_magenta: Some(rgba(0x9079a9ff).into()),
-                        terminal_ansi_bright_cyan: Some(rgba(0xd7827dff).into()),
+                        terminal_ansi_bright_blue: Some(rgba(0x56949fff).into()),
+                        terminal_ansi_bright_magenta: Some(rgba(0x907aa9ff).into()),
+                        terminal_ansi_bright_cyan: Some(rgba(0xd7827eff).into()),
                         terminal_ansi_bright_white: Some(rgba(0x575279ff).into()),
                         terminal_ansi_black: Some(rgba(0xf2e9e1ff).into()),
-                        terminal_ansi_red: Some(rgba(0xb3627aff).into()),
-                        terminal_ansi_green: Some(rgba(0x276983ff).into()),
+                        terminal_ansi_red: Some(rgba(0xb4637aff).into()),
+                        terminal_ansi_green: Some(rgba(0x286983ff).into()),
                         terminal_ansi_yellow: Some(rgba(0xea9d34ff).into()),
-                        terminal_ansi_blue: Some(rgba(0x55949fff).into()),
-                        terminal_ansi_magenta: Some(rgba(0x9079a9ff).into()),
-                        terminal_ansi_cyan: Some(rgba(0xd7827dff).into()),
+                        terminal_ansi_blue: Some(rgba(0x56949fff).into()),
+                        terminal_ansi_magenta: Some(rgba(0x907aa9ff).into()),
+                        terminal_ansi_cyan: Some(rgba(0xd7827eff).into()),
                         terminal_ansi_white: Some(rgba(0x575279ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xb3627aff).into()),
-                        error: Some(rgba(0xb3627aff).into()),
+                        conflict: Some(rgba(0xb4637aff).into()),
+                        created: Some(rgba(0x56949fff).into()),
+                        deleted: Some(rgba(0xb4637aff).into()),
+                        error: Some(rgba(0xb4637aff).into()),
                         hidden: Some(rgba(0x797593ff).into()),
+                        hint: Some(rgba(0x797593ff).into()),
+                        ignored: Some(rgba(0x9893a5ff).into()),
+                        modified: Some(rgba(0xd7827eff).into()),
                         warning: Some(rgba(0xea9d34ff).into()),
                         ..Default::default()
                     },
@@ -402,7 +586,7 @@ pub fn rose_pine() -> UserThemeFamily {
                             (
                                 "attribute".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x9079a9ff).into()),
+                                    color: Some(rgba(0x907aa9ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
@@ -410,7 +594,7 @@ pub fn rose_pine() -> UserThemeFamily {
                             (
                                 "boolean".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd7827dff).into()),
+                                    color: Some(rgba(0xd7827eff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -423,31 +607,52 @@ pub fn rose_pine() -> UserThemeFamily {
                                 },
                             ),
                             (
-                                "function".into(),
+                                "comment.doc".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb3627aff).into()),
+                                    color: Some(rgba(0x9893a5ff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "constant".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x286983ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x56949fff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "function".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xd7827eff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "keyword".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x276983ff).into()),
+                                    color: Some(rgba(0x286983ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "label".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd7827dff).into()),
+                                    color: Some(rgba(0xd7827eff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd7827dff).into()),
+                                    color: Some(rgba(0xd7827eff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -458,6 +663,34 @@ pub fn rose_pine() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x797593ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x797593ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x797593ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x797593ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
@@ -465,10 +698,38 @@ pub fn rose_pine() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "string.escape".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xea9d34ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xea9d34ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xea9d34ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xea9d34ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x55949fff).into()),
+                                    color: Some(rgba(0x56949fff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -482,21 +743,21 @@ pub fn rose_pine() -> UserThemeFamily {
                             (
                                 "title".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd7827dff).into()),
+                                    color: Some(rgba(0xd7827eff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x55949fff).into()),
+                                    color: Some(rgba(0x56949fff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "variable".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd7827dff).into()),
+                                    color: Some(rgba(0xd7827eff).into()),
                                     font_style: Some(UserFontStyle::Italic),
                                     ..Default::default()
                                 },

crates/theme2/src/themes/solarized.rs 🔗

@@ -21,44 +21,50 @@ pub fn solarized() -> UserThemeFamily {
                     colors: ThemeColorsRefinement {
                         border: Some(rgba(0x003847ff).into()),
                         border_variant: Some(rgba(0x003847ff).into()),
-                        border_focused: Some(rgba(0x29a19899).into()),
+                        border_focused: Some(rgba(0x2aa19899).into()),
                         border_selected: Some(rgba(0x003847ff).into()),
                         border_transparent: Some(rgba(0x003847ff).into()),
                         border_disabled: Some(rgba(0x003847ff).into()),
-                        background: Some(rgba(0x002a35ff).into()),
-                        element_background: Some(rgba(0x29a19899).into()),
-                        element_hover: Some(rgba(0x004353aa).into()),
+                        elevated_surface_background: Some(rgba(0x00212bff).into()),
+                        background: Some(rgba(0x002b36ff).into()),
+                        element_background: Some(rgba(0x2aa19899).into()),
+                        element_hover: Some(rgba(0x004454aa).into()),
                         element_selected: Some(rgba(0x005a6fff).into()),
-                        drop_target_background: Some(rgba(0x00435388).into()),
-                        ghost_element_hover: Some(rgba(0x004353aa).into()),
+                        drop_target_background: Some(rgba(0x00445488).into()),
+                        ghost_element_hover: Some(rgba(0x004454aa).into()),
+                        ghost_element_selected: Some(rgba(0x005a6fff).into()),
                         text: Some(rgba(0xbbbbbbff).into()),
-                        tab_inactive_background: Some(rgba(0x003f51ff).into()),
-                        tab_active_background: Some(rgba(0x002a36ff).into()),
-                        editor_background: Some(rgba(0x002a35ff).into()),
-                        editor_gutter_background: Some(rgba(0x002a35ff).into()),
+                        status_bar_background: Some(rgba(0x00212bff).into()),
+                        title_bar_background: Some(rgba(0x002c39ff).into()),
+                        toolbar_background: Some(rgba(0x002b36ff).into()),
+                        tab_bar_background: Some(rgba(0x004052ff).into()),
+                        tab_inactive_background: Some(rgba(0x004052ff).into()),
+                        tab_active_background: Some(rgba(0x002b37ff).into()),
+                        editor_background: Some(rgba(0x002b36ff).into()),
+                        editor_gutter_background: Some(rgba(0x002b36ff).into()),
                         editor_line_number: Some(rgba(0x566c74ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x586e75ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xcb4b15ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xcb4b16ff).into()),
                         terminal_ansi_bright_green: Some(rgba(0x859900ff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0x657b83ff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x839496ff).into()),
                         terminal_ansi_bright_magenta: Some(rgba(0x6c71c4ff).into()),
                         terminal_ansi_bright_cyan: Some(rgba(0x93a1a1ff).into()),
                         terminal_ansi_bright_white: Some(rgba(0x839496ff).into()),
-                        terminal_ansi_black: Some(rgba(0x063642ff).into()),
-                        terminal_ansi_red: Some(rgba(0xdc312eff).into()),
+                        terminal_ansi_black: Some(rgba(0x073642ff).into()),
+                        terminal_ansi_red: Some(rgba(0xdc322fff).into()),
                         terminal_ansi_green: Some(rgba(0x859900ff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xb58800ff).into()),
-                        terminal_ansi_blue: Some(rgba(0x258ad2ff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xd33582ff).into()),
-                        terminal_ansi_cyan: Some(rgba(0x29a198ff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xb58900ff).into()),
+                        terminal_ansi_blue: Some(rgba(0x268bd2ff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xd33682ff).into()),
+                        terminal_ansi_cyan: Some(rgba(0x2aa198ff).into()),
                         terminal_ansi_white: Some(rgba(0x839496ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
-                        deleted: Some(rgba(0xffeaeaff).into()),
                         error: Some(rgba(0xffeaeaff).into()),
                         hidden: Some(rgba(0x93a1a1ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -73,7 +79,7 @@ pub fn solarized() -> UserThemeFamily {
                             (
                                 "boolean".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb58800ff).into()),
+                                    color: Some(rgba(0xb58900ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -85,10 +91,25 @@ pub fn solarized() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x657b83ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "constant".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xcb4b15ff).into()),
+                                    color: Some(rgba(0xb58900ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x268bd2ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -102,21 +123,21 @@ pub fn solarized() -> UserThemeFamily {
                             (
                                 "emphasis".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd33582ff).into()),
+                                    color: Some(rgba(0xd33682ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd33582ff).into()),
+                                    color: Some(rgba(0xd33682ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x258ad2ff).into()),
+                                    color: Some(rgba(0x839496ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -130,7 +151,14 @@ pub fn solarized() -> UserThemeFamily {
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd33582ff).into()),
+                                    color: Some(rgba(0xd33682ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "preproc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb58900ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -148,52 +176,101 @@ pub fn solarized() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "punctuation.bracket".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x657b83ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.delimiter".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x657b83ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.list_marker".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x657b83ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "punctuation.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x657b83ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x29a198ff).into()),
+                                    color: Some(rgba(0x2aa198ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "string.escape".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xcb4b15ff).into()),
+                                    color: Some(rgba(0xcb4b16ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x2aa198ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x2aa198ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x2aa198ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x258ad2ff).into()),
+                                    color: Some(rgba(0x268bd2ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x29a198ff).into()),
+                                    color: Some(rgba(0x2aa198ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xcb4b15ff).into()),
+                                    color: Some(rgba(0xb58900ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "variable".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x258ad2ff).into()),
+                                    color: Some(rgba(0x268bd2ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x258ad2ff).into()),
+                                    color: Some(rgba(0x268bd2ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -212,19 +289,25 @@ pub fn solarized() -> UserThemeFamily {
                         border_selected: Some(rgba(0xddd6c1ff).into()),
                         border_transparent: Some(rgba(0xddd6c1ff).into()),
                         border_disabled: Some(rgba(0xddd6c1ff).into()),
+                        elevated_surface_background: Some(rgba(0xeee8d5ff).into()),
                         background: Some(rgba(0xfdf6e3ff).into()),
-                        element_background: Some(rgba(0xab9d56ff).into()),
-                        element_hover: Some(rgba(0xdec98744).into()),
-                        element_selected: Some(rgba(0xdec987ff).into()),
-                        ghost_element_hover: Some(rgba(0xdec98744).into()),
+                        element_background: Some(rgba(0xac9d57ff).into()),
+                        element_hover: Some(rgba(0xdfca8844).into()),
+                        element_selected: Some(rgba(0xdfca88ff).into()),
+                        ghost_element_hover: Some(rgba(0xdfca8844).into()),
+                        ghost_element_selected: Some(rgba(0xdfca88ff).into()),
                         text: Some(rgba(0x333333ff).into()),
+                        status_bar_background: Some(rgba(0xeee8d5ff).into()),
+                        title_bar_background: Some(rgba(0xeee8d5ff).into()),
+                        toolbar_background: Some(rgba(0xfdf6e3ff).into()),
+                        tab_bar_background: Some(rgba(0xd9d2c2ff).into()),
                         tab_inactive_background: Some(rgba(0xd3cbb7ff).into()),
                         tab_active_background: Some(rgba(0xfdf6e3ff).into()),
                         editor_background: Some(rgba(0xfdf6e3ff).into()),
                         editor_gutter_background: Some(rgba(0xfdf6e3ff).into()),
                         editor_line_number: Some(rgba(0x9ca8a6ff).into()),
                         terminal_ansi_bright_black: Some(rgba(0x657b83ff).into()),
-                        terminal_ansi_bright_red: Some(rgba(0xcb4b15ff).into()),
+                        terminal_ansi_bright_red: Some(rgba(0xcb4b16ff).into()),
                         terminal_ansi_bright_green: Some(rgba(0x859900ff).into()),
                         terminal_ansi_bright_yellow: Some(rgba(0x657b83ff).into()),
                         terminal_ansi_bright_blue: Some(rgba(0x839496ff).into()),
@@ -232,17 +315,18 @@ pub fn solarized() -> UserThemeFamily {
                         terminal_ansi_bright_cyan: Some(rgba(0x93a1a1ff).into()),
                         terminal_ansi_bright_white: Some(rgba(0xeee8d5ff).into()),
                         terminal_ansi_black: Some(rgba(0x657b83ff).into()),
-                        terminal_ansi_red: Some(rgba(0xdc312eff).into()),
+                        terminal_ansi_red: Some(rgba(0xdc322fff).into()),
                         terminal_ansi_green: Some(rgba(0x859900ff).into()),
-                        terminal_ansi_yellow: Some(rgba(0xb58800ff).into()),
-                        terminal_ansi_blue: Some(rgba(0x258ad2ff).into()),
-                        terminal_ansi_magenta: Some(rgba(0xd33582ff).into()),
-                        terminal_ansi_cyan: Some(rgba(0x29a198ff).into()),
+                        terminal_ansi_yellow: Some(rgba(0xb58900ff).into()),
+                        terminal_ansi_blue: Some(rgba(0x268bd2ff).into()),
+                        terminal_ansi_magenta: Some(rgba(0xd33682ff).into()),
+                        terminal_ansi_cyan: Some(rgba(0x2aa198ff).into()),
                         terminal_ansi_white: Some(rgba(0xeee8d5ff).into()),
                         ..Default::default()
                     },
                     status: StatusColorsRefinement {
                         hidden: Some(rgba(0x586e75ff).into()),
+                        hint: Some(rgba(0x969696ff).into()),
                         ..Default::default()
                     },
                     syntax: Some(UserSyntaxTheme {
@@ -257,7 +341,7 @@ pub fn solarized() -> UserThemeFamily {
                             (
                                 "boolean".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xb58800ff).into()),
+                                    color: Some(rgba(0xb58900ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -269,10 +353,25 @@ pub fn solarized() -> UserThemeFamily {
                                     ..Default::default()
                                 },
                             ),
+                            (
+                                "comment.doc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x93a1a1ff).into()),
+                                    font_style: Some(UserFontStyle::Italic),
+                                    ..Default::default()
+                                },
+                            ),
                             (
                                 "constant".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xcb4b15ff).into()),
+                                    color: Some(rgba(0xb58900ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "constructor".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x268bd2ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -286,21 +385,21 @@ pub fn solarized() -> UserThemeFamily {
                             (
                                 "emphasis".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd33582ff).into()),
+                                    color: Some(rgba(0xd33682ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "emphasis.strong".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd33582ff).into()),
+                                    color: Some(rgba(0xd33682ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "function".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x258ad2ff).into()),
+                                    color: Some(rgba(0x657b83ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -314,7 +413,14 @@ pub fn solarized() -> UserThemeFamily {
                             (
                                 "number".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xd33582ff).into()),
+                                    color: Some(rgba(0xd33682ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "preproc".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0xb58900ff).into()),
                                     ..Default::default()
                                 },
                             ),
@@ -328,49 +434,70 @@ pub fn solarized() -> UserThemeFamily {
                             (
                                 "string".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x29a198ff).into()),
+                                    color: Some(rgba(0x2aa198ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "string.escape".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0xcb4b15ff).into()),
+                                    color: Some(rgba(0xcb4b16ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.regex".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x2aa198ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x2aa198ff).into()),
+                                    ..Default::default()
+                                },
+                            ),
+                            (
+                                "string.special.symbol".into(),
+                                UserHighlightStyle {
+                                    color: Some(rgba(0x2aa198ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "tag".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x258ad2ff).into()),
+                                    color: Some(rgba(0x268bd2ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "text.literal".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x29a198ff).into()),
+                                    color: Some(rgba(0x2aa198ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "type".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x258ad2ff).into()),
+                                    color: Some(rgba(0xb58900ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "variable".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x258ad2ff).into()),
+                                    color: Some(rgba(0x268bd2ff).into()),
                                     ..Default::default()
                                 },
                             ),
                             (
                                 "variable.special".into(),
                                 UserHighlightStyle {
-                                    color: Some(rgba(0x258ad2ff).into()),
+                                    color: Some(rgba(0x268bd2ff).into()),
                                     ..Default::default()
                                 },
                             ),

crates/theme2/src/themes/synthwave_84.rs 🔗

@@ -19,35 +19,45 @@ pub fn synthwave_84() -> UserThemeFamily {
             styles: UserThemeStylesRefinement {
                 colors: ThemeColorsRefinement {
                     border_focused: Some(rgba(0x1f212bff).into()),
-                    background: Some(rgba(0x252334ff).into()),
+                    elevated_surface_background: Some(rgba(0x232530ff).into()),
+                    background: Some(rgba(0x262335ff).into()),
                     element_background: Some(rgba(0x614d85ff).into()),
                     element_hover: Some(rgba(0x37294d99).into()),
                     element_selected: Some(rgba(0xffffff20).into()),
                     drop_target_background: Some(rgba(0x34294f66).into()),
                     ghost_element_hover: Some(rgba(0x37294d99).into()),
+                    ghost_element_selected: Some(rgba(0xffffff20).into()),
                     text: Some(rgba(0xffffffff).into()),
-                    tab_inactive_background: Some(rgba(0x252334ff).into()),
-                    editor_background: Some(rgba(0x252334ff).into()),
-                    editor_gutter_background: Some(rgba(0x252334ff).into()),
+                    status_bar_background: Some(rgba(0x241b2fff).into()),
+                    title_bar_background: Some(rgba(0x241b2fff).into()),
+                    toolbar_background: Some(rgba(0x262335ff).into()),
+                    tab_bar_background: Some(rgba(0x241b2fff).into()),
+                    tab_inactive_background: Some(rgba(0x262335ff).into()),
+                    editor_background: Some(rgba(0x262335ff).into()),
+                    editor_gutter_background: Some(rgba(0x262335ff).into()),
                     editor_line_number: Some(rgba(0xffffff73).into()),
-                    terminal_ansi_bright_red: Some(rgba(0xfe444fff).into()),
-                    terminal_ansi_bright_green: Some(rgba(0x71f1b7ff).into()),
-                    terminal_ansi_bright_yellow: Some(rgba(0xfede5cff).into()),
-                    terminal_ansi_bright_blue: Some(rgba(0x02edf9ff).into()),
-                    terminal_ansi_bright_magenta: Some(rgba(0xff7ddaff).into()),
-                    terminal_ansi_bright_cyan: Some(rgba(0x02edf9ff).into()),
-                    terminal_ansi_red: Some(rgba(0xfe444fff).into()),
-                    terminal_ansi_green: Some(rgba(0x71f1b7ff).into()),
+                    terminal_ansi_bright_red: Some(rgba(0xfe4450ff).into()),
+                    terminal_ansi_bright_green: Some(rgba(0x72f1b8ff).into()),
+                    terminal_ansi_bright_yellow: Some(rgba(0xfede5dff).into()),
+                    terminal_ansi_bright_blue: Some(rgba(0x03edf9ff).into()),
+                    terminal_ansi_bright_magenta: Some(rgba(0xff7edbff).into()),
+                    terminal_ansi_bright_cyan: Some(rgba(0x03edf9ff).into()),
+                    terminal_ansi_red: Some(rgba(0xfe4450ff).into()),
+                    terminal_ansi_green: Some(rgba(0x72f1b8ff).into()),
                     terminal_ansi_yellow: Some(rgba(0xf3e70fff).into()),
-                    terminal_ansi_blue: Some(rgba(0x02edf9ff).into()),
-                    terminal_ansi_magenta: Some(rgba(0xff7ddaff).into()),
-                    terminal_ansi_cyan: Some(rgba(0x02edf9ff).into()),
+                    terminal_ansi_blue: Some(rgba(0x03edf9ff).into()),
+                    terminal_ansi_magenta: Some(rgba(0xff7edbff).into()),
+                    terminal_ansi_cyan: Some(rgba(0x03edf9ff).into()),
                     ..Default::default()
                 },
                 status: StatusColorsRefinement {
-                    deleted: Some(rgba(0xfe444fff).into()),
-                    error: Some(rgba(0xfe444fff).into()),
-                    warning: Some(rgba(0x71f1b7bb).into()),
+                    created: Some(rgba(0x206d4bd6).into()),
+                    deleted: Some(rgba(0xfa2e46a4).into()),
+                    error: Some(rgba(0xfe4450ff).into()),
+                    hint: Some(rgba(0x969696ff).into()),
+                    ignored: Some(rgba(0xffffff59).into()),
+                    modified: Some(rgba(0xb893ce8f).into()),
+                    warning: Some(rgba(0x72f1b8bb).into()),
                     ..Default::default()
                 },
                 syntax: Some(UserSyntaxTheme {
@@ -55,14 +65,14 @@ pub fn synthwave_84() -> UserThemeFamily {
                         (
                             "attribute".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xfede5cff).into()),
+                                color: Some(rgba(0xfede5dff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "boolean".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xf97d71ff).into()),
+                                color: Some(rgba(0xf97e72ff).into()),
                                 ..Default::default()
                             },
                         ),
@@ -74,24 +84,46 @@ pub fn synthwave_84() -> UserThemeFamily {
                                 ..Default::default()
                             },
                         ),
+                        (
+                            "comment.doc".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0x848bbdff).into()),
+                                font_style: Some(UserFontStyle::Italic),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "constant".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0xf97e72ff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "constructor".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0x72f1b8ff).into()),
+                                ..Default::default()
+                            },
+                        ),
                         (
                             "function".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0x35f9f5ff).into()),
+                                color: Some(rgba(0x36f9f6ff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "keyword".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xfede5cff).into()),
+                                color: Some(rgba(0xfede5dff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "label".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xfe444fff).into()),
+                                color: Some(rgba(0xfe4450ff).into()),
                                 ..Default::default()
                             },
                         ),
@@ -112,63 +144,91 @@ pub fn synthwave_84() -> UserThemeFamily {
                         (
                             "number".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xf97d71ff).into()),
+                                color: Some(rgba(0xf97e72ff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "operator".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xfede5cff).into()),
+                                color: Some(rgba(0xfede5dff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "property".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xff7ddaff).into()),
+                                color: Some(rgba(0xff7edbff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "punctuation".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0x35f9f5ff).into()),
+                                color: Some(rgba(0x36f9f6ff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "punctuation.bracket".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0x36f9f6ff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "punctuation.delimiter".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0x36f9f6ff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "punctuation.list_marker".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0x36f9f6ff).into()),
+                                ..Default::default()
+                            },
+                        ),
+                        (
+                            "punctuation.special".into(),
+                            UserHighlightStyle {
+                                color: Some(rgba(0x36f9f6ff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "tag".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0x71f1b7ff).into()),
+                                color: Some(rgba(0x72f1b8ff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "title".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xfe444fff).into()),
+                                color: Some(rgba(0xfe4450ff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "type".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xfe444fff).into()),
+                                color: Some(rgba(0xfe4450ff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "variable".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xff7ddaff).into()),
+                                color: Some(rgba(0xff7edbff).into()),
                                 ..Default::default()
                             },
                         ),
                         (
                             "variable.special".into(),
                             UserHighlightStyle {
-                                color: Some(rgba(0xfe444fff).into()),
+                                color: Some(rgba(0xfe4450ff).into()),
                                 font_weight: Some(UserFontWeight(700.0)),
                                 ..Default::default()
                             },

crates/theme_importer/Cargo.toml 🔗

@@ -10,9 +10,10 @@ publish = false
 anyhow.workspace = true
 convert_case = "0.6.0"
 gpui = { package = "gpui2", path = "../gpui2" }
-indexmap = "1.6.2"
+indexmap = { version = "1.6.2", features = ["serde"] }
 json_comments = "0.2.2"
 log.workspace = true
+palette = { version = "0.7.3", default-features = false, features = ["std"] }
 rust-embed.workspace = true
 serde.workspace = true
 simplelog = "0.9"

crates/theme_importer/src/color.rs 🔗

@@ -0,0 +1,54 @@
+use anyhow::Result;
+use gpui::Hsla;
+use palette::FromColor;
+
+pub(crate) fn try_parse_color(color: &str) -> Result<Hsla> {
+    let rgba = gpui::Rgba::try_from(color)?;
+    let rgba = palette::rgb::Srgba::from_components((rgba.r, rgba.g, rgba.b, rgba.a));
+    let hsla = palette::Hsla::from_color(rgba);
+
+    let hsla = gpui::hsla(
+        hsla.hue.into_positive_degrees() / 360.,
+        hsla.saturation,
+        hsla.lightness,
+        hsla.alpha,
+    );
+
+    Ok(hsla)
+}
+
+pub(crate) fn pack_color(color: Hsla) -> u32 {
+    let hsla = palette::Hsla::from_components((color.h * 360., color.s, color.l, color.a));
+    let rgba = palette::rgb::Srgba::from_color(hsla);
+    let rgba = rgba.into_format::<u8, u8>();
+
+    u32::from(rgba)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    pub fn test_serialize_color() {
+        let color = "#b4637aff";
+        let hsla = try_parse_color(color).unwrap();
+        let packed = pack_color(hsla);
+
+        assert_eq!(format!("#{:x}", packed), color);
+    }
+
+    #[test]
+    pub fn test_serialize_color_with_palette() {
+        let color = "#b4637aff";
+
+        let rgba = gpui::Rgba::try_from(color).unwrap();
+        let rgba = palette::rgb::Srgba::from_components((rgba.r, rgba.g, rgba.b, rgba.a));
+        let hsla = palette::Hsla::from_color(rgba);
+
+        let rgba = palette::rgb::Srgba::from_color(hsla);
+        let rgba = rgba.into_format::<u8, u8>();
+
+        assert_eq!(format!("#{:x}", rgba), color);
+    }
+}

crates/theme_importer/src/main.rs 🔗

@@ -1,3 +1,4 @@
+mod color;
 mod theme_printer;
 mod util;
 mod vscode;
@@ -11,10 +12,11 @@ use std::str::FromStr;
 use anyhow::{anyhow, Context, Result};
 use convert_case::{Case, Casing};
 use gpui::serde_json;
+use indexmap::IndexMap;
 use json_comments::StripComments;
 use log::LevelFilter;
 use serde::Deserialize;
-use simplelog::SimpleLogger;
+use simplelog::{TermLogger, TerminalMode};
 use theme::{Appearance, UserThemeFamily};
 
 use crate::theme_printer::UserThemeFamilyPrinter;
@@ -26,6 +28,14 @@ struct FamilyMetadata {
     pub name: String,
     pub author: String,
     pub themes: Vec<ThemeMetadata>,
+
+    /// Overrides for specific syntax tokens.
+    ///
+    /// Use this to ensure certain Zed syntax tokens are matched
+    /// to an exact set of scopes when it is not otherwise possible
+    /// to rely on the default mappings in the theme importer.
+    #[serde(default)]
+    pub syntax: IndexMap<String, Vec<String>>,
 }
 
 #[derive(Debug, Clone, Copy, Deserialize)]
@@ -55,9 +65,17 @@ fn main() -> Result<()> {
     const SOURCE_PATH: &str = "assets/themes/src/vscode";
     const OUT_PATH: &str = "crates/theme2/src/themes";
 
-    SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
+    let log_config = simplelog::ConfigBuilder::new()
+        .set_level_color(log::Level::Trace, simplelog::Color::Cyan)
+        .set_level_color(log::Level::Info, simplelog::Color::Blue)
+        .set_level_color(log::Level::Warn, simplelog::Color::Yellow)
+        .set_level_color(log::Level::Error, simplelog::Color::Red)
+        .build();
+
+    TermLogger::init(LevelFilter::Trace, log_config, TerminalMode::Mixed)
+        .expect("could not initialize logger");
 
-    println!("Loading themes source...");
+    log::info!("Loading themes source...");
     let vscode_themes_path = PathBuf::from_str(SOURCE_PATH)?;
     if !vscode_themes_path.exists() {
         return Err(anyhow!(format!(
@@ -90,7 +108,7 @@ fn main() -> Result<()> {
         let license_file_path = theme_family_dir.path().join("LICENSE");
 
         if !license_file_path.exists() {
-            println!("Skipping theme family '{}' because it does not have a LICENSE file. This theme will only be imported once a LICENSE file is provided.", theme_family_slug);
+            log::info!("Skipping theme family '{}' because it does not have a LICENSE file. This theme will only be imported once a LICENSE file is provided.", theme_family_slug);
             continue;
         }
 
@@ -102,12 +120,14 @@ fn main() -> Result<()> {
         let mut themes = Vec::new();
 
         for theme_metadata in family_metadata.themes {
+            log::info!("Converting '{}' theme", &theme_metadata.name);
+
             let theme_file_path = theme_family_dir.path().join(&theme_metadata.file_name);
 
             let theme_file = match File::open(&theme_file_path) {
                 Ok(file) => file,
                 Err(_) => {
-                    println!("Failed to open file at path: {:?}", theme_file_path);
+                    log::info!("Failed to open file at path: {:?}", theme_file_path);
                     continue;
                 }
             };
@@ -116,7 +136,11 @@ fn main() -> Result<()> {
             let vscode_theme: VsCodeTheme = serde_json::from_reader(theme_without_comments)
                 .context(format!("failed to parse theme {theme_file_path:?}"))?;
 
-            let converter = VsCodeThemeConverter::new(vscode_theme, theme_metadata);
+            let converter = VsCodeThemeConverter::new(
+                vscode_theme,
+                theme_metadata,
+                family_metadata.syntax.clone(),
+            );
 
             let theme = converter.convert()?;
 
@@ -135,7 +159,7 @@ fn main() -> Result<()> {
     let themes_output_path = PathBuf::from_str(OUT_PATH)?;
 
     if !themes_output_path.exists() {
-        println!("Creating directory: {:?}", themes_output_path);
+        log::info!("Creating directory: {:?}", themes_output_path);
         fs::create_dir_all(&themes_output_path)?;
     }
 
@@ -148,7 +172,7 @@ fn main() -> Result<()> {
 
         let mut output_file =
             File::create(themes_output_path.join(format!("{theme_family_slug}.rs")))?;
-        println!(
+        log::info!(
             "Creating file: {:?}",
             themes_output_path.join(format!("{theme_family_slug}.rs"))
         );
@@ -219,17 +243,17 @@ fn main() -> Result<()> {
 
     mod_rs_file.write_all(mod_rs_contents.as_bytes())?;
 
-    println!("Formatting themes...");
+    log::info!("Formatting themes...");
 
     let format_result = format_themes_crate()
         // We need to format a second time to catch all of the formatting issues.
         .and_then(|_| format_themes_crate());
 
     if let Err(err) = format_result {
-        eprintln!("Failed to format themes: {}", err);
+        log::error!("Failed to format themes: {}", err);
     }
 
-    println!("Done!");
+    log::info!("Done!");
 
     Ok(())
 }

crates/theme_importer/src/theme_printer.rs 🔗

@@ -1,12 +1,14 @@
 use std::fmt::{self, Debug};
 
-use gpui::{Hsla, Rgba};
+use gpui::Hsla;
 use theme::{
     Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, SystemColors,
     ThemeColorsRefinement, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily,
     UserThemeStylesRefinement,
 };
 
+use crate::color::pack_color;
+
 struct RawSyntaxPrinter<'a>(&'a str);
 
 impl<'a> Debug for RawSyntaxPrinter<'a> {
@@ -19,7 +21,7 @@ struct HslaPrinter(Hsla);
 
 impl Debug for HslaPrinter {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{:?}", IntoPrinter(&Rgba::from(self.0)))
+        write!(f, "rgba({:#010x}).into()", pack_color(self.0))
     }
 }
 
@@ -283,11 +285,14 @@ impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
             ("deleted", self.0.deleted),
             ("error", self.0.error),
             ("hidden", self.0.hidden),
+            ("hint", self.0.hint),
             ("ignored", self.0.ignored),
             ("info", self.0.info),
             ("modified", self.0.modified),
+            ("predictive", self.0.predictive),
             ("renamed", self.0.renamed),
             ("success", self.0.success),
+            ("unreachable", self.0.unreachable),
             ("warning", self.0.warning),
         ];
 

crates/theme_importer/src/vscode/converter.rs 🔗

@@ -1,5 +1,5 @@
 use anyhow::Result;
-use gpui::{Hsla, Rgba};
+use gpui::rgba;
 use indexmap::IndexMap;
 use strum::IntoEnumIterator;
 use theme::{
@@ -7,16 +7,13 @@ use theme::{
     UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeStylesRefinement,
 };
 
+use crate::color::try_parse_color;
 use crate::util::Traverse;
-use crate::vscode::VsCodeTheme;
+use crate::vscode::{VsCodeTheme, VsCodeTokenScope};
 use crate::ThemeMetadata;
 
 use super::ZedSyntaxToken;
 
-pub(crate) fn try_parse_color(color: &str) -> Result<Hsla> {
-    Ok(Rgba::try_from(color)?.into())
-}
-
 pub(crate) fn try_parse_font_weight(font_style: &str) -> Option<UserFontWeight> {
     match font_style {
         style if style.contains("bold") => Some(UserFontWeight::BOLD),
@@ -35,13 +32,19 @@ pub(crate) fn try_parse_font_style(font_style: &str) -> Option<UserFontStyle> {
 pub struct VsCodeThemeConverter {
     theme: VsCodeTheme,
     theme_metadata: ThemeMetadata,
+    syntax_overrides: IndexMap<String, Vec<String>>,
 }
 
 impl VsCodeThemeConverter {
-    pub fn new(theme: VsCodeTheme, theme_metadata: ThemeMetadata) -> Self {
+    pub fn new(
+        theme: VsCodeTheme,
+        theme_metadata: ThemeMetadata,
+        syntax_overrides: IndexMap<String, Vec<String>>,
+    ) -> Self {
         Self {
             theme,
             theme_metadata,
+            syntax_overrides,
         }
     }
 
@@ -66,11 +69,26 @@ impl VsCodeThemeConverter {
     fn convert_status_colors(&self) -> Result<StatusColorsRefinement> {
         let vscode_colors = &self.theme.colors;
 
+        let vscode_base_status_colors = StatusColorsRefinement {
+            hint: Some(rgba(0x969696ff).into()),
+            ..Default::default()
+        };
+
         Ok(StatusColorsRefinement {
-            // conflict: None,
-            // created: None,
+            created: vscode_colors
+                .editor_gutter_added_background
+                .as_ref()
+                .traverse(|color| try_parse_color(&color))?,
+            modified: vscode_colors
+                .editor_gutter_modified_background
+                .as_ref()
+                .traverse(|color| try_parse_color(&color))?,
             deleted: vscode_colors
-                .error_foreground
+                .editor_gutter_deleted_background
+                .as_ref()
+                .traverse(|color| try_parse_color(&color))?,
+            conflict: vscode_colors
+                .git_decoration_conflicting_resource_foreground
                 .as_ref()
                 .traverse(|color| try_parse_color(&color))?,
             error: vscode_colors
@@ -81,9 +99,16 @@ impl VsCodeThemeConverter {
                 .tab_inactive_foreground
                 .as_ref()
                 .traverse(|color| try_parse_color(&color))?,
-            // ignored: None,
+            hint: vscode_colors
+                .editor_inlay_hint_foreground
+                .as_ref()
+                .traverse(|color| try_parse_color(&color))?
+                .or(vscode_base_status_colors.hint),
+            ignored: vscode_colors
+                .git_decoration_ignored_resource_foreground
+                .as_ref()
+                .traverse(|color| try_parse_color(&color))?,
             // info: None,
-            // modified: None,
             // renamed: None,
             // success: None,
             warning: vscode_colors
@@ -97,6 +122,11 @@ impl VsCodeThemeConverter {
     fn convert_theme_colors(&self) -> Result<ThemeColorsRefinement> {
         let vscode_colors = &self.theme.colors;
 
+        let vscode_editor_background = vscode_colors
+            .editor_background
+            .as_ref()
+            .traverse(|color| try_parse_color(&color))?;
+
         Ok(ThemeColorsRefinement {
             border: vscode_colors
                 .panel_border
@@ -123,15 +153,20 @@ impl VsCodeThemeConverter {
                 .as_ref()
                 .traverse(|color| try_parse_color(&color))?,
             elevated_surface_background: vscode_colors
-                .panel_background
+                .dropdown_background
                 .as_ref()
                 .traverse(|color| try_parse_color(&color))?,
             surface_background: vscode_colors
                 .panel_background
                 .as_ref()
                 .traverse(|color| try_parse_color(&color))?,
-            background: vscode_colors
-                .editor_background
+            background: vscode_editor_background,
+            title_bar_background: vscode_colors
+                .title_bar_active_background
+                .as_ref()
+                .traverse(|color| try_parse_color(&color))?,
+            status_bar_background: vscode_colors
+                .status_bar_background
                 .as_ref()
                 .traverse(|color| try_parse_color(&color))?,
             element_background: vscode_colors
@@ -150,6 +185,10 @@ impl VsCodeThemeConverter {
                 .list_hover_background
                 .as_ref()
                 .traverse(|color| try_parse_color(&color))?,
+            ghost_element_selected: vscode_colors
+                .list_active_selection_background
+                .as_ref()
+                .traverse(|color| try_parse_color(&color))?,
             drop_target_background: vscode_colors
                 .list_drop_background
                 .as_ref()
@@ -168,6 +207,10 @@ impl VsCodeThemeConverter {
                         .ok()
                         .flatten()
                 }),
+            tab_bar_background: vscode_colors
+                .editor_group_header_tabs_background
+                .as_ref()
+                .traverse(|color| try_parse_color(&color))?,
             tab_active_background: vscode_colors
                 .tab_active_background
                 .as_ref()
@@ -176,14 +219,13 @@ impl VsCodeThemeConverter {
                 .tab_inactive_background
                 .as_ref()
                 .traverse(|color| try_parse_color(&color))?,
-            editor_background: vscode_colors
-                .editor_background
-                .as_ref()
-                .traverse(|color| try_parse_color(&color))?,
-            editor_gutter_background: vscode_colors
-                .editor_background
+            toolbar_background: vscode_colors
+                .breadcrumb_background
                 .as_ref()
-                .traverse(|color| try_parse_color(&color))?,
+                .traverse(|color| try_parse_color(&color))?
+                .or(vscode_editor_background),
+            editor_background: vscode_editor_background,
+            editor_gutter_background: vscode_editor_background,
             editor_line_number: vscode_colors
                 .editor_line_number_foreground
                 .as_ref()
@@ -268,20 +310,40 @@ impl VsCodeThemeConverter {
         let mut highlight_styles = IndexMap::new();
 
         for syntax_token in ZedSyntaxToken::iter() {
-            let multimatch_scopes = syntax_token.to_vscode();
-
-            let token_color = self.theme.token_colors.iter().find(|token_color| {
-                token_color
-                    .scope
-                    .as_ref()
-                    .map(|scope| scope.multimatch(&multimatch_scopes))
-                    .unwrap_or(false)
-            });
+            let override_match = self
+                .syntax_overrides
+                .get(&syntax_token.to_string())
+                .and_then(|scope| {
+                    self.theme.token_colors.iter().find(|token_color| {
+                        token_color.scope == Some(VsCodeTokenScope::Many(scope.clone()))
+                    })
+                });
+
+            let best_match = override_match
+                .or_else(|| syntax_token.find_best_token_color_match(&self.theme.token_colors))
+                .or_else(|| {
+                    syntax_token.fallbacks().iter().find_map(|fallback| {
+                        fallback.find_best_token_color_match(&self.theme.token_colors)
+                    })
+                });
 
-            let Some(token_color) = token_color else {
+            let Some(token_color) = best_match else {
+                log::warn!("No matching token color found for '{syntax_token}'");
                 continue;
             };
 
+            log::info!(
+                "Matched '{syntax_token}' to '{}'",
+                token_color
+                    .name
+                    .clone()
+                    .or_else(|| token_color
+                        .scope
+                        .as_ref()
+                        .map(|scope| format!("{:?}", scope)))
+                    .unwrap_or_else(|| "no identifier".to_string())
+            );
+
             let highlight_style = UserHighlightStyle {
                 color: token_color
                     .settings
@@ -310,63 +372,5 @@ impl VsCodeThemeConverter {
         Ok(UserSyntaxTheme {
             highlights: highlight_styles.into_iter().collect(),
         })
-
-        // let mut highlight_styles = IndexMap::new();
-
-        // for token_color in self.theme.token_colors {
-        //     highlight_styles.extend(token_color.highlight_styles()?);
-        // }
-
-        // let syntax_theme = UserSyntaxTheme {
-        //     highlights: highlight_styles.into_iter().collect(),
-        // };
-
-        // pub fn highlight_styles(&self) -> Result<IndexMap<String, UserHighlightStyle>> {
-        // let mut highlight_styles = IndexMap::new();
-
-        // for syntax_token in ZedSyntaxToken::iter() {
-        //     let scope = syntax_token.to_scope();
-
-        //     // let token_color =
-        // }
-
-        // let scope = match self.scope {
-        //     Some(VsCodeTokenScope::One(ref scope)) => vec![scope.clone()],
-        //     Some(VsCodeTokenScope::Many(ref scopes)) => scopes.clone(),
-        //     None => return Ok(IndexMap::new()),
-        // };
-
-        // for scope in &scope {
-        //     let Some(syntax_token) = Self::to_zed_token(&scope) else {
-        //         continue;
-        //     };
-
-        //     let highlight_style = UserHighlightStyle {
-        //         color: self
-        //             .settings
-        //             .foreground
-        //             .as_ref()
-        //             .traverse(|color| try_parse_color(&color))?,
-        //         font_style: self
-        //             .settings
-        //             .font_style
-        //             .as_ref()
-        //             .and_then(|style| try_parse_font_style(&style)),
-        //         font_weight: self
-        //             .settings
-        //             .font_style
-        //             .as_ref()
-        //             .and_then(|style| try_parse_font_weight(&style)),
-        //     };
-
-        //     if highlight_style.is_empty() {
-        //         continue;
-        //     }
-
-        //     highlight_styles.insert(syntax_token, highlight_style);
-        // }
-
-        // Ok(highlight_styles)
-        // }
     }
 }

crates/theme_importer/src/vscode/syntax.rs 🔗

@@ -1,26 +1,17 @@
+use indexmap::IndexMap;
 use serde::Deserialize;
 use strum::EnumIter;
 
-#[derive(Debug, Deserialize)]
+#[derive(Debug, PartialEq, Eq, Deserialize)]
 #[serde(untagged)]
 pub enum VsCodeTokenScope {
     One(String),
     Many(Vec<String>),
 }
 
-impl VsCodeTokenScope {
-    pub fn multimatch(&self, matches: &[&'static str]) -> bool {
-        match self {
-            VsCodeTokenScope::One(scope) => matches.iter().any(|&s| s == scope),
-            VsCodeTokenScope::Many(scopes) => {
-                matches.iter().any(|s| scopes.contains(&s.to_string()))
-            }
-        }
-    }
-}
-
 #[derive(Debug, Deserialize)]
 pub struct VsCodeTokenColor {
+    pub name: Option<String>,
     pub scope: Option<VsCodeTokenScope>,
     pub settings: VsCodeTokenColorSettings,
 }
@@ -35,184 +26,285 @@ pub struct VsCodeTokenColorSettings {
 
 #[derive(Debug, PartialEq, Copy, Clone, EnumIter)]
 pub enum ZedSyntaxToken {
-    SyntaxAttribute,
-    SyntaxBoolean,
-    SyntaxComment,
-    SyntaxCommentDoc,
-    SyntaxConstant,
-    SyntaxConstructor,
-    SyntaxEmbedded,
-    SyntaxEmphasis,
-    SyntaxEmphasisStrong,
-    SyntaxEnum,
-    SyntaxFunction,
-    SyntaxHint,
-    SyntaxKeyword,
-    SyntaxLabel,
-    SyntaxLinkText,
-    SyntaxLinkUri,
-    SyntaxNumber,
-    SyntaxOperator,
-    SyntaxPredictive,
-    SyntaxPreproc,
-    SyntaxPrimary,
-    SyntaxProperty,
-    SyntaxPunctuation,
-    SyntaxPunctuationBracket,
-    SyntaxPunctuationDelimiter,
-    SyntaxPunctuationListMarker,
-    SyntaxPunctuationSpecial,
-    SyntaxString,
-    SyntaxStringEscape,
-    SyntaxStringRegex,
-    SyntaxStringSpecial,
-    SyntaxStringSpecialSymbol,
-    SyntaxTag,
-    SyntaxTextLiteral,
-    SyntaxTitle,
-    SyntaxType,
-    SyntaxVariable,
-    SyntaxVariableSpecial,
-    SyntaxVariant,
+    Attribute,
+    Boolean,
+    Comment,
+    CommentDoc,
+    Constant,
+    Constructor,
+    Embedded,
+    Emphasis,
+    EmphasisStrong,
+    Enum,
+    Function,
+    Hint,
+    Keyword,
+    Label,
+    LinkText,
+    LinkUri,
+    Number,
+    Operator,
+    Predictive,
+    Preproc,
+    Primary,
+    Property,
+    Punctuation,
+    PunctuationBracket,
+    PunctuationDelimiter,
+    PunctuationListMarker,
+    PunctuationSpecial,
+    String,
+    StringEscape,
+    StringRegex,
+    StringSpecial,
+    StringSpecialSymbol,
+    Tag,
+    TextLiteral,
+    Title,
+    Type,
+    Variable,
+    VariableSpecial,
+    Variant,
 }
 
 impl std::fmt::Display for ZedSyntaxToken {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        use ZedSyntaxToken::*;
-
         write!(
             f,
             "{}",
             match self {
-                SyntaxAttribute => "attribute",
-                SyntaxBoolean => "boolean",
-                SyntaxComment => "comment",
-                SyntaxCommentDoc => "comment.doc",
-                SyntaxConstant => "constant",
-                SyntaxConstructor => "constructor",
-                SyntaxEmbedded => "embedded",
-                SyntaxEmphasis => "emphasis",
-                SyntaxEmphasisStrong => "emphasis.strong",
-                SyntaxEnum => "enum",
-                SyntaxFunction => "function",
-                SyntaxHint => "hint",
-                SyntaxKeyword => "keyword",
-                SyntaxLabel => "label",
-                SyntaxLinkText => "link_text",
-                SyntaxLinkUri => "link_uri",
-                SyntaxNumber => "number",
-                SyntaxOperator => "operator",
-                SyntaxPredictive => "predictive",
-                SyntaxPreproc => "preproc",
-                SyntaxPrimary => "primary",
-                SyntaxProperty => "property",
-                SyntaxPunctuation => "punctuation",
-                SyntaxPunctuationBracket => "punctuation.bracket",
-                SyntaxPunctuationDelimiter => "punctuation.delimiter",
-                SyntaxPunctuationListMarker => "punctuation.list_marker",
-                SyntaxPunctuationSpecial => "punctuation.special",
-                SyntaxString => "string",
-                SyntaxStringEscape => "string.escape",
-                SyntaxStringRegex => "string.regex",
-                SyntaxStringSpecial => "string.special",
-                SyntaxStringSpecialSymbol => "string.special.symbol",
-                SyntaxTag => "tag",
-                SyntaxTextLiteral => "text.literal",
-                SyntaxTitle => "title",
-                SyntaxType => "type",
-                SyntaxVariable => "variable",
-                SyntaxVariableSpecial => "variable.special",
-                SyntaxVariant => "variant",
+                ZedSyntaxToken::Attribute => "attribute",
+                ZedSyntaxToken::Boolean => "boolean",
+                ZedSyntaxToken::Comment => "comment",
+                ZedSyntaxToken::CommentDoc => "comment.doc",
+                ZedSyntaxToken::Constant => "constant",
+                ZedSyntaxToken::Constructor => "constructor",
+                ZedSyntaxToken::Embedded => "embedded",
+                ZedSyntaxToken::Emphasis => "emphasis",
+                ZedSyntaxToken::EmphasisStrong => "emphasis.strong",
+                ZedSyntaxToken::Enum => "enum",
+                ZedSyntaxToken::Function => "function",
+                ZedSyntaxToken::Hint => "hint",
+                ZedSyntaxToken::Keyword => "keyword",
+                ZedSyntaxToken::Label => "label",
+                ZedSyntaxToken::LinkText => "link_text",
+                ZedSyntaxToken::LinkUri => "link_uri",
+                ZedSyntaxToken::Number => "number",
+                ZedSyntaxToken::Operator => "operator",
+                ZedSyntaxToken::Predictive => "predictive",
+                ZedSyntaxToken::Preproc => "preproc",
+                ZedSyntaxToken::Primary => "primary",
+                ZedSyntaxToken::Property => "property",
+                ZedSyntaxToken::Punctuation => "punctuation",
+                ZedSyntaxToken::PunctuationBracket => "punctuation.bracket",
+                ZedSyntaxToken::PunctuationDelimiter => "punctuation.delimiter",
+                ZedSyntaxToken::PunctuationListMarker => "punctuation.list_marker",
+                ZedSyntaxToken::PunctuationSpecial => "punctuation.special",
+                ZedSyntaxToken::String => "string",
+                ZedSyntaxToken::StringEscape => "string.escape",
+                ZedSyntaxToken::StringRegex => "string.regex",
+                ZedSyntaxToken::StringSpecial => "string.special",
+                ZedSyntaxToken::StringSpecialSymbol => "string.special.symbol",
+                ZedSyntaxToken::Tag => "tag",
+                ZedSyntaxToken::TextLiteral => "text.literal",
+                ZedSyntaxToken::Title => "title",
+                ZedSyntaxToken::Type => "type",
+                ZedSyntaxToken::Variable => "variable",
+                ZedSyntaxToken::VariableSpecial => "variable.special",
+                ZedSyntaxToken::Variant => "variant",
             }
         )
     }
 }
 
 impl ZedSyntaxToken {
-    pub fn to_vscode(&self) -> Vec<&'static str> {
-        use ZedSyntaxToken::*;
+    pub fn find_best_token_color_match<'a>(
+        &self,
+        token_colors: &'a [VsCodeTokenColor],
+    ) -> Option<&'a VsCodeTokenColor> {
+        let mut ranked_matches = IndexMap::new();
+
+        for (ix, token_color) in token_colors.iter().enumerate() {
+            if token_color.settings.foreground.is_none() {
+                continue;
+            }
+
+            let Some(rank) = self.rank_match(token_color) else {
+                continue;
+            };
+
+            if rank > 0 {
+                ranked_matches.insert(ix, rank);
+            }
+        }
+
+        ranked_matches
+            .into_iter()
+            .max_by_key(|(_, rank)| *rank)
+            .map(|(ix, _)| &token_colors[ix])
+    }
+
+    fn rank_match(&self, token_color: &VsCodeTokenColor) -> Option<u32> {
+        let candidate_scopes = match token_color.scope.as_ref()? {
+            VsCodeTokenScope::One(scope) => vec![scope],
+            VsCodeTokenScope::Many(scopes) => scopes.iter().collect(),
+        }
+        .iter()
+        .map(|scope| scope.as_str())
+        .collect::<Vec<_>>();
+
+        let scopes_to_match = self.to_vscode();
+        let number_of_scopes_to_match = scopes_to_match.len();
+
+        let mut matches = 0;
 
+        for (ix, scope) in scopes_to_match.into_iter().enumerate() {
+            // Assign each entry a weight that is inversely proportional to its
+            // position in the list.
+            //
+            // Entries towards the front are weighted higher than those towards the end.
+            let weight = (number_of_scopes_to_match - ix) as u32;
+
+            if candidate_scopes.contains(&scope) {
+                matches += 1 + weight;
+            }
+        }
+
+        Some(matches)
+    }
+
+    pub fn fallbacks(&self) -> &[Self] {
+        match self {
+            ZedSyntaxToken::CommentDoc => &[ZedSyntaxToken::Comment],
+            ZedSyntaxToken::Number => &[ZedSyntaxToken::Constant],
+            ZedSyntaxToken::VariableSpecial => &[ZedSyntaxToken::Variable],
+            ZedSyntaxToken::PunctuationBracket
+            | ZedSyntaxToken::PunctuationDelimiter
+            | ZedSyntaxToken::PunctuationListMarker
+            | ZedSyntaxToken::PunctuationSpecial => &[ZedSyntaxToken::Punctuation],
+            ZedSyntaxToken::StringEscape
+            | ZedSyntaxToken::StringRegex
+            | ZedSyntaxToken::StringSpecial
+            | ZedSyntaxToken::StringSpecialSymbol => &[ZedSyntaxToken::String],
+            _ => &[],
+        }
+    }
+
+    pub fn to_vscode(&self) -> Vec<&'static str> {
         match self {
-            SyntaxAttribute => vec!["entity.other.attribute-name"],
-            SyntaxBoolean => vec!["constant.language"],
-            SyntaxComment => vec!["comment"],
-            SyntaxCommentDoc => vec!["comment.block.documentation"],
-            SyntaxConstant => vec!["constant.character"],
-            SyntaxConstructor => vec!["entity.name.function.definition.special.constructor"],
-            SyntaxEmbedded => vec!["meta.embedded"],
-            SyntaxEmphasis => vec!["markup.italic"],
-            SyntaxEmphasisStrong => vec![
+            ZedSyntaxToken::Attribute => vec!["entity.other.attribute-name"],
+            ZedSyntaxToken::Boolean => vec!["constant.language"],
+            ZedSyntaxToken::Comment => vec!["comment"],
+            ZedSyntaxToken::CommentDoc => vec!["comment.block.documentation"],
+            ZedSyntaxToken::Constant => vec!["constant", "constant.language", "constant.character"],
+            ZedSyntaxToken::Constructor => {
+                vec![
+                    "entity.name.tag",
+                    "entity.name.function.definition.special.constructor",
+                ]
+            }
+            ZedSyntaxToken::Embedded => vec!["meta.embedded"],
+            ZedSyntaxToken::Emphasis => vec!["markup.italic"],
+            ZedSyntaxToken::EmphasisStrong => vec![
                 "markup.bold",
                 "markup.italic markup.bold",
                 "markup.bold markup.italic",
             ],
-            SyntaxEnum => vec!["support.type.enum"],
-            SyntaxFunction => vec![
+            ZedSyntaxToken::Enum => vec!["support.type.enum"],
+            ZedSyntaxToken::Function => vec![
+                "entity.function",
                 "entity.name.function",
                 "variable.function",
-                "support.function",
             ],
-            SyntaxKeyword => vec!["keyword"],
-            SyntaxLabel => vec![
+            ZedSyntaxToken::Hint => vec![],
+            ZedSyntaxToken::Keyword => vec![
+                "keyword",
+                "keyword.other.fn.rust",
+                "keyword.control",
+                "keyword.control.fun",
+                "keyword.control.class",
+                "punctuation.accessor",
+                "entity.name.tag",
+            ],
+            ZedSyntaxToken::Label => vec![
                 "label",
                 "entity.name",
                 "entity.name.import",
                 "entity.name.package",
             ],
-            SyntaxLinkText => vec!["markup.underline.link", "string.other.link"],
-            SyntaxLinkUri => vec!["markup.underline.link", "string.other.link"],
-            SyntaxNumber => vec!["constant.numeric", "number"],
-            SyntaxOperator => vec!["operator", "keyword.operator"],
-            SyntaxPreproc => vec!["preproc"],
-            SyntaxProperty => vec![
+            ZedSyntaxToken::LinkText => vec!["markup.underline.link", "string.other.link"],
+            ZedSyntaxToken::LinkUri => vec!["markup.underline.link", "string.other.link"],
+            ZedSyntaxToken::Number => vec!["constant.numeric", "number"],
+            ZedSyntaxToken::Operator => vec!["operator", "keyword.operator"],
+            ZedSyntaxToken::Predictive => vec![],
+            ZedSyntaxToken::Preproc => vec![
+                "preproc",
+                "meta.preprocessor",
+                "punctuation.definition.preprocessor",
+            ],
+            ZedSyntaxToken::Primary => vec![],
+            ZedSyntaxToken::Property => vec![
                 "variable.member",
                 "support.type.property-name",
                 "variable.object.property",
                 "variable.other.field",
             ],
-            SyntaxPunctuation => vec![
+            ZedSyntaxToken::Punctuation => vec![
                 "punctuation",
                 "punctuation.section",
                 "punctuation.accessor",
                 "punctuation.separator",
-                "punctuation.terminator",
                 "punctuation.definition.tag",
             ],
-            SyntaxPunctuationBracket => vec![
+            ZedSyntaxToken::PunctuationBracket => vec![
                 "punctuation.bracket",
                 "punctuation.definition.tag.begin",
                 "punctuation.definition.tag.end",
             ],
-            SyntaxPunctuationDelimiter => vec![
+            ZedSyntaxToken::PunctuationDelimiter => vec![
                 "punctuation.delimiter",
                 "punctuation.separator",
                 "punctuation.terminator",
             ],
-            SyntaxPunctuationListMarker => vec!["markup.list punctuation.definition.list.begin"],
-            SyntaxPunctuationSpecial => vec!["punctuation.special"],
-            SyntaxString => vec!["string"],
-            SyntaxStringEscape => vec!["string.escape", "constant.character", "constant.other"],
-            SyntaxStringRegex => vec!["string.regex"],
-            SyntaxStringSpecial => vec!["string.special", "constant.other.symbol"],
-            SyntaxStringSpecialSymbol => vec!["string.special.symbol", "constant.other.symbol"],
-            SyntaxTag => vec!["tag", "entity.name.tag", "meta.tag.sgml"],
-            SyntaxTextLiteral => vec!["text.literal", "string"],
-            SyntaxTitle => vec!["title", "entity.name"],
-            SyntaxType => vec!["entity.name.type", "support.type", "support.class"],
-            SyntaxVariable => vec![
+            ZedSyntaxToken::PunctuationListMarker => {
+                vec!["markup.list punctuation.definition.list.begin"]
+            }
+            ZedSyntaxToken::PunctuationSpecial => vec!["punctuation.special"],
+            ZedSyntaxToken::String => vec!["string"],
+            ZedSyntaxToken::StringEscape => {
+                vec!["string.escape", "constant.character", "constant.other"]
+            }
+            ZedSyntaxToken::StringRegex => vec!["string.regex"],
+            ZedSyntaxToken::StringSpecial => vec!["string.special", "constant.other.symbol"],
+            ZedSyntaxToken::StringSpecialSymbol => {
+                vec!["string.special.symbol", "constant.other.symbol"]
+            }
+            ZedSyntaxToken::Tag => vec!["tag", "entity.name.tag", "meta.tag.sgml"],
+            ZedSyntaxToken::TextLiteral => vec!["text.literal", "string"],
+            ZedSyntaxToken::Title => vec!["title", "entity.name"],
+            ZedSyntaxToken::Type => vec![
+                "entity.name.type",
+                "entity.name.type.primitive",
+                "entity.name.type.numeric",
+                "keyword.type",
+                "support.type",
+                "support.type.primitive",
+                "support.class",
+            ],
+            ZedSyntaxToken::Variable => vec![
                 "variable",
                 "variable.language",
                 "variable.member",
+                "variable.parameter",
                 "variable.parameter.function-call",
             ],
-            SyntaxVariableSpecial => vec![
+            ZedSyntaxToken::VariableSpecial => vec![
                 "variable.special",
                 "variable.member",
                 "variable.annotation",
                 "variable.language",
             ],
-            SyntaxVariant => vec!["variant"],
-            _ => vec![],
+            ZedSyntaxToken::Variant => vec!["variant"],
         }
     }
 }

crates/theme_importer/src/vscode/theme.rs 🔗

@@ -1,7 +1,15 @@
-use serde::Deserialize;
+use serde::{Deserialize, Deserializer};
 
 use crate::vscode::VsCodeTokenColor;
 
+fn empty_string_as_none<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
+where
+    D: Deserializer<'de>,
+{
+    let value = Option::<String>::deserialize(deserializer)?;
+    Ok(value.filter(|value| !value.is_empty()))
+}
+
 #[derive(Deserialize, Debug)]
 pub struct VsCodeTheme {
     #[serde(rename = "$schema")]
@@ -20,393 +28,1406 @@ pub struct VsCodeTheme {
 
 #[derive(Debug, Deserialize)]
 pub struct VsCodeColors {
-    #[serde(rename = "terminal.background")]
+    #[serde(
+        default,
+        rename = "terminal.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_background: Option<String>,
-    #[serde(rename = "terminal.foreground")]
+
+    #[serde(
+        default,
+        rename = "terminal.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_foreground: Option<String>,
-    #[serde(rename = "terminal.ansiBrightBlack")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiBrightBlack",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_bright_black: Option<String>,
-    #[serde(rename = "terminal.ansiBrightRed")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiBrightRed",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_bright_red: Option<String>,
-    #[serde(rename = "terminal.ansiBrightGreen")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiBrightGreen",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_bright_green: Option<String>,
-    #[serde(rename = "terminal.ansiBrightYellow")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiBrightYellow",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_bright_yellow: Option<String>,
-    #[serde(rename = "terminal.ansiBrightBlue")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiBrightBlue",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_bright_blue: Option<String>,
-    #[serde(rename = "terminal.ansiBrightMagenta")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiBrightMagenta",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_bright_magenta: Option<String>,
-    #[serde(rename = "terminal.ansiBrightCyan")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiBrightCyan",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_bright_cyan: Option<String>,
-    #[serde(rename = "terminal.ansiBrightWhite")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiBrightWhite",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_bright_white: Option<String>,
-    #[serde(rename = "terminal.ansiBlack")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiBlack",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_black: Option<String>,
-    #[serde(rename = "terminal.ansiRed")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiRed",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_red: Option<String>,
-    #[serde(rename = "terminal.ansiGreen")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiGreen",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_green: Option<String>,
-    #[serde(rename = "terminal.ansiYellow")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiYellow",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_yellow: Option<String>,
-    #[serde(rename = "terminal.ansiBlue")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiBlue",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_blue: Option<String>,
-    #[serde(rename = "terminal.ansiMagenta")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiMagenta",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_magenta: Option<String>,
-    #[serde(rename = "terminal.ansiCyan")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiCyan",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_cyan: Option<String>,
-    #[serde(rename = "terminal.ansiWhite")]
+
+    #[serde(
+        default,
+        rename = "terminal.ansiWhite",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub terminal_ansi_white: Option<String>,
-    #[serde(rename = "focusBorder")]
+
+    #[serde(
+        default,
+        rename = "focusBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub focus_border: Option<String>,
+
+    #[serde(default, deserialize_with = "empty_string_as_none")]
     pub foreground: Option<String>,
-    #[serde(rename = "selection.background")]
+
+    #[serde(
+        default,
+        rename = "selection.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub selection_background: Option<String>,
-    #[serde(rename = "errorForeground")]
+
+    #[serde(
+        default,
+        rename = "errorForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub error_foreground: Option<String>,
-    #[serde(rename = "button.background")]
+
+    #[serde(
+        default,
+        rename = "button.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub button_background: Option<String>,
-    #[serde(rename = "button.foreground")]
+
+    #[serde(
+        default,
+        rename = "button.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub button_foreground: Option<String>,
-    #[serde(rename = "button.secondaryBackground")]
+
+    #[serde(
+        default,
+        rename = "button.secondaryBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub button_secondary_background: Option<String>,
-    #[serde(rename = "button.secondaryForeground")]
+
+    #[serde(
+        default,
+        rename = "button.secondaryForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub button_secondary_foreground: Option<String>,
-    #[serde(rename = "button.secondaryHoverBackground")]
+
+    #[serde(
+        default,
+        rename = "button.secondaryHoverBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub button_secondary_hover_background: Option<String>,
-    #[serde(rename = "dropdown.background")]
+
+    #[serde(
+        default,
+        rename = "dropdown.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub dropdown_background: Option<String>,
-    #[serde(rename = "dropdown.border")]
+
+    #[serde(
+        default,
+        rename = "dropdown.border",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub dropdown_border: Option<String>,
-    #[serde(rename = "dropdown.foreground")]
+
+    #[serde(
+        default,
+        rename = "dropdown.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub dropdown_foreground: Option<String>,
-    #[serde(rename = "input.background")]
+
+    #[serde(
+        default,
+        rename = "input.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub input_background: Option<String>,
-    #[serde(rename = "input.foreground")]
+
+    #[serde(
+        default,
+        rename = "input.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub input_foreground: Option<String>,
-    #[serde(rename = "input.border")]
+
+    #[serde(
+        default,
+        rename = "input.border",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub input_border: Option<String>,
-    #[serde(rename = "input.placeholderForeground")]
+
+    #[serde(
+        default,
+        rename = "input.placeholderForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub input_placeholder_foreground: Option<String>,
-    #[serde(rename = "inputOption.activeBorder")]
+
+    #[serde(
+        default,
+        rename = "inputOption.activeBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub input_option_active_border: Option<String>,
-    #[serde(rename = "inputValidation.infoBorder")]
+
+    #[serde(
+        default,
+        rename = "inputValidation.infoBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub input_validation_info_border: Option<String>,
-    #[serde(rename = "inputValidation.warningBorder")]
+
+    #[serde(
+        default,
+        rename = "inputValidation.warningBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub input_validation_warning_border: Option<String>,
-    #[serde(rename = "inputValidation.errorBorder")]
+
+    #[serde(
+        default,
+        rename = "inputValidation.errorBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub input_validation_error_border: Option<String>,
-    #[serde(rename = "badge.foreground")]
+
+    #[serde(
+        default,
+        rename = "badge.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub badge_foreground: Option<String>,
-    #[serde(rename = "badge.background")]
+
+    #[serde(
+        default,
+        rename = "badge.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub badge_background: Option<String>,
-    #[serde(rename = "progressBar.background")]
+
+    #[serde(
+        default,
+        rename = "progressBar.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub progress_bar_background: Option<String>,
-    #[serde(rename = "list.activeSelectionBackground")]
+
+    #[serde(
+        default,
+        rename = "list.activeSelectionBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_active_selection_background: Option<String>,
-    #[serde(rename = "list.activeSelectionForeground")]
+
+    #[serde(
+        default,
+        rename = "list.activeSelectionForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_active_selection_foreground: Option<String>,
-    #[serde(rename = "list.dropBackground")]
+
+    #[serde(
+        default,
+        rename = "list.dropBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_drop_background: Option<String>,
-    #[serde(rename = "list.focusBackground")]
+
+    #[serde(
+        default,
+        rename = "list.focusBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_focus_background: Option<String>,
-    #[serde(rename = "list.highlightForeground")]
+
+    #[serde(
+        default,
+        rename = "list.highlightForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_highlight_foreground: Option<String>,
-    #[serde(rename = "list.hoverBackground")]
+
+    #[serde(
+        default,
+        rename = "list.hoverBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_hover_background: Option<String>,
-    #[serde(rename = "list.inactiveSelectionBackground")]
+
+    #[serde(
+        default,
+        rename = "list.inactiveSelectionBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_inactive_selection_background: Option<String>,
-    #[serde(rename = "list.warningForeground")]
+
+    #[serde(
+        default,
+        rename = "list.warningForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_warning_foreground: Option<String>,
-    #[serde(rename = "list.errorForeground")]
+
+    #[serde(
+        default,
+        rename = "list.errorForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_error_foreground: Option<String>,
-    #[serde(rename = "activityBar.background")]
+
+    #[serde(
+        default,
+        rename = "activityBar.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub activity_bar_background: Option<String>,
-    #[serde(rename = "activityBar.inactiveForeground")]
+
+    #[serde(
+        default,
+        rename = "activityBar.inactiveForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub activity_bar_inactive_foreground: Option<String>,
-    #[serde(rename = "activityBar.foreground")]
+
+    #[serde(
+        default,
+        rename = "activityBar.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub activity_bar_foreground: Option<String>,
-    #[serde(rename = "activityBar.activeBorder")]
+
+    #[serde(
+        default,
+        rename = "activityBar.activeBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub activity_bar_active_border: Option<String>,
-    #[serde(rename = "activityBar.activeBackground")]
+
+    #[serde(
+        default,
+        rename = "activityBar.activeBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub activity_bar_active_background: Option<String>,
-    #[serde(rename = "activityBarBadge.background")]
+
+    #[serde(
+        default,
+        rename = "activityBarBadge.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub activity_bar_badge_background: Option<String>,
-    #[serde(rename = "activityBarBadge.foreground")]
+
+    #[serde(
+        default,
+        rename = "activityBarBadge.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub activity_bar_badge_foreground: Option<String>,
-    #[serde(rename = "sideBar.background")]
+
+    #[serde(
+        default,
+        rename = "sideBar.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub side_bar_background: Option<String>,
-    #[serde(rename = "sideBarTitle.foreground")]
+
+    #[serde(
+        default,
+        rename = "sideBarTitle.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub side_bar_title_foreground: Option<String>,
-    #[serde(rename = "sideBarSectionHeader.background")]
+
+    #[serde(
+        default,
+        rename = "sideBarSectionHeader.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub side_bar_section_header_background: Option<String>,
-    #[serde(rename = "sideBarSectionHeader.border")]
+
+    #[serde(
+        default,
+        rename = "sideBarSectionHeader.border",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub side_bar_section_header_border: Option<String>,
-    #[serde(rename = "editorGroup.border")]
+
+    #[serde(
+        default,
+        rename = "editorGroup.border",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_group_border: Option<String>,
-    #[serde(rename = "editorGroup.dropBackground")]
+
+    #[serde(
+        default,
+        rename = "editorGroup.dropBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_group_drop_background: Option<String>,
-    #[serde(rename = "editorGroupHeader.tabsBackground")]
+
+    #[serde(
+        default,
+        rename = "editorGroupHeader.tabsBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_group_header_tabs_background: Option<String>,
-    #[serde(rename = "tab.activeBackground")]
+
+    #[serde(
+        default,
+        rename = "tab.activeBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub tab_active_background: Option<String>,
-    #[serde(rename = "tab.activeForeground")]
+
+    #[serde(
+        default,
+        rename = "tab.activeForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub tab_active_foreground: Option<String>,
-    #[serde(rename = "tab.border")]
+
+    #[serde(
+        default,
+        rename = "tab.border",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub tab_border: Option<String>,
-    #[serde(rename = "tab.activeBorderTop")]
+
+    #[serde(
+        default,
+        rename = "tab.activeBorderTop",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub tab_active_border_top: Option<String>,
-    #[serde(rename = "tab.inactiveBackground")]
+
+    #[serde(
+        default,
+        rename = "tab.inactiveBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub tab_inactive_background: Option<String>,
-    #[serde(rename = "tab.inactiveForeground")]
+
+    #[serde(
+        default,
+        rename = "tab.inactiveForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub tab_inactive_foreground: Option<String>,
-    #[serde(rename = "editor.foreground")]
+
+    #[serde(
+        default,
+        rename = "editor.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_foreground: Option<String>,
-    #[serde(rename = "editor.background")]
+
+    #[serde(
+        default,
+        rename = "editor.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_background: Option<String>,
-    #[serde(rename = "editorLineNumber.foreground")]
+
+    #[serde(
+        default,
+        rename = "editorInlayHint.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
+    pub editor_inlay_hint_foreground: Option<String>,
+
+    #[serde(
+        default,
+        rename = "editorInlayHint.background",
+        deserialize_with = "empty_string_as_none"
+    )]
+    pub editor_inlay_hint_background: Option<String>,
+
+    #[serde(
+        default,
+        rename = "editorInlayHint.parameterForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
+    pub editor_inlay_hint_parameter_foreground: Option<String>,
+
+    #[serde(
+        default,
+        rename = "editorInlayHint.parameterBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
+    pub editor_inlay_hint_parameter_background: Option<String>,
+
+    #[serde(
+        default,
+        rename = "editorInlayHint.typForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
+    pub editor_inlay_hint_typ_foreground: Option<String>,
+
+    #[serde(
+        default,
+        rename = "editorInlayHint.typBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
+    pub editor_inlay_hint_typ_background: Option<String>,
+
+    #[serde(
+        default,
+        rename = "editorLineNumber.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_line_number_foreground: Option<String>,
-    #[serde(rename = "editor.selectionBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.selectionBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_selection_background: Option<String>,
-    #[serde(rename = "editor.selectionHighlightBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.selectionHighlightBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_selection_highlight_background: Option<String>,
-    #[serde(rename = "editor.foldBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.foldBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_fold_background: Option<String>,
-    #[serde(rename = "editor.wordHighlightBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.wordHighlightBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_word_highlight_background: Option<String>,
-    #[serde(rename = "editor.wordHighlightStrongBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.wordHighlightStrongBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_word_highlight_strong_background: Option<String>,
-    #[serde(rename = "editor.findMatchBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.findMatchBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_find_match_background: Option<String>,
-    #[serde(rename = "editor.findMatchHighlightBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.findMatchHighlightBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_find_match_highlight_background: Option<String>,
-    #[serde(rename = "editor.findRangeHighlightBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.findRangeHighlightBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_find_range_highlight_background: Option<String>,
-    #[serde(rename = "editor.hoverHighlightBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.hoverHighlightBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_hover_highlight_background: Option<String>,
-    #[serde(rename = "editor.lineHighlightBorder")]
+
+    #[serde(
+        default,
+        rename = "editor.lineHighlightBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_line_highlight_border: Option<String>,
-    #[serde(rename = "editorLink.activeForeground")]
+
+    #[serde(
+        default,
+        rename = "editorLink.activeForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_link_active_foreground: Option<String>,
-    #[serde(rename = "editor.rangeHighlightBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.rangeHighlightBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_range_highlight_background: Option<String>,
-    #[serde(rename = "editor.snippetTabstopHighlightBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.snippetTabstopHighlightBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_snippet_tabstop_highlight_background: Option<String>,
-    #[serde(rename = "editor.snippetTabstopHighlightBorder")]
+
+    #[serde(
+        default,
+        rename = "editor.snippetTabstopHighlightBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_snippet_tabstop_highlight_border: Option<String>,
-    #[serde(rename = "editor.snippetFinalTabstopHighlightBackground")]
+
+    #[serde(
+        default,
+        rename = "editor.snippetFinalTabstopHighlightBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_snippet_final_tabstop_highlight_background: Option<String>,
-    #[serde(rename = "editor.snippetFinalTabstopHighlightBorder")]
+
+    #[serde(
+        default,
+        rename = "editor.snippetFinalTabstopHighlightBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_snippet_final_tabstop_highlight_border: Option<String>,
-    #[serde(rename = "editorWhitespace.foreground")]
+
+    #[serde(
+        default,
+        rename = "editorWhitespace.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_whitespace_foreground: Option<String>,
-    #[serde(rename = "editorIndentGuide.background")]
+
+    #[serde(
+        default,
+        rename = "editorIndentGuide.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_indent_guide_background: Option<String>,
-    #[serde(rename = "editorIndentGuide.activeBackground")]
+
+    #[serde(
+        default,
+        rename = "editorIndentGuide.activeBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_indent_guide_active_background: Option<String>,
-    #[serde(rename = "editorRuler.foreground")]
+
+    #[serde(
+        default,
+        rename = "editorRuler.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_ruler_foreground: Option<String>,
-    #[serde(rename = "editorCodeLens.foreground")]
+
+    #[serde(
+        default,
+        rename = "editorCodeLens.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_code_lens_foreground: Option<String>,
-    #[serde(rename = "editorBracketHighlight.foreground1")]
+
+    #[serde(
+        default,
+        rename = "editorBracketHighlight.foreground1",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_bracket_highlight_foreground1: Option<String>,
-    #[serde(rename = "editorBracketHighlight.foreground2")]
+
+    #[serde(
+        default,
+        rename = "editorBracketHighlight.foreground2",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_bracket_highlight_foreground2: Option<String>,
-    #[serde(rename = "editorBracketHighlight.foreground3")]
+
+    #[serde(
+        default,
+        rename = "editorBracketHighlight.foreground3",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_bracket_highlight_foreground3: Option<String>,
-    #[serde(rename = "editorBracketHighlight.foreground4")]
+
+    #[serde(
+        default,
+        rename = "editorBracketHighlight.foreground4",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_bracket_highlight_foreground4: Option<String>,
-    #[serde(rename = "editorBracketHighlight.foreground5")]
+
+    #[serde(
+        default,
+        rename = "editorBracketHighlight.foreground5",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_bracket_highlight_foreground5: Option<String>,
-    #[serde(rename = "editorBracketHighlight.foreground6")]
+
+    #[serde(
+        default,
+        rename = "editorBracketHighlight.foreground6",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_bracket_highlight_foreground6: Option<String>,
-    #[serde(rename = "editorBracketHighlight.unexpectedBracket.foreground")]
+
+    #[serde(
+        default,
+        rename = "editorBracketHighlight.unexpectedBracket.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_bracket_highlight_unexpected_bracket_foreground: Option<String>,
-    #[serde(rename = "editorOverviewRuler.border")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.border",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_border: Option<String>,
-    #[serde(rename = "editorOverviewRuler.selectionHighlightForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.selectionHighlightForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_selection_highlight_foreground: Option<String>,
-    #[serde(rename = "editorOverviewRuler.wordHighlightForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.wordHighlightForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_word_highlight_foreground: Option<String>,
-    #[serde(rename = "editorOverviewRuler.wordHighlightStrongForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.wordHighlightStrongForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_word_highlight_strong_foreground: Option<String>,
-    #[serde(rename = "editorOverviewRuler.modifiedForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.modifiedForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_modified_foreground: Option<String>,
-    #[serde(rename = "editorOverviewRuler.addedForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.addedForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_added_foreground: Option<String>,
-    #[serde(rename = "editorOverviewRuler.deletedForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.deletedForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_deleted_foreground: Option<String>,
-    #[serde(rename = "editorOverviewRuler.errorForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.errorForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_error_foreground: Option<String>,
-    #[serde(rename = "editorOverviewRuler.warningForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.warningForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_warning_foreground: Option<String>,
-    #[serde(rename = "editorOverviewRuler.infoForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.infoForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_info_foreground: Option<String>,
-    #[serde(rename = "editorError.foreground")]
+
+    #[serde(
+        default,
+        rename = "editorError.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_error_foreground: Option<String>,
-    #[serde(rename = "editorWarning.foreground")]
+
+    #[serde(
+        default,
+        rename = "editorWarning.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_warning_foreground: Option<String>,
-    #[serde(rename = "editorGutter.modifiedBackground")]
+
+    #[serde(
+        default,
+        rename = "editorGutter.modifiedBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_gutter_modified_background: Option<String>,
-    #[serde(rename = "editorGutter.addedBackground")]
+
+    #[serde(
+        default,
+        rename = "editorGutter.addedBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_gutter_added_background: Option<String>,
-    #[serde(rename = "editorGutter.deletedBackground")]
+
+    #[serde(
+        default,
+        rename = "editorGutter.deletedBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_gutter_deleted_background: Option<String>,
-    #[serde(rename = "gitDecoration.modifiedResourceForeground")]
+
+    #[serde(
+        default,
+        rename = "gitDecoration.modifiedResourceForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub git_decoration_modified_resource_foreground: Option<String>,
-    #[serde(rename = "gitDecoration.deletedResourceForeground")]
+
+    #[serde(
+        default,
+        rename = "gitDecoration.deletedResourceForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub git_decoration_deleted_resource_foreground: Option<String>,
-    #[serde(rename = "gitDecoration.untrackedResourceForeground")]
+
+    #[serde(
+        default,
+        rename = "gitDecoration.untrackedResourceForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub git_decoration_untracked_resource_foreground: Option<String>,
-    #[serde(rename = "gitDecoration.ignoredResourceForeground")]
+
+    #[serde(
+        default,
+        rename = "gitDecoration.ignoredResourceForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub git_decoration_ignored_resource_foreground: Option<String>,
-    #[serde(rename = "gitDecoration.conflictingResourceForeground")]
+
+    #[serde(
+        default,
+        rename = "gitDecoration.conflictingResourceForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub git_decoration_conflicting_resource_foreground: Option<String>,
-    #[serde(rename = "diffEditor.insertedTextBackground")]
+
+    #[serde(
+        default,
+        rename = "diffEditor.insertedTextBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub diff_editor_inserted_text_background: Option<String>,
-    #[serde(rename = "diffEditor.removedTextBackground")]
+
+    #[serde(
+        default,
+        rename = "diffEditor.removedTextBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub diff_editor_removed_text_background: Option<String>,
-    #[serde(rename = "inlineChat.regionHighlight")]
+
+    #[serde(
+        default,
+        rename = "inlineChat.regionHighlight",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub inline_chat_region_highlight: Option<String>,
-    #[serde(rename = "editorWidget.background")]
+
+    #[serde(
+        default,
+        rename = "editorWidget.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_widget_background: Option<String>,
-    #[serde(rename = "editorSuggestWidget.background")]
+
+    #[serde(
+        default,
+        rename = "editorSuggestWidget.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_suggest_widget_background: Option<String>,
-    #[serde(rename = "editorSuggestWidget.foreground")]
+
+    #[serde(
+        default,
+        rename = "editorSuggestWidget.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_suggest_widget_foreground: Option<String>,
-    #[serde(rename = "editorSuggestWidget.selectedBackground")]
+
+    #[serde(
+        default,
+        rename = "editorSuggestWidget.selectedBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_suggest_widget_selected_background: Option<String>,
-    #[serde(rename = "editorHoverWidget.background")]
+
+    #[serde(
+        default,
+        rename = "editorHoverWidget.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_hover_widget_background: Option<String>,
-    #[serde(rename = "editorHoverWidget.border")]
+
+    #[serde(
+        default,
+        rename = "editorHoverWidget.border",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_hover_widget_border: Option<String>,
-    #[serde(rename = "editorMarkerNavigation.background")]
+
+    #[serde(
+        default,
+        rename = "editorMarkerNavigation.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_marker_navigation_background: Option<String>,
-    #[serde(rename = "peekView.border")]
+
+    #[serde(
+        default,
+        rename = "peekView.border",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_border: Option<String>,
-    #[serde(rename = "peekViewEditor.background")]
+
+    #[serde(
+        default,
+        rename = "peekViewEditor.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_editor_background: Option<String>,
-    #[serde(rename = "peekViewEditor.matchHighlightBackground")]
+
+    #[serde(
+        default,
+        rename = "peekViewEditor.matchHighlightBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_editor_match_highlight_background: Option<String>,
-    #[serde(rename = "peekViewResult.background")]
+
+    #[serde(
+        default,
+        rename = "peekViewResult.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_result_background: Option<String>,
-    #[serde(rename = "peekViewResult.fileForeground")]
+
+    #[serde(
+        default,
+        rename = "peekViewResult.fileForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_result_file_foreground: Option<String>,
-    #[serde(rename = "peekViewResult.lineForeground")]
+
+    #[serde(
+        default,
+        rename = "peekViewResult.lineForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_result_line_foreground: Option<String>,
-    #[serde(rename = "peekViewResult.matchHighlightBackground")]
+
+    #[serde(
+        default,
+        rename = "peekViewResult.matchHighlightBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_result_match_highlight_background: Option<String>,
-    #[serde(rename = "peekViewResult.selectionBackground")]
+
+    #[serde(
+        default,
+        rename = "peekViewResult.selectionBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_result_selection_background: Option<String>,
-    #[serde(rename = "peekViewResult.selectionForeground")]
+
+    #[serde(
+        default,
+        rename = "peekViewResult.selectionForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_result_selection_foreground: Option<String>,
-    #[serde(rename = "peekViewTitle.background")]
+
+    #[serde(
+        default,
+        rename = "peekViewTitle.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_title_background: Option<String>,
-    #[serde(rename = "peekViewTitleDescription.foreground")]
+
+    #[serde(
+        default,
+        rename = "peekViewTitleDescription.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_title_description_foreground: Option<String>,
-    #[serde(rename = "peekViewTitleLabel.foreground")]
+
+    #[serde(
+        default,
+        rename = "peekViewTitleLabel.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub peek_view_title_label_foreground: Option<String>,
-    #[serde(rename = "merge.currentHeaderBackground")]
+
+    #[serde(
+        default,
+        rename = "merge.currentHeaderBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub merge_current_header_background: Option<String>,
-    #[serde(rename = "merge.incomingHeaderBackground")]
+
+    #[serde(
+        default,
+        rename = "merge.incomingHeaderBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub merge_incoming_header_background: Option<String>,
-    #[serde(rename = "editorOverviewRuler.currentContentForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.currentContentForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_current_content_foreground: Option<String>,
-    #[serde(rename = "editorOverviewRuler.incomingContentForeground")]
+
+    #[serde(
+        default,
+        rename = "editorOverviewRuler.incomingContentForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub editor_overview_ruler_incoming_content_foreground: Option<String>,
-    #[serde(rename = "panel.background")]
+
+    #[serde(
+        default,
+        rename = "panel.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub panel_background: Option<String>,
-    #[serde(rename = "panel.border")]
+
+    #[serde(
+        default,
+        rename = "panel.border",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub panel_border: Option<String>,
-    #[serde(rename = "panelTitle.activeBorder")]
+
+    #[serde(
+        default,
+        rename = "panelTitle.activeBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub panel_title_active_border: Option<String>,
-    #[serde(rename = "panelTitle.activeForeground")]
+
+    #[serde(
+        default,
+        rename = "panelTitle.activeForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub panel_title_active_foreground: Option<String>,
-    #[serde(rename = "panelTitle.inactiveForeground")]
+
+    #[serde(
+        default,
+        rename = "panelTitle.inactiveForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub panel_title_inactive_foreground: Option<String>,
-    #[serde(rename = "statusBar.background")]
+
+    #[serde(
+        default,
+        rename = "statusBar.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub status_bar_background: Option<String>,
-    #[serde(rename = "statusBar.foreground")]
+
+    #[serde(
+        default,
+        rename = "statusBar.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub status_bar_foreground: Option<String>,
-    #[serde(rename = "statusBar.debuggingBackground")]
+
+    #[serde(
+        default,
+        rename = "statusBar.debuggingBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub status_bar_debugging_background: Option<String>,
-    #[serde(rename = "statusBar.debuggingForeground")]
+
+    #[serde(
+        default,
+        rename = "statusBar.debuggingForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub status_bar_debugging_foreground: Option<String>,
-    #[serde(rename = "statusBar.noFolderBackground")]
+
+    #[serde(
+        default,
+        rename = "statusBar.noFolderBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub status_bar_no_folder_background: Option<String>,
-    #[serde(rename = "statusBar.noFolderForeground")]
+
+    #[serde(
+        default,
+        rename = "statusBar.noFolderForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub status_bar_no_folder_foreground: Option<String>,
-    #[serde(rename = "statusBarItem.prominentBackground")]
+
+    #[serde(
+        default,
+        rename = "statusBarItem.prominentBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub status_bar_item_prominent_background: Option<String>,
-    #[serde(rename = "statusBarItem.prominentHoverBackground")]
+
+    #[serde(
+        default,
+        rename = "statusBarItem.prominentHoverBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub status_bar_item_prominent_hover_background: Option<String>,
-    #[serde(rename = "statusBarItem.remoteForeground")]
+
+    #[serde(
+        default,
+        rename = "statusBarItem.remoteForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub status_bar_item_remote_foreground: Option<String>,
-    #[serde(rename = "statusBarItem.remoteBackground")]
+
+    #[serde(
+        default,
+        rename = "statusBarItem.remoteBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub status_bar_item_remote_background: Option<String>,
-    #[serde(rename = "titleBar.activeBackground")]
+
+    #[serde(
+        default,
+        rename = "titleBar.activeBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub title_bar_active_background: Option<String>,
-    #[serde(rename = "titleBar.activeForeground")]
+
+    #[serde(
+        default,
+        rename = "titleBar.activeForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub title_bar_active_foreground: Option<String>,
-    #[serde(rename = "titleBar.inactiveBackground")]
+
+    #[serde(
+        default,
+        rename = "titleBar.inactiveBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub title_bar_inactive_background: Option<String>,
-    #[serde(rename = "titleBar.inactiveForeground")]
+
+    #[serde(
+        default,
+        rename = "titleBar.inactiveForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub title_bar_inactive_foreground: Option<String>,
-    #[serde(rename = "extensionButton.prominentForeground")]
+
+    #[serde(
+        default,
+        rename = "extensionButton.prominentForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub extension_button_prominent_foreground: Option<String>,
-    #[serde(rename = "extensionButton.prominentBackground")]
+
+    #[serde(
+        default,
+        rename = "extensionButton.prominentBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub extension_button_prominent_background: Option<String>,
-    #[serde(rename = "extensionButton.prominentHoverBackground")]
+
+    #[serde(
+        default,
+        rename = "extensionButton.prominentHoverBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub extension_button_prominent_hover_background: Option<String>,
-    #[serde(rename = "pickerGroup.border")]
+
+    #[serde(
+        default,
+        rename = "pickerGroup.border",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub picker_group_border: Option<String>,
-    #[serde(rename = "pickerGroup.foreground")]
+
+    #[serde(
+        default,
+        rename = "pickerGroup.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub picker_group_foreground: Option<String>,
-    #[serde(rename = "debugToolBar.background")]
+
+    #[serde(
+        default,
+        rename = "debugToolBar.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub debug_tool_bar_background: Option<String>,
-    #[serde(rename = "walkThrough.embeddedEditorBackground")]
+
+    #[serde(
+        default,
+        rename = "walkThrough.embeddedEditorBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub walk_through_embedded_editor_background: Option<String>,
-    #[serde(rename = "settings.headerForeground")]
+
+    #[serde(
+        default,
+        rename = "settings.headerForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_header_foreground: Option<String>,
-    #[serde(rename = "settings.modifiedItemIndicator")]
+
+    #[serde(
+        default,
+        rename = "settings.modifiedItemIndicator",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_modified_item_indicator: Option<String>,
-    #[serde(rename = "settings.dropdownBackground")]
+
+    #[serde(
+        default,
+        rename = "settings.dropdownBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_dropdown_background: Option<String>,
-    #[serde(rename = "settings.dropdownForeground")]
+
+    #[serde(
+        default,
+        rename = "settings.dropdownForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_dropdown_foreground: Option<String>,
-    #[serde(rename = "settings.dropdownBorder")]
+
+    #[serde(
+        default,
+        rename = "settings.dropdownBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_dropdown_border: Option<String>,
-    #[serde(rename = "settings.checkboxBackground")]
+
+    #[serde(
+        default,
+        rename = "settings.checkboxBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_checkbox_background: Option<String>,
-    #[serde(rename = "settings.checkboxForeground")]
+
+    #[serde(
+        default,
+        rename = "settings.checkboxForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_checkbox_foreground: Option<String>,
-    #[serde(rename = "settings.checkboxBorder")]
+
+    #[serde(
+        default,
+        rename = "settings.checkboxBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_checkbox_border: Option<String>,
-    #[serde(rename = "settings.textInputBackground")]
+
+    #[serde(
+        default,
+        rename = "settings.textInputBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_text_input_background: Option<String>,
-    #[serde(rename = "settings.textInputForeground")]
+
+    #[serde(
+        default,
+        rename = "settings.textInputForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_text_input_foreground: Option<String>,
-    #[serde(rename = "settings.textInputBorder")]
+
+    #[serde(
+        default,
+        rename = "settings.textInputBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_text_input_border: Option<String>,
-    #[serde(rename = "settings.numberInputBackground")]
+
+    #[serde(
+        default,
+        rename = "settings.numberInputBackground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_number_input_background: Option<String>,
-    #[serde(rename = "settings.numberInputForeground")]
+
+    #[serde(
+        default,
+        rename = "settings.numberInputForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_number_input_foreground: Option<String>,
-    #[serde(rename = "settings.numberInputBorder")]
+
+    #[serde(
+        default,
+        rename = "settings.numberInputBorder",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub settings_number_input_border: Option<String>,
-    #[serde(rename = "breadcrumb.foreground")]
+
+    #[serde(
+        default,
+        rename = "breadcrumb.foreground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub breadcrumb_foreground: Option<String>,
-    #[serde(rename = "breadcrumb.background")]
+
+    #[serde(
+        default,
+        rename = "breadcrumb.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub breadcrumb_background: Option<String>,
-    #[serde(rename = "breadcrumb.focusForeground")]
+
+    #[serde(
+        default,
+        rename = "breadcrumb.focusForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub breadcrumb_focus_foreground: Option<String>,
-    #[serde(rename = "breadcrumb.activeSelectionForeground")]
+
+    #[serde(
+        default,
+        rename = "breadcrumb.activeSelectionForeground",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub breadcrumb_active_selection_foreground: Option<String>,
-    #[serde(rename = "breadcrumbPicker.background")]
+
+    #[serde(
+        default,
+        rename = "breadcrumbPicker.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub breadcrumb_picker_background: Option<String>,
-    #[serde(rename = "listFilterWidget.background")]
+
+    #[serde(
+        default,
+        rename = "listFilterWidget.background",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_filter_widget_background: Option<String>,
-    #[serde(rename = "listFilterWidget.outline")]
+
+    #[serde(
+        default,
+        rename = "listFilterWidget.outline",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_filter_widget_outline: Option<String>,
-    #[serde(rename = "listFilterWidget.noMatchesOutline")]
+
+    #[serde(
+        default,
+        rename = "listFilterWidget.noMatchesOutline",
+        deserialize_with = "empty_string_as_none"
+    )]
     pub list_filter_widget_no_matches_outline: Option<String>,
 }

crates/theme_selector2/src/theme_selector.rs 🔗

@@ -2,18 +2,18 @@ use feature_flags::FeatureFlagAppExt;
 use fs::Fs;
 use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
 use gpui::{
-    actions, AppContext, DismissEvent, Div, EventEmitter, FocusableView, Render, SharedString,
-    View, ViewContext, VisualContext, WeakView,
+    actions, AppContext, DismissEvent, Div, EventEmitter, FocusableView, Render, View, ViewContext,
+    VisualContext, WeakView,
 };
 use picker::{Picker, PickerDelegate};
 use settings::{update_settings_file, SettingsStore};
 use std::sync::Arc;
-use theme::{Theme, ThemeRegistry, ThemeSettings};
+use theme::{Theme, ThemeMeta, ThemeRegistry, ThemeSettings};
 use ui::{prelude::*, v_stack, ListItem};
 use util::ResultExt;
-use workspace::{ui::HighlightedLabel, Workspace};
+use workspace::{ui::HighlightedLabel, ModalView, Workspace};
 
-actions!(Toggle, Reload);
+actions!(theme_selector, [Toggle, Reload]);
 
 pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(
@@ -52,6 +52,8 @@ pub fn reload(cx: &mut AppContext) {
     }
 }
 
+impl ModalView for ThemeSelector {}
+
 pub struct ThemeSelector {
     picker: View<Picker<ThemeSelectorDelegate>>,
 }
@@ -81,7 +83,7 @@ impl ThemeSelector {
 
 pub struct ThemeSelectorDelegate {
     fs: Arc<dyn Fs>,
-    theme_names: Vec<SharedString>,
+    themes: Vec<ThemeMeta>,
     matches: Vec<StringMatch>,
     original_theme: Arc<Theme>,
     selection_completed: bool,
@@ -99,21 +101,25 @@ impl ThemeSelectorDelegate {
 
         let staff_mode = cx.is_staff();
         let registry = cx.global::<ThemeRegistry>();
-        let theme_names = registry.list(staff_mode).collect::<Vec<_>>();
-        //todo!(theme sorting)
-        // theme_names.sort_unstable_by(|a, b| a.is_light.cmp(&b.is_light).then(a.name.cmp(&b.name)));
-        let matches = theme_names
+        let mut themes = registry.list(staff_mode).collect::<Vec<_>>();
+        themes.sort_unstable_by(|a, b| {
+            a.appearance
+                .is_light()
+                .cmp(&b.appearance.is_light())
+                .then(a.name.cmp(&b.name))
+        });
+        let matches = themes
             .iter()
             .map(|meta| StringMatch {
                 candidate_id: 0,
                 score: 0.0,
                 positions: Default::default(),
-                string: meta.to_string(),
+                string: meta.name.to_string(),
             })
             .collect();
         let mut this = Self {
             fs,
-            theme_names,
+            themes,
             matches,
             original_theme: original_theme.clone(),
             selected_index: 0,
@@ -213,13 +219,13 @@ impl PickerDelegate for ThemeSelectorDelegate {
     ) -> gpui::Task<()> {
         let background = cx.background_executor().clone();
         let candidates = self
-            .theme_names
+            .themes
             .iter()
             .enumerate()
             .map(|(id, meta)| StringMatchCandidate {
                 id,
-                char_bag: meta.as_ref().into(),
-                string: meta.to_string(),
+                char_bag: meta.name.as_ref().into(),
+                string: meta.name.to_string(),
             })
             .collect::<Vec<_>>();
 

crates/ui2/src/components.rs 🔗

@@ -13,6 +13,7 @@ mod popover;
 mod popover_menu;
 mod right_click_menu;
 mod stack;
+mod tab;
 mod tooltip;
 
 #[cfg(feature = "stories")]
@@ -33,6 +34,7 @@ pub use popover::*;
 pub use popover_menu::*;
 pub use right_click_menu::*;
 pub use stack::*;
+pub use tab::*;
 pub use tooltip::*;
 
 #[cfg(feature = "stories")]

crates/ui2/src/components/avatar.rs 🔗

@@ -1,7 +1,6 @@
-use std::sync::Arc;
-
 use crate::prelude::*;
-use gpui::{img, rems, Div, ImageData, ImageSource, IntoElement, Styled};
+use gpui::{img, Div, Hsla, ImageData, ImageSource, Img, IntoElement, Styled};
+use std::sync::Arc;
 
 #[derive(Debug, Default, PartialEq, Clone)]
 pub enum Shape {
@@ -12,35 +11,39 @@ pub enum Shape {
 
 #[derive(IntoElement)]
 pub struct Avatar {
-    src: ImageSource,
+    image: Img,
+    border_color: Option<Hsla>,
     is_available: Option<bool>,
-    shape: Shape,
 }
 
 impl RenderOnce for Avatar {
     type Rendered = Div;
 
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
-        let mut img = img(self.src);
-
-        if self.shape == Shape::Circle {
-            img = img.rounded_full();
-        } else {
-            img = img.rounded_md();
+    fn render(mut self, cx: &mut WindowContext) -> Self::Rendered {
+        if self.image.style().corner_radii.top_left.is_none() {
+            self = self.shape(Shape::Circle);
         }
 
-        let size = rems(1.0);
+        let size = cx.rem_size();
 
         div()
-            .size(size)
+            .size(size + px(2.))
+            .map(|mut div| {
+                div.style().corner_radii = self.image.style().corner_radii.clone();
+                div
+            })
+            .when_some(self.border_color, |this, color| {
+                this.border().border_color(color)
+            })
             .child(
-                img.size(size)
+                self.image
+                    .size(size)
                     // todo!(Pull the avatar fallback background from the theme.)
                     .bg(gpui::red()),
             )
             .children(self.is_available.map(|is_free| {
                 // HACK: non-integer sizes result in oval indicators.
-                let indicator_size = (size.0 * cx.rem_size() * 0.4).round();
+                let indicator_size = (size * 0.4).round();
 
                 div()
                     .absolute()
@@ -56,31 +59,39 @@ impl RenderOnce for Avatar {
 
 impl Avatar {
     pub fn uri(src: impl Into<SharedString>) -> Self {
-        Self {
-            src: src.into().into(),
-            shape: Shape::Circle,
-            is_available: None,
-        }
+        Self::source(src.into().into())
     }
+
     pub fn data(src: Arc<ImageData>) -> Self {
-        Self {
-            src: src.into(),
-            shape: Shape::Circle,
-            is_available: None,
-        }
+        Self::source(src.into())
     }
 
     pub fn source(src: ImageSource) -> Self {
         Self {
-            src,
-            shape: Shape::Circle,
+            image: img(src),
             is_available: None,
+            border_color: None,
         }
     }
+
     pub fn shape(mut self, shape: Shape) -> Self {
-        self.shape = shape;
+        self.image = match shape {
+            Shape::Circle => self.image.rounded_full(),
+            Shape::RoundedRectangle => self.image.rounded_md(),
+        };
+        self
+    }
+
+    pub fn grayscale(mut self, grayscale: bool) -> Self {
+        self.image = self.image.grayscale(grayscale);
         self
     }
+
+    pub fn border_color(mut self, color: impl Into<Hsla>) -> Self {
+        self.border_color = Some(color.into());
+        self
+    }
+
     pub fn availability_indicator(mut self, is_available: impl Into<Option<bool>>) -> Self {
         self.is_available = is_available.into();
         self

crates/ui2/src/components/button/button.rs 🔗

@@ -1,6 +1,6 @@
 use gpui::{AnyView, DefiniteLength};
 
-use crate::prelude::*;
+use crate::{prelude::*, IconPosition};
 use crate::{
     ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, Icon, IconSize, Label, LineHeightStyle,
 };
@@ -14,6 +14,7 @@ pub struct Button {
     label_color: Option<Color>,
     selected_label: Option<SharedString>,
     icon: Option<Icon>,
+    icon_position: Option<IconPosition>,
     icon_size: Option<IconSize>,
     icon_color: Option<Color>,
     selected_icon: Option<Icon>,
@@ -27,6 +28,7 @@ impl Button {
             label_color: None,
             selected_label: None,
             icon: None,
+            icon_position: None,
             icon_size: None,
             icon_color: None,
             selected_icon: None,
@@ -48,6 +50,11 @@ impl Button {
         self
     }
 
+    pub fn icon_position(mut self, icon_position: impl Into<Option<IconPosition>>) -> Self {
+        self.icon_position = icon_position.into();
+        self
+    }
+
     pub fn icon_size(mut self, icon_size: impl Into<Option<IconSize>>) -> Self {
         self.icon_size = icon_size.into();
         self
@@ -141,19 +148,29 @@ impl RenderOnce for Button {
             self.label_color.unwrap_or_default()
         };
 
-        self.base
-            .children(self.icon.map(|icon| {
-                ButtonIcon::new(icon)
-                    .disabled(is_disabled)
-                    .selected(is_selected)
-                    .selected_icon(self.selected_icon)
-                    .size(self.icon_size)
-                    .color(self.icon_color)
-            }))
-            .child(
-                Label::new(label)
-                    .color(label_color)
-                    .line_height_style(LineHeightStyle::UILabel),
-            )
+        self.base.child(
+            h_stack()
+                .gap_1()
+                .map(|this| {
+                    if self.icon_position == Some(IconPosition::End) {
+                        this.flex_row_reverse()
+                    } else {
+                        this
+                    }
+                })
+                .child(
+                    Label::new(label)
+                        .color(label_color)
+                        .line_height_style(LineHeightStyle::UILabel),
+                )
+                .children(self.icon.map(|icon| {
+                    ButtonIcon::new(icon)
+                        .disabled(is_disabled)
+                        .selected(is_selected)
+                        .selected_icon(self.selected_icon)
+                        .size(self.icon_size)
+                        .color(self.icon_color)
+                })),
+        )
     }
 }

crates/ui2/src/components/button/button_like.rs 🔗

@@ -30,6 +30,13 @@ pub trait ButtonCommon: Clickable + Disableable {
     fn tooltip(self, tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self;
 }
 
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
+pub enum IconPosition {
+    #[default]
+    Start,
+    End,
+}
+
 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
 pub enum ButtonStyle {
     /// A filled button with a solid background color. Provides emphasis versus
@@ -342,8 +349,12 @@ impl RenderOnce for ButtonLike {
             .when_some(self.width, |this, width| this.w(width))
             .rounded_md()
             .gap_1()
-            .px_1()
+            .map(|this| match self.size {
+                ButtonSize::Default | ButtonSize::Compact => this.px_1(),
+                ButtonSize::None => this,
+            })
             .bg(self.style.enabled(cx).background)
+            .when(self.disabled, |this| this.cursor_not_allowed())
             .when(!self.disabled, |this| {
                 this.cursor_pointer()
                     .hover(|hover| hover.bg(self.style.hovered(cx).background))

crates/ui2/src/components/context_menu.rs 🔗

@@ -239,7 +239,6 @@ impl Render for ContextMenu {
                                 action,
                             } => {
                                 let handler = handler.clone();
-                                let dismiss = cx.listener(|_, _, cx| cx.emit(DismissEvent));
 
                                 let label_element = if let Some(icon) = icon {
                                     h_stack()
@@ -263,10 +262,7 @@ impl Render for ContextMenu {
                                             })),
                                     )
                                     .selected(Some(ix) == self.selected_index)
-                                    .on_click(move |event, cx| {
-                                        handler(cx);
-                                        dismiss(event, cx)
-                                    })
+                                    .on_click(move |_, cx| handler(cx))
                                     .into_any_element()
                             }
                         },

crates/ui2/src/components/icon.rs 🔗

@@ -51,6 +51,7 @@ pub enum Icon {
     CopilotDisabled,
     Dash,
     Envelope,
+    ExternalLink,
     ExclamationTriangle,
     Exit,
     File,
@@ -124,13 +125,13 @@ impl Icon {
             Icon::Close => "icons/x.svg",
             Icon::Collab => "icons/user_group_16.svg",
             Icon::Copilot => "icons/copilot.svg",
-
             Icon::CopilotInit => "icons/copilot_init.svg",
             Icon::CopilotError => "icons/copilot_error.svg",
             Icon::CopilotDisabled => "icons/copilot_disabled.svg",
             Icon::Dash => "icons/dash.svg",
             Icon::Envelope => "icons/feedback.svg",
             Icon::ExclamationTriangle => "icons/warning.svg",
+            Icon::ExternalLink => "icons/external_link.svg",
             Icon::Exit => "icons/exit.svg",
             Icon::File => "icons/file.svg",
             Icon::FileDoc => "icons/file_icons/book.svg",

crates/ui2/src/components/keybinding.rs 🔗

@@ -98,11 +98,13 @@ impl RenderOnce for Key {
 
         div()
             .py_0()
-            .when_else(
-                single_char,
-                |el| el.w(rems(14. / 16.)).flex().flex_none().justify_center(),
-                |el| el.px_0p5(),
-            )
+            .map(|this| {
+                if single_char {
+                    this.w(rems(14. / 16.)).flex().flex_none().justify_center()
+                } else {
+                    this.px_0p5()
+                }
+            })
             .h(rems(14. / 16.))
             .text_ui()
             .line_height(relative(1.))

crates/ui2/src/components/stories.rs 🔗

@@ -10,6 +10,7 @@ mod label;
 mod list;
 mod list_header;
 mod list_item;
+mod tab;
 
 pub use avatar::*;
 pub use button::*;
@@ -23,3 +24,4 @@ pub use label::*;
 pub use list::*;
 pub use list_header::*;
 pub use list_item::*;
+pub use tab::*;

crates/ui2/src/components/stories/context_menu.rs 🔗

@@ -4,7 +4,7 @@ use story::Story;
 use crate::prelude::*;
 use crate::{right_click_menu, ContextMenu, Label};
 
-actions!(PrintCurrentDate, PrintBestFood);
+actions!(context_menu, [PrintCurrentDate, PrintBestFood]);
 
 fn build_menu(cx: &mut WindowContext, header: impl Into<SharedString>) -> View<ContextMenu> {
     ContextMenu::build(cx, |menu, _| {

crates/ui2/src/components/stories/keybinding.rs 🔗

@@ -1,4 +1,5 @@
-use gpui::{actions, Div, Render};
+use gpui::NoAction;
+use gpui::{Div, Render};
 use itertools::Itertools;
 use story::Story;
 
@@ -7,8 +8,6 @@ use crate::KeyBinding;
 
 pub struct KeybindingStory;
 
-actions!(NoAction);
-
 pub fn binding(key: &str) -> gpui::KeyBinding {
     gpui::KeyBinding::new(key, NoAction {}, None)
 }

crates/ui2/src/components/stories/tab.rs 🔗

@@ -0,0 +1,114 @@
+use std::cmp::Ordering;
+
+use gpui::{Div, Render};
+use story::Story;
+
+use crate::{prelude::*, TabPosition};
+use crate::{Indicator, Tab};
+
+pub struct TabStory;
+
+impl Render for TabStory {
+    type Element = Div;
+
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
+        Story::container()
+            .child(Story::title_for::<Tab>())
+            .child(Story::label("Default"))
+            .child(h_stack().child(Tab::new("tab_1").child("Tab 1")))
+            .child(Story::label("With indicator"))
+            .child(
+                h_stack().child(
+                    Tab::new("tab_1")
+                        .start_slot(Indicator::dot().color(Color::Warning))
+                        .child("Tab 1"),
+                ),
+            )
+            .child(Story::label("With close button"))
+            .child(
+                h_stack().child(
+                    Tab::new("tab_1")
+                        .end_slot(
+                            IconButton::new("close_button", Icon::Close)
+                                .icon_color(Color::Muted)
+                                .size(ButtonSize::None)
+                                .icon_size(IconSize::XSmall),
+                        )
+                        .child("Tab 1"),
+                ),
+            )
+            .child(Story::label("List of tabs"))
+            .child(
+                h_stack()
+                    .child(Tab::new("tab_1").child("Tab 1"))
+                    .child(Tab::new("tab_2").child("Tab 2")),
+            )
+            .child(Story::label("List of tabs with first tab selected"))
+            .child(
+                h_stack()
+                    .child(
+                        Tab::new("tab_1")
+                            .selected(true)
+                            .position(TabPosition::First)
+                            .child("Tab 1"),
+                    )
+                    .child(
+                        Tab::new("tab_2")
+                            .position(TabPosition::Middle(Ordering::Greater))
+                            .child("Tab 2"),
+                    )
+                    .child(
+                        Tab::new("tab_3")
+                            .position(TabPosition::Middle(Ordering::Greater))
+                            .child("Tab 3"),
+                    )
+                    .child(Tab::new("tab_4").position(TabPosition::Last).child("Tab 4")),
+            )
+            .child(Story::label("List of tabs with last tab selected"))
+            .child(
+                h_stack()
+                    .child(
+                        Tab::new("tab_1")
+                            .position(TabPosition::First)
+                            .child("Tab 1"),
+                    )
+                    .child(
+                        Tab::new("tab_2")
+                            .position(TabPosition::Middle(Ordering::Less))
+                            .child("Tab 2"),
+                    )
+                    .child(
+                        Tab::new("tab_3")
+                            .position(TabPosition::Middle(Ordering::Less))
+                            .child("Tab 3"),
+                    )
+                    .child(
+                        Tab::new("tab_4")
+                            .position(TabPosition::Last)
+                            .selected(true)
+                            .child("Tab 4"),
+                    ),
+            )
+            .child(Story::label("List of tabs with second tab selected"))
+            .child(
+                h_stack()
+                    .child(
+                        Tab::new("tab_1")
+                            .position(TabPosition::First)
+                            .child("Tab 1"),
+                    )
+                    .child(
+                        Tab::new("tab_2")
+                            .position(TabPosition::Middle(Ordering::Equal))
+                            .selected(true)
+                            .child("Tab 2"),
+                    )
+                    .child(
+                        Tab::new("tab_3")
+                            .position(TabPosition::Middle(Ordering::Greater))
+                            .child("Tab 3"),
+                    )
+                    .child(Tab::new("tab_4").position(TabPosition::Last).child("Tab 4")),
+            )
+    }
+}

crates/ui2/src/components/tab.rs 🔗

@@ -0,0 +1,198 @@
+use std::cmp::Ordering;
+use std::rc::Rc;
+
+use gpui::{AnyElement, AnyView, ClickEvent, IntoElement, MouseButton};
+use smallvec::SmallVec;
+
+use crate::prelude::*;
+
+/// The position of a [`Tab`] within a list of tabs.
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+pub enum TabPosition {
+    /// The tab is first in the list.
+    First,
+
+    /// The tab is in the middle of the list (i.e., it is not the first or last tab).
+    ///
+    /// The [`Ordering`] is where this tab is positioned with respect to the selected tab.
+    Middle(Ordering),
+
+    /// The tab is last in the list.
+    Last,
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+pub enum TabCloseSide {
+    Start,
+    End,
+}
+
+#[derive(IntoElement)]
+pub struct Tab {
+    id: ElementId,
+    selected: bool,
+    position: TabPosition,
+    close_side: TabCloseSide,
+    on_click: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
+    tooltip: Option<Box<dyn Fn(&mut WindowContext) -> AnyView + 'static>>,
+    start_slot: Option<AnyElement>,
+    end_slot: Option<AnyElement>,
+    children: SmallVec<[AnyElement; 2]>,
+}
+
+impl Tab {
+    pub fn new(id: impl Into<ElementId>) -> Self {
+        Self {
+            id: id.into(),
+            selected: false,
+            position: TabPosition::First,
+            close_side: TabCloseSide::End,
+            on_click: None,
+            tooltip: None,
+            start_slot: None,
+            end_slot: None,
+            children: SmallVec::new(),
+        }
+    }
+
+    pub fn position(mut self, position: TabPosition) -> Self {
+        self.position = position;
+        self
+    }
+
+    pub fn close_side(mut self, close_side: TabCloseSide) -> Self {
+        self.close_side = close_side;
+        self
+    }
+
+    pub fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut WindowContext) + 'static) -> Self {
+        self.on_click = Some(Rc::new(handler));
+        self
+    }
+
+    pub fn tooltip(mut self, tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self {
+        self.tooltip = Some(Box::new(tooltip));
+        self
+    }
+
+    pub fn start_slot<E: IntoElement>(mut self, element: impl Into<Option<E>>) -> Self {
+        self.start_slot = element.into().map(IntoElement::into_any_element);
+        self
+    }
+
+    pub fn end_slot<E: IntoElement>(mut self, element: impl Into<Option<E>>) -> Self {
+        self.end_slot = element.into().map(IntoElement::into_any_element);
+        self
+    }
+}
+
+impl Selectable for Tab {
+    fn selected(mut self, selected: bool) -> Self {
+        self.selected = selected;
+        self
+    }
+}
+
+impl ParentElement for Tab {
+    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> {
+        &mut self.children
+    }
+}
+
+impl RenderOnce for Tab {
+    type Rendered = Div;
+
+    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
+        const HEIGHT_IN_REMS: f32 = 30. / 16.;
+
+        let (text_color, tab_bg, _tab_hover_bg, _tab_active_bg) = match self.selected {
+            false => (
+                cx.theme().colors().text_muted,
+                cx.theme().colors().tab_inactive_background,
+                cx.theme().colors().ghost_element_hover,
+                cx.theme().colors().ghost_element_active,
+            ),
+            true => (
+                cx.theme().colors().text,
+                cx.theme().colors().tab_active_background,
+                cx.theme().colors().element_hover,
+                cx.theme().colors().element_active,
+            ),
+        };
+
+        div()
+            .h(rems(HEIGHT_IN_REMS))
+            .bg(tab_bg)
+            .border_color(cx.theme().colors().border)
+            .map(|this| match self.position {
+                TabPosition::First => {
+                    if self.selected {
+                        this.pl_px().border_r().pb_px()
+                    } else {
+                        this.pl_px().pr_px().border_b()
+                    }
+                }
+                TabPosition::Last => {
+                    if self.selected {
+                        this.border_l().border_r().pb_px()
+                    } else {
+                        this.pr_px().pl_px().border_b()
+                    }
+                }
+                TabPosition::Middle(Ordering::Equal) => this.border_l().border_r().pb_px(),
+                TabPosition::Middle(Ordering::Less) => this.border_l().pr_px().border_b(),
+                TabPosition::Middle(Ordering::Greater) => this.border_r().pl_px().border_b(),
+            })
+            .child(
+                h_stack()
+                    .group("")
+                    .id(self.id)
+                    .relative()
+                    .h_full()
+                    .px_5()
+                    .gap_1()
+                    .text_color(text_color)
+                    // .hover(|style| style.bg(tab_hover_bg))
+                    // .active(|style| style.bg(tab_active_bg))
+                    .when_some(self.on_click, |tab, on_click| {
+                        tab.cursor_pointer().on_click(move |event, cx| {
+                            // HACK: GPUI currently fires `on_click` with any mouse button,
+                            // but we only care about the left button.
+                            if event.down.button == MouseButton::Left {
+                                (on_click)(event, cx)
+                            }
+                        })
+                    })
+                    .when_some(self.tooltip, |tab, tooltip| {
+                        tab.tooltip(move |cx| tooltip(cx))
+                    })
+                    .child(
+                        h_stack()
+                            .w_3()
+                            .h_3()
+                            .justify_center()
+                            .absolute()
+                            .map(|this| match self.close_side {
+                                TabCloseSide::Start => this.right_1(),
+                                TabCloseSide::End => this.left_1(),
+                            })
+                            .children(self.start_slot),
+                    )
+                    .child(
+                        h_stack()
+                            .invisible()
+                            .w_3()
+                            .h_3()
+                            .justify_center()
+                            .absolute()
+                            .map(|this| match self.close_side {
+                                TabCloseSide::Start => this.left_1(),
+                                TabCloseSide::End => this.right_1(),
+                            })
+                            .group_hover("", |style| style.visible())
+                            .children(self.end_slot),
+                    )
+                    .children(self.children),
+            )
+    }
+}

crates/ui2/src/prelude.rs 🔗

@@ -12,6 +12,6 @@ pub use crate::selectable::*;
 pub use crate::{h_stack, v_stack};
 pub use crate::{Button, ButtonSize, ButtonStyle, IconButton};
 pub use crate::{ButtonCommon, Color, StyledExt};
-pub use crate::{Icon, IconElement, IconSize};
+pub use crate::{Icon, IconElement, IconPosition, IconSize};
 pub use crate::{Label, LabelCommon, LabelSize, LineHeightStyle};
 pub use theme::ActiveTheme;

crates/welcome2/src/base_keymap_picker.rs 🔗

@@ -10,9 +10,9 @@ use settings::{update_settings_file, Settings};
 use std::sync::Arc;
 use ui::{prelude::*, ListItem};
 use util::ResultExt;
-use workspace::{ui::HighlightedLabel, Workspace};
+use workspace::{ui::HighlightedLabel, ModalView, Workspace};
 
-actions!(ToggleBaseKeymapSelector);
+actions!(welcome, [ToggleBaseKeymapSelector]);
 
 pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(|workspace: &mut Workspace, _cx| {
@@ -47,6 +47,7 @@ impl FocusableView for BaseKeymapSelector {
 }
 
 impl EventEmitter<DismissEvent> for BaseKeymapSelector {}
+impl ModalView for BaseKeymapSelector {}
 
 impl BaseKeymapSelector {
     pub fn new(

crates/workspace2/src/dock.rs 🔗

@@ -133,13 +133,13 @@ pub struct Dock {
     panel_entries: Vec<PanelEntry>,
     is_open: bool,
     active_panel_index: usize,
+    focus_handle: FocusHandle,
+    focus_subscription: Subscription,
 }
 
 impl FocusableView for Dock {
-    fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
-        self.panel_entries[self.active_panel_index]
-            .panel
-            .focus_handle(cx)
+    fn focus_handle(&self, _: &AppContext) -> FocusHandle {
+        self.focus_handle.clone()
     }
 }
 
@@ -190,12 +190,20 @@ pub struct PanelButtons {
 }
 
 impl Dock {
-    pub fn new(position: DockPosition) -> Self {
+    pub fn new(position: DockPosition, cx: &mut ViewContext<'_, Self>) -> Self {
+        let focus_handle = cx.focus_handle();
+        let focus_subscription = cx.on_focus(&focus_handle, |dock, cx| {
+            if let Some(active_entry) = dock.panel_entries.get(dock.active_panel_index) {
+                active_entry.panel.focus_handle(cx).focus(cx)
+            }
+        });
         Self {
             position,
             panel_entries: Default::default(),
             active_panel_index: 0,
             is_open: false,
+            focus_handle,
+            focus_subscription,
         }
     }
 
@@ -207,6 +215,7 @@ impl Dock {
         self.is_open
     }
 
+    // todo!()
     //     pub fn has_focus(&self, cx: &WindowContext) -> bool {
     //         self.visible_panel()
     //             .map_or(false, |panel| panel.has_focus(cx))
@@ -761,7 +770,7 @@ pub mod test {
         pub focus_handle: FocusHandle,
         pub size: f32,
     }
-    actions!(ToggleTestPanel);
+    actions!(test, [ToggleTestPanel]);
 
     impl EventEmitter<PanelEvent> for TestPanel {}
 

crates/workspace2/src/modal_layer.rs 🔗

@@ -1,11 +1,32 @@
 use gpui::{
-    div, prelude::*, px, AnyView, Div, FocusHandle, ManagedView, Render, Subscription, View,
-    ViewContext,
+    div, prelude::*, px, AnyView, Div, FocusHandle, ManagedView, Render, Subscription, Task, View,
+    ViewContext, WindowContext,
 };
 use ui::{h_stack, v_stack};
 
+pub trait ModalView: ManagedView {
+    fn dismiss(&mut self, cx: &mut ViewContext<Self>) -> Task<bool> {
+        Task::ready(true)
+    }
+}
+
+trait ModalViewHandle {
+    fn should_dismiss(&mut self, cx: &mut WindowContext) -> Task<bool>;
+    fn view(&self) -> AnyView;
+}
+
+impl<V: ModalView> ModalViewHandle for View<V> {
+    fn should_dismiss(&mut self, cx: &mut WindowContext) -> Task<bool> {
+        self.update(cx, |this, cx| this.dismiss(cx))
+    }
+
+    fn view(&self) -> AnyView {
+        self.clone().into()
+    }
+}
+
 pub struct ActiveModal {
-    modal: AnyView,
+    modal: Box<dyn ModalViewHandle>,
     subscription: Subscription,
     previous_focus_handle: Option<FocusHandle>,
     focus_handle: FocusHandle,
@@ -22,11 +43,11 @@ impl ModalLayer {
 
     pub fn toggle_modal<V, B>(&mut self, cx: &mut ViewContext<Self>, build_view: B)
     where
-        V: ManagedView,
+        V: ModalView,
         B: FnOnce(&mut ViewContext<V>) -> V,
     {
         if let Some(active_modal) = &self.active_modal {
-            let is_close = active_modal.modal.clone().downcast::<V>().is_ok();
+            let is_close = active_modal.modal.view().downcast::<V>().is_ok();
             self.hide_modal(cx);
             if is_close {
                 return;
@@ -38,10 +59,10 @@ impl ModalLayer {
 
     pub fn show_modal<V>(&mut self, new_modal: View<V>, cx: &mut ViewContext<Self>)
     where
-        V: ManagedView,
+        V: ModalView,
     {
         self.active_modal = Some(ActiveModal {
-            modal: new_modal.clone().into(),
+            modal: Box::new(new_modal.clone()),
             subscription: cx.subscribe(&new_modal, |this, modal, e, cx| this.hide_modal(cx)),
             previous_focus_handle: cx.focused(),
             focus_handle: cx.focus_handle(),
@@ -51,15 +72,28 @@ impl ModalLayer {
     }
 
     pub fn hide_modal(&mut self, cx: &mut ViewContext<Self>) {
-        if let Some(active_modal) = self.active_modal.take() {
-            if let Some(previous_focus) = active_modal.previous_focus_handle {
-                if active_modal.focus_handle.contains_focused(cx) {
-                    previous_focus.focus(cx);
-                }
-            }
-        }
+        let Some(active_modal) = self.active_modal.as_mut() else {
+            return;
+        };
 
-        cx.notify();
+        let dismiss = active_modal.modal.should_dismiss(cx);
+
+        cx.spawn(|this, mut cx| async move {
+            if dismiss.await {
+                this.update(&mut cx, |this, cx| {
+                    if let Some(active_modal) = this.active_modal.take() {
+                        if let Some(previous_focus) = active_modal.previous_focus_handle {
+                            if active_modal.focus_handle.contains_focused(cx) {
+                                previous_focus.focus(cx);
+                            }
+                        }
+                        cx.notify();
+                    }
+                })
+                .ok();
+            }
+        })
+        .detach();
     }
 
     pub fn active_modal<V>(&self) -> Option<View<V>>
@@ -67,7 +101,7 @@ impl ModalLayer {
         V: 'static,
     {
         let active_modal = self.active_modal.as_ref()?;
-        active_modal.modal.clone().downcast::<V>().ok()
+        active_modal.modal.view().downcast::<V>().ok()
     }
 }
 
@@ -98,7 +132,7 @@ impl Render for ModalLayer {
                             .on_mouse_down_out(cx.listener(|this, _, cx| {
                                 this.hide_modal(cx);
                             }))
-                            .child(active_modal.modal.clone()),
+                            .child(active_modal.modal.view()),
                     ),
             )
     }

crates/workspace2/src/pane.rs 🔗

@@ -7,10 +7,10 @@ use crate::{
 use anyhow::Result;
 use collections::{HashMap, HashSet, VecDeque};
 use gpui::{
-    actions, overlay, prelude::*, rems, Action, AnchorCorner, AnyWeakView, AppContext,
-    AsyncWindowContext, DismissEvent, Div, EntityId, EventEmitter, FocusHandle, Focusable,
-    FocusableView, Model, Pixels, Point, PromptLevel, Render, Task, View, ViewContext,
-    VisualContext, WeakView, WindowContext,
+    actions, impl_actions, overlay, prelude::*, rems, Action, AnchorCorner, AnyWeakView,
+    AppContext, AsyncWindowContext, DismissEvent, Div, EntityId, EventEmitter, FocusHandle,
+    Focusable, FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel,
+    Render, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
 };
 use parking_lot::Mutex;
 use project::{Project, ProjectEntryId, ProjectPath};
@@ -28,10 +28,10 @@ use std::{
 
 use ui::{
     h_stack, prelude::*, right_click_menu, ButtonSize, Color, Icon, IconButton, IconSize,
-    Indicator, Label, Tooltip,
+    Indicator, Label, Tab, TabPosition, Tooltip,
 };
 use ui::{v_stack, ContextMenu};
-use util::truncate_and_remove_front;
+use util::{maybe, truncate_and_remove_front};
 
 #[derive(PartialEq, Clone, Copy, Deserialize, Debug)]
 #[serde(rename_all = "camelCase")]
@@ -52,9 +52,7 @@ pub enum SaveIntent {
     Skip,
 }
 
-//todo!("Do we need the default bound on actions? Decide soon")
-// #[register_action]
-#[derive(Action, Clone, Deserialize, PartialEq, Debug)]
+#[derive(Clone, Deserialize, PartialEq, Debug)]
 pub struct ActivateItem(pub usize);
 
 // #[derive(Clone, PartialEq)]
@@ -75,34 +73,38 @@ pub struct ActivateItem(pub usize);
 //     pub pane: WeakView<Pane>,
 // }
 
-#[derive(Clone, PartialEq, Debug, Deserialize, Default, Action)]
+#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
 #[serde(rename_all = "camelCase")]
 pub struct CloseActiveItem {
     pub save_intent: Option<SaveIntent>,
 }
 
-#[derive(Clone, PartialEq, Debug, Deserialize, Default, Action)]
+#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
 #[serde(rename_all = "camelCase")]
 pub struct CloseAllItems {
     pub save_intent: Option<SaveIntent>,
 }
 
-// todo!(These used to be under pane::{Action}. Are they now workspace::pane::{Action}?)
+impl_actions!(pane, [CloseAllItems, CloseActiveItem, ActivateItem]);
+
 actions!(
-    ActivatePrevItem,
-    ActivateNextItem,
-    ActivateLastItem,
-    CloseInactiveItems,
-    CloseCleanItems,
-    CloseItemsToTheLeft,
-    CloseItemsToTheRight,
-    GoBack,
-    GoForward,
-    ReopenClosedItem,
-    SplitLeft,
-    SplitUp,
-    SplitRight,
-    SplitDown,
+    pane,
+    [
+        ActivatePrevItem,
+        ActivateNextItem,
+        ActivateLastItem,
+        CloseInactiveItems,
+        CloseCleanItems,
+        CloseItemsToTheLeft,
+        CloseItemsToTheRight,
+        GoBack,
+        GoForward,
+        ReopenClosedItem,
+        SplitLeft,
+        SplitUp,
+        SplitRight,
+        SplitDown,
+    ]
 );
 
 const MAX_NAVIGATION_HISTORY_LEN: usize = 1024;
@@ -157,6 +159,7 @@ pub struct Pane {
     items: Vec<Box<dyn ItemHandle>>,
     activation_history: Vec<EntityId>,
     zoomed: bool,
+    was_focused: bool,
     active_item_index: usize,
     last_focused_view_by_item: HashMap<EntityId, FocusHandle>,
     autoscroll: bool,
@@ -315,6 +318,7 @@ impl Pane {
             focus_handle: cx.focus_handle(),
             items: Vec::new(),
             activation_history: Vec::new(),
+            was_focused: false,
             zoomed: false,
             active_item_index: 0,
             last_focused_view_by_item: Default::default(),
@@ -411,7 +415,8 @@ impl Pane {
     }
 
     fn focus_in(&mut self, cx: &mut ViewContext<Self>) {
-        if !self.has_focus(cx) {
+        if !self.was_focused {
+            self.was_focused = true;
             cx.emit(Event::Focus);
             cx.notify();
         }
@@ -442,6 +447,7 @@ impl Pane {
     }
 
     fn focus_out(&mut self, cx: &mut ViewContext<Self>) {
+        self.was_focused = false;
         self.toolbar.update(cx, |toolbar, cx| {
             toolbar.focus_changed(false, cx);
         });
@@ -1438,43 +1444,49 @@ impl Pane {
 
         let is_active = ix == self.active_item_index;
 
-        let indicator = {
+        let indicator = maybe!({
             let indicator_color = match (item.has_conflict(cx), item.is_dirty(cx)) {
-                (true, _) => Some(Color::Warning),
-                (_, true) => Some(Color::Accent),
-                (false, false) => None,
+                (true, _) => Color::Warning,
+                (_, true) => Color::Accent,
+                (false, false) => return None,
             };
 
-            h_stack()
-                .w_3()
-                .h_3()
-                .justify_center()
-                .absolute()
-                .map(|this| match close_side {
-                    ClosePosition::Left => this.right_1(),
-                    ClosePosition::Right => this.left_1(),
+            Some(Indicator::dot().color(indicator_color))
+        });
+
+        let id = item.item_id();
+
+        let is_first_item = ix == 0;
+        let is_last_item = ix == self.items.len() - 1;
+        let position_relative_to_active_item = ix.cmp(&self.active_item_index);
+
+        let tab =
+            Tab::new(ix)
+                .position(if is_first_item {
+                    TabPosition::First
+                } else if is_last_item {
+                    TabPosition::Last
+                } else {
+                    TabPosition::Middle(position_relative_to_active_item)
                 })
-                .when_some(indicator_color, |this, indicator_color| {
-                    this.child(Indicator::dot().color(indicator_color))
+                .close_side(match close_side {
+                    ClosePosition::Left => ui::TabCloseSide::Start,
+                    ClosePosition::Right => ui::TabCloseSide::End,
                 })
-        };
-
-        let close_button = {
-            let id = item.item_id();
-
-            h_stack()
-                .invisible()
-                .w_3()
-                .h_3()
-                .justify_center()
-                .absolute()
-                .map(|this| match close_side {
-                    ClosePosition::Left => this.left_1(),
-                    ClosePosition::Right => this.right_1(),
+                .selected(ix == self.active_item_index())
+                .on_click(cx.listener(move |pane: &mut Self, event, cx| {
+                    pane.activate_item(ix, true, true, cx)
+                }))
+                // .on_drag(move |pane, cx| pane.render_tab(ix, item.boxed_clone(), detail, cx))
+                // .drag_over::<DraggedTab>(|d| d.bg(cx.theme().colors().element_drop_target))
+                // .on_drop(|_view, state: View<DraggedTab>, cx| {
+                //     eprintln!("{:?}", state.read(cx));
+                // })
+                .when_some(item.tab_tooltip_text(cx), |tab, text| {
+                    tab.tooltip(move |cx| Tooltip::text(text.clone(), cx))
                 })
-                .group_hover("", |style| style.visible())
-                .child(
-                    // TODO: Fix button size
+                .start_slot::<Indicator>(indicator)
+                .end_slot(
                     IconButton::new("close tab", Icon::Close)
                         .icon_color(Color::Muted)
                         .size(ButtonSize::None)
@@ -1484,67 +1496,7 @@ impl Pane {
                                 .detach_and_log_err(cx);
                         })),
                 )
-        };
-
-        let tab = div()
-            .border_color(cx.theme().colors().border)
-            .bg(tab_bg)
-            // 30px @ 16px/rem
-            .h(rems(1.875))
-            .map(|this| {
-                let is_first_item = ix == 0;
-                let is_last_item = ix == self.items.len() - 1;
-                match ix.cmp(&self.active_item_index) {
-                    cmp::Ordering::Less => {
-                        if is_first_item {
-                            this.pl_px().pr_px().border_b()
-                        } else {
-                            this.border_l().pr_px().border_b()
-                        }
-                    }
-                    cmp::Ordering::Greater => {
-                        if is_last_item {
-                            this.pr_px().pl_px().border_b()
-                        } else {
-                            this.border_r().pl_px().border_b()
-                        }
-                    }
-                    cmp::Ordering::Equal => {
-                        if is_first_item {
-                            this.pl_px().border_r().pb_px()
-                        } else {
-                            this.border_l().border_r().pb_px()
-                        }
-                    }
-                }
-            })
-            .child(
-                h_stack()
-                    .group("")
-                    .id(ix)
-                    .relative()
-                    .h_full()
-                    .cursor_pointer()
-                    .when_some(item.tab_tooltip_text(cx), |div, text| {
-                        div.tooltip(move |cx| cx.build_view(|cx| Tooltip::new(text.clone())).into())
-                    })
-                    .on_click(
-                        cx.listener(move |v: &mut Self, e, cx| v.activate_item(ix, true, true, cx)),
-                    )
-                    // .on_drag(move |pane, cx| pane.render_tab(ix, item.boxed_clone(), detail, cx))
-                    // .drag_over::<DraggedTab>(|d| d.bg(cx.theme().colors().element_drop_target))
-                    // .on_drop(|_view, state: View<DraggedTab>, cx| {
-                    //     eprintln!("{:?}", state.read(cx));
-                    // })
-                    .px_5()
-                    // .hover(|h| h.bg(tab_hover_bg))
-                    // .active(|a| a.bg(tab_active_bg))
-                    .gap_1()
-                    .text_color(text_color)
-                    .child(indicator)
-                    .child(close_button)
-                    .child(label),
-            );
+                .child(label);
 
         right_click_menu(ix).trigger(tab).menu(|cx| {
             ContextMenu::build(cx, |menu, cx| {
@@ -2193,183 +2145,174 @@ impl Render for Pane {
                     .justify_center()
                     .child(Label::new("Open a file or project to get started.").color(Color::Muted))
             })
-
-        // enum MouseNavigationHandler {}
-
-        // MouseEventHandler::new::<MouseNavigationHandler, _>(0, cx, |_, cx| {
-        //     let active_item_index = self.active_item_index;
-
-        //     if let Some(active_item) = self.active_item() {
-        //         Flex::column()
-        //             .with_child({
-        //                 let theme = theme::current(cx).clone();
-
-        //                 let mut stack = Stack::new();
-
-        //                 enum TabBarEventHandler {}
-        //                 stack.add_child(
-        //                     MouseEventHandler::new::<TabBarEventHandler, _>(0, cx, |_, _| {
-        //                         Empty::new()
-        //                             .contained()
-        //                             .with_style(theme.workspace.tab_bar.container)
-        //                     })
-        //                     .on_down(
-        //                         MouseButton::Left,
-        //                         move |_, this, cx| {
-        //                             this.activate_item(active_item_index, true, true, cx);
-        //                         },
-        //                     ),
-        //                 );
-        //                 let tooltip_style = theme.tooltip.clone();
-        //                 let tab_bar_theme = theme.workspace.tab_bar.clone();
-
-        //                 let nav_button_height = tab_bar_theme.height;
-        //                 let button_style = tab_bar_theme.nav_button;
-        //                 let border_for_nav_buttons = tab_bar_theme
-        //                     .tab_style(false, false)
-        //                     .container
-        //                     .border
-        //                     .clone();
-
-        //                 let mut tab_row = Flex::row()
-        //                     .with_child(nav_button(
-        //                         "icons/arrow_left.svg",
-        //                         button_style.clone(),
-        //                         nav_button_height,
-        //                         tooltip_style.clone(),
-        //                         self.can_navigate_backward(),
-        //                         {
-        //                             move |pane, cx| {
-        //                                 if let Some(workspace) = pane.workspace.upgrade(cx) {
-        //                                     let pane = cx.weak_handle();
-        //                                     cx.window_context().defer(move |cx| {
-        //                                         workspace.update(cx, |workspace, cx| {
-        //                                             workspace
-        //                                                 .go_back(pane, cx)
-        //                                                 .detach_and_log_err(cx)
-        //                                         })
-        //                                     })
-        //                                 }
-        //                             }
-        //                         },
-        //                         super::GoBack,
-        //                         "Go Back",
-        //                         cx,
-        //                     ))
-        //                     .with_child(
-        //                         nav_button(
-        //                             "icons/arrow_right.svg",
-        //                             button_style.clone(),
-        //                             nav_button_height,
-        //                             tooltip_style,
-        //                             self.can_navigate_forward(),
-        //                             {
-        //                                 move |pane, cx| {
-        //                                     if let Some(workspace) = pane.workspace.upgrade(cx) {
-        //                                         let pane = cx.weak_handle();
-        //                                         cx.window_context().defer(move |cx| {
-        //                                             workspace.update(cx, |workspace, cx| {
-        //                                                 workspace
-        //                                                     .go_forward(pane, cx)
-        //                                                     .detach_and_log_err(cx)
-        //                                             })
-        //                                         })
-        //                                     }
-        //                                 }
-        //                             },
-        //                             super::GoForward,
-        //                             "Go Forward",
-        //                             cx,
-        //                         )
-        //                         .contained()
-        //                         .with_border(border_for_nav_buttons),
-        //                     )
-        //                     .with_child(self.render_tabs(cx).flex(1., true).into_any_named("tabs"));
-
-        //                 if self.has_focus {
-        //                     let render_tab_bar_buttons = self.render_tab_bar_buttons.clone();
-        //                     tab_row.add_child(
-        //                         (render_tab_bar_buttons)(self, cx)
-        //                             .contained()
-        //                             .with_style(theme.workspace.tab_bar.pane_button_container)
-        //                             .flex(1., false)
-        //                             .into_any(),
-        //                     )
-        //                 }
-
-        //                 stack.add_child(tab_row);
-        //                 stack
-        //                     .constrained()
-        //                     .with_height(theme.workspace.tab_bar.height)
-        //                     .flex(1., false)
-        //                     .into_any_named("tab bar")
-        //             })
-        //             .with_child({
-        //                 enum PaneContentTabDropTarget {}
-        //                 dragged_item_receiver::<PaneContentTabDropTarget, _, _>(
-        //                     self,
-        //                     0,
-        //                     self.active_item_index + 1,
-        //                     !self.can_split,
-        //                     if self.can_split { Some(100.) } else { None },
-        //                     cx,
-        //                     {
-        //                         let toolbar = self.toolbar.clone();
-        //                         let toolbar_hidden = toolbar.read(cx).hidden();
-        //                         move |_, cx| {
-        //                             Flex::column()
-        //                                 .with_children(
-        //                                     (!toolbar_hidden)
-        //                                         .then(|| ChildView::new(&toolbar, cx).expanded()),
-        //                                 )
-        //                                 .with_child(
-        //                                     ChildView::new(active_item.as_any(), cx).flex(1., true),
-        //                                 )
-        //                         }
-        //                     },
-        //                 )
-        //                 .flex(1., true)
-        //             })
-        //             .with_child(ChildView::new(&self.tab_context_menu, cx))
-        //             .into_any()
-        //     } else {
-        //         enum EmptyPane {}
-        //         let theme = theme::current(cx).clone();
-
-        //         dragged_item_receiver::<EmptyPane, _, _>(self, 0, 0, false, None, cx, |_, cx| {
-        //             self.render_blank_pane(&theme, cx)
-        //         })
-        //         .on_down(MouseButton::Left, |_, _, cx| {
-        //             cx.focus_parent();
-        //         })
-        //         .into_any()
-        //     }
-        // })
-        // .on_down(
-        //     MouseButton::Navigate(NavigationDirection::Back),
-        //     move |_, pane, cx| {
-        //         if let Some(workspace) = pane.workspace.upgrade(cx) {
-        //             let pane = cx.weak_handle();
-        //             cx.window_context().defer(move |cx| {
-        //                 workspace.update(cx, |workspace, cx| {
-        //                     workspace.go_back(pane, cx).detach_and_log_err(cx)
-        //                 })
-        //             })
-        //         }
-        //     },
-        // )
-        // .on_down(MouseButton::Navigate(NavigationDirection::Forward), {
-        //     move |_, pane, cx| {
-        //         if let Some(workspace) = pane.workspace.upgrade(cx) {
-        //             let pane = cx.weak_handle();
-        //             cx.window_context().defer(move |cx| {
-        //                 workspace.update(cx, |workspace, cx| {
-        //                     workspace.go_forward(pane, cx).detach_and_log_err(cx)
-        //                 })
-        //             })
-        //         }
-        //     }
-        // })
+            // enum MouseNavigationHandler {}
+            // MouseEventHandler::new::<MouseNavigationHandler, _>(0, cx, |_, cx| {
+            //     let active_item_index = self.active_item_index;
+            //     if let Some(active_item) = self.active_item() {
+            //         Flex::column()
+            //             .with_child({
+            //                 let theme = theme::current(cx).clone();
+            //                 let mut stack = Stack::new();
+            //                 enum TabBarEventHandler {}
+            //                 stack.add_child(
+            //                     MouseEventHandler::new::<TabBarEventHandler, _>(0, cx, |_, _| {
+            //                         Empty::new()
+            //                             .contained()
+            //                             .with_style(theme.workspace.tab_bar.container)
+            //                     })
+            //                     .on_down(
+            //                         MouseButton::Left,
+            //                         move |_, this, cx| {
+            //                             this.activate_item(active_item_index, true, true, cx);
+            //                         },
+            //                     ),
+            //                 );
+            //                 let tooltip_style = theme.tooltip.clone();
+            //                 let tab_bar_theme = theme.workspace.tab_bar.clone();
+            //                 let nav_button_height = tab_bar_theme.height;
+            //                 let button_style = tab_bar_theme.nav_button;
+            //                 let border_for_nav_buttons = tab_bar_theme
+            //                     .tab_style(false, false)
+            //                     .container
+            //                     .border
+            //                     .clone();
+            //                 let mut tab_row = Flex::row()
+            //                     .with_child(nav_button(
+            //                         "icons/arrow_left.svg",
+            //                         button_style.clone(),
+            //                         nav_button_height,
+            //                         tooltip_style.clone(),
+            //                         self.can_navigate_backward(),
+            //                         {
+            //                             move |pane, cx| {
+            //                                 if let Some(workspace) = pane.workspace.upgrade(cx) {
+            //                                     let pane = cx.weak_handle();
+            //                                     cx.window_context().defer(move |cx| {
+            //                                         workspace.update(cx, |workspace, cx| {
+            //                                             workspace
+            //                                                 .go_back(pane, cx)
+            //                                                 .detach_and_log_err(cx)
+            //                                         })
+            //                                     })
+            //                                 }
+            //                             }
+            //                         },
+            //                         super::GoBack,
+            //                         "Go Back",
+            //                         cx,
+            //                     ))
+            //                     .with_child(
+            //                         nav_button(
+            //                             "icons/arrow_right.svg",
+            //                             button_style.clone(),
+            //                             nav_button_height,
+            //                             tooltip_style,
+            //                             self.can_navigate_forward(),
+            //                             {
+            //                                 move |pane, cx| {
+            //                                     if let Some(workspace) = pane.workspace.upgrade(cx) {
+            //                                         let pane = cx.weak_handle();
+            //                                         cx.window_context().defer(move |cx| {
+            //                                             workspace.update(cx, |workspace, cx| {
+            //                                                 workspace
+            //                                                     .go_forward(pane, cx)
+            //                                                     .detach_and_log_err(cx)
+            //                                             })
+            //                                         })
+            //                                     }
+            //                                 }
+            //                             },
+            //                             super::GoForward,
+            //                             "Go Forward",
+            //                             cx,
+            //                         )
+            //                         .contained()
+            //                         .with_border(border_for_nav_buttons),
+            //                     )
+            //                     .with_child(self.render_tabs(cx).flex(1., true).into_any_named("tabs"));
+            //                 if self.has_focus {
+            //                     let render_tab_bar_buttons = self.render_tab_bar_buttons.clone();
+            //                     tab_row.add_child(
+            //                         (render_tab_bar_buttons)(self, cx)
+            //                             .contained()
+            //                             .with_style(theme.workspace.tab_bar.pane_button_container)
+            //                             .flex(1., false)
+            //                             .into_any(),
+            //                     )
+            //                 }
+            //                 stack.add_child(tab_row);
+            //                 stack
+            //                     .constrained()
+            //                     .with_height(theme.workspace.tab_bar.height)
+            //                     .flex(1., false)
+            //                     .into_any_named("tab bar")
+            //             })
+            //             .with_child({
+            //                 enum PaneContentTabDropTarget {}
+            //                 dragged_item_receiver::<PaneContentTabDropTarget, _, _>(
+            //                     self,
+            //                     0,
+            //                     self.active_item_index + 1,
+            //                     !self.can_split,
+            //                     if self.can_split { Some(100.) } else { None },
+            //                     cx,
+            //                     {
+            //                         let toolbar = self.toolbar.clone();
+            //                         let toolbar_hidden = toolbar.read(cx).hidden();
+            //                         move |_, cx| {
+            //                             Flex::column()
+            //                                 .with_children(
+            //                                     (!toolbar_hidden)
+            //                                         .then(|| ChildView::new(&toolbar, cx).expanded()),
+            //                                 )
+            //                                 .with_child(
+            //                                     ChildView::new(active_item.as_any(), cx).flex(1., true),
+            //                                 )
+            //                         }
+            //                     },
+            //                 )
+            //                 .flex(1., true)
+            //             })
+            //             .with_child(ChildView::new(&self.tab_context_menu, cx))
+            //             .into_any()
+            //     } else {
+            //         enum EmptyPane {}
+            //         let theme = theme::current(cx).clone();
+            //         dragged_item_receiver::<EmptyPane, _, _>(self, 0, 0, false, None, cx, |_, cx| {
+            //             self.render_blank_pane(&theme, cx)
+            //         })
+            //         .on_down(MouseButton::Left, |_, _, cx| {
+            //             cx.focus_parent();
+            //         })
+            //         .into_any()
+            //     }
+            // })
+            .on_mouse_down(
+                MouseButton::Navigate(NavigationDirection::Back),
+                cx.listener(|pane, _, cx| {
+                    if let Some(workspace) = pane.workspace.upgrade() {
+                        let pane = cx.view().downgrade();
+                        cx.window_context().defer(move |cx| {
+                            workspace.update(cx, |workspace, cx| {
+                                workspace.go_back(pane, cx).detach_and_log_err(cx)
+                            })
+                        })
+                    }
+                }),
+            )
+            .on_mouse_down(
+                MouseButton::Navigate(NavigationDirection::Forward),
+                cx.listener(|pane, _, cx| {
+                    if let Some(workspace) = pane.workspace.upgrade() {
+                        let pane = cx.view().downgrade();
+                        cx.window_context().defer(move |cx| {
+                            workspace.update(cx, |workspace, cx| {
+                                workspace.go_forward(pane, cx).detach_and_log_err(cx)
+                            })
+                        })
+                    }
+                }),
+            )
         // .into_any_named("pane")
     }
 

crates/workspace2/src/status_bar.rs 🔗

@@ -1,12 +1,10 @@
-use std::any::TypeId;
-
 use crate::{ItemHandle, Pane};
 use gpui::{
     div, AnyView, Div, IntoElement, ParentElement, Render, Styled, Subscription, View, ViewContext,
     WindowContext,
 };
-use ui::prelude::*;
-use ui::{h_stack, Icon, IconButton};
+use std::any::TypeId;
+use ui::{h_stack, prelude::*};
 use util::ResultExt;
 
 pub trait StatusItemView: Render {
@@ -47,31 +45,8 @@ impl Render for StatusBar {
             .w_full()
             .h_8()
             .bg(cx.theme().colors().status_bar_background)
-            .child(h_stack().gap_1().child(self.render_left_tools(cx)))
-            .child(
-                h_stack()
-                    .gap_4()
-                    .child(
-                        h_stack().gap_1().child(
-                            // Feedback Tool
-                            div()
-                                .border()
-                                .border_color(gpui::red())
-                                .child(IconButton::new("status-feedback", Icon::Envelope)),
-                        ),
-                    )
-                    .child(
-                        // Right Dock
-                        h_stack().gap_1().child(
-                            // Terminal
-                            div()
-                                .border()
-                                .border_color(gpui::red())
-                                .child(IconButton::new("status-chat", Icon::MessageBubbles)),
-                        ),
-                    )
-                    .child(self.render_right_tools(cx)),
-            )
+            .child(self.render_left_tools(cx))
+            .child(self.render_right_tools(cx))
     }
 }
 

crates/workspace2/src/workspace2.rs 🔗

@@ -29,12 +29,12 @@ use futures::{
     Future, FutureExt, StreamExt,
 };
 use gpui::{
-    actions, div, point, size, Action, AnyModel, AnyView, AnyWeakView, AnyWindowHandle, AppContext,
-    AsyncAppContext, AsyncWindowContext, Bounds, Context, Div, Entity, EntityId, EventEmitter,
-    FocusHandle, FocusableView, GlobalPixels, InteractiveElement, KeyContext, ManagedView, Model,
-    ModelContext, ParentElement, PathPromptOptions, Point, PromptLevel, Render, Size, Styled,
-    Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowBounds, WindowContext,
-    WindowHandle, WindowOptions,
+    actions, div, impl_actions, point, size, Action, AnyModel, AnyView, AnyWeakView,
+    AnyWindowHandle, AppContext, AsyncAppContext, AsyncWindowContext, Bounds, Context, Div, Entity,
+    EntityId, EventEmitter, FocusHandle, FocusableView, GlobalPixels, InteractiveElement,
+    KeyContext, ManagedView, Model, ModelContext, ParentElement, PathPromptOptions, Point,
+    PromptLevel, Render, Size, Styled, Subscription, Task, View, ViewContext, VisualContext,
+    WeakView, WindowBounds, WindowContext, WindowHandle, WindowOptions,
 };
 use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem};
 use itertools::Itertools;
@@ -91,30 +91,33 @@ lazy_static! {
 pub struct RemoveWorktreeFromProject(pub WorktreeId);
 
 actions!(
-    Open,
-    NewFile,
-    NewWindow,
-    CloseWindow,
-    CloseInactiveTabsAndPanes,
-    AddFolderToProject,
-    Unfollow,
-    SaveAs,
-    ReloadActiveItem,
-    ActivatePreviousPane,
-    ActivateNextPane,
-    FollowNextCollaborator,
-    NewTerminal,
-    NewCenterTerminal,
-    ToggleTerminalFocus,
-    NewSearch,
-    Feedback,
-    Restart,
-    Welcome,
-    ToggleZoom,
-    ToggleLeftDock,
-    ToggleRightDock,
-    ToggleBottomDock,
-    CloseAllDocks,
+    workspace,
+    [
+        Open,
+        NewFile,
+        NewWindow,
+        CloseWindow,
+        CloseInactiveTabsAndPanes,
+        AddFolderToProject,
+        Unfollow,
+        SaveAs,
+        ReloadActiveItem,
+        ActivatePreviousPane,
+        ActivateNextPane,
+        FollowNextCollaborator,
+        NewTerminal,
+        NewCenterTerminal,
+        ToggleTerminalFocus,
+        NewSearch,
+        Feedback,
+        Restart,
+        Welcome,
+        ToggleZoom,
+        ToggleLeftDock,
+        ToggleRightDock,
+        ToggleBottomDock,
+        CloseAllDocks,
+    ]
 );
 
 #[derive(Clone, PartialEq)]
@@ -122,36 +125,50 @@ pub struct OpenPaths {
     pub paths: Vec<PathBuf>,
 }
 
-#[derive(Clone, Deserialize, PartialEq, Action)]
+#[derive(Clone, Deserialize, PartialEq)]
 pub struct ActivatePane(pub usize);
 
-#[derive(Clone, Deserialize, PartialEq, Action)]
+#[derive(Clone, Deserialize, PartialEq)]
 pub struct ActivatePaneInDirection(pub SplitDirection);
 
-#[derive(Clone, Deserialize, PartialEq, Action)]
+#[derive(Clone, Deserialize, PartialEq)]
 pub struct SwapPaneInDirection(pub SplitDirection);
 
-#[derive(Clone, Deserialize, PartialEq, Action)]
+#[derive(Clone, Deserialize, PartialEq)]
 pub struct NewFileInDirection(pub SplitDirection);
 
-#[derive(Clone, PartialEq, Debug, Deserialize, Action)]
+#[derive(Clone, PartialEq, Debug, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct SaveAll {
     pub save_intent: Option<SaveIntent>,
 }
 
-#[derive(Clone, PartialEq, Debug, Deserialize, Action)]
+#[derive(Clone, PartialEq, Debug, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct Save {
     pub save_intent: Option<SaveIntent>,
 }
 
-#[derive(Clone, PartialEq, Debug, Deserialize, Default, Action)]
+#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
 #[serde(rename_all = "camelCase")]
 pub struct CloseAllItemsAndPanes {
     pub save_intent: Option<SaveIntent>,
 }
 
+impl_actions!(
+    workspace,
+    [
+        ActivatePane,
+        ActivatePaneInDirection,
+        CloseAllItemsAndPanes,
+        NewFileInDirection,
+        OpenTerminal,
+        Save,
+        SaveAll,
+        SwapPaneInDirection,
+    ]
+);
+
 #[derive(Deserialize)]
 pub struct Toast {
     id: usize,
@@ -197,7 +214,7 @@ impl Clone for Toast {
     }
 }
 
-#[derive(Debug, Default, Clone, Deserialize, PartialEq, Action)]
+#[derive(Debug, Default, Clone, Deserialize, PartialEq)]
 pub struct OpenTerminal {
     pub working_directory: PathBuf,
 }
@@ -566,9 +583,9 @@ impl Workspace {
 
         cx.emit(Event::WorkspaceCreated(weak_handle.clone()));
 
-        let left_dock = cx.build_view(|_| Dock::new(DockPosition::Left));
-        let bottom_dock = cx.build_view(|_| Dock::new(DockPosition::Bottom));
-        let right_dock = cx.build_view(|_| Dock::new(DockPosition::Right));
+        let left_dock = cx.build_view(|cx| Dock::new(DockPosition::Left, cx));
+        let bottom_dock = cx.build_view(|cx| Dock::new(DockPosition::Bottom, cx));
+        let right_dock = cx.build_view(|cx| Dock::new(DockPosition::Right, cx));
         let left_dock_buttons =
             cx.build_view(|cx| PanelButtons::new(left_dock.clone(), weak_handle.clone(), cx));
         let bottom_dock_buttons =
@@ -3414,7 +3431,7 @@ impl Workspace {
         self.modal_layer.read(cx).active_modal()
     }
 
-    pub fn toggle_modal<V: ManagedView, B>(&mut self, cx: &mut ViewContext<Self>, build: B)
+    pub fn toggle_modal<V: ModalView, B>(&mut self, cx: &mut ViewContext<Self>, build: B)
     where
         B: FnOnce(&mut ViewContext<V>) -> V,
     {
@@ -4188,14 +4205,14 @@ pub fn open_paths(
     });
     cx.spawn(move |mut cx| async move {
         if let Some(existing) = existing {
-            // // Ok((
-            //     existing.clone(),
-            //     cx.update_window_root(&existing, |workspace, cx| {
-            //         workspace.open_paths(abs_paths, true, cx)
-            //     })?
-            //     .await,
-            // ))
-            todo!()
+            Ok((
+                existing.clone(),
+                existing
+                    .update(&mut cx, |workspace, cx| {
+                        workspace.open_paths(abs_paths, true, cx)
+                    })?
+                    .await,
+            ))
         } else {
             cx.update(move |cx| {
                 Workspace::new_local(abs_paths, app_state.clone(), requesting_window, cx)

crates/zed2/build.rs 🔗

@@ -27,10 +27,20 @@ fn main() {
     // Populate git sha environment variable if git is available
     if let Ok(output) = Command::new("git").args(["rev-parse", "HEAD"]).output() {
         if output.status.success() {
-            println!(
-                "cargo:rustc-env=ZED_COMMIT_SHA={}",
-                String::from_utf8_lossy(&output.stdout).trim()
-            );
+            let git_sha = String::from_utf8_lossy(&output.stdout);
+            let git_sha = git_sha.trim();
+
+            println!("cargo:rustc-env=ZED_COMMIT_SHA={git_sha}");
+
+            if let Ok(build_profile) = std::env::var("PROFILE") {
+                if build_profile == "release" {
+                    // This is currently the best way to make `cargo build ...`'s build script
+                    // to print something to stdout without extra verbosity.
+                    println!(
+                        "cargo:warning=Info: using '{git_sha}' hash for ZED_COMMIT_SHA env var"
+                    );
+                }
+            }
         }
     }
 }

crates/zed2/src/zed2.rs 🔗

@@ -44,27 +44,30 @@ use workspace::{
 use zed_actions::{OpenBrowser, OpenZedURL};
 
 actions!(
-    About,
-    DebugElements,
-    DecreaseBufferFontSize,
-    Hide,
-    HideOthers,
-    IncreaseBufferFontSize,
-    Minimize,
-    OpenDefaultKeymap,
-    OpenDefaultSettings,
-    OpenKeymap,
-    OpenLicenses,
-    OpenLocalSettings,
-    OpenLog,
-    OpenSettings,
-    OpenTelemetryLog,
-    Quit,
-    ResetBufferFontSize,
-    ResetDatabase,
-    ShowAll,
-    ToggleFullScreen,
-    Zoom,
+    zed,
+    [
+        About,
+        DebugElements,
+        DecreaseBufferFontSize,
+        Hide,
+        HideOthers,
+        IncreaseBufferFontSize,
+        Minimize,
+        OpenDefaultKeymap,
+        OpenDefaultSettings,
+        OpenKeymap,
+        OpenLicenses,
+        OpenLocalSettings,
+        OpenLog,
+        OpenSettings,
+        OpenTelemetryLog,
+        Quit,
+        ResetBufferFontSize,
+        ResetDatabase,
+        ShowAll,
+        ToggleFullScreen,
+        Zoom,
+    ]
 );
 
 pub fn build_window_options(
@@ -161,8 +164,8 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
             let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone());
             let channels_panel =
                 collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
-            // let chat_panel =
-            //     collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
+            let chat_panel =
+                collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
             // let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
             //     workspace_handle.clone(),
             //     cx.clone(),
@@ -172,14 +175,14 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
                 terminal_panel,
                 assistant_panel,
                 channels_panel,
-                //     chat_panel,
+                chat_panel,
                 //     notification_panel,
             ) = futures::try_join!(
                 project_panel,
                 terminal_panel,
                 assistant_panel,
                 channels_panel,
-                //     chat_panel,
+                chat_panel,
                 //     notification_panel,
             )?;
 
@@ -189,7 +192,7 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
                 workspace.add_panel(terminal_panel, cx);
                 workspace.add_panel(assistant_panel, cx);
                 workspace.add_panel(channels_panel, cx);
-                //     workspace.add_panel(chat_panel, cx);
+                workspace.add_panel(chat_panel, cx);
                 //     workspace.add_panel(notification_panel, cx);
 
                 // if !was_deserialized
@@ -417,7 +420,7 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
 fn initialize_pane(workspace: &mut Workspace, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) {
     pane.update(cx, |pane, cx| {
         pane.toolbar().update(cx, |toolbar, cx| {
-            let breadcrumbs = cx.build_view(|_| Breadcrumbs::new(workspace));
+            let breadcrumbs = cx.build_view(|_| Breadcrumbs::new());
             toolbar.add_item(breadcrumbs, cx);
             let buffer_search_bar = cx.build_view(search::BufferSearchBar::new);
             toolbar.add_item(buffer_search_bar.clone(), cx);

crates/zed_actions2/src/lib.rs 🔗

@@ -1,4 +1,4 @@
-use gpui::Action;
+use gpui::impl_actions;
 use serde::Deserialize;
 
 // If the zed binary doesn't use anything in this crate, it will be optimized away
@@ -10,12 +10,14 @@ use serde::Deserialize;
 // https://github.com/mmastrac/rust-ctor/issues/280
 pub fn init() {}
 
-#[derive(Clone, PartialEq, Deserialize, Action)]
+#[derive(Clone, PartialEq, Deserialize)]
 pub struct OpenBrowser {
     pub url: String,
 }
 
-#[derive(Clone, PartialEq, Deserialize, Action)]
+#[derive(Clone, PartialEq, Deserialize)]
 pub struct OpenZedURL {
     pub url: String,
 }
+
+impl_actions!(zed, [OpenBrowser, OpenZedURL]);

script/upload-nightly 🔗

@@ -20,7 +20,7 @@ function uploadToSpaces
   string="PUT\n\n${content_type}\n${date}\n${acl}\n${storage_type}\n/${SPACE}/${space_path}/${file_name}"
   signature=$(echo -en "${string}" | openssl sha1 -hmac "${DIGITALOCEAN_SPACES_SECRET_KEY}" -binary | base64)
 
-  curl -vv -s -X PUT -T "$file_to_upload" \
+  curl --fail -vv -s -X PUT -T "$file_to_upload" \
     -H "Host: ${SPACE}.${REGION}.digitaloceanspaces.com" \
     -H "Date: $date" \
     -H "Content-Type: $content_type" \