Detailed changes
@@ -14508,6 +14508,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"assets",
+ "client",
"command_palette_hooks",
"editor",
"feature_flags",
@@ -14516,9 +14517,11 @@ dependencies = [
"gpui",
"language",
"menu",
+ "node_runtime",
"paths",
"project",
"serde",
+ "session",
"settings",
"theme",
"ui",
@@ -43,7 +43,7 @@ impl Session {
}
}
- #[cfg(any(test, feature = "test-support"))]
+ // #[cfg(any(test, feature = "test-support"))]
pub fn test() -> Self {
Self {
session_id: Uuid::new_v4().to_string(),
@@ -24,7 +24,8 @@ pub use keymap_file::{
pub use settings_file::*;
pub use settings_json::*;
pub use settings_store::{
- InvalidSettingsError, LocalSettingsKind, Settings, SettingsKey, SettingsLocation, SettingsStore,
+ InvalidSettingsError, LocalSettingsKind, Settings, SettingsFile, SettingsKey, SettingsLocation,
+ SettingsStore,
};
pub use vscode_import::{VsCodeSettings, VsCodeSettingsSource};
@@ -156,6 +156,16 @@ pub struct SettingsStore {
mpsc::UnboundedSender<Box<dyn FnOnce(AsyncApp) -> LocalBoxFuture<'static, Result<()>>>>,
}
+#[derive(Clone, PartialEq)]
+pub enum SettingsFile {
+ User,
+ Global,
+ Extension,
+ Server,
+ Default,
+ Local((WorktreeId, Arc<Path>)),
+}
+
#[derive(Clone)]
pub struct Editorconfig {
pub is_root: bool,
@@ -479,6 +489,36 @@ impl SettingsStore {
})
})
}
+
+ pub fn get_all_files(&self) -> Vec<SettingsFile> {
+ let mut files = Vec::from_iter(
+ self.local_settings
+ .keys()
+ // rev because these are sorted by path, so highest precedence is last
+ .rev()
+ .cloned()
+ .map(SettingsFile::Local),
+ );
+
+ if self.server_settings.is_some() {
+ files.push(SettingsFile::Server);
+ }
+ // ignoring profiles
+ // ignoring os profiles
+ // ignoring release channel profiles
+
+ if self.user_settings.is_some() {
+ files.push(SettingsFile::User);
+ }
+ if self.extension_settings.is_some() {
+ files.push(SettingsFile::Extension);
+ }
+ if self.global_settings.is_some() {
+ files.push(SettingsFile::Global);
+ }
+ files.push(SettingsFile::Default);
+ files
+ }
}
impl SettingsStore {
@@ -32,12 +32,15 @@ workspace-hack.workspace = true
workspace.workspace = true
[dev-dependencies]
-settings = { workspace = true, features = ["test-support"] }
+settings.workspace = true
futures.workspace = true
language.workspace = true
assets.workspace = true
paths.workspace = true
zlog.workspace = true
+client.workspace = true
+session.workspace = true
+node_runtime.workspace = true
[[example]]
name = "ui"
@@ -0,0 +1 @@
+{}
@@ -1,11 +1,42 @@
use std::sync::Arc;
use futures::StreamExt;
+use gpui::AppContext as _;
use settings::{DEFAULT_KEYMAP_PATH, KeymapFile, SettingsStore, watch_config_file};
use settings_ui::open_settings_editor;
use ui::BorrowAppContext;
+fn merge_paths(a: &std::path::Path, b: &std::path::Path) -> std::path::PathBuf {
+ let a_parts: Vec<_> = a.components().collect();
+ let b_parts: Vec<_> = b.components().collect();
+
+ let mut overlap = 0;
+ for i in 0..=a_parts.len().min(b_parts.len()) {
+ if a_parts[a_parts.len() - i..] == b_parts[..i] {
+ overlap = i;
+ }
+ }
+
+ let mut result = std::path::PathBuf::new();
+ for part in &a_parts {
+ result.push(part.as_os_str());
+ }
+ for part in &b_parts[overlap..] {
+ result.push(part.as_os_str());
+ }
+ result
+}
+
fn main() {
+ zlog::init();
+ zlog::init_output_stderr();
+
+ let [crate_path, file_path] = [env!("CARGO_MANIFEST_DIR"), file!()].map(std::path::Path::new);
+ let example_dir_abs_path = merge_paths(crate_path, file_path)
+ .parent()
+ .unwrap()
+ .to_path_buf();
+
let app = gpui::Application::new().with_assets(assets::Assets);
let fs = Arc::new(fs::RealFs::new(None, app.background_executor()));
@@ -14,15 +45,49 @@ fn main() {
fs.clone(),
paths::settings_file().clone(),
);
- zlog::init();
- zlog::init_output_stderr();
app.run(move |cx| {
<dyn fs::Fs>::set_global(fs.clone(), cx);
settings::init(cx);
theme::init(theme::LoadThemes::JustBase, cx);
+
+ client::init_settings(cx);
workspace::init_settings(cx);
- project::Project::init_settings(cx);
+ // production client because fake client requires gpui/test-support
+ // and that causes issues with the real stuff we want to do
+ let client = client::Client::production(cx);
+ let user_store = cx.new(|cx| client::UserStore::new(client.clone(), cx));
+ let languages = Arc::new(language::LanguageRegistry::new(
+ cx.background_executor().clone(),
+ ));
+
+ client::init(&client, cx);
+
+ project::Project::init(&client, cx);
+
+ zlog::info!(
+ "Creating fake worktree in {}",
+ example_dir_abs_path.display(),
+ );
+ let project = project::Project::local(
+ client.clone(),
+ node_runtime::NodeRuntime::unavailable(),
+ user_store,
+ languages,
+ fs.clone(),
+ Some(Default::default()), // WARN: if None is passed here, prepare to be process bombed
+ cx,
+ );
+ let worktree_task = project.update(cx, |project, cx| {
+ project.create_worktree(example_dir_abs_path, true, cx)
+ });
+ cx.spawn(async move |_| {
+ let worktree = worktree_task.await.unwrap();
+ std::mem::forget(worktree);
+ })
+ .detach();
+ std::mem::forget(project);
+
language::init(cx);
editor::init(cx);
menu::init();
@@ -200,7 +200,7 @@ struct SettingItem {
}
#[allow(unused)]
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
enum SettingsFile {
User, // Uses all settings.
Local((WorktreeId, Arc<Path>)), // Has a special name, and special set of settings
@@ -216,11 +216,11 @@ impl SettingsFile {
}
}
- fn name(&self) -> String {
+ fn name(&self) -> SharedString {
match self {
- SettingsFile::User => "User".to_string(),
- SettingsFile::Local((_, path)) => format!("Local ({})", path.display()),
- SettingsFile::Server(file) => format!("Server ({})", file),
+ SettingsFile::User => SharedString::new_static("User"),
+ SettingsFile::Local((_, path)) => format!("Local ({})", path.display()).into(),
+ SettingsFile::Server(file) => format!("Server ({})", file).into(),
}
}
}
@@ -234,22 +234,18 @@ impl SettingsWindow {
editor
});
let mut this = Self {
- files: vec![
- SettingsFile::User,
- SettingsFile::Local((
- WorktreeId::from_usize(0),
- Arc::from(Path::new("/my-project/")),
- )),
- ],
+ files: vec![],
current_file: current_file,
pages: vec![],
current_page: 0,
search,
};
- cx.observe_global_in::<SettingsStore>(window, move |_, _, cx| {
+ cx.observe_global_in::<SettingsStore>(window, move |this, _, cx| {
+ this.fetch_files(cx);
cx.notify();
})
.detach();
+ this.fetch_files(cx);
this.build_ui();
this
@@ -259,7 +255,36 @@ impl SettingsWindow {
self.pages = self.current_file.pages();
}
+ fn fetch_files(&mut self, cx: &mut App) {
+ let settings_store = cx.global::<SettingsStore>();
+ let mut ui_files = vec![];
+ let all_files = settings_store.get_all_files();
+ for file in all_files {
+ let settings_ui_file = match file {
+ settings::SettingsFile::User => SettingsFile::User,
+ settings::SettingsFile::Global => continue,
+ settings::SettingsFile::Extension => continue,
+ settings::SettingsFile::Server => SettingsFile::Server("todo: server name"),
+ settings::SettingsFile::Default => continue,
+ settings::SettingsFile::Local(location) => SettingsFile::Local(location),
+ };
+ ui_files.push(settings_ui_file);
+ }
+ ui_files.reverse();
+ if !ui_files.contains(&self.current_file) {
+ self.change_file(0);
+ }
+ self.files = ui_files;
+ }
+
fn change_file(&mut self, ix: usize) {
+ if ix >= self.files.len() {
+ self.current_file = SettingsFile::User;
+ return;
+ }
+ if self.files[ix] == self.current_file {
+ return;
+ }
self.current_file = self.files[ix].clone();
self.build_ui();
}