Use rocksdb to store project paths' public/private state
This commit is contained in:
parent
724affc442
commit
f7e7a7c6a7
8 changed files with 324 additions and 28 deletions
45
Cargo.lock
generated
45
Cargo.lock
generated
|
@ -616,6 +616,17 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bzip2-sys"
|
||||||
|
version = "0.1.11+1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cache-padded"
|
name = "cache-padded"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
|
@ -2506,6 +2517,21 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "librocksdb-sys"
|
||||||
|
version = "0.6.1+6.28.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "81bc587013734dadb7cf23468e531aa120788b87243648be42e2d3a072186291"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"bzip2-sys",
|
||||||
|
"cc",
|
||||||
|
"glob",
|
||||||
|
"libc",
|
||||||
|
"libz-sys",
|
||||||
|
"zstd-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libz-sys"
|
name = "libz-sys"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
|
@ -3395,6 +3421,7 @@ dependencies = [
|
||||||
"postage",
|
"postage",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
"regex",
|
"regex",
|
||||||
|
"rocksdb",
|
||||||
"rpc",
|
"rpc",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -3713,9 +3740,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.5.4"
|
version = "1.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -3733,9 +3760,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.25"
|
version = "0.6.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "remove_dir_all"
|
name = "remove_dir_all"
|
||||||
|
@ -3822,6 +3849,16 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rocksdb"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "620f4129485ff1a7128d184bc687470c21c7951b64779ebc9cfdad3dcd920290"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"librocksdb-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "roxmltree"
|
name = "roxmltree"
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
|
|
|
@ -4604,7 +4604,7 @@ impl TestServer {
|
||||||
});
|
});
|
||||||
|
|
||||||
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http, cx));
|
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http, cx));
|
||||||
let project_store = cx.add_model(|_| ProjectStore::default());
|
let project_store = cx.add_model(|_| ProjectStore::new(project::Db::open_fake()));
|
||||||
let app_state = Arc::new(workspace::AppState {
|
let app_state = Arc::new(workspace::AppState {
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
user_store: user_store.clone(),
|
user_store: user_store.clone(),
|
||||||
|
|
|
@ -1175,7 +1175,7 @@ mod tests {
|
||||||
let http_client = FakeHttpClient::with_404_response();
|
let http_client = FakeHttpClient::with_404_response();
|
||||||
let client = Client::new(http_client.clone());
|
let client = Client::new(http_client.clone());
|
||||||
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx));
|
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx));
|
||||||
let project_store = cx.add_model(|_| ProjectStore::default());
|
let project_store = cx.add_model(|_| ProjectStore::new(project::Db::open_fake()));
|
||||||
let server = FakeServer::for_client(current_user_id, &client, &cx).await;
|
let server = FakeServer::for_client(current_user_id, &client, &cx).await;
|
||||||
let fs = FakeFs::new(cx.background());
|
let fs = FakeFs::new(cx.background());
|
||||||
fs.insert_tree("/private_dir", json!({ "one.rs": "" }))
|
fs.insert_tree("/private_dir", json!({ "one.rs": "" }))
|
||||||
|
|
|
@ -47,6 +47,7 @@ similar = "1.3"
|
||||||
smol = "1.2.5"
|
smol = "1.2.5"
|
||||||
thiserror = "1.0.29"
|
thiserror = "1.0.29"
|
||||||
toml = "0.5"
|
toml = "0.5"
|
||||||
|
rocksdb = "0.18"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
client = { path = "../client", features = ["test-support"] }
|
client = { path = "../client", features = ["test-support"] }
|
||||||
|
|
161
crates/project/src/db.rs
Normal file
161
crates/project/src/db.rs
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub struct Db(DbStore);
|
||||||
|
|
||||||
|
enum DbStore {
|
||||||
|
Null,
|
||||||
|
Real(rocksdb::DB),
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
Fake {
|
||||||
|
data: parking_lot::Mutex<collections::HashMap<Vec<u8>, Vec<u8>>>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Db {
|
||||||
|
/// Open or create a database at the given file path.
|
||||||
|
pub fn open(path: PathBuf) -> Result<Arc<Self>> {
|
||||||
|
let db = rocksdb::DB::open_default(&path)?;
|
||||||
|
Ok(Arc::new(Self(DbStore::Real(db))))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open a null database that stores no data, for use as a fallback
|
||||||
|
/// when there is an error opening the real database.
|
||||||
|
pub fn null() -> Arc<Self> {
|
||||||
|
Arc::new(Self(DbStore::Null))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Open a fake database for testing.
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
pub fn open_fake() -> Arc<Self> {
|
||||||
|
Arc::new(Self(DbStore::Fake {
|
||||||
|
data: Default::default(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read<K, I>(&self, keys: I) -> Result<Vec<Option<Vec<u8>>>>
|
||||||
|
where
|
||||||
|
K: AsRef<[u8]>,
|
||||||
|
I: IntoIterator<Item = K>,
|
||||||
|
{
|
||||||
|
match &self.0 {
|
||||||
|
DbStore::Real(db) => db
|
||||||
|
.multi_get(keys)
|
||||||
|
.into_iter()
|
||||||
|
.map(|e| e.map_err(Into::into))
|
||||||
|
.collect(),
|
||||||
|
|
||||||
|
DbStore::Null => Ok(keys.into_iter().map(|_| None).collect()),
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
DbStore::Fake { data: db } => {
|
||||||
|
let db = db.lock();
|
||||||
|
Ok(keys
|
||||||
|
.into_iter()
|
||||||
|
.map(|key| db.get(key.as_ref()).cloned())
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete<K, I>(&self, keys: I) -> Result<()>
|
||||||
|
where
|
||||||
|
K: AsRef<[u8]>,
|
||||||
|
I: IntoIterator<Item = K>,
|
||||||
|
{
|
||||||
|
match &self.0 {
|
||||||
|
DbStore::Real(db) => {
|
||||||
|
let mut batch = rocksdb::WriteBatch::default();
|
||||||
|
for key in keys {
|
||||||
|
batch.delete(key);
|
||||||
|
}
|
||||||
|
db.write(batch)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbStore::Null => {}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
DbStore::Fake { data: db } => {
|
||||||
|
let mut db = db.lock();
|
||||||
|
for key in keys {
|
||||||
|
db.remove(key.as_ref());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write<K, V, I>(&self, entries: I) -> Result<()>
|
||||||
|
where
|
||||||
|
K: AsRef<[u8]>,
|
||||||
|
V: AsRef<[u8]>,
|
||||||
|
I: IntoIterator<Item = (K, V)>,
|
||||||
|
{
|
||||||
|
match &self.0 {
|
||||||
|
DbStore::Real(db) => {
|
||||||
|
let mut batch = rocksdb::WriteBatch::default();
|
||||||
|
for (key, value) in entries {
|
||||||
|
batch.put(key, value);
|
||||||
|
}
|
||||||
|
db.write(batch)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbStore::Null => {}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
DbStore::Fake { data: db } => {
|
||||||
|
let mut db = db.lock();
|
||||||
|
for (key, value) in entries {
|
||||||
|
db.insert(key.as_ref().into(), value.as_ref().into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use tempdir::TempDir;
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
fn test_db() {
|
||||||
|
let dir = TempDir::new("db-test").unwrap();
|
||||||
|
let fake_db = Db::open_fake();
|
||||||
|
let real_db = Db::open(dir.path().join("test.db")).unwrap();
|
||||||
|
|
||||||
|
for db in [&real_db, &fake_db] {
|
||||||
|
assert_eq!(
|
||||||
|
db.read(["key-1", "key-2", "key-3"]).unwrap(),
|
||||||
|
&[None, None, None]
|
||||||
|
);
|
||||||
|
|
||||||
|
db.write([("key-1", "one"), ("key-3", "three")]).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
db.read(["key-1", "key-2", "key-3"]).unwrap(),
|
||||||
|
&[
|
||||||
|
Some("one".as_bytes().to_vec()),
|
||||||
|
None,
|
||||||
|
Some("three".as_bytes().to_vec())
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
db.delete(["key-3", "key-4"]).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
db.read(["key-1", "key-2", "key-3"]).unwrap(),
|
||||||
|
&[Some("one".as_bytes().to_vec()), None, None,]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(real_db);
|
||||||
|
|
||||||
|
let real_db = Db::open(dir.path().join("test.db")).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
real_db.read(["key-1", "key-2", "key-3"]).unwrap(),
|
||||||
|
&[Some("one".as_bytes().to_vec()), None, None,]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod db;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
mod ignore;
|
mod ignore;
|
||||||
mod lsp_command;
|
mod lsp_command;
|
||||||
|
@ -53,6 +54,7 @@ use std::{
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use util::{post_inc, ResultExt, TryFutureExt as _};
|
use util::{post_inc, ResultExt, TryFutureExt as _};
|
||||||
|
|
||||||
|
pub use db::Db;
|
||||||
pub use fs::*;
|
pub use fs::*;
|
||||||
pub use worktree::*;
|
pub use worktree::*;
|
||||||
|
|
||||||
|
@ -60,8 +62,8 @@ pub trait Item: Entity {
|
||||||
fn entry_id(&self, cx: &AppContext) -> Option<ProjectEntryId>;
|
fn entry_id(&self, cx: &AppContext) -> Option<ProjectEntryId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct ProjectStore {
|
pub struct ProjectStore {
|
||||||
|
db: Arc<Db>,
|
||||||
projects: Vec<WeakModelHandle<Project>>,
|
projects: Vec<WeakModelHandle<Project>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +535,7 @@ impl Project {
|
||||||
let http_client = client::test::FakeHttpClient::with_404_response();
|
let http_client = client::test::FakeHttpClient::with_404_response();
|
||||||
let client = client::Client::new(http_client.clone());
|
let client = client::Client::new(http_client.clone());
|
||||||
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx));
|
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx));
|
||||||
let project_store = cx.add_model(|_| ProjectStore::default());
|
let project_store = cx.add_model(|_| ProjectStore::new(Db::open_fake()));
|
||||||
let project = cx.update(|cx| {
|
let project = cx.update(|cx| {
|
||||||
Project::local(true, client, user_store, project_store, languages, fs, cx)
|
Project::local(true, client, user_store, project_store, languages, fs, cx)
|
||||||
});
|
});
|
||||||
|
@ -568,6 +570,10 @@ impl Project {
|
||||||
self.user_store.clone()
|
self.user_store.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn project_store(&self) -> ModelHandle<ProjectStore> {
|
||||||
|
self.project_store.clone()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub fn check_invariants(&self, cx: &AppContext) {
|
pub fn check_invariants(&self, cx: &AppContext) {
|
||||||
if self.is_local() {
|
if self.is_local() {
|
||||||
|
@ -743,9 +749,6 @@ impl Project {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn metadata_changed(&mut self, cx: &mut ModelContext<Self>) {
|
fn metadata_changed(&mut self, cx: &mut ModelContext<Self>) {
|
||||||
cx.notify();
|
|
||||||
self.project_store.update(cx, |_, cx| cx.notify());
|
|
||||||
|
|
||||||
if let ProjectClientState::Local {
|
if let ProjectClientState::Local {
|
||||||
remote_id_rx,
|
remote_id_rx,
|
||||||
public_rx,
|
public_rx,
|
||||||
|
@ -768,6 +771,9 @@ impl Project {
|
||||||
})
|
})
|
||||||
.log_err();
|
.log_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.project_store.update(cx, |_, cx| cx.notify());
|
||||||
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5215,6 +5221,13 @@ impl Project {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProjectStore {
|
impl ProjectStore {
|
||||||
|
pub fn new(db: Arc<Db>) -> Self {
|
||||||
|
Self {
|
||||||
|
db,
|
||||||
|
projects: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn projects<'a>(
|
pub fn projects<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
cx: &'a AppContext,
|
cx: &'a AppContext,
|
||||||
|
@ -5248,6 +5261,56 @@ impl ProjectStore {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn are_all_project_paths_public(
|
||||||
|
&self,
|
||||||
|
project: &Project,
|
||||||
|
cx: &AppContext,
|
||||||
|
) -> Task<Result<bool>> {
|
||||||
|
let project_path_keys = self.project_path_keys(project, cx);
|
||||||
|
let db = self.db.clone();
|
||||||
|
cx.background().spawn(async move {
|
||||||
|
let values = db.read(project_path_keys)?;
|
||||||
|
Ok(values.into_iter().all(|e| e.is_some()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_project_paths_public(
|
||||||
|
&self,
|
||||||
|
project: &Project,
|
||||||
|
public: bool,
|
||||||
|
cx: &AppContext,
|
||||||
|
) -> Task<Result<()>> {
|
||||||
|
let project_path_keys = self.project_path_keys(project, cx);
|
||||||
|
let db = self.db.clone();
|
||||||
|
cx.background().spawn(async move {
|
||||||
|
if public {
|
||||||
|
db.write(project_path_keys.into_iter().map(|key| (key, &[])))
|
||||||
|
} else {
|
||||||
|
db.delete(project_path_keys)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn project_path_keys(&self, project: &Project, cx: &AppContext) -> Vec<String> {
|
||||||
|
project
|
||||||
|
.worktrees
|
||||||
|
.iter()
|
||||||
|
.filter_map(|worktree| {
|
||||||
|
worktree.upgrade(&cx).map(|worktree| {
|
||||||
|
format!(
|
||||||
|
"public-project-path:{}",
|
||||||
|
worktree
|
||||||
|
.read(cx)
|
||||||
|
.as_local()
|
||||||
|
.unwrap()
|
||||||
|
.abs_path()
|
||||||
|
.to_string_lossy()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorktreeHandle {
|
impl WorktreeHandle {
|
||||||
|
|
|
@ -692,7 +692,7 @@ impl AppState {
|
||||||
let languages = Arc::new(LanguageRegistry::test());
|
let languages = Arc::new(LanguageRegistry::test());
|
||||||
let http_client = client::test::FakeHttpClient::with_404_response();
|
let http_client = client::test::FakeHttpClient::with_404_response();
|
||||||
let client = Client::new(http_client.clone());
|
let client = Client::new(http_client.clone());
|
||||||
let project_store = cx.add_model(|_| ProjectStore::default());
|
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 user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx));
|
||||||
let themes = ThemeRegistry::new((), cx.font_cache().clone());
|
let themes = ThemeRegistry::new((), cx.font_cache().clone());
|
||||||
Arc::new(Self {
|
Arc::new(Self {
|
||||||
|
@ -1055,8 +1055,15 @@ impl Workspace {
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| self.project.clone());
|
.unwrap_or_else(|| self.project.clone());
|
||||||
project.update(cx, |project, cx| {
|
project.update(cx, |project, cx| {
|
||||||
let is_public = project.is_public();
|
let public = !project.is_public();
|
||||||
project.set_public(!is_public, cx);
|
eprintln!("toggle_project_public => {}", public);
|
||||||
|
project.set_public(public, cx);
|
||||||
|
project.project_store().update(cx, |store, cx| {
|
||||||
|
store
|
||||||
|
.set_project_paths_public(project, public, cx)
|
||||||
|
.detach_and_log_err(cx);
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2407,6 +2414,7 @@ pub fn open_paths(
|
||||||
let app_state = app_state.clone();
|
let app_state = app_state.clone();
|
||||||
let abs_paths = abs_paths.to_vec();
|
let abs_paths = abs_paths.to_vec();
|
||||||
cx.spawn(|mut cx| async move {
|
cx.spawn(|mut cx| async move {
|
||||||
|
let mut new_project = None;
|
||||||
let workspace = if let Some(existing) = existing {
|
let workspace = if let Some(existing) = existing {
|
||||||
existing
|
existing
|
||||||
} else {
|
} else {
|
||||||
|
@ -2416,18 +2424,17 @@ pub fn open_paths(
|
||||||
.contains(&false);
|
.contains(&false);
|
||||||
|
|
||||||
cx.add_window((app_state.build_window_options)(), |cx| {
|
cx.add_window((app_state.build_window_options)(), |cx| {
|
||||||
let mut workspace = Workspace::new(
|
let project = Project::local(
|
||||||
Project::local(
|
false,
|
||||||
false,
|
app_state.client.clone(),
|
||||||
app_state.client.clone(),
|
app_state.user_store.clone(),
|
||||||
app_state.user_store.clone(),
|
app_state.project_store.clone(),
|
||||||
app_state.project_store.clone(),
|
app_state.languages.clone(),
|
||||||
app_state.languages.clone(),
|
app_state.fs.clone(),
|
||||||
app_state.fs.clone(),
|
|
||||||
cx,
|
|
||||||
),
|
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
new_project = Some(project.clone());
|
||||||
|
let mut workspace = Workspace::new(project, cx);
|
||||||
(app_state.initialize_workspace)(&mut workspace, &app_state, cx);
|
(app_state.initialize_workspace)(&mut workspace, &app_state, cx);
|
||||||
if contains_directory {
|
if contains_directory {
|
||||||
workspace.toggle_sidebar_item(
|
workspace.toggle_sidebar_item(
|
||||||
|
@ -2446,6 +2453,26 @@ pub fn open_paths(
|
||||||
let items = workspace
|
let items = workspace
|
||||||
.update(&mut cx, |workspace, cx| workspace.open_paths(abs_paths, cx))
|
.update(&mut cx, |workspace, cx| workspace.open_paths(abs_paths, cx))
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
if let Some(project) = new_project {
|
||||||
|
let public = project
|
||||||
|
.read_with(&cx, |project, cx| {
|
||||||
|
app_state
|
||||||
|
.project_store
|
||||||
|
.read(cx)
|
||||||
|
.are_all_project_paths_public(project, cx)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.log_err()
|
||||||
|
.unwrap_or(false);
|
||||||
|
if public {
|
||||||
|
project.update(&mut cx, |project, cx| {
|
||||||
|
eprintln!("initialize new project public");
|
||||||
|
project.set_public(true, cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(workspace, items)
|
(workspace, items)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,10 @@ use zed::{
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let http = http::client();
|
let http = http::client();
|
||||||
let logs_dir_path = dirs::home_dir()
|
let home_dir = dirs::home_dir().expect("could not find home dir");
|
||||||
.expect("could not find home dir")
|
let db_dir_path = home_dir.join("Library/Application Support/Zed");
|
||||||
.join("Library/Logs/Zed");
|
let logs_dir_path = home_dir.join("Library/Logs/Zed");
|
||||||
|
fs::create_dir_all(&db_dir_path).expect("could not create database path");
|
||||||
fs::create_dir_all(&logs_dir_path).expect("could not create logs path");
|
fs::create_dir_all(&logs_dir_path).expect("could not create logs path");
|
||||||
init_logger(&logs_dir_path);
|
init_logger(&logs_dir_path);
|
||||||
|
|
||||||
|
@ -59,6 +60,11 @@ fn main() {
|
||||||
.or_else(|| app.platform().app_version().ok())
|
.or_else(|| app.platform().app_version().ok())
|
||||||
.map_or("dev".to_string(), |v| v.to_string());
|
.map_or("dev".to_string(), |v| v.to_string());
|
||||||
init_panic_hook(logs_dir_path, app_version, http.clone(), app.background());
|
init_panic_hook(logs_dir_path, app_version, http.clone(), app.background());
|
||||||
|
let db = app.background().spawn(async move {
|
||||||
|
project::Db::open(db_dir_path.join("zed.db"))
|
||||||
|
.log_err()
|
||||||
|
.unwrap_or(project::Db::null())
|
||||||
|
});
|
||||||
|
|
||||||
load_embedded_fonts(&app);
|
load_embedded_fonts(&app);
|
||||||
|
|
||||||
|
@ -136,7 +142,6 @@ fn main() {
|
||||||
let client = client::Client::new(http.clone());
|
let client = client::Client::new(http.clone());
|
||||||
let mut languages = languages::build_language_registry(login_shell_env_loaded);
|
let mut languages = languages::build_language_registry(login_shell_env_loaded);
|
||||||
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx));
|
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx));
|
||||||
let project_store = cx.add_model(|_| ProjectStore::default());
|
|
||||||
|
|
||||||
context_menu::init(cx);
|
context_menu::init(cx);
|
||||||
auto_update::init(http, client::ZED_SERVER_URL.clone(), cx);
|
auto_update::init(http, client::ZED_SERVER_URL.clone(), cx);
|
||||||
|
@ -156,6 +161,7 @@ fn main() {
|
||||||
search::init(cx);
|
search::init(cx);
|
||||||
vim::init(cx);
|
vim::init(cx);
|
||||||
|
|
||||||
|
let db = cx.background().block(db);
|
||||||
let (settings_file, keymap_file) = cx.background().block(config_files).unwrap();
|
let (settings_file, keymap_file) = cx.background().block(config_files).unwrap();
|
||||||
let mut settings_rx = settings_from_files(
|
let mut settings_rx = settings_from_files(
|
||||||
default_settings,
|
default_settings,
|
||||||
|
@ -191,6 +197,7 @@ fn main() {
|
||||||
.detach();
|
.detach();
|
||||||
cx.set_global(settings);
|
cx.set_global(settings);
|
||||||
|
|
||||||
|
let project_store = cx.add_model(|_| ProjectStore::new(db));
|
||||||
let app_state = Arc::new(AppState {
|
let app_state = Arc::new(AppState {
|
||||||
languages,
|
languages,
|
||||||
themes,
|
themes,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue