diff --git a/.gitignore b/.gitignore index 1b39c0720c..5e6963ba8b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ /crates/collab/static/styles.css /vendor/bin /assets/themes/*.json -/assets/themes/internal/*.json \ No newline at end of file +/assets/themes/internal/*.json +/assets/themes/experiments/*.json \ No newline at end of file diff --git a/crates/collab/src/integration_tests.rs b/crates/collab/src/integration_tests.rs index c037d9719a..905aa328f2 100644 --- a/crates/collab/src/integration_tests.rs +++ b/crates/collab/src/integration_tests.rs @@ -5220,7 +5220,7 @@ impl TestServer { user_store: user_store.clone(), project_store: project_store.clone(), languages: Arc::new(LanguageRegistry::new(Task::ready(()))), - themes: ThemeRegistry::new((), cx.font_cache(), false), + themes: ThemeRegistry::new((), cx.font_cache()), fs: fs.clone(), build_window_options: Default::default, initialize_workspace: |_, _, _| unimplemented!(), diff --git a/crates/settings/src/settings.rs b/crates/settings/src/settings.rs index 4e4bd8c8c3..c0eb858e48 100644 --- a/crates/settings/src/settings.rs +++ b/crates/settings/src/settings.rs @@ -41,7 +41,9 @@ pub struct Settings { } #[derive(Copy, Clone, Debug, Default, Deserialize, JsonSchema)] -pub struct FeatureFlags {} +pub struct FeatureFlags { + pub experimental_themes: bool, +} impl FeatureFlags { pub fn keymap_files(&self) -> Vec<&'static str> { diff --git a/crates/theme/src/theme_registry.rs b/crates/theme/src/theme_registry.rs index 98bd4e301e..5735f13b14 100644 --- a/crates/theme/src/theme_registry.rs +++ b/crates/theme/src/theme_registry.rs @@ -10,26 +10,34 @@ pub struct ThemeRegistry { themes: Mutex>>, theme_data: Mutex>>, font_cache: Arc, - internal: bool, } impl ThemeRegistry { - pub fn new(source: impl AssetSource, font_cache: Arc, internal: bool) -> Arc { + pub fn new(source: impl AssetSource, font_cache: Arc) -> Arc { Arc::new(Self { assets: Box::new(source), themes: Default::default(), theme_data: Default::default(), font_cache, - internal, }) } - pub fn list(&self) -> impl Iterator + '_ { + pub fn list(&self, internal: bool, experiments: bool) -> impl Iterator + '_ { let mut dirs = self.assets.list("themes/"); - if self.internal { - dirs.extend(self.assets.list("themes/internal/")) - }; + if !internal { + dirs = dirs + .into_iter() + .filter(|path| !path.starts_with("themes/internal")) + .collect() + } + + if !experiments { + dirs = dirs + .into_iter() + .filter(|path| !path.starts_with("themes/experiments")) + .collect() + } dirs.into_iter().filter_map(|path| { let filename = path.strip_prefix("themes/")?; diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index 76c426e290..32a7736659 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -39,13 +39,17 @@ impl ThemeSelector { fn new(registry: Arc, cx: &mut ViewContext) -> Self { let handle = cx.weak_handle(); let picker = cx.add_view(|cx| Picker::new(handle, cx)); - let original_theme = cx.global::().theme.clone(); - let mut theme_names = registry.list().collect::>(); + let settings = cx.global::(); + let original_theme = settings.theme.clone(); + + let mut theme_names = registry + .list(settings.internal, settings.experiments.experimental_themes) + .collect::>(); theme_names.sort_unstable_by(|a, b| { - a.is_light.cmp(&b.is_light).reverse() - // a.ends_with("dark") - // .cmp(&b.ends_with("dark")) - // .then_with(|| a.cmp(b)) + a.is_light + .cmp(&b.is_light) + .reverse() + .then(a.name.cmp(&b.name)) }); let matches = theme_names .iter() diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 1d4bed7a94..9f6c7f1612 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -860,7 +860,7 @@ impl AppState { let client = Client::new(http_client.clone()); let project_store = cx.add_model(|_| ProjectStore::new(project::Db::open_fake())); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx)); - let themes = ThemeRegistry::new((), cx.font_cache().clone(), false); + let themes = ThemeRegistry::new((), cx.font_cache().clone()); Arc::new(Self { client, themes, diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 0edebeed7e..e3ae35bc08 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -70,7 +70,6 @@ fn main() { .await .map(|github| { &github == "as-cii" - || &github == "ForLoveOfCats" || &github == "ForLoveOfCats" || &github == "gibusu" || &github == "iamnbutler" @@ -85,7 +84,7 @@ fn main() { } }); - let themes = ThemeRegistry::new(Assets, app.font_cache(), internal); + let themes = ThemeRegistry::new(Assets, app.font_cache()); let default_settings = Settings::defaults(Assets, &app.font_cache(), &themes); let config_files = load_config_files(&app, fs.clone()); @@ -127,9 +126,12 @@ fn main() { let fs = fs.clone(); async move { while let Some(user) = current_user.recv().await { - let user_name = user - .map(|user| user.github_login.clone()) - .unwrap_or_else(|| String::new()); + // When the user logs out, `user` is None. + if user.is_none() { + continue; + } + + let user_name = user.unwrap().github_login.clone(); fs.save( &*zed::paths::LAST_USERNAME, diff --git a/crates/zed/src/settings_file.rs b/crates/zed/src/settings_file.rs index 77ac6f8b64..6d28efbcbc 100644 --- a/crates/zed/src/settings_file.rs +++ b/crates/zed/src/settings_file.rs @@ -153,7 +153,7 @@ mod tests { watch_settings_file( default_settings.clone(), source, - ThemeRegistry::new((), font_cache, false), + ThemeRegistry::new((), font_cache), false, cx, ) diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index e3fd2ee8d1..18d0cfa76f 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -244,7 +244,13 @@ pub fn initialize_workspace( cx.emit(workspace::Event::PaneAdded(workspace.active_pane().clone())); - let theme_names = app_state.themes.list().map(|meta| meta.name).collect(); + let settings = cx.global::(); + + let theme_names = app_state + .themes + .list(settings.internal, settings.experiments.experimental_themes) + .map(|meta| meta.name) + .collect(); let language_names = &languages::LANGUAGE_NAMES; workspace.project().update(cx, |project, cx| { @@ -1664,11 +1670,11 @@ mod tests { .into(), ]) .unwrap(); - let themes = ThemeRegistry::new(Assets, cx.font_cache().clone(), false); + let themes = ThemeRegistry::new(Assets, cx.font_cache().clone()); let settings = Settings::defaults(Assets, cx.font_cache(), &themes); let mut has_default_theme = false; - for theme_name in themes.list().map(|meta| meta.name) { + for theme_name in themes.list(false, false).map(|meta| meta.name) { let theme = themes.get(&theme_name).unwrap(); if theme.meta.name == settings.theme.meta.name { has_default_theme = true; diff --git a/styles/src/buildThemes.ts b/styles/src/buildThemes.ts index 47444eb077..10fb62bdd3 100644 --- a/styles/src/buildThemes.ts +++ b/styles/src/buildThemes.ts @@ -2,12 +2,13 @@ import * as fs from "fs"; import * as path from "path"; import { tmpdir } from "os"; import app from "./styleTree/app"; -import themes, { internalThemes } from "./themes"; +import themes, { internalThemes, experimentalThemes } from "./themes"; import snakeCase from "./utils/snakeCase"; import Theme from "./themes/common/theme"; const themeDirectory = `${__dirname}/../../assets/themes`; const internalDirectory = `${themeDirectory}/internal`; +const experimentsDirectory = `${themeDirectory}/experiments`; const tempDirectory = fs.mkdtempSync(path.join(tmpdir(), "build-themes")); // Clear existing themes @@ -24,6 +25,7 @@ function clearThemes(themeDirectory: string) { clearThemes(themeDirectory); clearThemes(internalDirectory); +clearThemes(experimentsDirectory); function writeThemes(themes: Theme[], outputDirectory: string) { for (let theme of themes) { @@ -40,3 +42,4 @@ function writeThemes(themes: Theme[], outputDirectory: string) { // Write new themes to theme directory writeThemes(themes, themeDirectory); writeThemes(internalThemes, internalDirectory); +writeThemes(experimentalThemes, experimentsDirectory); diff --git a/styles/src/themes.ts b/styles/src/themes.ts index e8bf8fc390..fb9b05d786 100644 --- a/styles/src/themes.ts +++ b/styles/src/themes.ts @@ -8,6 +8,10 @@ export default themes; const internalThemes: Theme[] = []; export { internalThemes } +const experimentalThemes: Theme[] = []; +export { experimentalThemes } + + function fillThemes(themesPath: string, themes: Theme[]) { for (const fileName of fs.readdirSync(themesPath)) { if (fileName == "template.ts") continue; @@ -23,3 +27,5 @@ function fillThemes(themesPath: string, themes: Theme[]) { fillThemes(path.resolve(`${__dirname}/themes`), themes) fillThemes(path.resolve(`${__dirname}/themes/internal`), internalThemes) +fillThemes(path.resolve(`${__dirname}/themes/experiments`), experimentalThemes) + diff --git a/styles/src/themes/experiments/cave-experiments.ts b/styles/src/themes/experiments/cave-experiments.ts new file mode 100644 index 0000000000..4b2dd582bf --- /dev/null +++ b/styles/src/themes/experiments/cave-experiments.ts @@ -0,0 +1,28 @@ +import chroma from "chroma-js"; +import { colorRamp, createTheme } from "../common/base16"; + +const name = "cave-experiments"; + +const ramps = { + neutral: chroma.scale([ + "#555555", + "#555555", + "#555555", + "#555555", + "#555555", + "#555555", + "#555555", + "#555555", + ]), + red: colorRamp(chroma("#555555")), + orange: colorRamp(chroma("#555555")), + yellow: colorRamp(chroma("#555555")), + green: colorRamp(chroma("#555555")), + cyan: colorRamp(chroma("#555555")), + blue: colorRamp(chroma("#555555")), + violet: colorRamp(chroma("#555555")), + magenta: colorRamp(chroma("#555555")), +}; + +export const dark = createTheme(`${name}-dark`, false, ramps); +export const light = createTheme(`${name}-light`, true, ramps);