Moved fs to it's own crate, build failing due to cyclic dependency on rope

Mikayla Maki created

Change summary

Cargo.lock                      | 16 +++++++++
crates/fs/Cargo.toml            | 18 ++++++++++
crates/fs/src/fs.rs             | 59 +++++++++++++++++++++++++++++++++-
crates/fs/src/repository.rs     |  0 
crates/text/Cargo.toml          |  1 
crates/text/src/text.rs         | 56 ---------------------------------
crates/zed/src/settings_file.rs |  4 ++
7 files changed, 96 insertions(+), 58 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -1984,6 +1984,22 @@ dependencies = [
  "pkg-config",
 ]
 
+[[package]]
+name = "fs"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "collections",
+ "fsevent",
+ "futures",
+ "git",
+ "parking_lot 0.11.2",
+ "smol",
+ "text",
+ "util",
+]
+
 [[package]]
 name = "fs-set-times"
 version = "0.15.0"

crates/fs/Cargo.toml 🔗

@@ -0,0 +1,18 @@
+[package]
+name = "fs"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+path = "src/fs.rs"
+
+[dependencies]
+collections = { path = "../collections" }
+fsevent = { path = "../fsevent" }
+anyhow = "1.0.57"
+async-trait = "0.1"
+futures = "0.3"
+parking_lot = "0.11.1"
+smol = "1.2.5"
+text = { path = "../text" }
+util = { path = "../util" }

crates/project/src/fs.rs → crates/fs/src/fs.rs 🔗

@@ -1,8 +1,8 @@
+pub mod repository;
+
 use anyhow::{anyhow, Result};
 use fsevent::EventStream;
 use futures::{future::BoxFuture, Stream, StreamExt};
-use git::repository::{GitRepository, LibGitRepository};
-use language::LineEnding;
 use parking_lot::Mutex as SyncMutex;
 use smol::io::{AsyncReadExt, AsyncWriteExt};
 use std::sync::Arc;
@@ -25,6 +25,61 @@ use git::repository::FakeGitRepositoryState;
 #[cfg(any(test, feature = "test-support"))]
 use std::sync::Weak;
 
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum LineEnding {
+    Unix,
+    Windows,
+}
+
+impl Default for LineEnding {
+    fn default() -> Self {
+        #[cfg(unix)]
+        return Self::Unix;
+
+        #[cfg(not(unix))]
+        return Self::CRLF;
+    }
+}
+
+impl LineEnding {
+    pub fn as_str(&self) -> &'static str {
+        match self {
+            LineEnding::Unix => "\n",
+            LineEnding::Windows => "\r\n",
+        }
+    }
+
+    pub fn detect(text: &str) -> Self {
+        let mut max_ix = cmp::min(text.len(), 1000);
+        while !text.is_char_boundary(max_ix) {
+            max_ix -= 1;
+        }
+
+        if let Some(ix) = text[..max_ix].find(&['\n']) {
+            if ix > 0 && text.as_bytes()[ix - 1] == b'\r' {
+                Self::Windows
+            } else {
+                Self::Unix
+            }
+        } else {
+            Self::default()
+        }
+    }
+
+    pub fn normalize(text: &mut String) {
+        if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(text, "\n") {
+            *text = replaced;
+        }
+    }
+
+    fn normalize_arc(text: Arc<str>) -> Arc<str> {
+        if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(&text, "\n") {
+            replaced.into()
+        } else {
+            text
+        }
+    }
+}
 #[async_trait::async_trait]
 pub trait Fs: Send + Sync {
     async fn create_dir(&self, path: &Path) -> Result<()>;

crates/text/Cargo.toml 🔗

@@ -13,6 +13,7 @@ test-support = ["rand"]
 [dependencies]
 clock = { path = "../clock" }
 collections = { path = "../collections" }
+fs = { path = "../fs" }
 sum_tree = { path = "../sum_tree" }
 anyhow = "1.0.38"
 arrayvec = "0.7.1"

crates/text/src/text.rs 🔗

@@ -96,12 +96,6 @@ pub struct Transaction {
     pub start: clock::Global,
 }
 
-#[derive(Clone, Copy, Debug, PartialEq)]
-pub enum LineEnding {
-    Unix,
-    Windows,
-}
-
 impl HistoryEntry {
     pub fn transaction_id(&self) -> TransactionId {
         self.transaction.id
@@ -2370,56 +2364,6 @@ impl operation_queue::Operation for Operation {
     }
 }
 
-impl Default for LineEnding {
-    fn default() -> Self {
-        #[cfg(unix)]
-        return Self::Unix;
-
-        #[cfg(not(unix))]
-        return Self::CRLF;
-    }
-}
-
-impl LineEnding {
-    pub fn as_str(&self) -> &'static str {
-        match self {
-            LineEnding::Unix => "\n",
-            LineEnding::Windows => "\r\n",
-        }
-    }
-
-    pub fn detect(text: &str) -> Self {
-        let mut max_ix = cmp::min(text.len(), 1000);
-        while !text.is_char_boundary(max_ix) {
-            max_ix -= 1;
-        }
-
-        if let Some(ix) = text[..max_ix].find(&['\n']) {
-            if ix > 0 && text.as_bytes()[ix - 1] == b'\r' {
-                Self::Windows
-            } else {
-                Self::Unix
-            }
-        } else {
-            Self::default()
-        }
-    }
-
-    pub fn normalize(text: &mut String) {
-        if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(text, "\n") {
-            *text = replaced;
-        }
-    }
-
-    fn normalize_arc(text: Arc<str>) -> Arc<str> {
-        if let Cow::Owned(replaced) = CARRIAGE_RETURNS_REGEX.replace_all(&text, "\n") {
-            replaced.into()
-        } else {
-            text
-        }
-    }
-}
-
 pub trait ToOffset {
     fn to_offset(&self, snapshot: &BufferSnapshot) -> usize;
 }

crates/zed/src/settings_file.rs 🔗

@@ -12,6 +12,10 @@ use util::ResultExt;
 #[derive(Clone)]
 pub struct WatchedJsonFile<T>(pub watch::Receiver<T>);
 
+// 1) Do the refactoring to pull WatchedJSON and fs out and into everything else
+// 2) Scaffold this by making the basic structs we'll need SettingsFile::atomic_write_theme()
+// 3) Fix the overeager settings writing, if that works, and there's no data loss, call it?
+
 impl<T> WatchedJsonFile<T>
 where
     T: 'static + for<'de> Deserialize<'de> + Clone + Default + Send + Sync,