ui.rs

  1use std::sync::Arc;
  2
  3use futures::StreamExt;
  4use gpui::AppContext as _;
  5use settings::{DEFAULT_KEYMAP_PATH, KeymapFile, SettingsStore, watch_config_file};
  6use settings_ui::open_settings_editor;
  7use ui::BorrowAppContext;
  8
  9fn merge_paths(a: &std::path::Path, b: &std::path::Path) -> std::path::PathBuf {
 10    let a_parts: Vec<_> = a.components().collect();
 11    let b_parts: Vec<_> = b.components().collect();
 12
 13    let mut overlap = 0;
 14    for i in 0..=a_parts.len().min(b_parts.len()) {
 15        if a_parts[a_parts.len() - i..] == b_parts[..i] {
 16            overlap = i;
 17        }
 18    }
 19
 20    let mut result = std::path::PathBuf::new();
 21    for part in &a_parts {
 22        result.push(part.as_os_str());
 23    }
 24    for part in &b_parts[overlap..] {
 25        result.push(part.as_os_str());
 26    }
 27    result
 28}
 29
 30fn main() {
 31    zlog::init();
 32    zlog::init_output_stderr();
 33
 34    let [crate_path, file_path] = [env!("CARGO_MANIFEST_DIR"), file!()].map(std::path::Path::new);
 35    let example_dir_abs_path = merge_paths(crate_path, file_path)
 36        .parent()
 37        .unwrap()
 38        .to_path_buf();
 39
 40    let app = gpui::Application::new().with_assets(assets::Assets);
 41
 42    let fs = Arc::new(fs::RealFs::new(None, app.background_executor()));
 43    let mut user_settings_file_rx = watch_config_file(
 44        &app.background_executor(),
 45        fs.clone(),
 46        paths::settings_file().clone(),
 47    );
 48
 49    app.run(move |cx| {
 50        <dyn fs::Fs>::set_global(fs.clone(), cx);
 51        settings::init(cx);
 52        settings_ui::init(cx);
 53        theme::init(theme::LoadThemes::JustBase, cx);
 54        client::init_settings(cx);
 55        workspace::init_settings(cx);
 56        // production client because fake client requires gpui/test-support
 57        // and that causes issues with the real stuff we want to do
 58        let client = client::Client::production(cx);
 59        let user_store = cx.new(|cx| client::UserStore::new(client.clone(), cx));
 60        let languages = Arc::new(language::LanguageRegistry::new(
 61            cx.background_executor().clone(),
 62        ));
 63
 64        client::init(&client, cx);
 65
 66        project::Project::init(&client, cx);
 67
 68        zlog::info!(
 69            "Creating fake worktree in {}",
 70            example_dir_abs_path.display(),
 71        );
 72        let project = project::Project::local(
 73            client.clone(),
 74            node_runtime::NodeRuntime::unavailable(),
 75            user_store,
 76            languages,
 77            fs.clone(),
 78            Some(Default::default()), // WARN: if None is passed here, prepare to be process bombed
 79            cx,
 80        );
 81        let worktree_task = project.update(cx, |project, cx| {
 82            project.create_worktree(example_dir_abs_path, true, cx)
 83        });
 84        cx.spawn(async move |_| {
 85            let worktree = worktree_task.await.unwrap();
 86            std::mem::forget(worktree);
 87        })
 88        .detach();
 89        std::mem::forget(project);
 90
 91        language::init(cx);
 92        editor::init(cx);
 93        menu::init();
 94
 95        let keybindings =
 96            KeymapFile::load_asset_allow_partial_failure(DEFAULT_KEYMAP_PATH, cx).unwrap();
 97        cx.bind_keys(keybindings);
 98        cx.spawn(async move |cx| {
 99            while let Some(content) = user_settings_file_rx.next().await {
100                cx.update(|cx| {
101                    cx.update_global(|store: &mut SettingsStore, cx| {
102                        store.set_user_settings(&content, cx).unwrap()
103                    })
104                })
105                .ok();
106            }
107        })
108        .detach();
109
110        open_settings_editor(cx).unwrap();
111        cx.activate(true);
112    });
113}