- Add optional encoding parameter to Worktree::load_file

R Aadarsh created

- Remove the parameter from `BufferStore::open_buffer` as it is not
needed

Change summary

crates/edit_prediction_context/src/syntax_index.rs |  3 -
crates/languages/src/json.rs                       |  2 
crates/project/src/buffer_store.rs                 | 21 +++++++++++
crates/worktree/src/worktree.rs                    | 28 +++++++++++++--
crates/worktree/src/worktree_tests.rs              |  4 +-
crates/zeta/src/zeta.rs                            |  2 
6 files changed, 49 insertions(+), 11 deletions(-)

Detailed changes

crates/edit_prediction_context/src/syntax_index.rs 🔗

@@ -523,8 +523,7 @@ impl SyntaxIndex {
         };
 
         let snapshot_task = worktree.update(cx, |worktree, cx| {
-            let load_task = worktree.load_file(&project_path.path, cx);
-            let worktree_abs_path = worktree.abs_path();
+            let load_task = worktree.load_file(&project_path.path, None, cx);
             cx.spawn(async move |_this, cx| {
                 let loaded_file = load_task.await?;
                 let language = language.await?;

crates/languages/src/json.rs 🔗

@@ -56,7 +56,7 @@ impl ContextProvider for JsonTaskProvider {
         cx.spawn(async move |cx| {
             let contents = file
                 .worktree
-                .update(cx, |this, cx| this.load_file(&file.path, cx))
+                .update(cx, |this, cx| this.load_file(&file.path, None, cx))
                 .ok()?
                 .await
                 .ok()?;

crates/project/src/buffer_store.rs 🔗

@@ -633,7 +633,26 @@ impl LocalBufferStore {
         worktree: Entity<Worktree>,
         cx: &mut Context<BufferStore>,
     ) -> Task<Result<Entity<Buffer>>> {
-        let load_file = worktree.update(cx, |worktree, cx| worktree.load_file(path.as_ref(), cx));
+        let load_buffer = worktree.update(cx, |worktree, cx| {
+            let load_file = worktree.load_file(path.as_ref(), None, cx);
+            let reservation = cx.reserve_entity();
+            let buffer_id = BufferId::from(reservation.entity_id().as_non_zero_u64());
+            let path = path.clone();
+            cx.spawn(async move |_, cx| {
+                let loaded = load_file.await.with_context(|| {
+                    format!("Could not open path: {}", path.display(PathStyle::local()))
+                })?;
+                let text_buffer = cx
+                    .background_spawn(async move {
+                        text::Buffer::new(ReplicaId::LOCAL, buffer_id, loaded.text)
+                    })
+                    .await;
+                cx.insert_entity(reservation, |_| {
+                    Buffer::build(text_buffer, Some(loaded.file), Capability::ReadWrite)
+                })
+            })
+        });
+
         cx.spawn(async move |this, cx| {
             let buffer = match load_buffer.await {
                 Ok(buffer) => {

crates/worktree/src/worktree.rs 🔗

@@ -707,9 +707,14 @@ impl Worktree {
         }
     }
 
-    pub fn load_file(&self, path: &RelPath, cx: &Context<Worktree>) -> Task<Result<LoadedFile>> {
+    pub fn load_file(
+        &self,
+        path: &Path,
+        encoding: Option<Arc<std::sync::Mutex<&'static Encoding>>>,
+        cx: &Context<Worktree>,
+    ) -> Task<Result<LoadedFile>> {
         match self {
-            Worktree::Local(this) => this.load_file(path, cx),
+            Worktree::Local(this) => this.load_file(path, encoding, cx),
             Worktree::Remote(_) => {
                 Task::ready(Err(anyhow!("remote worktrees can't yet load files")))
             }
@@ -1316,7 +1321,12 @@ impl LocalWorktree {
         })
     }
 
-    fn load_file(&self, path: &RelPath, cx: &Context<Worktree>) -> Task<Result<LoadedFile>> {
+    fn load_file(
+        &self,
+        path: &Path,
+        encoding: Option<Arc<std::sync::Mutex<&'static Encoding>>>,
+        cx: &Context<Worktree>,
+    ) -> Task<Result<LoadedFile>> {
         let path = Arc::from(path);
         let abs_path = self.absolutize(&path);
         let fs = self.fs.clone();
@@ -1339,7 +1349,17 @@ impl LocalWorktree {
                     anyhow::bail!("File is too large to load");
                 }
             }
-            let text = fs.load(&abs_path).await?;
+            let text = fs
+                .load_with_encoding(
+                    &abs_path,
+                    if let Some(encoding) = encoding {
+                        EncodingWrapper::new(*encoding.lock().unwrap())
+                    } else {
+                        EncodingWrapper::new(encoding_rs::UTF_8)
+                    },
+                    false,
+                )
+                .await?;
 
             let worktree = this.upgrade().context("worktree was dropped")?;
             let file = match entry.await? {

crates/worktree/src/worktree_tests.rs 🔗

@@ -468,7 +468,7 @@ async fn test_open_gitignored_files(cx: &mut TestAppContext) {
     let prev_read_dir_count = fs.read_dir_call_count();
     let loaded = tree
         .update(cx, |tree, cx| {
-            tree.load_file(rel_path("one/node_modules/b/b1.js"), cx)
+            tree.load_file("one/node_modules/b/b1.js".as_ref(), None, cx)
         })
         .await
         .unwrap();
@@ -508,7 +508,7 @@ async fn test_open_gitignored_files(cx: &mut TestAppContext) {
     let prev_read_dir_count = fs.read_dir_call_count();
     let loaded = tree
         .update(cx, |tree, cx| {
-            tree.load_file(rel_path("one/node_modules/a/a2.js"), cx)
+            tree.load_file("one/node_modules/a/a2.js".as_ref(), None, cx)
         })
         .await
         .unwrap();

crates/zeta/src/zeta.rs 🔗

@@ -1986,7 +1986,7 @@ mod tests {
                     .worktree_for_root_name("closed_source_worktree", cx)
                     .unwrap();
                 worktree2.update(cx, |worktree2, cx| {
-                    worktree2.load_file(rel_path("main.rs"), cx)
+                    worktree2.load_file(Path::new("main.rs"), None, cx)
                 })
             })
             .await