Remove 2 suffix for theme

Max Brunsfeld and Mikayla created

Co-authored-by: Mikayla <mikayla@zed.dev>

Change summary

Cargo.lock                                 |   88 
Cargo.toml                                 |    1 
crates/activity_indicator/Cargo.toml       |    2 
crates/assistant/Cargo.toml                |    2 
crates/auto_update/Cargo.toml              |    2 
crates/breadcrumbs/Cargo.toml              |    2 
crates/collab/Cargo.toml                   |    2 
crates/collab2/Cargo.toml                  |   99 +
crates/collab_ui/Cargo.toml                |    2 
crates/command_palette/Cargo.toml          |    2 
crates/copilot/Cargo.toml                  |    2 
crates/copilot_button/Cargo.toml           |    2 
crates/diagnostics/Cargo.toml              |    4 
crates/editor/Cargo.toml                   |    2 
crates/feedback/Cargo.toml                 |    2 
crates/file_finder/Cargo.toml              |    4 
crates/go_to_line/Cargo.toml               |    2 
crates/language/Cargo.toml                 |    2 
crates/language_selector/Cargo.toml        |    2 
crates/language_tools/Cargo.toml           |    2 
crates/multi_buffer/Cargo.toml             |    2 
crates/outline/Cargo.toml                  |    2 
crates/picker/Cargo.toml                   |    2 
crates/project_panel/Cargo.toml            |    2 
crates/project_symbols/Cargo.toml          |    4 
crates/recent_projects/Cargo.toml          |    2 
crates/rich_text/Cargo.toml                |    2 
crates/search/Cargo.toml                   |    2 
crates/storybook/Cargo.toml                |    2 
crates/storybook/src/storybook.rs          |    4 
crates/terminal/Cargo.toml                 |    2 
crates/terminal_view/Cargo.toml            |    2 
crates/theme/Cargo.toml                    |   18 
crates/theme/src/components.rs             |  480 --------
crates/theme/src/default_colors.rs         |    0 
crates/theme/src/default_theme.rs          |    0 
crates/theme/src/one_themes.rs             |    0 
crates/theme/src/prelude.rs                |    0 
crates/theme/src/registry.rs               |    0 
crates/theme/src/scale.rs                  |    0 
crates/theme/src/settings.rs               |    0 
crates/theme/src/styles.rs                 |    0 
crates/theme/src/styles/colors.rs          |    0 
crates/theme/src/styles/players.rs         |    0 
crates/theme/src/styles/status.rs          |    0 
crates/theme/src/styles/stories/color.rs   |    0 
crates/theme/src/styles/stories/mod.rs     |    0 
crates/theme/src/styles/stories/players.rs |    0 
crates/theme/src/styles/syntax.rs          |    0 
crates/theme/src/styles/system.rs          |    0 
crates/theme/src/theme.rs                  | 1401 +----------------------
crates/theme/src/theme_registry.rs         |  106 -
crates/theme/src/theme_settings.rs         |  214 ---
crates/theme/src/themes/andromeda.rs       |    0 
crates/theme/src/themes/atelier.rs         |    0 
crates/theme/src/themes/ayu.rs             |    0 
crates/theme/src/themes/gruvbox.rs         |    0 
crates/theme/src/themes/mod.rs             |    0 
crates/theme/src/themes/one.rs             |    0 
crates/theme/src/themes/rose_pine.rs       |    0 
crates/theme/src/themes/sandcastle.rs      |    0 
crates/theme/src/themes/solarized.rs       |    0 
crates/theme/src/themes/summercamp.rs      |    0 
crates/theme/src/ui.rs                     |  244 ----
crates/theme/src/user_theme.rs             |    0 
crates/theme/util/hex_to_hsla.py           |    0 
crates/theme2/Cargo.toml                   |   42 
crates/theme2/src/theme2.rs                |  148 --
crates/theme_importer/Cargo.toml           |    2 
crates/theme_importer/src/main.rs          |    4 
crates/theme_selector/Cargo.toml           |    2 
crates/ui/Cargo.toml                       |    2 
crates/ui/docs/hello-world.md              |    2 
crates/vim/Cargo.toml                      |    4 
crates/welcome/Cargo.toml                  |    2 
crates/workspace/Cargo.toml                |    2 
crates/workspace/src/notifications.rs      |    2 
crates/workspace/src/pane.rs               |    2 
crates/zed/Cargo.toml                      |    2 
79 files changed, 302 insertions(+), 2,631 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -15,7 +15,7 @@ dependencies = [
  "project",
  "settings",
  "smallvec",
- "theme2",
+ "theme",
  "ui",
  "util",
  "workspace",
@@ -331,7 +331,7 @@ dependencies = [
  "serde_json",
  "settings",
  "smol",
- "theme2",
+ "theme",
  "tiktoken-rs",
  "ui",
  "util",
@@ -688,7 +688,7 @@ dependencies = [
  "settings",
  "smol",
  "tempdir",
- "theme2",
+ "theme",
  "util",
  "workspace",
 ]
@@ -1017,7 +1017,7 @@ dependencies = [
  "project",
  "search",
  "settings",
- "theme2",
+ "theme",
  "ui",
  "workspace",
 ]
@@ -1501,7 +1501,7 @@ dependencies = [
  "smallvec",
  "sqlx",
  "text",
- "theme2",
+ "theme",
  "time",
  "tokio",
  "tokio-tungstenite",
@@ -1552,7 +1552,7 @@ dependencies = [
  "serde_derive",
  "settings",
  "smallvec",
- "theme2",
+ "theme",
  "theme_selector",
  "time",
  "tree-sitter-markdown",
@@ -1611,7 +1611,7 @@ dependencies = [
  "serde",
  "serde_json",
  "settings",
- "theme2",
+ "theme",
  "ui",
  "util",
  "workspace",
@@ -1713,7 +1713,7 @@ dependencies = [
  "serde_derive",
  "settings",
  "smol",
- "theme2",
+ "theme",
  "ui",
  "util",
 ]
@@ -1731,7 +1731,7 @@ dependencies = [
  "language",
  "settings",
  "smol",
- "theme2",
+ "theme",
  "util",
  "workspace",
  "zed_actions",
@@ -2241,7 +2241,7 @@ dependencies = [
  "serde_json",
  "settings",
  "smallvec",
- "theme2",
+ "theme",
  "ui",
  "unindent",
  "util",
@@ -2423,7 +2423,7 @@ dependencies = [
  "sqlez",
  "sum_tree",
  "text",
- "theme2",
+ "theme",
  "tree-sitter",
  "tree-sitter-html",
  "tree-sitter-rust",
@@ -2636,7 +2636,7 @@ dependencies = [
  "smallvec",
  "smol",
  "sysinfo",
- "theme2",
+ "theme",
  "tree-sitter-markdown",
  "ui",
  "urlencoding",
@@ -2663,7 +2663,7 @@ dependencies = [
  "serde_json",
  "settings",
  "text",
- "theme2",
+ "theme",
  "ui",
  "util",
  "workspace",
@@ -3155,7 +3155,7 @@ dependencies = [
  "serde",
  "settings",
  "text",
- "theme2",
+ "theme",
  "ui",
  "util",
  "workspace",
@@ -3961,7 +3961,7 @@ dependencies = [
  "smol",
  "sum_tree",
  "text",
- "theme2",
+ "theme",
  "tree-sitter",
  "tree-sitter-elixir",
  "tree-sitter-embedded-template",
@@ -3990,7 +3990,7 @@ dependencies = [
  "picker",
  "project",
  "settings",
- "theme2",
+ "theme",
  "ui",
  "util",
  "workspace",
@@ -4012,7 +4012,7 @@ dependencies = [
  "project",
  "serde",
  "settings",
- "theme2",
+ "theme",
  "tree-sitter",
  "ui",
  "unindent",
@@ -4625,7 +4625,7 @@ dependencies = [
  "snippet",
  "sum_tree",
  "text",
- "theme2",
+ "theme",
  "tree-sitter",
  "tree-sitter-html",
  "tree-sitter-rust",
@@ -5203,7 +5203,7 @@ dependencies = [
  "settings",
  "smol",
  "text",
- "theme2",
+ "theme",
  "ui",
  "util",
  "workspace",
@@ -5424,7 +5424,7 @@ dependencies = [
  "parking_lot 0.11.2",
  "serde_json",
  "settings",
- "theme2",
+ "theme",
  "ui",
  "util",
  "workspace",
@@ -5776,7 +5776,7 @@ dependencies = [
  "serde_json",
  "settings",
  "smallvec",
- "theme2",
+ "theme",
  "ui",
  "unicase",
  "util",
@@ -5801,7 +5801,7 @@ dependencies = [
  "settings",
  "smol",
  "text",
- "theme2",
+ "theme",
  "util",
  "workspace",
 ]
@@ -6150,7 +6150,7 @@ dependencies = [
  "settings",
  "smol",
  "text",
- "theme2",
+ "theme",
  "ui",
  "util",
  "workspace",
@@ -6346,7 +6346,7 @@ dependencies = [
  "smallvec",
  "smol",
  "sum_tree",
- "theme2",
+ "theme",
  "util",
 ]
 
@@ -6933,7 +6933,7 @@ dependencies = [
  "settings",
  "smallvec",
  "smol",
- "theme2",
+ "theme",
  "ui",
  "unindent",
  "util",
@@ -7777,7 +7777,7 @@ dependencies = [
  "smallvec",
  "story",
  "strum",
- "theme2",
+ "theme",
  "ui",
  "util",
 ]
@@ -8081,7 +8081,7 @@ dependencies = [
  "shellexpand",
  "smallvec",
  "smol",
- "theme2",
+ "theme",
  "thiserror",
  "util",
 ]
@@ -8113,7 +8113,7 @@ dependencies = [
  "smallvec",
  "smol",
  "terminal",
- "theme2",
+ "theme",
  "thiserror",
  "ui",
  "util",
@@ -8152,24 +8152,6 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
 [[package]]
 name = "theme"
 version = "0.1.0"
-dependencies = [
- "anyhow",
- "fs",
- "gpui",
- "indexmap 1.9.3",
- "parking_lot 0.11.2",
- "schemars",
- "serde",
- "serde_derive",
- "serde_json",
- "settings",
- "toml 0.5.11",
- "util",
-]
-
-[[package]]
-name = "theme2"
-version = "0.1.0"
 dependencies = [
  "anyhow",
  "fs",
@@ -8207,7 +8189,7 @@ dependencies = [
  "serde",
  "simplelog",
  "strum",
- "theme2",
+ "theme",
  "uuid 1.4.1",
 ]
 
@@ -8227,7 +8209,7 @@ dependencies = [
  "postage",
  "settings",
  "smol",
- "theme2",
+ "theme",
  "ui",
  "util",
  "workspace",
@@ -9046,7 +9028,7 @@ dependencies = [
  "smallvec",
  "story",
  "strum",
- "theme2",
+ "theme",
 ]
 
 [[package]]
@@ -9329,7 +9311,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "settings",
- "theme2",
+ "theme",
  "tokio",
  "ui",
  "util",
@@ -9742,7 +9724,7 @@ dependencies = [
  "schemars",
  "serde",
  "settings",
- "theme2",
+ "theme",
  "theme_selector",
  "ui",
  "util",
@@ -10021,7 +10003,7 @@ dependencies = [
  "settings",
  "smallvec",
  "terminal",
- "theme2",
+ "theme",
  "ui",
  "util",
  "uuid 1.4.1",
@@ -10190,7 +10172,7 @@ dependencies = [
  "tempdir",
  "terminal_view",
  "text",
- "theme2",
+ "theme",
  "theme_selector",
  "thiserror",
  "tiny_http",

Cargo.toml 🔗

@@ -76,7 +76,6 @@ members = [
     "crates/terminal_view",
     "crates/text",
     "crates/theme",
-    "crates/theme2",
     "crates/theme_importer",
     "crates/theme_selector",
     "crates/ui",

crates/activity_indicator/Cargo.toml 🔗

@@ -17,7 +17,7 @@ project = { path = "../project" }
 settings = { path = "../settings" }
 ui = { path = "../ui" }
 util = { path = "../util" }
-theme = { path = "../theme2", package = "theme2" }
+theme = { path = "../theme" }
 workspace = { path = "../workspace", package = "workspace" }
 
 anyhow.workspace = true

crates/assistant/Cargo.toml 🔗

@@ -22,7 +22,7 @@ project = { path = "../project" }
 search = { path = "../search" }
 semantic_index = { path = "../semantic_index" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 ui = { path = "../ui" }
 util = { path = "../util" }
 workspace = { path = "../workspace" }

crates/auto_update/Cargo.toml 🔗

@@ -15,7 +15,7 @@ gpui = { package = "gpui2", path = "../gpui2" }
 menu = { path = "../menu" }
 project = { path = "../project" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 workspace = { path = "../workspace" }
 util = { path = "../util" }
 anyhow.workspace = true

crates/breadcrumbs/Cargo.toml 🔗

@@ -17,7 +17,7 @@ language = { path = "../language" }
 project = { path = "../project" }
 search = { path = "../search" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 workspace = { path = "../workspace" }
 outline = { path = "../outline" }
 itertools = "0.10"

crates/collab/Cargo.toml 🔗

@@ -78,7 +78,7 @@ notifications = { path = "../notifications", features = ["test-support"] }
 project = { path = "../project", features = ["test-support"] }
 rpc = { path = "../rpc", features = ["test-support"] }
 settings = { path = "../settings", features = ["test-support"] }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 workspace = { path = "../workspace", features = ["test-support"] }
 
 collab_ui = { path = "../collab_ui", features = ["test-support"] }

crates/collab2/Cargo.toml 🔗

@@ -0,0 +1,99 @@
+[package]
+authors = ["Nathan Sobo <nathan@zed.dev>"]
+default-run = "collab"
+edition = "2021"
+name = "collab"
+version = "0.28.0"
+publish = false
+
+[[bin]]
+name = "collab"
+
+[[bin]]
+name = "seed"
+required-features = ["seed-support"]
+
+[dependencies]
+clock = { path = "../clock" }
+collections = { path = "../collections" }
+live_kit_server = { path = "../live_kit_server" }
+text = { path = "../text" }
+rpc = { path = "../rpc" }
+util = { path = "../util" }
+
+anyhow.workspace = true
+async-tungstenite = "0.16"
+axum = { version = "0.5", features = ["json", "headers", "ws"] }
+axum-extra = { version = "0.3", features = ["erased-json"] }
+base64 = "0.13"
+clap = { version = "3.1", features = ["derive"], optional = true }
+dashmap = "5.4"
+envy = "0.4.2"
+futures.workspace = true
+hyper = "0.14"
+lazy_static.workspace = true
+lipsum = { version = "0.8", optional = true }
+log.workspace = true
+nanoid = "0.4"
+parking_lot.workspace = true
+prometheus = "0.13"
+prost.workspace = true
+rand.workspace = true
+reqwest = { version = "0.11", features = ["json"], optional = true }
+scrypt = "0.7"
+smallvec.workspace = true
+sea-orm = { version = "0.12.x", features = ["sqlx-postgres", "postgres-array", "runtime-tokio-rustls", "with-uuid"] }
+serde.workspace = true
+serde_derive.workspace = true
+serde_json.workspace = true
+sha-1 = "0.9"
+sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "json", "time", "uuid", "any"] }
+time.workspace = true
+tokio = { version = "1", features = ["full"] }
+tokio-tungstenite = "0.17"
+tonic = "0.6"
+tower = "0.4"
+toml.workspace = true
+tracing = "0.1.34"
+tracing-log = "0.1.3"
+tracing-subscriber = { version = "0.3.11", features = ["env-filter", "json"] }
+uuid.workspace = true
+
+[dev-dependencies]
+audio = { path = "../audio" }
+collections = { path = "../collections", features = ["test-support"] }
+gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
+call = { path = "../call", features = ["test-support"] }
+client = { path = "../client", features = ["test-support"] }
+channel = { path = "../channel" }
+editor = { path = "../editor", features = ["test-support"] }
+language = { path = "../language", features = ["test-support"] }
+fs = { path = "../fs", features = ["test-support"] }
+git = { path = "../git", features = ["test-support"] }
+live_kit_client = { package = "live_kit_client2", path = "../live_kit_client2", features = ["test-support"] }
+lsp = { path = "../lsp", features = ["test-support"] }
+node_runtime = { path = "../node_runtime" }
+notifications = { path = "../notifications", features = ["test-support"] }
+
+project = { path = "../project", features = ["test-support"] }
+rpc = { path = "../rpc", features = ["test-support"] }
+settings = { path = "../settings", features = ["test-support"] }
+theme = { path = "../theme" }
+workspace = { path = "../workspace", features = ["test-support"] }
+
+collab_ui = { path = "../collab_ui", features = ["test-support"] }
+
+async-trait.workspace = true
+pretty_assertions.workspace = true
+ctor.workspace = true
+env_logger.workspace = true
+indoc.workspace = true
+util = { path = "../util" }
+lazy_static.workspace = true
+sea-orm = { version = "0.12.x", features = ["sqlx-sqlite"] }
+serde_json.workspace = true
+sqlx = { version = "0.7", features = ["sqlite"] }
+unindent.workspace = true
+
+[features]
+seed-support = ["clap", "lipsum", "reqwest"]

crates/collab_ui/Cargo.toml 🔗

@@ -45,7 +45,7 @@ recent_projects = { path = "../recent_projects" }
 rpc = { path = "../rpc" }
 settings = { path = "../settings" }
 feature_flags = { path = "../feature_flags"}
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 theme_selector = { path = "../theme_selector" }
 vcs_menu = { path = "../vcs_menu" }
 ui = { path = "../ui" }

crates/command_palette/Cargo.toml 🔗

@@ -18,7 +18,7 @@ project = { path = "../project" }
 settings = { path = "../settings" }
 ui = { path = "../ui" }
 util = { path = "../util" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 workspace = { path = "../workspace" }
 zed_actions = { path = "../zed_actions" }
 anyhow.workspace = true

crates/copilot/Cargo.toml 🔗

@@ -24,7 +24,7 @@ collections = { path = "../collections" }
 gpui = { package = "gpui2", path = "../gpui2" }
 language = { path = "../language" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 lsp = { path = "../lsp" }
 node_runtime = { path = "../node_runtime"}
 util = { path = "../util" }

crates/copilot_button/Cargo.toml 🔗

@@ -16,7 +16,7 @@ zed_actions = { path = "../zed_actions"}
 gpui = { package = "gpui2", path = "../gpui2" }
 language = { path = "../language" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 util = { path = "../util" }
 workspace = {path = "../workspace" }
 anyhow.workspace = true

crates/diagnostics/Cargo.toml 🔗

@@ -17,7 +17,7 @@ language = { path = "../language" }
 lsp = { path = "../lsp" }
 project = { path = "../project" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 util = { path = "../util" }
 workspace = {path = "../workspace" }
 
@@ -37,7 +37,7 @@ language = { path = "../language", features = ["test-support"] }
 lsp = { path = "../lsp", features = ["test-support"] }
 gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
 workspace = {path = "../workspace", features = ["test-support"] }
-theme = { package = "theme2", path = "../theme2", features = ["test-support"] }
+theme = { path = "../theme", features = ["test-support"] }
 
 serde_json.workspace = true
 unindent.workspace = true

crates/editor/Cargo.toml 🔗

@@ -42,7 +42,7 @@ settings = { path = "../settings" }
 snippet = { path = "../snippet" }
 sum_tree = { path = "../sum_tree" }
 text = { path = "../text" }
-theme = { package="theme2", path = "../theme2" }
+theme = { path = "../theme" }
 ui = { path = "../ui" }
 util = { path = "../util" }
 sqlez = { path = "../sqlez" }

crates/feedback/Cargo.toml 🔗

@@ -20,7 +20,7 @@ menu = { path = "../menu" }
 project = { path = "../project" }
 search = { path = "../search" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 ui = { path = "../ui" }
 util = { path = "../util" }
 workspace = { path = "../workspace"}

crates/file_finder/Cargo.toml 🔗

@@ -19,7 +19,7 @@ project = { path = "../project" }
 settings = { path = "../settings" }
 text = { path = "../text" }
 util = { path = "../util" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 ui = { path = "../ui" }
 workspace = { path = "../workspace" }
 postage.workspace = true
@@ -30,7 +30,7 @@ editor = { path = "../editor", features = ["test-support"] }
 gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
 language = { path = "../language", features = ["test-support"] }
 workspace = { path = "../workspace", features = ["test-support"] }
-theme = { package = "theme2", path = "../theme2", features = ["test-support"] }
+theme = { path = "../theme", features = ["test-support"] }
 
 serde_json.workspace = true
 ctor.workspace = true

crates/go_to_line/Cargo.toml 🔗

@@ -17,7 +17,7 @@ settings = { path = "../settings" }
 text = { path = "../text" }
 workspace = { path = "../workspace" }
 postage.workspace = true
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 ui = { path = "../ui" }
 util = { path = "../util" }
 

crates/language/Cargo.toml 🔗

@@ -32,7 +32,7 @@ rpc = { path = "../rpc" }
 settings = { path = "../settings" }
 sum_tree = { path = "../sum_tree" }
 text = { path = "../text" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 util = { path = "../util" }
 
 anyhow.workspace = true

crates/language_selector/Cargo.toml 🔗

@@ -15,7 +15,7 @@ language = { path = "../language" }
 gpui = { package = "gpui2", path = "../gpui2" }
 picker = { path = "../picker" }
 project = { path = "../project" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 ui = { path = "../ui" }
 settings = { path = "../settings" }
 util = { path = "../util" }

crates/language_tools/Cargo.toml 🔗

@@ -12,7 +12,7 @@ doctest = false
 collections = { path = "../collections" }
 editor = { path = "../editor" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 language = { path = "../language" }
 project = { path = "../project" }
 workspace = { path = "../workspace" }

crates/multi_buffer/Cargo.toml 🔗

@@ -32,7 +32,7 @@ settings = { path = "../settings" }
 snippet = { path = "../snippet" }
 sum_tree = { path = "../sum_tree" }
 text = { path = "../text" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 util = { path = "../util" }
 
 aho-corasick = "1.1"

crates/outline/Cargo.toml 🔗

@@ -17,7 +17,7 @@ language = { path = "../language" }
 picker = { path = "../picker" }
 settings = { path = "../settings" }
 text = { path = "../text" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 workspace = { path = "../workspace" }
 util = { path = "../util" }
 

crates/picker/Cargo.toml 🔗

@@ -15,7 +15,7 @@ gpui = { package = "gpui2", path = "../gpui2" }
 menu = { path = "../menu" }
 settings = { path = "../settings" }
 util = { path = "../util" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 workspace = { path = "../workspace"}
 
 parking_lot.workspace = true

crates/project_panel/Cargo.toml 🔗

@@ -17,7 +17,7 @@ menu = {  path = "../menu" }
 project = { path = "../project" }
 search = { path = "../search" }
 settings = { path = "../settings" }
-theme = { path = "../theme2", package = "theme2" }
+theme = { path = "../theme" }
 ui = { path = "../ui" }
 util = { path = "../util" }
 workspace = { path = "../workspace", package = "workspace" }

crates/project_symbols/Cargo.toml 🔗

@@ -17,7 +17,7 @@ project = { path = "../project" }
 text = { path = "../text" }
 settings = { path = "../settings" }
 workspace = { path = "../workspace" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 util = { path = "../util" }
 
 anyhow.workspace = true
@@ -33,5 +33,5 @@ gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
 language = { path = "../language", features = ["test-support"] }
 lsp = { path = "../lsp", features = ["test-support"] }
 project = { path = "../project", features = ["test-support"] }
-theme = { package = "theme2", path = "../theme2", features = ["test-support"] }
+theme = { path = "../theme", features = ["test-support"] }
 workspace = { path = "../workspace", features = ["test-support"] }

crates/recent_projects/Cargo.toml 🔗

@@ -17,7 +17,7 @@ picker = { path = "../picker" }
 settings = { path = "../settings" }
 text = { path = "../text" }
 util = { path = "../util"}
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 ui = { path = "../ui" }
 workspace = { path = "../workspace" }
 

crates/rich_text/Cargo.toml 🔗

@@ -18,7 +18,7 @@ test-support = [
 collections = { path = "../collections" }
 gpui = { package = "gpui2", path = "../gpui2" }
 sum_tree = { path = "../sum_tree" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 language = { path = "../language" }
 util = { path = "../util" }
 anyhow.workspace = true

crates/search/Cargo.toml 🔗

@@ -17,7 +17,7 @@ language = { path = "../language" }
 menu = { path = "../menu" }
 project = { path = "../project" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 util = { path = "../util" }
 ui = {path = "../ui"}
 workspace = { path = "../workspace" }

crates/storybook/Cargo.toml 🔗

@@ -29,7 +29,7 @@ simplelog = "0.9"
 smallvec.workspace = true
 story = { path = "../story" }
 strum = { version = "0.25.0", features = ["derive"] }
-theme2 = { path = "../theme2" }
+theme = { path = "../theme" }
 menu = { path = "../menu" }
 ui = { path = "../ui", features = ["stories"] }
 util = { path = "../util" }

crates/storybook/src/storybook.rs 🔗

@@ -14,7 +14,7 @@ use log::LevelFilter;
 use settings::{default_settings, Settings, SettingsStore};
 use simplelog::SimpleLogger;
 use strum::IntoEnumIterator;
-use theme2::{ThemeRegistry, ThemeSettings};
+use theme::{ThemeRegistry, ThemeSettings};
 use ui::prelude::*;
 
 use crate::assets::Assets;
@@ -69,7 +69,7 @@ fn main() {
             .unwrap();
         cx.set_global(store);
 
-        theme2::init(theme2::LoadThemes::All, cx);
+        theme::init(theme::LoadThemes::All, cx);
 
         let selector = story_selector;
 

crates/terminal/Cargo.toml 🔗

@@ -13,7 +13,7 @@ doctest = false
 gpui = { package = "gpui2", path = "../gpui2" }
 settings = { path = "../settings" }
 db = { path = "../db" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 util = { path = "../util" }
 
 alacritty_terminal = { git = "https://github.com/zed-industries/alacritty", rev = "33306142195b354ef3485ca2b1d8a85dfc6605ca" }

crates/terminal_view/Cargo.toml 🔗

@@ -15,7 +15,7 @@ gpui = { package = "gpui2", path = "../gpui2" }
 project = { path = "../project" }
 # search = { path = "../search" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 util = { path = "../util" }
 workspace = { path = "../workspace" }
 db = { path = "../db" }

crates/theme/Cargo.toml 🔗

@@ -5,6 +5,9 @@ edition = "2021"
 publish = false
 
 [features]
+default = []
+importing-themes = []
+stories = ["dep:itertools", "dep:story"]
 test-support = [
     "gpui/test-support",
     "fs/test-support",
@@ -16,21 +19,24 @@ path = "src/theme.rs"
 doctest = false
 
 [dependencies]
-gpui = { path = "../gpui" }
-fs = { path = "../fs" }
-settings = { path = "../settings" }
-util = { path = "../util" }
-
 anyhow.workspace = true
+fs = { path = "../fs" }
+gpui = { package = "gpui2", path = "../gpui2" }
 indexmap = "1.6.2"
 parking_lot.workspace = true
+refineable.workspace = true
 schemars.workspace = true
 serde.workspace = true
 serde_derive.workspace = true
 serde_json.workspace = true
+settings = { path = "../settings" }
+story = { path = "../story", optional = true }
 toml.workspace = true
+uuid.workspace = true
+util = { path = "../util" }
+itertools = { version = "0.11.0", optional = true }
 
 [dev-dependencies]
-gpui = { path = "../gpui", features = ["test-support"] }
+gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
 fs = { path = "../fs", features = ["test-support"] }
 settings = { path = "../settings", features = ["test-support"] }

crates/theme/src/components.rs 🔗

@@ -1,480 +0,0 @@
-use gpui::{elements::SafeStylable, Action};
-
-use crate::{Interactive, Toggleable};
-
-use self::{action_button::ButtonStyle, disclosure::Disclosable, svg::SvgStyle, toggle::Toggle};
-
-pub type IconButtonStyle = Interactive<ButtonStyle<SvgStyle>>;
-pub type ToggleIconButtonStyle = Toggleable<IconButtonStyle>;
-
-pub trait ComponentExt<C: SafeStylable> {
-    fn toggleable(self, active: bool) -> Toggle<C, ()>;
-    fn disclosable(self, disclosed: Option<bool>, action: Box<dyn Action>) -> Disclosable<C, ()>;
-}
-
-impl<C: SafeStylable> ComponentExt<C> for C {
-    fn toggleable(self, active: bool) -> Toggle<C, ()> {
-        Toggle::new(self, active)
-    }
-
-    /// Some(True) => disclosed => content is visible
-    /// Some(false) => closed => content is hidden
-    /// None => No disclosure button, but reserve disclosure spacing
-    fn disclosable(self, disclosed: Option<bool>, action: Box<dyn Action>) -> Disclosable<C, ()> {
-        Disclosable::new(disclosed, self, action)
-    }
-}
-
-pub mod disclosure {
-    use gpui::{
-        elements::{Component, ContainerStyle, Empty, Flex, ParentElement, SafeStylable},
-        Action, Element,
-    };
-    use schemars::JsonSchema;
-    use serde_derive::Deserialize;
-
-    use super::{action_button::Button, svg::Svg, IconButtonStyle};
-
-    #[derive(Clone, Default, Deserialize, JsonSchema)]
-    pub struct DisclosureStyle<S> {
-        pub button: IconButtonStyle,
-        #[serde(flatten)]
-        pub container: ContainerStyle,
-        pub spacing: f32,
-        #[serde(flatten)]
-        content: S,
-    }
-
-    impl<S> DisclosureStyle<S> {
-        pub fn button_space(&self) -> f32 {
-            self.spacing + self.button.button_width.unwrap()
-        }
-    }
-
-    pub struct Disclosable<C, S> {
-        disclosed: Option<bool>,
-        action: Box<dyn Action>,
-        id: usize,
-        content: C,
-        style: S,
-    }
-
-    impl Disclosable<(), ()> {
-        pub fn new<C>(
-            disclosed: Option<bool>,
-            content: C,
-            action: Box<dyn Action>,
-        ) -> Disclosable<C, ()> {
-            Disclosable {
-                disclosed,
-                content,
-                action,
-                id: 0,
-                style: (),
-            }
-        }
-    }
-
-    impl<C> Disclosable<C, ()> {
-        pub fn with_id(mut self, id: usize) -> Disclosable<C, ()> {
-            self.id = id;
-            self
-        }
-    }
-
-    impl<C: SafeStylable> SafeStylable for Disclosable<C, ()> {
-        type Style = DisclosureStyle<C::Style>;
-
-        type Output = Disclosable<C, Self::Style>;
-
-        fn with_style(self, style: Self::Style) -> Self::Output {
-            Disclosable {
-                disclosed: self.disclosed,
-                action: self.action,
-                content: self.content,
-                id: self.id,
-                style,
-            }
-        }
-    }
-
-    impl<C: SafeStylable> Component for Disclosable<C, DisclosureStyle<C::Style>> {
-        fn render<V: 'static>(self, cx: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
-            Flex::row()
-                .with_spacing(self.style.spacing)
-                .with_child(if let Some(disclosed) = self.disclosed {
-                    Button::dynamic_action(self.action)
-                        .with_id(self.id)
-                        .with_contents(Svg::new(if disclosed {
-                            "icons/file_icons/chevron_down.svg"
-                        } else {
-                            "icons/file_icons/chevron_right.svg"
-                        }))
-                        .with_style(self.style.button)
-                        .element()
-                        .into_any()
-                } else {
-                    Empty::new()
-                        .into_any()
-                        .constrained()
-                        // TODO: Why is this optional at all?
-                        .with_width(self.style.button.button_width.unwrap())
-                        .into_any()
-                })
-                .with_child(
-                    self.content
-                        .with_style(self.style.content)
-                        .render(cx)
-                        .flex(1., true),
-                )
-                .align_children_center()
-                .contained()
-                .with_style(self.style.container)
-                .into_any()
-        }
-    }
-}
-
-pub mod toggle {
-    use gpui::elements::{Component, SafeStylable};
-
-    use crate::Toggleable;
-
-    pub struct Toggle<C, S> {
-        style: S,
-        active: bool,
-        component: C,
-    }
-
-    impl<C: SafeStylable> Toggle<C, ()> {
-        pub fn new(component: C, active: bool) -> Self {
-            Toggle {
-                active,
-                component,
-                style: (),
-            }
-        }
-    }
-
-    impl<C: SafeStylable> SafeStylable for Toggle<C, ()> {
-        type Style = Toggleable<C::Style>;
-
-        type Output = Toggle<C, Self::Style>;
-
-        fn with_style(self, style: Self::Style) -> Self::Output {
-            Toggle {
-                active: self.active,
-                component: self.component,
-                style,
-            }
-        }
-    }
-
-    impl<C: SafeStylable> Component for Toggle<C, Toggleable<C::Style>> {
-        fn render<V: 'static>(self, cx: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
-            self.component
-                .with_style(self.style.in_state(self.active).clone())
-                .render(cx)
-        }
-    }
-}
-
-pub mod action_button {
-    use std::borrow::Cow;
-
-    use gpui::{
-        elements::{Component, ContainerStyle, MouseEventHandler, SafeStylable, TooltipStyle},
-        platform::{CursorStyle, MouseButton},
-        Action, Element, TypeTag,
-    };
-    use schemars::JsonSchema;
-    use serde_derive::Deserialize;
-
-    use crate::Interactive;
-
-    #[derive(Clone, Deserialize, Default, JsonSchema)]
-    pub struct ButtonStyle<C> {
-        #[serde(flatten)]
-        pub container: ContainerStyle,
-        // TODO: These are incorrect for the intended usage of the buttons.
-        // The size should be constant, but putting them here duplicates them
-        // across the states the buttons can be in
-        pub button_width: Option<f32>,
-        pub button_height: Option<f32>,
-        #[serde(flatten)]
-        contents: C,
-    }
-
-    pub struct Button<C, S> {
-        action: Box<dyn Action>,
-        tooltip: Option<(Cow<'static, str>, TooltipStyle)>,
-        tag: TypeTag,
-        id: usize,
-        contents: C,
-        style: Interactive<S>,
-    }
-
-    impl Button<(), ()> {
-        pub fn dynamic_action(action: Box<dyn Action>) -> Button<(), ()> {
-            Self {
-                contents: (),
-                tag: action.type_tag(),
-                action,
-                style: Interactive::new_blank(),
-                tooltip: None,
-                id: 0,
-            }
-        }
-
-        pub fn action<A: Action + Clone>(action: A) -> Self {
-            Self::dynamic_action(Box::new(action))
-        }
-
-        pub fn with_tooltip(
-            mut self,
-            tooltip: impl Into<Cow<'static, str>>,
-            tooltip_style: TooltipStyle,
-        ) -> Self {
-            self.tooltip = Some((tooltip.into(), tooltip_style));
-            self
-        }
-
-        pub fn with_id(mut self, id: usize) -> Self {
-            self.id = id;
-            self
-        }
-
-        pub fn with_contents<C: SafeStylable>(self, contents: C) -> Button<C, ()> {
-            Button {
-                action: self.action,
-                tag: self.tag,
-                style: self.style,
-                tooltip: self.tooltip,
-                id: self.id,
-                contents,
-            }
-        }
-    }
-
-    impl<C: SafeStylable> SafeStylable for Button<C, ()> {
-        type Style = Interactive<ButtonStyle<C::Style>>;
-        type Output = Button<C, ButtonStyle<C::Style>>;
-
-        fn with_style(self, style: Self::Style) -> Self::Output {
-            Button {
-                action: self.action,
-                tag: self.tag,
-                contents: self.contents,
-                tooltip: self.tooltip,
-                id: self.id,
-                style,
-            }
-        }
-    }
-
-    impl<C: SafeStylable> Component for Button<C, ButtonStyle<C::Style>> {
-        fn render<V: 'static>(self, cx: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
-            let mut button = MouseEventHandler::new_dynamic(self.tag, self.id, cx, |state, cx| {
-                let style = self.style.style_for(state);
-                let mut contents = self
-                    .contents
-                    .with_style(style.contents.to_owned())
-                    .render(cx)
-                    .contained()
-                    .with_style(style.container)
-                    .constrained();
-
-                if let Some(height) = style.button_height {
-                    contents = contents.with_height(height);
-                }
-
-                if let Some(width) = style.button_width {
-                    contents = contents.with_width(width);
-                }
-
-                contents.into_any()
-            })
-            .on_click(MouseButton::Left, {
-                let action = self.action.boxed_clone();
-                move |_, _, cx| {
-                    let window = cx.window();
-                    let view = cx.view_id();
-                    let action = action.boxed_clone();
-                    cx.spawn(|_, mut cx| async move {
-                        window.dispatch_action(view, action.as_ref(), &mut cx)
-                    })
-                    .detach();
-                }
-            })
-            .with_cursor_style(CursorStyle::PointingHand)
-            .into_any();
-
-            if let Some((tooltip, style)) = self.tooltip {
-                button = button
-                    .with_dynamic_tooltip(self.tag, 0, tooltip, Some(self.action), style, cx)
-                    .into_any()
-            }
-
-            button
-        }
-    }
-}
-
-pub mod svg {
-    use std::borrow::Cow;
-
-    use gpui::{
-        elements::{Component, Empty, SafeStylable},
-        Element,
-    };
-    use schemars::JsonSchema;
-    use serde::Deserialize;
-
-    #[derive(Clone, Default, JsonSchema)]
-    pub struct SvgStyle {
-        icon_width: f32,
-        icon_height: f32,
-        color: gpui::color::Color,
-    }
-
-    impl<'de> Deserialize<'de> for SvgStyle {
-        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-        where
-            D: serde::Deserializer<'de>,
-        {
-            #[derive(Deserialize)]
-            #[serde(untagged)]
-            pub enum IconSize {
-                IconSize { icon_size: f32 },
-                Dimensions { width: f32, height: f32 },
-                IconDimensions { icon_width: f32, icon_height: f32 },
-            }
-
-            #[derive(Deserialize)]
-            struct SvgStyleHelper {
-                #[serde(flatten)]
-                size: IconSize,
-                color: gpui::color::Color,
-            }
-
-            let json = SvgStyleHelper::deserialize(deserializer)?;
-            let color = json.color;
-
-            let result = match json.size {
-                IconSize::IconSize { icon_size } => SvgStyle {
-                    icon_width: icon_size,
-                    icon_height: icon_size,
-                    color,
-                },
-                IconSize::Dimensions { width, height } => SvgStyle {
-                    icon_width: width,
-                    icon_height: height,
-                    color,
-                },
-                IconSize::IconDimensions {
-                    icon_width,
-                    icon_height,
-                } => SvgStyle {
-                    icon_width,
-                    icon_height,
-                    color,
-                },
-            };
-
-            Ok(result)
-        }
-    }
-
-    pub struct Svg<S> {
-        path: Option<Cow<'static, str>>,
-        style: S,
-    }
-
-    impl Svg<()> {
-        pub fn new(path: impl Into<Cow<'static, str>>) -> Self {
-            Self {
-                path: Some(path.into()),
-                style: (),
-            }
-        }
-
-        pub fn optional(path: Option<impl Into<Cow<'static, str>>>) -> Self {
-            Self {
-                path: path.map(Into::into),
-                style: (),
-            }
-        }
-    }
-
-    impl SafeStylable for Svg<()> {
-        type Style = SvgStyle;
-
-        type Output = Svg<SvgStyle>;
-
-        fn with_style(self, style: Self::Style) -> Self::Output {
-            Svg {
-                path: self.path,
-                style,
-            }
-        }
-    }
-
-    impl Component for Svg<SvgStyle> {
-        fn render<V: 'static>(self, _: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
-            if let Some(path) = self.path {
-                gpui::elements::Svg::new(path)
-                    .with_color(self.style.color)
-                    .constrained()
-            } else {
-                Empty::new().constrained()
-            }
-            .constrained()
-            .with_width(self.style.icon_width)
-            .with_height(self.style.icon_height)
-            .into_any()
-        }
-    }
-}
-
-pub mod label {
-    use std::borrow::Cow;
-
-    use gpui::{
-        elements::{Component, LabelStyle, SafeStylable},
-        fonts::TextStyle,
-        Element,
-    };
-
-    pub struct Label<S> {
-        text: Cow<'static, str>,
-        style: S,
-    }
-
-    impl Label<()> {
-        pub fn new(text: impl Into<Cow<'static, str>>) -> Self {
-            Self {
-                text: text.into(),
-                style: (),
-            }
-        }
-    }
-
-    impl SafeStylable for Label<()> {
-        type Style = TextStyle;
-
-        type Output = Label<LabelStyle>;
-
-        fn with_style(self, style: Self::Style) -> Self::Output {
-            Label {
-                text: self.text,
-                style: style.into(),
-            }
-        }
-    }
-
-    impl Component for Label<LabelStyle> {
-        fn render<V: 'static>(self, _: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
-            gpui::elements::Label::new(self.text, self.style).into_any()
-        }
-    }
-}

crates/theme/src/theme.rs 🔗

@@ -1,1329 +1,148 @@
-pub mod components;
-mod theme_registry;
-mod theme_settings;
-pub mod ui;
-
-use components::{
-    action_button::ButtonStyle, disclosure::DisclosureStyle, IconButtonStyle, ToggleIconButtonStyle,
-};
-use gpui::{
-    color::Color,
-    elements::{Border, ContainerStyle, ImageStyle, LabelStyle, SvgStyle, TooltipStyle},
-    fonts::{HighlightStyle, TextStyle},
-    platform, AppContext, AssetSource, MouseState,
-};
-use parking_lot::Mutex;
-use schemars::JsonSchema;
-use serde::{de::DeserializeOwned, Deserialize};
-use serde_json::Value;
-use settings::SettingsStore;
-use std::{any::Any, collections::HashMap, ops::Deref, sync::Arc};
-use ui::{CheckboxStyle, CopilotCTAButton, IconStyle, ModalStyle};
-
-pub use theme_registry::*;
-pub use theme_settings::*;
-
-pub fn current(cx: &AppContext) -> Arc<Theme> {
-    settings::get::<ThemeSettings>(cx).theme.clone()
-}
-
-pub fn init(source: impl AssetSource, cx: &mut AppContext) {
-    cx.set_global(ThemeRegistry::new(source, cx.font_cache().clone()));
-    settings::register::<ThemeSettings>(cx);
-
-    let mut prev_buffer_font_size = settings::get::<ThemeSettings>(cx).buffer_font_size;
-    cx.observe_global::<SettingsStore, _>(move |cx| {
-        let buffer_font_size = settings::get::<ThemeSettings>(cx).buffer_font_size;
-        if buffer_font_size != prev_buffer_font_size {
-            prev_buffer_font_size = buffer_font_size;
-            reset_font_size(cx);
-        }
-    })
-    .detach();
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct Theme {
-    #[serde(default)]
-    pub meta: ThemeMeta,
-    pub workspace: Workspace,
-    pub context_menu: ContextMenu,
-    pub toolbar_dropdown_menu: DropdownMenu,
-    pub copilot: Copilot,
-    pub collab_panel: CollabPanel,
-    pub project_panel: ProjectPanel,
-    pub chat_panel: ChatPanel,
-    pub notification_panel: NotificationPanel,
-    pub command_palette: CommandPalette,
-    pub picker: Picker,
-    pub editor: Editor,
-    pub search: Search,
-    pub project_diagnostics: ProjectDiagnostics,
-    pub shared_screen: ContainerStyle,
-    pub contact_notification: ContactNotification,
-    pub update_notification: UpdateNotification,
-    pub simple_message_notification: MessageNotification,
-    pub project_shared_notification: ProjectSharedNotification,
-    pub incoming_call_notification: IncomingCallNotification,
-    pub tooltip: TooltipStyle,
-    pub terminal: TerminalStyle,
-    pub assistant: AssistantStyle,
-    pub feedback: FeedbackStyle,
-    pub welcome: WelcomeStyle,
-    pub titlebar: Titlebar,
-    pub component_test: ComponentTest,
-    // Nathan: New elements are styled in Rust, directly from the base theme.
-    // We store it on the legacy theme so we can mix both kinds of elements during the transition.
-    #[schemars(skip)]
-    pub base_theme: serde_json::Value,
-    // A place to cache deserialized base theme.
-    #[serde(skip_deserializing)]
-    #[schemars(skip)]
-    pub deserialized_base_theme: Mutex<Option<Box<dyn Any + Send + Sync>>>,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct ThemeMeta {
-    #[serde(skip_deserializing)]
-    pub id: usize,
-    pub name: String,
-    pub is_light: bool,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct Workspace {
-    pub background: Color,
-    pub blank_pane: BlankPaneStyle,
-    pub tab_bar: TabBar,
-    pub pane_divider: Border,
-    pub leader_border_opacity: f32,
-    pub leader_border_width: f32,
-    pub dock: Dock,
-    pub status_bar: StatusBar,
-    pub toolbar: Toolbar,
-    pub disconnected_overlay: ContainedText,
-    pub modal: ContainerStyle,
-    pub zoomed_panel_foreground: ContainerStyle,
-    pub zoomed_pane_foreground: ContainerStyle,
-    pub zoomed_background: ContainerStyle,
-    pub notification: ContainerStyle,
-    pub notifications: Notifications,
-    pub joining_project_avatar: ImageStyle,
-    pub joining_project_message: ContainedText,
-    pub external_location_message: ContainedText,
-    pub drop_target_overlay_color: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct BlankPaneStyle {
-    pub logo: SvgStyle,
-    pub logo_shadow: SvgStyle,
-    pub logo_container: ContainerStyle,
-    pub keyboard_hints: ContainerStyle,
-    pub keyboard_hint: Interactive<ContainedText>,
-    pub keyboard_hint_width: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Titlebar {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub height: f32,
-    pub menu: TitlebarMenu,
-    pub project_menu_button: Toggleable<Interactive<ContainedText>>,
-    pub git_menu_button: Toggleable<Interactive<ContainedText>>,
-    pub project_host: Interactive<ContainedText>,
-    pub item_spacing: f32,
-    pub face_pile_spacing: f32,
-    pub avatar_ribbon: AvatarRibbon,
-    pub follower_avatar_overlap: f32,
-    pub leader_selection: ContainerStyle,
-    pub offline_icon: OfflineIcon,
-    pub leader_avatar: AvatarStyle,
-    pub follower_avatar: AvatarStyle,
-    pub inactive_avatar_grayscale: bool,
-    pub sign_in_button: Toggleable<Interactive<ContainedText>>,
-    pub outdated_warning: ContainedText,
-    pub share_button: Toggleable<Interactive<ContainedText>>,
-    pub muted: Color,
-    pub speaking: Color,
-    pub screen_share_button: Toggleable<Interactive<IconButton>>,
-    pub toggle_contacts_button: Toggleable<Interactive<IconButton>>,
-    pub toggle_microphone_button: Toggleable<Interactive<IconButton>>,
-    pub toggle_speakers_button: Toggleable<Interactive<IconButton>>,
-    pub leave_call_button: Interactive<IconButton>,
-    pub toggle_contacts_badge: ContainerStyle,
-    pub user_menu: UserMenu,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct TitlebarMenu {
-    pub width: f32,
-    pub height: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct UserMenu {
-    pub user_menu_button_online: UserMenuButton,
-    pub user_menu_button_offline: UserMenuButton,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct UserMenuButton {
-    pub user_menu: Toggleable<Interactive<Icon>>,
-    pub avatar: AvatarStyle,
-    pub icon: Icon,
-}
-
-#[derive(Copy, Clone, Deserialize, Default, JsonSchema)]
-pub struct AvatarStyle {
-    #[serde(flatten)]
-    pub image: ImageStyle,
-    pub outer_width: f32,
-    pub outer_corner_radius: f32,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct Copilot {
-    pub out_link_icon: Interactive<IconStyle>,
-    pub modal: ModalStyle,
-    pub auth: CopilotAuth,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct CopilotAuth {
-    pub content_width: f32,
-    pub prompting: CopilotAuthPrompting,
-    pub not_authorized: CopilotAuthNotAuthorized,
-    pub authorized: CopilotAuthAuthorized,
-    pub cta_button: CopilotCTAButton,
-    pub header: IconStyle,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct CopilotAuthPrompting {
-    pub subheading: ContainedText,
-    pub hint: ContainedText,
-    pub device_code: DeviceCode,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct DeviceCode {
-    pub text: TextStyle,
-    pub cta: CopilotCTAButton,
-    pub left: f32,
-    pub left_container: ContainerStyle,
-    pub right: f32,
-    pub right_container: Interactive<ContainerStyle>,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct CopilotAuthNotAuthorized {
-    pub subheading: ContainedText,
-    pub warning: ContainedText,
-}
-
-#[derive(Deserialize, Default, Clone, JsonSchema)]
-pub struct CopilotAuthAuthorized {
-    pub subheading: ContainedText,
-    pub hint: ContainedText,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct CollabPanel {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub disclosure: DisclosureStyle<()>,
-    pub list_empty_state: Toggleable<Interactive<ContainedText>>,
-    pub list_empty_icon: Icon,
-    pub list_empty_label_container: ContainerStyle,
-    pub log_in_button: Interactive<ContainedText>,
-    pub channel_editor: ContainerStyle,
-    pub channel_hash: Icon,
-    pub channel_note_active_color: Color,
-    pub tabbed_modal: TabbedModal,
-    pub contact_finder: ContactFinder,
-    pub channel_modal: ChannelModal,
-    pub user_query_editor: FieldEditor,
-    pub user_query_editor_height: f32,
-    pub leave_call_button: Toggleable<Interactive<IconButton>>,
-    pub add_contact_button: Toggleable<Interactive<IconButton>>,
-    pub add_channel_button: Toggleable<Interactive<IconButton>>,
-    pub header_row: ContainedText,
-    pub dragged_over_header: ContainerStyle,
-    pub subheader_row: Toggleable<Interactive<ContainedText>>,
-    pub leave_call: Interactive<ContainedText>,
-    pub contact_row: Toggleable<Interactive<ContainerStyle>>,
-    pub channel_row: Toggleable<Interactive<ContainerStyle>>,
-    pub channel_name: Toggleable<ContainedText>,
-    pub row_height: f32,
-    pub project_row: Toggleable<Interactive<ProjectRow>>,
-    pub tree_branch: Toggleable<Interactive<TreeBranch>>,
-    pub contact_avatar: ImageStyle,
-    pub channel_avatar: ImageStyle,
-    pub extra_participant_label: ContainedText,
-    pub contact_status_free: ContainerStyle,
-    pub contact_status_busy: ContainerStyle,
-    pub contact_username: ContainedText,
-    pub contact_button: Interactive<IconButton>,
-    pub contact_button_spacing: f32,
-    pub channel_indent: f32,
-    pub disabled_button: IconButton,
-    pub section_icon_size: f32,
-    pub calling_indicator: ContainedText,
-    pub face_overlap: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ComponentTest {
-    pub button: Interactive<ButtonStyle<TextStyle>>,
-    pub toggle: Toggleable<Interactive<ButtonStyle<TextStyle>>>,
-    pub disclosure: DisclosureStyle<TextStyle>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct TabbedModal {
-    pub tab_button: Toggleable<Interactive<ContainedText>>,
-    pub modal: ContainerStyle,
-    pub header: ContainerStyle,
-    pub body: ContainerStyle,
-    pub title: ContainedText,
-    pub visibility_toggle: Interactive<ContainedText>,
-    pub channel_link: Interactive<ContainedText>,
-    pub picker: Picker,
-    pub max_height: f32,
-    pub max_width: f32,
-    pub row_height: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ChannelModal {
-    pub contact_avatar: ImageStyle,
-    pub contact_username: ContainerStyle,
-    pub remove_member_button: ContainedText,
-    pub cancel_invite_button: ContainedText,
-    pub member_icon: IconButton,
-    pub invitee_icon: IconButton,
-    pub member_tag: ContainedText,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ProjectRow {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub icon: Icon,
-    pub name: ContainedText,
-}
-
-#[derive(Deserialize, Default, Clone, Copy, JsonSchema)]
-pub struct TreeBranch {
-    pub width: f32,
-    pub color: Color,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ContactFinder {
-    pub contact_avatar: ImageStyle,
-    pub contact_username: ContainerStyle,
-    pub contact_button: IconButton,
-    pub disabled_contact_button: IconButton,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct DropdownMenu {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub header: Interactive<DropdownMenuItem>,
-    pub section_header: ContainedText,
-    pub item: Toggleable<Interactive<DropdownMenuItem>>,
-    pub row_height: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct DropdownMenuItem {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    #[serde(flatten)]
-    pub text: TextStyle,
-    pub secondary_text: Option<TextStyle>,
-    #[serde(default)]
-    pub secondary_text_spacing: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct TabBar {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub pane_button: Toggleable<Interactive<IconButton>>,
-    pub pane_button_container: ContainerStyle,
-    pub active_pane: TabStyles,
-    pub inactive_pane: TabStyles,
-    pub dragged_tab: Tab,
-    pub height: f32,
-    pub nav_button: Interactive<IconButton>,
-}
-
-impl TabBar {
-    pub fn tab_style(&self, pane_active: bool, tab_active: bool) -> &Tab {
-        let tabs = if pane_active {
-            &self.active_pane
-        } else {
-            &self.inactive_pane
-        };
-
-        if tab_active {
-            &tabs.active_tab
-        } else {
-            &tabs.inactive_tab
+mod default_colors;
+mod default_theme;
+mod one_themes;
+pub mod prelude;
+mod registry;
+mod scale;
+mod settings;
+mod styles;
+#[cfg(not(feature = "importing-themes"))]
+mod themes;
+mod user_theme;
+
+use std::sync::Arc;
+
+use ::settings::Settings;
+pub use default_colors::*;
+pub use default_theme::*;
+pub use registry::*;
+pub use scale::*;
+pub use settings::*;
+pub use styles::*;
+#[cfg(not(feature = "importing-themes"))]
+pub use themes::*;
+pub use user_theme::*;
+
+use gpui::{AppContext, Hsla, SharedString};
+use serde::Deserialize;
+
+#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
+pub enum Appearance {
+    Light,
+    Dark,
+}
+
+impl Appearance {
+    pub fn is_light(&self) -> bool {
+        match self {
+            Self::Light => true,
+            Self::Dark => false,
         }
     }
 }
 
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct TabStyles {
-    pub active_tab: Tab,
-    pub inactive_tab: Tab,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct AvatarRibbon {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub width: f32,
-    pub height: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct OfflineIcon {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub width: f32,
-    pub color: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Tab {
-    pub height: f32,
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    #[serde(flatten)]
-    pub label: LabelStyle,
-    pub description: ContainedText,
-    pub spacing: f32,
-    pub close_icon_width: f32,
-    pub type_icon_width: f32,
-    pub icon_close: Color,
-    pub icon_close_active: Color,
-    pub icon_dirty: Color,
-    pub icon_conflict: Color,
-    pub git: GitProjectStatus,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Toolbar {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub height: f32,
-    pub item_spacing: f32,
-    pub toggleable_tool: Toggleable<Interactive<IconButton>>,
-    pub toggleable_text_tool: Toggleable<Interactive<ContainedText>>,
-    pub breadcrumb_height: f32,
-    pub breadcrumbs: Interactive<ContainedText>,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Notifications {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub width: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Search {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub editor: FindEditor,
-    pub invalid_editor: ContainerStyle,
-    pub option_button_group: ContainerStyle,
-    pub include_exclude_editor: FindEditor,
-    pub invalid_include_exclude_editor: ContainerStyle,
-    pub include_exclude_inputs: ContainedText,
-    pub option_button_component: ToggleIconButtonStyle,
-    pub match_background: Color,
-    pub match_index: ContainedText,
-    pub major_results_status: TextStyle,
-    pub minor_results_status: TextStyle,
-    pub editor_icon: IconStyle,
-    pub mode_button: Toggleable<Interactive<ContainedText>>,
-    pub nav_button: Toggleable<Interactive<ContainedLabel>>,
-    pub search_bar_row_height: f32,
-    pub search_row_spacing: f32,
-    pub option_button_height: f32,
-    pub modes_container: ContainerStyle,
-    pub replace_icon: IconStyle,
-    // Used for filters and replace
-    pub option_button: Toggleable<Interactive<IconButton>>,
-    pub action_button: IconButtonStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct FindEditor {
-    #[serde(flatten)]
-    pub input: FieldEditor,
-    pub min_width: f32,
-    pub max_width: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct StatusBar {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub height: f32,
-    pub item_spacing: f32,
-    pub cursor_position: TextStyle,
-    pub vim_mode_indicator: ContainedText,
-    pub active_language: Interactive<ContainedText>,
-    pub auto_update_progress_message: TextStyle,
-    pub auto_update_done_message: TextStyle,
-    pub lsp_status: Interactive<StatusBarLspStatus>,
-    pub panel_buttons: StatusBarPanelButtons,
-    pub diagnostic_summary: Interactive<StatusBarDiagnosticSummary>,
-    pub diagnostic_message: Interactive<ContainedText>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct StatusBarPanelButtons {
-    pub group_left: ContainerStyle,
-    pub group_bottom: ContainerStyle,
-    pub group_right: ContainerStyle,
-    pub button: Toggleable<Interactive<PanelButton>>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct StatusBarDiagnosticSummary {
-    pub container_ok: ContainerStyle,
-    pub container_warning: ContainerStyle,
-    pub container_error: ContainerStyle,
-    pub text: TextStyle,
-    pub icon_color_ok: Color,
-    pub icon_color_warning: Color,
-    pub icon_color_error: Color,
-    pub height: f32,
-    pub icon_width: f32,
-    pub icon_spacing: f32,
-    pub summary_spacing: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct StatusBarLspStatus {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub height: f32,
-    pub icon_spacing: f32,
-    pub icon_color: Color,
-    pub icon_width: f32,
-    pub message: TextStyle,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct Dock {
-    pub left: ContainerStyle,
-    pub bottom: ContainerStyle,
-    pub right: ContainerStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct PanelButton {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub icon_color: Color,
-    pub icon_size: f32,
-    pub label: ContainedText,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ProjectPanel {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub entry: Toggleable<Interactive<ProjectPanelEntry>>,
-    pub dragged_entry: ProjectPanelEntry,
-    pub ignored_entry: Toggleable<Interactive<ProjectPanelEntry>>,
-    pub cut_entry: Toggleable<Interactive<ProjectPanelEntry>>,
-    pub filename_editor: FieldEditor,
-    pub indent_width: f32,
-    pub open_project_button: Interactive<ContainedText>,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct ProjectPanelEntry {
-    pub height: f32,
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub text: TextStyle,
-    pub icon_size: f32,
-    pub icon_color: Color,
-    pub chevron_color: Color,
-    pub chevron_size: f32,
-    pub icon_spacing: f32,
-    pub status: EntryStatus,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct EntryStatus {
-    pub git: GitProjectStatus,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct GitProjectStatus {
-    pub modified: Color,
-    pub inserted: Color,
-    pub conflict: Color,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct ContextMenu {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub item: Toggleable<Interactive<ContextMenuItem>>,
-    pub keystroke_margin: f32,
-    pub separator: ContainerStyle,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct ContextMenuItem {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub label: TextStyle,
-    pub keystroke: ContainedText,
-    pub icon_width: f32,
-    pub icon_spacing: f32,
-}
-
-#[derive(Debug, Deserialize, Default, JsonSchema)]
-pub struct CommandPalette {
-    pub key: Toggleable<ContainedLabel>,
-    pub keystroke_spacing: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct InviteLink {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    #[serde(flatten)]
-    pub label: LabelStyle,
-    pub icon: Icon,
-}
-
-#[derive(Deserialize, Clone, Copy, Default, JsonSchema)]
-pub struct Icon {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub color: Color,
-    pub width: f32,
-}
-
-#[derive(Deserialize, Clone, Copy, Default, JsonSchema)]
-pub struct IconButton {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub color: Color,
-    pub icon_width: f32,
-    pub button_width: f32,
-}
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+pub enum LoadThemes {
+    /// Only load the base theme.
+    ///
+    /// No user themes will be loaded.
+    JustBase,
 
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ChatPanel {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub list: ContainerStyle,
-    pub channel_select: ChannelSelect,
-    pub input_editor: FieldEditor,
-    pub avatar: AvatarStyle,
-    pub avatar_container: ContainerStyle,
-    pub rich_text: RichTextStyle,
-    pub message_sender: ContainedText,
-    pub message_timestamp: ContainedText,
-    pub message: Interactive<ContainerStyle>,
-    pub continuation_message: Interactive<ContainerStyle>,
-    pub pending_message: Interactive<ContainerStyle>,
-    pub last_message_bottom_spacing: f32,
-    pub sign_in_prompt: Interactive<TextStyle>,
-    pub icon_button: Interactive<IconButton>,
+    /// Load all of the built-in themes.
+    All,
 }
 
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct RichTextStyle {
-    pub text: TextStyle,
-    pub mention_highlight: HighlightStyle,
-    pub mention_background: Option<Color>,
-    pub self_mention_highlight: HighlightStyle,
-    pub self_mention_background: Option<Color>,
-    pub code_background: Option<Color>,
-}
+pub fn init(themes_to_load: LoadThemes, cx: &mut AppContext) {
+    cx.set_global(ThemeRegistry::default());
 
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct NotificationPanel {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub title: ContainedText,
-    pub title_icon: SvgStyle,
-    pub title_height: f32,
-    pub list: ContainerStyle,
-    pub avatar: AvatarStyle,
-    pub avatar_container: ContainerStyle,
-    pub sign_in_prompt: Interactive<TextStyle>,
-    pub icon_button: Interactive<IconButton>,
-    pub unread_text: ContainedText,
-    pub read_text: ContainedText,
-    pub timestamp: ContainedText,
-    pub button: Interactive<ContainedText>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ChannelSelect {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub header: ChannelName,
-    pub item: ChannelName,
-    pub active_item: ChannelName,
-    pub hovered_item: ChannelName,
-    pub menu: ContainerStyle,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ChannelName {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub hash: ContainedText,
-    pub name: TextStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Picker {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub empty_container: ContainerStyle,
-    pub input_editor: FieldEditor,
-    pub empty_input_editor: FieldEditor,
-    pub no_matches: ContainedLabel,
-    pub item: Toggleable<Interactive<ContainedLabel>>,
-    pub header: ContainedLabel,
-    pub footer: Interactive<ContainedLabel>,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct ContainedText {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    #[serde(flatten)]
-    pub text: TextStyle,
-}
-
-#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
-pub struct ContainedLabel {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    #[serde(flatten)]
-    pub label: LabelStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ProjectDiagnostics {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub empty_message: TextStyle,
-    pub tab_icon_width: f32,
-    pub tab_icon_spacing: f32,
-    pub tab_summary_spacing: f32,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ContactNotification {
-    pub header_avatar: ImageStyle,
-    pub header_message: ContainedText,
-    pub header_height: f32,
-    pub body_message: ContainedText,
-    pub button: Interactive<ContainedText>,
-    pub dismiss_button: Interactive<IconButton>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct UpdateNotification {
-    pub message: ContainedText,
-    pub action_message: Interactive<ContainedText>,
-    pub dismiss_button: Interactive<IconButton>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct MessageNotification {
-    pub message: ContainedText,
-    pub action_message: Interactive<ContainedText>,
-    pub dismiss_button: Interactive<IconButton>,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct ProjectSharedNotification {
-    pub window_height: f32,
-    pub window_width: f32,
-    #[serde(default)]
-    pub background: Color,
-    pub owner_container: ContainerStyle,
-    pub owner_avatar: ImageStyle,
-    pub owner_metadata: ContainerStyle,
-    pub owner_username: ContainedText,
-    pub message: ContainedText,
-    pub worktree_roots: ContainedText,
-    pub button_width: f32,
-    pub open_button: ContainedText,
-    pub dismiss_button: ContainedText,
-}
-
-#[derive(Deserialize, Default, JsonSchema)]
-pub struct IncomingCallNotification {
-    pub window_height: f32,
-    pub window_width: f32,
-    #[serde(default)]
-    pub background: Color,
-    pub caller_container: ContainerStyle,
-    pub caller_avatar: ImageStyle,
-    pub caller_metadata: ContainerStyle,
-    pub caller_username: ContainedText,
-    pub caller_message: ContainedText,
-    pub worktree_roots: ContainedText,
-    pub button_width: f32,
-    pub accept_button: ContainedText,
-    pub decline_button: ContainedText,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Editor {
-    pub text_color: Color,
-    #[serde(default)]
-    pub background: Color,
-    pub selection: SelectionStyle,
-    pub gutter_background: Color,
-    pub gutter_padding_factor: f32,
-    pub active_line_background: Color,
-    pub highlighted_line_background: Color,
-    pub rename_fade: f32,
-    pub document_highlight_read_background: Color,
-    pub document_highlight_write_background: Color,
-    pub diff: DiffStyle,
-    pub wrap_guide: Color,
-    pub active_wrap_guide: Color,
-    pub line_number: Color,
-    pub line_number_active: Color,
-    pub guest_selections: Vec<SelectionStyle>,
-    pub absent_selection: SelectionStyle,
-    pub syntax: Arc<SyntaxTheme>,
-    pub hint: HighlightStyle,
-    pub suggestion: HighlightStyle,
-    pub diagnostic_path_header: DiagnosticPathHeader,
-    pub diagnostic_header: DiagnosticHeader,
-    pub error_diagnostic: DiagnosticStyle,
-    pub invalid_error_diagnostic: DiagnosticStyle,
-    pub warning_diagnostic: DiagnosticStyle,
-    pub invalid_warning_diagnostic: DiagnosticStyle,
-    pub information_diagnostic: DiagnosticStyle,
-    pub invalid_information_diagnostic: DiagnosticStyle,
-    pub hint_diagnostic: DiagnosticStyle,
-    pub invalid_hint_diagnostic: DiagnosticStyle,
-    pub autocomplete: AutocompleteStyle,
-    pub code_actions: CodeActions,
-    pub folds: Folds,
-    pub unnecessary_code_fade: f32,
-    pub hover_popover: HoverPopover,
-    pub link_definition: HighlightStyle,
-    pub composition_mark: HighlightStyle,
-    pub jump_icon: Interactive<IconButton>,
-    pub scrollbar: Scrollbar,
-    pub whitespace: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Scrollbar {
-    pub track: ContainerStyle,
-    pub thumb: ContainerStyle,
-    pub width: f32,
-    pub min_height_factor: f32,
-    pub git: BufferGitDiffColors,
-    pub selections: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct BufferGitDiffColors {
-    pub inserted: Color,
-    pub modified: Color,
-    pub deleted: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct DiagnosticPathHeader {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub filename: ContainedText,
-    pub path: ContainedText,
-    pub text_scale_factor: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct DiagnosticHeader {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub source: ContainedLabel,
-    pub message: ContainedLabel,
-    pub code: ContainedText,
-    pub text_scale_factor: f32,
-    pub icon_width_factor: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct DiagnosticStyle {
-    pub message: LabelStyle,
-    #[serde(default)]
-    pub header: ContainerStyle,
-    pub text_scale_factor: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct AutocompleteStyle {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub item: ContainerStyle,
-    pub selected_item: ContainerStyle,
-    pub hovered_item: ContainerStyle,
-    pub match_highlight: HighlightStyle,
-    pub completion_min_width: f32,
-    pub completion_max_width: f32,
-    pub inline_docs_container: ContainerStyle,
-    pub inline_docs_color: Color,
-    pub inline_docs_size_percent: f32,
-    pub alongside_docs_max_width: f32,
-    pub alongside_docs_container: ContainerStyle,
-}
-
-#[derive(Clone, Copy, Default, Deserialize, JsonSchema)]
-pub struct SelectionStyle {
-    pub cursor: Color,
-    pub selection: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct FieldEditor {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub text: TextStyle,
-    #[serde(default)]
-    pub placeholder_text: Option<TextStyle>,
-    pub selection: SelectionStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct InteractiveColor {
-    pub color: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct CodeActions {
-    #[serde(default)]
-    pub indicator: Toggleable<Interactive<InteractiveColor>>,
-    pub vertical_scale: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Folds {
-    pub indicator: Toggleable<Interactive<InteractiveColor>>,
-    pub ellipses: FoldEllipses,
-    pub fold_background: Color,
-    pub icon_margin_scale: f32,
-    pub folded_icon: String,
-    pub foldable_icon: String,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct FoldEllipses {
-    pub text_color: Color,
-    pub background: Interactive<InteractiveColor>,
-    pub corner_radius_factor: f32,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct DiffStyle {
-    pub inserted: Color,
-    pub modified: Color,
-    pub deleted: Color,
-    pub removed_width_em: f32,
-    pub width_em: f32,
-    pub corner_radius: f32,
-}
-
-#[derive(Debug, Default, Clone, Copy, JsonSchema)]
-pub struct Interactive<T> {
-    pub default: T,
-    pub hovered: Option<T>,
-    pub clicked: Option<T>,
-    pub disabled: Option<T>,
-}
-
-impl<T> Deref for Interactive<T> {
-    type Target = T;
-
-    fn deref(&self) -> &Self::Target {
-        &self.default
+    match themes_to_load {
+        LoadThemes::JustBase => (),
+        LoadThemes::All => cx.global_mut::<ThemeRegistry>().load_user_themes(),
     }
-}
 
-impl Interactive<()> {
-    pub fn new_blank() -> Self {
-        Self {
-            default: (),
-            hovered: None,
-            clicked: None,
-            disabled: None,
-        }
-    }
+    ThemeSettings::register(cx);
 }
 
-#[derive(Clone, Copy, Debug, Default, Deserialize, JsonSchema)]
-pub struct Toggleable<T> {
-    active: T,
-    inactive: T,
+pub trait ActiveTheme {
+    fn theme(&self) -> &Arc<Theme>;
 }
 
-impl<T> Deref for Toggleable<T> {
-    type Target = T;
-
-    fn deref(&self) -> &Self::Target {
-        &self.inactive
+impl ActiveTheme for AppContext {
+    fn theme(&self) -> &Arc<Theme> {
+        &ThemeSettings::get_global(self).active_theme
     }
 }
 
-impl Toggleable<()> {
-    pub fn new_blank() -> Self {
-        Self {
-            active: (),
-            inactive: (),
-        }
-    }
+// todo!()
+// impl<'a> ActiveTheme for WindowContext<'a> {
+//     fn theme(&self) -> &Arc<Theme> {
+//         &ThemeSettings::get_global(self.app()).active_theme
+//     }
+// }
+
+pub struct ThemeFamily {
+    pub id: String,
+    pub name: SharedString,
+    pub author: SharedString,
+    pub themes: Vec<Theme>,
+    pub scales: ColorScales,
 }
 
-impl<T> Toggleable<T> {
-    pub fn new(active: T, inactive: T) -> Self {
-        Self { active, inactive }
-    }
-    pub fn in_state(&self, active: bool) -> &T {
-        if active {
-            &self.active
-        } else {
-            &self.inactive
-        }
-    }
-    pub fn active_state(&self) -> &T {
-        self.in_state(true)
-    }
+impl ThemeFamily {}
 
-    pub fn inactive_state(&self) -> &T {
-        self.in_state(false)
-    }
+pub struct Theme {
+    pub id: String,
+    pub name: SharedString,
+    pub appearance: Appearance,
+    pub styles: ThemeStyles,
 }
 
-impl<T> Interactive<T> {
-    pub fn style_for(&self, state: &mut MouseState) -> &T {
-        if state.clicked() == Some(platform::MouseButton::Left) && self.clicked.is_some() {
-            self.clicked.as_ref().unwrap()
-        } else if state.hovered() {
-            self.hovered.as_ref().unwrap_or(&self.default)
-        } else {
-            &self.default
-        }
-    }
-    pub fn disabled_style(&self) -> &T {
-        self.disabled.as_ref().unwrap_or(&self.default)
+impl Theme {
+    /// Returns the [`SystemColors`] for the theme.
+    #[inline(always)]
+    pub fn system(&self) -> &SystemColors {
+        &self.styles.system
     }
-}
 
-impl<T> Toggleable<Interactive<T>> {
-    pub fn style_for(&self, active: bool, state: &mut MouseState) -> &T {
-        self.in_state(active).style_for(state)
+    /// Returns the [`PlayerColors`] for the theme.
+    #[inline(always)]
+    pub fn players(&self) -> &PlayerColors {
+        &self.styles.player
     }
 
-    pub fn default_style(&self) -> &T {
-        &self.inactive.default
+    /// Returns the [`ThemeColors`] for the theme.
+    #[inline(always)]
+    pub fn colors(&self) -> &ThemeColors {
+        &self.styles.colors
     }
-}
-
-impl<'de, T: DeserializeOwned> Deserialize<'de> for Interactive<T> {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: serde::Deserializer<'de>,
-    {
-        #[derive(Deserialize)]
-        struct Helper {
-            default: Value,
-            hovered: Option<Value>,
-            clicked: Option<Value>,
-            disabled: Option<Value>,
-        }
-
-        let json = Helper::deserialize(deserializer)?;
-
-        let deserialize_state = |state_json: Option<Value>| -> Result<Option<T>, D::Error> {
-            if let Some(mut state_json) = state_json {
-                if let Value::Object(state_json) = &mut state_json {
-                    if let Value::Object(default) = &json.default {
-                        for (key, value) in default {
-                            if !state_json.contains_key(key) {
-                                state_json.insert(key.clone(), value.clone());
-                            }
-                        }
-                    }
-                }
-                Ok(Some(
-                    serde_json::from_value::<T>(state_json).map_err(serde::de::Error::custom)?,
-                ))
-            } else {
-                Ok(None)
-            }
-        };
-
-        let hovered = deserialize_state(json.hovered)?;
-        let clicked = deserialize_state(json.clicked)?;
-        let disabled = deserialize_state(json.disabled)?;
-        let default = serde_json::from_value(json.default).map_err(serde::de::Error::custom)?;
 
-        Ok(Interactive {
-            default,
-            hovered,
-            clicked,
-            disabled,
-        })
+    /// Returns the [`SyntaxTheme`] for the theme.
+    #[inline(always)]
+    pub fn syntax(&self) -> &Arc<SyntaxTheme> {
+        &self.styles.syntax
     }
-}
 
-impl Editor {
-    pub fn selection_style_for_room_participant(&self, participant_index: u32) -> SelectionStyle {
-        if self.guest_selections.is_empty() {
-            return SelectionStyle::default();
-        }
-        let style_ix = participant_index as usize % self.guest_selections.len();
-        self.guest_selections[style_ix]
+    /// Returns the [`StatusColors`] for the theme.
+    #[inline(always)]
+    pub fn status(&self) -> &StatusColors {
+        &self.styles.status
     }
-}
 
-#[derive(Default, JsonSchema)]
-pub struct SyntaxTheme {
-    pub highlights: Vec<(String, HighlightStyle)>,
-}
-
-impl SyntaxTheme {
-    pub fn new(highlights: Vec<(String, HighlightStyle)>) -> Self {
-        Self { highlights }
+    /// Returns the color for the syntax node with the given name.
+    #[inline(always)]
+    pub fn syntax_color(&self, name: &str) -> Hsla {
+        self.syntax().color(name)
     }
-}
-
-impl<'de> Deserialize<'de> for SyntaxTheme {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: serde::Deserializer<'de>,
-    {
-        let syntax_data: HashMap<String, HighlightStyle> = Deserialize::deserialize(deserializer)?;
 
-        let mut result = Self::new(Vec::new());
-        for (key, style) in syntax_data {
-            match result
-                .highlights
-                .binary_search_by(|(needle, _)| needle.cmp(&key))
-            {
-                Ok(i) | Err(i) => {
-                    result.highlights.insert(i, (key, style));
-                }
-            }
-        }
-
-        Ok(result)
+    /// Returns the [`Appearance`] for the theme.
+    #[inline(always)]
+    pub fn appearance(&self) -> Appearance {
+        self.appearance
     }
 }
 
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct HoverPopover {
-    pub container: ContainerStyle,
-    pub info_container: ContainerStyle,
-    pub warning_container: ContainerStyle,
-    pub error_container: ContainerStyle,
-    pub block_style: ContainerStyle,
-    pub prose: TextStyle,
-    pub diagnostic_source_highlight: HighlightStyle,
-    pub highlight: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct TerminalStyle {
-    pub black: Color,
-    pub red: Color,
-    pub green: Color,
-    pub yellow: Color,
-    pub blue: Color,
-    pub magenta: Color,
-    pub cyan: Color,
-    pub white: Color,
-    pub bright_black: Color,
-    pub bright_red: Color,
-    pub bright_green: Color,
-    pub bright_yellow: Color,
-    pub bright_blue: Color,
-    pub bright_magenta: Color,
-    pub bright_cyan: Color,
-    pub bright_white: Color,
-    pub foreground: Color,
-    pub background: Color,
-    pub modal_background: Color,
-    pub cursor: Color,
-    pub dim_black: Color,
-    pub dim_red: Color,
-    pub dim_green: Color,
-    pub dim_yellow: Color,
-    pub dim_blue: Color,
-    pub dim_magenta: Color,
-    pub dim_cyan: Color,
-    pub dim_white: Color,
-    pub bright_foreground: Color,
-    pub dim_foreground: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct AssistantStyle {
-    pub container: ContainerStyle,
-    pub hamburger_button: Interactive<IconStyle>,
-    pub split_button: Interactive<IconStyle>,
-    pub assist_button: Interactive<IconStyle>,
-    pub quote_button: Interactive<IconStyle>,
-    pub zoom_in_button: Interactive<IconStyle>,
-    pub zoom_out_button: Interactive<IconStyle>,
-    pub plus_button: Interactive<IconStyle>,
-    pub title: ContainedText,
-    pub message_header: ContainerStyle,
-    pub sent_at: ContainedText,
-    pub user_sender: Interactive<ContainedText>,
-    pub assistant_sender: Interactive<ContainedText>,
-    pub system_sender: Interactive<ContainedText>,
-    pub model: Interactive<ContainedText>,
-    pub remaining_tokens: ContainedText,
-    pub low_remaining_tokens: ContainedText,
-    pub no_remaining_tokens: ContainedText,
-    pub error_icon: Icon,
-    pub api_key_editor: FieldEditor,
-    pub api_key_prompt: ContainedText,
-    pub saved_conversation: SavedConversation,
-    pub inline: InlineAssistantStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct InlineAssistantStyle {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub editor: FieldEditor,
-    pub disabled_editor: FieldEditor,
-    pub pending_edit_background: Color,
-    pub include_conversation: ToggleIconButtonStyle,
-    pub retrieve_context: ToggleIconButtonStyle,
-    pub context_status: ContextStatusStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ContextStatusStyle {
-    pub error_icon: Icon,
-    pub in_progress_icon: Icon,
-    pub complete_icon: Icon,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Contained<T> {
-    container: ContainerStyle,
-    contained: T,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct SavedConversation {
-    pub container: Interactive<ContainerStyle>,
-    pub saved_at: ContainedText,
-    pub title: ContainedText,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct FeedbackStyle {
-    pub submit_button: Interactive<ContainedText>,
-    pub button_margin: f32,
-    pub info_text_default: ContainedText,
-    pub link_text_default: ContainedText,
-    pub link_text_hover: ContainedText,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct WelcomeStyle {
-    pub page_width: f32,
-    pub logo: SvgStyle,
-    pub logo_subheading: ContainedText,
-    pub usage_note: ContainedText,
-    pub checkbox: CheckboxStyle,
-    pub checkbox_container: ContainerStyle,
-    pub button: Interactive<ContainedText>,
-    pub button_group: ContainerStyle,
-    pub heading_group: ContainerStyle,
-    pub checkbox_group: ContainerStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ColorScheme {
-    pub name: String,
-    pub is_light: bool,
-    pub lowest: Layer,
-    pub middle: Layer,
-    pub highest: Layer,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Player {
-    pub cursor: Color,
-    pub selection: Color,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct RampSet {
-    pub neutral: Vec<Color>,
-    pub red: Vec<Color>,
-    pub orange: Vec<Color>,
-    pub yellow: Vec<Color>,
-    pub green: Vec<Color>,
-    pub cyan: Vec<Color>,
-    pub blue: Vec<Color>,
-    pub violet: Vec<Color>,
-    pub magenta: Vec<Color>,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Layer {
-    pub base: StyleSet,
-    pub variant: StyleSet,
-    pub on: StyleSet,
-    pub accent: StyleSet,
-    pub positive: StyleSet,
-    pub warning: StyleSet,
-    pub negative: StyleSet,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct StyleSet {
-    pub default: Style,
-    pub active: Style,
-    pub disabled: Style,
-    pub hovered: Style,
-    pub pressed: Style,
-    pub inverted: Style,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct Style {
-    pub background: Color,
-    pub border: Color,
-    pub foreground: Color,
+pub fn color_alpha(color: Hsla, alpha: f32) -> Hsla {
+    let mut color = color;
+    color.a = alpha;
+    color
 }

crates/theme/src/theme_registry.rs 🔗

@@ -1,106 +0,0 @@
-use crate::{Theme, ThemeMeta};
-use anyhow::{Context, Result};
-use gpui::{fonts, AssetSource, FontCache};
-use parking_lot::Mutex;
-use serde::Deserialize;
-use serde_json::Value;
-use std::{
-    borrow::Cow,
-    collections::HashMap,
-    sync::{
-        atomic::{AtomicUsize, Ordering::SeqCst},
-        Arc,
-    },
-};
-
-pub struct ThemeRegistry {
-    assets: Box<dyn AssetSource>,
-    themes: Mutex<HashMap<String, Arc<Theme>>>,
-    theme_data: Mutex<HashMap<String, Arc<Value>>>,
-    font_cache: Arc<FontCache>,
-    next_theme_id: AtomicUsize,
-}
-
-impl ThemeRegistry {
-    pub fn new(source: impl AssetSource, font_cache: Arc<FontCache>) -> Arc<Self> {
-        let this = Arc::new(Self {
-            assets: Box::new(source),
-            themes: Default::default(),
-            theme_data: Default::default(),
-            next_theme_id: Default::default(),
-            font_cache,
-        });
-
-        this.themes.lock().insert(
-            settings::EMPTY_THEME_NAME.to_string(),
-            gpui::fonts::with_font_cache(this.font_cache.clone(), || {
-                let mut theme = Theme::default();
-                theme.meta.id = this.next_theme_id.fetch_add(1, SeqCst);
-                theme.meta.name = settings::EMPTY_THEME_NAME.into();
-                Arc::new(theme)
-            }),
-        );
-
-        this
-    }
-
-    pub fn list_names(&self, staff: bool) -> impl Iterator<Item = Cow<str>> + '_ {
-        let mut dirs = self.assets.list("themes/");
-
-        if !staff {
-            dirs = dirs
-                .into_iter()
-                .filter(|path| !path.starts_with("themes/staff"))
-                .collect()
-        }
-
-        fn get_name(path: &str) -> Option<&str> {
-            path.strip_prefix("themes/")?.strip_suffix(".json")
-        }
-
-        dirs.into_iter().filter_map(|path| match path {
-            Cow::Borrowed(path) => Some(Cow::Borrowed(get_name(path)?)),
-            Cow::Owned(path) => Some(Cow::Owned(get_name(&path)?.to_string())),
-        })
-    }
-
-    pub fn list(&self, staff: bool) -> impl Iterator<Item = ThemeMeta> + '_ {
-        self.list_names(staff).filter_map(|theme_name| {
-            self.get(theme_name.as_ref())
-                .ok()
-                .map(|theme| theme.meta.clone())
-        })
-    }
-
-    pub fn clear(&self) {
-        self.theme_data.lock().clear();
-        self.themes.lock().clear();
-    }
-
-    pub fn get(&self, name: &str) -> Result<Arc<Theme>> {
-        if let Some(theme) = self.themes.lock().get(name) {
-            return Ok(theme.clone());
-        }
-
-        let asset_path = format!("themes/{}.json", name);
-        let theme_json = self
-            .assets
-            .load(&asset_path)
-            .with_context(|| format!("failed to load theme file {}", asset_path))?;
-
-        // Allocate into the heap directly, the Theme struct is too large to fit in the stack.
-        let mut theme = fonts::with_font_cache(self.font_cache.clone(), || {
-            let mut theme = Box::new(Theme::default());
-            let mut deserializer = serde_json::Deserializer::from_slice(&theme_json);
-            let result = Theme::deserialize_in_place(&mut deserializer, &mut theme);
-            result.map(|_| theme)
-        })?;
-
-        // Reset name to be the file path, so that we can use it to access the stored themes
-        theme.meta.name = name.into();
-        theme.meta.id = self.next_theme_id.fetch_add(1, SeqCst);
-        let theme: Arc<Theme> = theme.into();
-        self.themes.lock().insert(name.to_string(), theme.clone());
-        Ok(theme)
-    }
-}

crates/theme/src/theme_settings.rs 🔗

@@ -1,214 +0,0 @@
-use crate::{Theme, ThemeRegistry};
-use anyhow::Result;
-use gpui::{font_cache::FamilyId, fonts, AppContext};
-use schemars::{
-    gen::SchemaGenerator,
-    schema::{InstanceType, Schema, SchemaObject},
-    JsonSchema,
-};
-use serde::{Deserialize, Serialize};
-use serde_json::Value;
-use settings::SettingsJsonSchemaParams;
-use std::sync::Arc;
-use util::ResultExt as _;
-
-const MIN_FONT_SIZE: f32 = 6.0;
-const MIN_LINE_HEIGHT: f32 = 1.0;
-
-#[derive(Clone, JsonSchema)]
-pub struct ThemeSettings {
-    pub buffer_font_family_name: String,
-    pub buffer_font_features: fonts::Features,
-    pub buffer_font_family: FamilyId,
-    pub(crate) buffer_font_size: f32,
-    pub(crate) buffer_line_height: BufferLineHeight,
-    #[serde(skip)]
-    pub theme: Arc<Theme>,
-}
-
-pub struct AdjustedBufferFontSize(pub f32);
-
-#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
-pub struct ThemeSettingsContent {
-    #[serde(default)]
-    pub buffer_font_family: Option<String>,
-    #[serde(default)]
-    pub buffer_font_size: Option<f32>,
-    #[serde(default)]
-    pub buffer_line_height: Option<BufferLineHeight>,
-    #[serde(default)]
-    pub buffer_font_features: Option<fonts::Features>,
-    #[serde(default)]
-    pub theme: Option<String>,
-}
-
-#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, JsonSchema, Default)]
-#[serde(rename_all = "snake_case")]
-pub enum BufferLineHeight {
-    #[default]
-    Comfortable,
-    Standard,
-    Custom(f32),
-}
-
-impl BufferLineHeight {
-    pub fn value(&self) -> f32 {
-        match self {
-            BufferLineHeight::Comfortable => 1.618,
-            BufferLineHeight::Standard => 1.3,
-            BufferLineHeight::Custom(line_height) => *line_height,
-        }
-    }
-}
-
-impl ThemeSettings {
-    pub fn buffer_font_size(&self, cx: &AppContext) -> f32 {
-        if cx.has_global::<AdjustedBufferFontSize>() {
-            cx.global::<AdjustedBufferFontSize>().0
-        } else {
-            self.buffer_font_size
-        }
-        .max(MIN_FONT_SIZE)
-    }
-
-    pub fn line_height(&self) -> f32 {
-        f32::max(self.buffer_line_height.value(), MIN_LINE_HEIGHT)
-    }
-}
-
-pub fn adjusted_font_size(size: f32, cx: &AppContext) -> f32 {
-    if cx.has_global::<AdjustedBufferFontSize>() {
-        let buffer_font_size = settings::get::<ThemeSettings>(cx).buffer_font_size;
-        let delta = cx.global::<AdjustedBufferFontSize>().0 - buffer_font_size;
-        size + delta
-    } else {
-        size
-    }
-    .max(MIN_FONT_SIZE)
-}
-
-pub fn adjust_font_size(cx: &mut AppContext, f: fn(&mut f32)) {
-    if !cx.has_global::<AdjustedBufferFontSize>() {
-        let buffer_font_size = settings::get::<ThemeSettings>(cx).buffer_font_size;
-        cx.set_global(AdjustedBufferFontSize(buffer_font_size));
-    }
-
-    cx.update_global::<AdjustedBufferFontSize, _, _>(|delta, cx| {
-        f(&mut delta.0);
-        delta.0 = delta
-            .0
-            .max(MIN_FONT_SIZE - settings::get::<ThemeSettings>(cx).buffer_font_size);
-    });
-    cx.refresh_windows();
-}
-
-pub fn reset_font_size(cx: &mut AppContext) {
-    if cx.has_global::<AdjustedBufferFontSize>() {
-        cx.remove_global::<AdjustedBufferFontSize>();
-        cx.refresh_windows();
-    }
-}
-
-impl settings::Setting for ThemeSettings {
-    const KEY: Option<&'static str> = None;
-
-    type FileContent = ThemeSettingsContent;
-
-    fn load(
-        defaults: &Self::FileContent,
-        user_values: &[&Self::FileContent],
-        cx: &AppContext,
-    ) -> Result<Self> {
-        let buffer_font_features = defaults.buffer_font_features.clone().unwrap();
-        let themes = cx.global::<Arc<ThemeRegistry>>();
-
-        let mut this = Self {
-            buffer_font_family: cx
-                .font_cache()
-                .load_family(
-                    &[defaults.buffer_font_family.as_ref().unwrap()],
-                    &buffer_font_features,
-                )
-                .unwrap(),
-            buffer_font_family_name: defaults.buffer_font_family.clone().unwrap(),
-            buffer_font_features,
-            buffer_font_size: defaults.buffer_font_size.unwrap(),
-            buffer_line_height: defaults.buffer_line_height.unwrap(),
-            theme: themes.get(defaults.theme.as_ref().unwrap()).unwrap(),
-        };
-
-        for value in user_values.into_iter().copied().cloned() {
-            let font_cache = cx.font_cache();
-            let mut family_changed = false;
-            if let Some(value) = value.buffer_font_family {
-                this.buffer_font_family_name = value;
-                family_changed = true;
-            }
-            if let Some(value) = value.buffer_font_features {
-                this.buffer_font_features = value;
-                family_changed = true;
-            }
-            if family_changed {
-                if let Some(id) = font_cache
-                    .load_family(&[&this.buffer_font_family_name], &this.buffer_font_features)
-                    .log_err()
-                {
-                    this.buffer_font_family = id;
-                }
-            }
-
-            if let Some(value) = &value.theme {
-                if let Some(theme) = themes.get(value).log_err() {
-                    this.theme = theme;
-                }
-            }
-
-            merge(&mut this.buffer_font_size, value.buffer_font_size);
-            merge(&mut this.buffer_line_height, value.buffer_line_height);
-        }
-
-        Ok(this)
-    }
-
-    fn json_schema(
-        generator: &mut SchemaGenerator,
-        params: &SettingsJsonSchemaParams,
-        cx: &AppContext,
-    ) -> schemars::schema::RootSchema {
-        let mut root_schema = generator.root_schema_for::<ThemeSettingsContent>();
-        let theme_names = cx
-            .global::<Arc<ThemeRegistry>>()
-            .list_names(params.staff_mode)
-            .map(|theme_name| Value::String(theme_name.to_string()))
-            .collect();
-
-        let theme_name_schema = SchemaObject {
-            instance_type: Some(InstanceType::String.into()),
-            enum_values: Some(theme_names),
-            ..Default::default()
-        };
-
-        root_schema
-            .definitions
-            .extend([("ThemeName".into(), theme_name_schema.into())]);
-
-        root_schema
-            .schema
-            .object
-            .as_mut()
-            .unwrap()
-            .properties
-            .extend([(
-                "theme".to_owned(),
-                Schema::new_ref("#/definitions/ThemeName".into()),
-            )]);
-
-        root_schema
-    }
-}
-
-fn merge<T: Copy>(target: &mut T, value: Option<T>) {
-    if let Some(value) = value {
-        *target = value;
-    }
-}

crates/theme/src/ui.rs 🔗

@@ -1,244 +0,0 @@
-use std::borrow::Cow;
-
-use gpui::{
-    elements::{
-        ConstrainedBox, Container, ContainerStyle, Dimensions, Empty, Flex, KeystrokeLabel, Label,
-        MouseEventHandler, ParentElement, Stack, Svg, SvgStyle,
-    },
-    fonts::TextStyle,
-    geometry::vector::Vector2F,
-    platform,
-    platform::MouseButton,
-    scene::MouseClick,
-    Action, Element, EventContext, MouseState, ViewContext,
-};
-use schemars::JsonSchema;
-use serde::Deserialize;
-
-use crate::{ContainedText, Interactive};
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct CheckboxStyle {
-    pub icon: SvgStyle,
-    pub label: ContainedText,
-    pub default: ContainerStyle,
-    pub checked: ContainerStyle,
-    pub hovered: ContainerStyle,
-    pub hovered_and_checked: ContainerStyle,
-}
-
-pub fn checkbox<Tag, V, F>(
-    label: &'static str,
-    style: &CheckboxStyle,
-    checked: bool,
-    id: usize,
-    cx: &mut ViewContext<V>,
-    change: F,
-) -> MouseEventHandler<V>
-where
-    Tag: 'static,
-    V: 'static,
-    F: 'static + Fn(&mut V, bool, &mut EventContext<V>),
-{
-    let label = Label::new(label, style.label.text.clone())
-        .contained()
-        .with_style(style.label.container);
-    checkbox_with_label::<Tag, _, _, _>(label, style, checked, id, cx, change)
-}
-
-pub fn checkbox_with_label<Tag, D, V, F>(
-    label: D,
-    style: &CheckboxStyle,
-    checked: bool,
-    id: usize,
-    cx: &mut ViewContext<V>,
-    change: F,
-) -> MouseEventHandler<V>
-where
-    Tag: 'static,
-    D: Element<V>,
-    V: 'static,
-    F: 'static + Fn(&mut V, bool, &mut EventContext<V>),
-{
-    MouseEventHandler::new::<Tag, _>(id, cx, |state, _| {
-        let indicator = if checked {
-            svg(&style.icon)
-        } else {
-            Empty::new()
-                .constrained()
-                .with_width(style.icon.dimensions.width)
-                .with_height(style.icon.dimensions.height)
-        };
-
-        Flex::row()
-            .with_child(indicator.contained().with_style(if checked {
-                if state.hovered() {
-                    style.hovered_and_checked
-                } else {
-                    style.checked
-                }
-            } else {
-                if state.hovered() {
-                    style.hovered
-                } else {
-                    style.default
-                }
-            }))
-            .with_child(label)
-            .align_children_center()
-    })
-    .on_click(platform::MouseButton::Left, move |_, view, cx| {
-        change(view, !checked, cx)
-    })
-    .with_cursor_style(platform::CursorStyle::PointingHand)
-}
-
-pub fn svg<V: 'static>(style: &SvgStyle) -> ConstrainedBox<V> {
-    Svg::new(style.asset.clone())
-        .with_color(style.color)
-        .constrained()
-        .with_width(style.dimensions.width)
-        .with_height(style.dimensions.height)
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct IconStyle {
-    pub icon: SvgStyle,
-    pub container: ContainerStyle,
-}
-
-impl IconStyle {
-    pub fn width(&self) -> f32 {
-        self.icon.dimensions.width
-            + self.container.padding.left
-            + self.container.padding.right
-            + self.container.margin.left
-            + self.container.margin.right
-    }
-}
-
-pub fn icon<V: 'static>(style: &IconStyle) -> Container<V> {
-    svg(&style.icon).contained().with_style(style.container)
-}
-
-pub fn keystroke_label<V: 'static>(
-    label_text: &'static str,
-    label_style: &ContainedText,
-    keystroke_style: &ContainedText,
-    action: Box<dyn Action>,
-    cx: &mut ViewContext<V>,
-) -> Container<V> {
-    // FIXME: Put the theme in it's own global so we can
-    // query the keystroke style on our own
-    Flex::row()
-        .with_child(Label::new(label_text, label_style.text.clone()).contained())
-        .with_child(
-            KeystrokeLabel::new(
-                cx.view_id(),
-                action,
-                keystroke_style.container,
-                keystroke_style.text.clone(),
-            )
-            .flex_float(),
-        )
-        .contained()
-        .with_style(label_style.container)
-}
-
-pub type CopilotCTAButton = Interactive<ContainedText>;
-
-pub fn cta_button<Tag, L, V, F>(
-    label: L,
-    max_width: f32,
-    style: &CopilotCTAButton,
-    cx: &mut ViewContext<V>,
-    f: F,
-) -> MouseEventHandler<V>
-where
-    Tag: 'static,
-    L: Into<Cow<'static, str>>,
-    V: 'static,
-    F: Fn(MouseClick, &mut V, &mut EventContext<V>) + 'static,
-{
-    MouseEventHandler::new::<Tag, _>(0, cx, |state, _| {
-        let style = style.style_for(state);
-        Label::new(label, style.text.to_owned())
-            .aligned()
-            .contained()
-            .with_style(style.container)
-            .constrained()
-            .with_max_width(max_width)
-    })
-    .on_click(MouseButton::Left, f)
-    .with_cursor_style(platform::CursorStyle::PointingHand)
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ModalStyle {
-    close_icon: Interactive<IconStyle>,
-    container: ContainerStyle,
-    titlebar: ContainerStyle,
-    title_text: Interactive<TextStyle>,
-    dimensions: Dimensions,
-}
-
-impl ModalStyle {
-    pub fn dimensions(&self) -> Vector2F {
-        self.dimensions.to_vec()
-    }
-}
-
-pub fn modal<Tag, V, I, D, F>(
-    title: I,
-    style: &ModalStyle,
-    cx: &mut ViewContext<V>,
-    build_modal: F,
-) -> impl Element<V>
-where
-    Tag: 'static,
-    I: Into<Cow<'static, str>>,
-    D: Element<V>,
-    V: 'static,
-    F: FnOnce(&mut gpui::ViewContext<V>) -> D,
-{
-    const TITLEBAR_HEIGHT: f32 = 28.;
-
-    Flex::column()
-        .with_child(
-            Stack::new()
-                .with_child(Label::new(
-                    title,
-                    style
-                        .title_text
-                        .style_for(&mut MouseState::default())
-                        .clone(),
-                ))
-                .with_child(
-                    // FIXME: Get a better tag type
-                    MouseEventHandler::new::<Tag, _>(999999, cx, |state, _cx| {
-                        let style = style.close_icon.style_for(state);
-                        icon(style)
-                    })
-                    .on_click(platform::MouseButton::Left, move |_, _, cx| {
-                        cx.remove_window();
-                    })
-                    .with_cursor_style(platform::CursorStyle::PointingHand)
-                    .aligned()
-                    .right(),
-                )
-                .contained()
-                .with_style(style.titlebar)
-                .constrained()
-                .with_height(TITLEBAR_HEIGHT),
-        )
-        .with_child(
-            build_modal(cx)
-                .contained()
-                .with_style(style.container)
-                .constrained()
-                .with_width(style.dimensions().x())
-                .with_height(style.dimensions().y() - TITLEBAR_HEIGHT),
-        )
-        .constrained()
-        .with_height(style.dimensions().y())
-}

crates/theme2/Cargo.toml 🔗

@@ -1,42 +0,0 @@
-[package]
-name = "theme2"
-version = "0.1.0"
-edition = "2021"
-publish = false
-
-[features]
-default = []
-importing-themes = []
-stories = ["dep:itertools", "dep:story"]
-test-support = [
-    "gpui/test-support",
-    "fs/test-support",
-    "settings/test-support"
-]
-
-[lib]
-path = "src/theme2.rs"
-doctest = false
-
-[dependencies]
-anyhow.workspace = true
-fs = { path = "../fs" }
-gpui = { package = "gpui2", path = "../gpui2" }
-indexmap = "1.6.2"
-parking_lot.workspace = true
-refineable.workspace = true
-schemars.workspace = true
-serde.workspace = true
-serde_derive.workspace = true
-serde_json.workspace = true
-settings = { path = "../settings" }
-story = { path = "../story", optional = true }
-toml.workspace = true
-uuid.workspace = true
-util = { path = "../util" }
-itertools = { version = "0.11.0", optional = true }
-
-[dev-dependencies]
-gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
-fs = { path = "../fs", features = ["test-support"] }
-settings = { path = "../settings", features = ["test-support"] }

crates/theme2/src/theme2.rs 🔗

@@ -1,148 +0,0 @@
-mod default_colors;
-mod default_theme;
-mod one_themes;
-pub mod prelude;
-mod registry;
-mod scale;
-mod settings;
-mod styles;
-#[cfg(not(feature = "importing-themes"))]
-mod themes;
-mod user_theme;
-
-use std::sync::Arc;
-
-use ::settings::Settings;
-pub use default_colors::*;
-pub use default_theme::*;
-pub use registry::*;
-pub use scale::*;
-pub use settings::*;
-pub use styles::*;
-#[cfg(not(feature = "importing-themes"))]
-pub use themes::*;
-pub use user_theme::*;
-
-use gpui::{AppContext, Hsla, SharedString};
-use serde::Deserialize;
-
-#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
-pub enum Appearance {
-    Light,
-    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.
-    ///
-    /// No user themes will be loaded.
-    JustBase,
-
-    /// Load all of the built-in themes.
-    All,
-}
-
-pub fn init(themes_to_load: LoadThemes, cx: &mut AppContext) {
-    cx.set_global(ThemeRegistry::default());
-
-    match themes_to_load {
-        LoadThemes::JustBase => (),
-        LoadThemes::All => cx.global_mut::<ThemeRegistry>().load_user_themes(),
-    }
-
-    ThemeSettings::register(cx);
-}
-
-pub trait ActiveTheme {
-    fn theme(&self) -> &Arc<Theme>;
-}
-
-impl ActiveTheme for AppContext {
-    fn theme(&self) -> &Arc<Theme> {
-        &ThemeSettings::get_global(self).active_theme
-    }
-}
-
-// todo!()
-// impl<'a> ActiveTheme for WindowContext<'a> {
-//     fn theme(&self) -> &Arc<Theme> {
-//         &ThemeSettings::get_global(self.app()).active_theme
-//     }
-// }
-
-pub struct ThemeFamily {
-    pub id: String,
-    pub name: SharedString,
-    pub author: SharedString,
-    pub themes: Vec<Theme>,
-    pub scales: ColorScales,
-}
-
-impl ThemeFamily {}
-
-pub struct Theme {
-    pub id: String,
-    pub name: SharedString,
-    pub appearance: Appearance,
-    pub styles: ThemeStyles,
-}
-
-impl Theme {
-    /// Returns the [`SystemColors`] for the theme.
-    #[inline(always)]
-    pub fn system(&self) -> &SystemColors {
-        &self.styles.system
-    }
-
-    /// Returns the [`PlayerColors`] for the theme.
-    #[inline(always)]
-    pub fn players(&self) -> &PlayerColors {
-        &self.styles.player
-    }
-
-    /// Returns the [`ThemeColors`] for the theme.
-    #[inline(always)]
-    pub fn colors(&self) -> &ThemeColors {
-        &self.styles.colors
-    }
-
-    /// Returns the [`SyntaxTheme`] for the theme.
-    #[inline(always)]
-    pub fn syntax(&self) -> &Arc<SyntaxTheme> {
-        &self.styles.syntax
-    }
-
-    /// Returns the [`StatusColors`] for the theme.
-    #[inline(always)]
-    pub fn status(&self) -> &StatusColors {
-        &self.styles.status
-    }
-
-    /// Returns the color for the syntax node with the given name.
-    #[inline(always)]
-    pub fn syntax_color(&self, name: &str) -> Hsla {
-        self.syntax().color(name)
-    }
-
-    /// Returns the [`Appearance`] for the theme.
-    #[inline(always)]
-    pub fn appearance(&self) -> Appearance {
-        self.appearance
-    }
-}
-
-pub fn color_alpha(color: Hsla, alpha: f32) -> Hsla {
-    let mut color = color;
-    color.a = alpha;
-    color
-}

crates/theme_importer/Cargo.toml 🔗

@@ -19,5 +19,5 @@ rust-embed.workspace = true
 serde.workspace = true
 simplelog = "0.9"
 strum = { version = "0.25.0", features = ["derive"] }
-theme = { package = "theme2", path = "../theme2", features = ["importing-themes"] }
+theme = { path = "../theme", features = ["importing-themes"] }
 uuid.workspace = true

crates/theme_importer/src/main.rs 🔗

@@ -78,7 +78,7 @@ struct Args {
 
 fn main() -> Result<()> {
     const SOURCE_PATH: &str = "assets/themes/src/vscode";
-    const OUT_PATH: &str = "crates/theme2/src/themes";
+    const OUT_PATH: &str = "crates/theme/src/themes";
 
     let args = Args::parse();
 
@@ -376,6 +376,6 @@ fn main() -> Result<()> {
 
 fn format_themes_crate() -> std::io::Result<std::process::Output> {
     Command::new("cargo")
-        .args(["fmt", "--package", "theme2"])
+        .args(["fmt", "--package", "theme"])
         .output()
 }

crates/theme_selector/Cargo.toml 🔗

@@ -17,7 +17,7 @@ fuzzy = {  path = "../fuzzy" }
 gpui = { package = "gpui2", path = "../gpui2" }
 picker = { path = "../picker" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 ui = { path = "../ui" }
 util = { path = "../util" }
 workspace = { path = "../workspace" }

crates/ui/Cargo.toml 🔗

@@ -19,7 +19,7 @@ settings = { path = "../settings" }
 smallvec.workspace = true
 story = { path = "../story", optional = true }
 strum = { version = "0.25.0", features = ["derive"] }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 rand = "0.8"
 
 [features]

crates/ui/docs/hello-world.md 🔗

@@ -80,7 +80,7 @@ This may change in the future, but this is a little trick that let's you use fam
 
 ## Building out the container
 
-Let's grab our [theme2::colors::ThemeColors] from the theme and start building out a basic container.
+Let's grab our [theme::colors::ThemeColors] from the theme and start building out a basic container.
 
 We can access the current theme's colors like this:
 

crates/vim/Cargo.toml 🔗

@@ -32,7 +32,7 @@ language = { path = "../language" }
 search = { path = "../search" }
 settings = { path = "../settings" }
 workspace = { path = "../workspace" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 ui = { path = "../ui"}
 diagnostics = { path = "../diagnostics" }
 zed_actions = { path = "../zed_actions" }
@@ -49,5 +49,5 @@ project = { path = "../project", features = ["test-support"] }
 util = { path = "../util", features = ["test-support"] }
 settings = { path = "../settings" }
 workspace = { path = "../workspace", features = ["test-support"] }
-theme = { package = "theme2", path = "../theme2", features = ["test-support"] }
+theme = { path = "../theme", features = ["test-support"] }
 lsp = { path = "../lsp", features = ["test-support"] }

crates/welcome/Cargo.toml 🔗

@@ -21,7 +21,7 @@ db = { path = "../db" }
 install_cli = { path = "../install_cli" }
 project = { path = "../project" }
 settings = { path = "../settings" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 theme_selector = { path = "../theme_selector" }
 util = { path = "../util" }
 picker = { path = "../picker" }

crates/workspace/Cargo.toml 🔗

@@ -33,7 +33,7 @@ node_runtime = { path = "../node_runtime" }
 project = { path = "../project" }
 settings = { path = "../settings" }
 terminal = { path = "../terminal" }
-theme = { path = "../theme2", package = "theme2" }
+theme = { path = "../theme" }
 util = { path = "../util" }
 ui = { path = "../ui" }
 

crates/workspace/src/notifications.rs 🔗

@@ -254,7 +254,7 @@ pub mod simple_message_notification {
     //         }
 
     //         fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::AnyElement<Self> {
-    //             let theme = theme2::current(cx).clone();
+    //             let theme = theme::current(cx).clone();
     //             let theme = &theme.simple_message_notification;
 
     //             enum MessageNotificationTag {}

crates/workspace/src/pane.rs 🔗

@@ -272,7 +272,7 @@ pub struct DraggedTab {
 // #[allow(clippy::too_many_arguments)]
 // fn nav_button<A: Action, F: 'static + Fn(&mut Pane, &mut ViewContext<Pane>)>(
 //     svg_path: &'static str,
-//     style: theme2::Interactive<theme2::IconButton>,
+//     style: theme::Interactive<theme2::IconButton>,
 //     nav_button_height: f32,
 //     tooltip_style: TooltipStyle,
 //     enabled: bool,

crates/zed/Cargo.toml 🔗

@@ -66,7 +66,7 @@ sum_tree = { path = "../sum_tree" }
 shellexpand = "2.1.0"
 text = { path = "../text" }
 terminal_view = { path = "../terminal_view" }
-theme = { package = "theme2", path = "../theme2" }
+theme = { path = "../theme" }
 theme_selector = { path = "../theme_selector" }
 util = { path = "../util" }
 semantic_index = { path = "../semantic_index" }