Don't pass `&mut Workspace` when closing items in a `Pane`

Antonio Scandurra created

This allows closing items via actions even in the `TerminalPanel`
where the `Pane` is not directly owned by a `Workspace`.

Change summary

crates/workspace/src/item.rs      |   2 
crates/workspace/src/pane.rs      | 268 ++++++++------------------------
crates/workspace/src/workspace.rs |  43 +---
crates/zed/src/zed.rs             |  56 ++----
4 files changed, 110 insertions(+), 259 deletions(-)

Detailed changes

crates/workspace/src/item.rs 🔗

@@ -437,7 +437,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
                     for item_event in T::to_item_events(event).into_iter() {
                         match item_event {
                             ItemEvent::CloseItem => {
-                                Pane::close_item_by_id(workspace, pane, item.id(), cx)
+                                pane.update(cx, |pane, cx| pane.close_item_by_id(item.id(), cx))
                                     .detach_and_log_err(cx);
                                 return;
                             }

crates/workspace/src/pane.rs 🔗

@@ -681,187 +681,108 @@ impl Pane {
     }
 
     pub fn close_active_item(
-        workspace: &mut Workspace,
+        &mut self,
         _: &CloseActiveItem,
-        cx: &mut ViewContext<Workspace>,
+        cx: &mut ViewContext<Self>,
     ) -> Option<Task<Result<()>>> {
-        let pane_handle = workspace.active_pane().clone();
-        let pane = pane_handle.read(cx);
-
-        if pane.items.is_empty() {
+        if self.items.is_empty() {
             return None;
         }
-        let active_item_id = pane.items[pane.active_item_index].id();
-
-        let task = Self::close_item_by_id(workspace, pane_handle, active_item_id, cx);
-
-        Some(cx.foreground().spawn(async move {
-            task.await?;
-            Ok(())
-        }))
+        let active_item_id = self.items[self.active_item_index].id();
+        Some(self.close_item_by_id(active_item_id, cx))
     }
 
     pub fn close_item_by_id(
-        workspace: &mut Workspace,
-        pane: ViewHandle<Pane>,
+        &mut self,
         item_id_to_close: usize,
-        cx: &mut ViewContext<Workspace>,
+        cx: &mut ViewContext<Self>,
     ) -> Task<Result<()>> {
-        Self::close_items(workspace, pane, cx, move |view_id| {
-            view_id == item_id_to_close
-        })
+        self.close_items(cx, move |view_id| view_id == item_id_to_close)
     }
 
     pub fn close_inactive_items(
-        workspace: &mut Workspace,
+        &mut self,
         _: &CloseInactiveItems,
-        cx: &mut ViewContext<Workspace>,
+        cx: &mut ViewContext<Self>,
     ) -> Option<Task<Result<()>>> {
-        let pane_handle = workspace.active_pane().clone();
-        let pane = pane_handle.read(cx);
-        let active_item_id = pane.items[pane.active_item_index].id();
-
-        let task = Self::close_items(workspace, pane_handle, cx, move |item_id| {
-            item_id != active_item_id
-        });
-
-        Some(cx.foreground().spawn(async move {
-            task.await?;
-            Ok(())
-        }))
+        let active_item_id = self.items[self.active_item_index].id();
+        Some(self.close_items(cx, move |item_id| item_id != active_item_id))
     }
 
     pub fn close_clean_items(
-        workspace: &mut Workspace,
+        &mut self,
         _: &CloseCleanItems,
-        cx: &mut ViewContext<Workspace>,
+        cx: &mut ViewContext<Self>,
     ) -> Option<Task<Result<()>>> {
-        let pane_handle = workspace.active_pane().clone();
-        let pane = pane_handle.read(cx);
-
-        let item_ids: Vec<_> = pane
+        let item_ids: Vec<_> = self
             .items()
             .filter(|item| !item.is_dirty(cx))
             .map(|item| item.id())
             .collect();
-
-        let task = Self::close_items(workspace, pane_handle, cx, move |item_id| {
-            item_ids.contains(&item_id)
-        });
-
-        Some(cx.foreground().spawn(async move {
-            task.await?;
-            Ok(())
-        }))
+        Some(self.close_items(cx, move |item_id| item_ids.contains(&item_id)))
     }
 
     pub fn close_items_to_the_left(
-        workspace: &mut Workspace,
+        &mut self,
         _: &CloseItemsToTheLeft,
-        cx: &mut ViewContext<Workspace>,
+        cx: &mut ViewContext<Self>,
     ) -> Option<Task<Result<()>>> {
-        let pane_handle = workspace.active_pane().clone();
-        let pane = pane_handle.read(cx);
-        let active_item_id = pane.items[pane.active_item_index].id();
-
-        let task = Self::close_items_to_the_left_by_id(workspace, pane_handle, active_item_id, cx);
-
-        Some(cx.foreground().spawn(async move {
-            task.await?;
-            Ok(())
-        }))
+        let active_item_id = self.items[self.active_item_index].id();
+        Some(self.close_items_to_the_left_by_id(active_item_id, cx))
     }
 
     pub fn close_items_to_the_left_by_id(
-        workspace: &mut Workspace,
-        pane: ViewHandle<Pane>,
+        &mut self,
         item_id: usize,
-        cx: &mut ViewContext<Workspace>,
+        cx: &mut ViewContext<Self>,
     ) -> Task<Result<()>> {
-        let item_ids: Vec<_> = pane
-            .read(cx)
+        let item_ids: Vec<_> = self
             .items()
             .take_while(|item| item.id() != item_id)
             .map(|item| item.id())
             .collect();
-
-        let task = Self::close_items(workspace, pane, cx, move |item_id| {
-            item_ids.contains(&item_id)
-        });
-
-        cx.foreground().spawn(async move {
-            task.await?;
-            Ok(())
-        })
+        self.close_items(cx, move |item_id| item_ids.contains(&item_id))
     }
 
     pub fn close_items_to_the_right(
-        workspace: &mut Workspace,
+        &mut self,
         _: &CloseItemsToTheRight,
-        cx: &mut ViewContext<Workspace>,
+        cx: &mut ViewContext<Self>,
     ) -> Option<Task<Result<()>>> {
-        let pane_handle = workspace.active_pane().clone();
-        let pane = pane_handle.read(cx);
-        let active_item_id = pane.items[pane.active_item_index].id();
-
-        let task = Self::close_items_to_the_right_by_id(workspace, pane_handle, active_item_id, cx);
-
-        Some(cx.foreground().spawn(async move {
-            task.await?;
-            Ok(())
-        }))
+        let active_item_id = self.items[self.active_item_index].id();
+        Some(self.close_items_to_the_right_by_id(active_item_id, cx))
     }
 
     pub fn close_items_to_the_right_by_id(
-        workspace: &mut Workspace,
-        pane: ViewHandle<Pane>,
+        &mut self,
         item_id: usize,
-        cx: &mut ViewContext<Workspace>,
+        cx: &mut ViewContext<Self>,
     ) -> Task<Result<()>> {
-        let item_ids: Vec<_> = pane
-            .read(cx)
+        let item_ids: Vec<_> = self
             .items()
             .rev()
             .take_while(|item| item.id() != item_id)
             .map(|item| item.id())
             .collect();
-
-        let task = Self::close_items(workspace, pane, cx, move |item_id| {
-            item_ids.contains(&item_id)
-        });
-
-        cx.foreground().spawn(async move {
-            task.await?;
-            Ok(())
-        })
+        self.close_items(cx, move |item_id| item_ids.contains(&item_id))
     }
 
     pub fn close_all_items(
-        workspace: &mut Workspace,
+        &mut self,
         _: &CloseAllItems,
-        cx: &mut ViewContext<Workspace>,
+        cx: &mut ViewContext<Self>,
     ) -> Option<Task<Result<()>>> {
-        let pane_handle = workspace.active_pane().clone();
-
-        let task = Self::close_items(workspace, pane_handle, cx, move |_| true);
-
-        Some(cx.foreground().spawn(async move {
-            task.await?;
-            Ok(())
-        }))
+        Some(self.close_items(cx, move |_| true))
     }
 
     pub fn close_items(
-        workspace: &mut Workspace,
-        pane: ViewHandle<Pane>,
-        cx: &mut ViewContext<Workspace>,
+        &mut self,
+        cx: &mut ViewContext<Pane>,
         should_close: impl 'static + Fn(usize) -> bool,
     ) -> Task<Result<()>> {
-        let project = workspace.project().clone();
-
         // Find the items to close.
         let mut items_to_close = Vec::new();
-        for item in &pane.read(cx).items {
+        for item in &self.items {
             if should_close(item.id()) {
                 items_to_close.push(item.boxed_clone());
             }
@@ -873,8 +794,8 @@ impl Pane {
         // of what content they would be saving.
         items_to_close.sort_by_key(|item| !item.is_singleton(cx));
 
-        let pane = pane.downgrade();
-        cx.spawn(|workspace, mut cx| async move {
+        let workspace = self.workspace.clone();
+        cx.spawn(|pane, mut cx| async move {
             let mut saved_project_items_ids = HashSet::default();
             for item in items_to_close.clone() {
                 // Find the item's current index and its set of project item models. Avoid
@@ -892,7 +813,7 @@ impl Pane {
                 // Check if this view has any project items that are not open anywhere else
                 // in the workspace, AND that the user has not already been prompted to save.
                 // If there are any such project entries, prompt the user to save this item.
-                workspace.read_with(&cx, |workspace, cx| {
+                let project = workspace.read_with(&cx, |workspace, cx| {
                     for item in workspace.items(cx) {
                         if !items_to_close
                             .iter()
@@ -902,6 +823,7 @@ impl Pane {
                             project_item_ids.retain(|id| !other_project_item_ids.contains(id));
                         }
                     }
+                    workspace.project().clone()
                 })?;
                 let should_save = project_item_ids
                     .iter()
@@ -1200,14 +1122,11 @@ impl Pane {
                     // In the case of the user right clicking on a non-active tab, for some item-closing commands, we need to provide the id of the tab, for the others, we can reuse the existing command.
                     vec![
                         ContextMenuItem::handler("Close Inactive Item", {
-                            let workspace = self.workspace.clone();
                             let pane = target_pane.clone();
                             move |cx| {
-                                if let Some((workspace, pane)) =
-                                    workspace.upgrade(cx).zip(pane.upgrade(cx))
-                                {
-                                    workspace.update(cx, |workspace, cx| {
-                                        Self::close_item_by_id(workspace, pane, target_item_id, cx)
+                                if let Some(pane) = pane.upgrade(cx) {
+                                    pane.update(cx, |pane, cx| {
+                                        pane.close_item_by_id(target_item_id, cx)
                                             .detach_and_log_err(cx);
                                     })
                                 }
@@ -1216,39 +1135,23 @@ impl Pane {
                         ContextMenuItem::action("Close Inactive Items", CloseInactiveItems),
                         ContextMenuItem::action("Close Clean Items", CloseCleanItems),
                         ContextMenuItem::handler("Close Items To The Left", {
-                            let workspace = self.workspace.clone();
                             let pane = target_pane.clone();
                             move |cx| {
-                                if let Some((workspace, pane)) =
-                                    workspace.upgrade(cx).zip(pane.upgrade(cx))
-                                {
-                                    workspace.update(cx, |workspace, cx| {
-                                        Self::close_items_to_the_left_by_id(
-                                            workspace,
-                                            pane,
-                                            target_item_id,
-                                            cx,
-                                        )
-                                        .detach_and_log_err(cx);
+                                if let Some(pane) = pane.upgrade(cx) {
+                                    pane.update(cx, |pane, cx| {
+                                        pane.close_items_to_the_left_by_id(target_item_id, cx)
+                                            .detach_and_log_err(cx);
                                     })
                                 }
                             }
                         }),
                         ContextMenuItem::handler("Close Items To The Right", {
-                            let workspace = self.workspace.clone();
                             let pane = target_pane.clone();
                             move |cx| {
-                                if let Some((workspace, pane)) =
-                                    workspace.upgrade(cx).zip(pane.upgrade(cx))
-                                {
-                                    workspace.update(cx, |workspace, cx| {
-                                        Self::close_items_to_the_right_by_id(
-                                            workspace,
-                                            pane,
-                                            target_item_id,
-                                            cx,
-                                        )
-                                        .detach_and_log_err(cx);
+                                if let Some(pane) = pane.upgrade(cx) {
+                                    pane.update(cx, |pane, cx| {
+                                        pane.close_items_to_the_right_by_id(target_item_id, cx)
+                                            .detach_and_log_err(cx);
                                     })
                                 }
                             }
@@ -1336,20 +1239,7 @@ impl Pane {
                                 .on_click(MouseButton::Middle, {
                                     let item_id = item.id();
                                     move |_, pane, cx| {
-                                        let workspace = pane.workspace.clone();
-                                        let pane = cx.weak_handle();
-                                        cx.window_context().defer(move |cx| {
-                                            if let Some((workspace, pane)) =
-                                                workspace.upgrade(cx).zip(pane.upgrade(cx))
-                                            {
-                                                workspace.update(cx, |workspace, cx| {
-                                                    Self::close_item_by_id(
-                                                        workspace, pane, item_id, cx,
-                                                    )
-                                                    .detach_and_log_err(cx);
-                                                });
-                                            }
-                                        });
+                                        pane.close_item_by_id(item_id, cx).detach_and_log_err(cx);
                                     }
                                 })
                                 .on_down(
@@ -1556,12 +1446,9 @@ impl Pane {
                             let pane = pane.clone();
                             cx.window_context().defer(move |cx| {
                                 if let Some(pane) = pane.upgrade(cx) {
-                                    if let Some(workspace) = pane.read(cx).workspace.upgrade(cx) {
-                                        workspace.update(cx, |workspace, cx| {
-                                            Self::close_item_by_id(workspace, pane, item_id, cx)
-                                                .detach_and_log_err(cx);
-                                        });
-                                    }
+                                    pane.update(cx, |pane, cx| {
+                                        pane.close_item_by_id(item_id, cx).detach_and_log_err(cx);
+                                    });
                                 }
                             });
                         }
@@ -2028,9 +1915,10 @@ mod tests {
 
         let project = Project::test(fs, None, cx).await;
         let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
+        let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
 
-        workspace.update(cx, |workspace, cx| {
-            assert!(Pane::close_active_item(workspace, &CloseActiveItem, cx).is_none())
+        pane.update(cx, |pane, cx| {
+            assert!(pane.close_active_item(&CloseActiveItem, cx).is_none())
         });
     }
 
@@ -2327,30 +2215,22 @@ mod tests {
         add_labeled_item(&workspace, &pane, "1", false, cx);
         assert_item_labels(&pane, ["A", "B", "1*", "C", "D"], cx);
 
-        workspace.update(cx, |workspace, cx| {
-            Pane::close_active_item(workspace, &CloseActiveItem, cx);
-        });
+        pane.update(cx, |pane, cx| pane.close_active_item(&CloseActiveItem, cx));
         deterministic.run_until_parked();
         assert_item_labels(&pane, ["A", "B*", "C", "D"], cx);
 
         pane.update(cx, |pane, cx| pane.activate_item(3, false, false, cx));
         assert_item_labels(&pane, ["A", "B", "C", "D*"], cx);
 
-        workspace.update(cx, |workspace, cx| {
-            Pane::close_active_item(workspace, &CloseActiveItem, cx);
-        });
+        pane.update(cx, |pane, cx| pane.close_active_item(&CloseActiveItem, cx));
         deterministic.run_until_parked();
         assert_item_labels(&pane, ["A", "B*", "C"], cx);
 
-        workspace.update(cx, |workspace, cx| {
-            Pane::close_active_item(workspace, &CloseActiveItem, cx);
-        });
+        pane.update(cx, |pane, cx| pane.close_active_item(&CloseActiveItem, cx));
         deterministic.run_until_parked();
         assert_item_labels(&pane, ["A", "C*"], cx);
 
-        workspace.update(cx, |workspace, cx| {
-            Pane::close_active_item(workspace, &CloseActiveItem, cx);
-        });
+        pane.update(cx, |pane, cx| pane.close_active_item(&CloseActiveItem, cx));
         deterministic.run_until_parked();
         assert_item_labels(&pane, ["A*"], cx);
     }
@@ -2366,8 +2246,8 @@ mod tests {
 
         set_labeled_items(&workspace, &pane, ["A", "B", "C*", "D", "E"], cx);
 
-        workspace.update(cx, |workspace, cx| {
-            Pane::close_inactive_items(workspace, &CloseInactiveItems, cx);
+        pane.update(cx, |pane, cx| {
+            pane.close_inactive_items(&CloseInactiveItems, cx)
         });
 
         deterministic.run_until_parked();
@@ -2390,9 +2270,7 @@ mod tests {
         add_labeled_item(&workspace, &pane, "E", false, cx);
         assert_item_labels(&pane, ["A^", "B", "C^", "D", "E*"], cx);
 
-        workspace.update(cx, |workspace, cx| {
-            Pane::close_clean_items(workspace, &CloseCleanItems, cx);
-        });
+        pane.update(cx, |pane, cx| pane.close_clean_items(&CloseCleanItems, cx));
 
         deterministic.run_until_parked();
         assert_item_labels(&pane, ["A^", "C*^"], cx);
@@ -2412,8 +2290,8 @@ mod tests {
 
         set_labeled_items(&workspace, &pane, ["A", "B", "C*", "D", "E"], cx);
 
-        workspace.update(cx, |workspace, cx| {
-            Pane::close_items_to_the_left(workspace, &CloseItemsToTheLeft, cx);
+        pane.update(cx, |pane, cx| {
+            pane.close_items_to_the_left(&CloseItemsToTheLeft, cx)
         });
 
         deterministic.run_until_parked();
@@ -2434,8 +2312,8 @@ mod tests {
 
         set_labeled_items(&workspace, &pane, ["A", "B", "C*", "D", "E"], cx);
 
-        workspace.update(cx, |workspace, cx| {
-            Pane::close_items_to_the_right(workspace, &CloseItemsToTheRight, cx);
+        pane.update(cx, |pane, cx| {
+            pane.close_items_to_the_right(&CloseItemsToTheRight, cx)
         });
 
         deterministic.run_until_parked();
@@ -2456,9 +2334,7 @@ mod tests {
         add_labeled_item(&workspace, &pane, "C", false, cx);
         assert_item_labels(&pane, ["A", "B", "C*"], cx);
 
-        workspace.update(cx, |workspace, cx| {
-            Pane::close_all_items(workspace, &CloseAllItems, cx);
-        });
+        pane.update(cx, |pane, cx| pane.close_all_items(&CloseAllItems, cx));
 
         deterministic.run_until_parked();
         assert_item_labels(&pane, [], cx);

crates/workspace/src/workspace.rs 🔗

@@ -3125,6 +3125,7 @@ mod tests {
 
         let project = Project::test(fs, ["root1".as_ref()], cx).await;
         let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
+        let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
         let worktree_id = project.read_with(cx, |project, cx| {
             project.worktrees(cx).next().unwrap().read(cx).id()
         });
@@ -3167,12 +3168,11 @@ mod tests {
         });
 
         // Close the active item
-        workspace
-            .update(cx, |workspace, cx| {
-                Pane::close_active_item(workspace, &Default::default(), cx).unwrap()
-            })
-            .await
-            .unwrap();
+        pane.update(cx, |pane, cx| {
+            pane.close_active_item(&Default::default(), cx).unwrap()
+        })
+        .await
+        .unwrap();
         assert_eq!(
             cx.current_window_title(window_id).as_deref(),
             Some("one.txt — root1")
@@ -3281,18 +3281,13 @@ mod tests {
             workspace.active_pane().clone()
         });
 
-        let close_items = workspace.update(cx, |workspace, cx| {
-            pane.update(cx, |pane, cx| {
-                pane.activate_item(1, true, true, cx);
-                assert_eq!(pane.active_item().unwrap().id(), item2.id());
-            });
-
+        let close_items = pane.update(cx, |pane, cx| {
+            pane.activate_item(1, true, true, cx);
+            assert_eq!(pane.active_item().unwrap().id(), item2.id());
             let item1_id = item1.id();
             let item3_id = item3.id();
             let item4_id = item4.id();
-            Pane::close_items(workspace, pane.clone(), cx, move |id| {
-                [item1_id, item3_id, item4_id].contains(&id)
-            })
+            pane.close_items(cx, move |id| [item1_id, item3_id, item4_id].contains(&id))
         });
         cx.foreground().run_until_parked();
 
@@ -3426,10 +3421,7 @@ mod tests {
         // once for project entry 0, and once for project entry 2. After those two
         // prompts, the task should complete.
 
-        let close = workspace.update(cx, |workspace, cx| {
-            Pane::close_items(workspace, left_pane.clone(), cx, |_| true)
-        });
-
+        let close = left_pane.update(cx, |pane, cx| pane.close_items(cx, |_| true));
         cx.foreground().run_until_parked();
         left_pane.read_with(cx, |pane, cx| {
             assert_eq!(
@@ -3464,6 +3456,7 @@ mod tests {
 
         let project = Project::test(fs, [], cx).await;
         let (window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx));
+        let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
 
         let item = cx.add_view(window_id, |cx| {
             TestItem::new().with_project_items(&[TestProjectItem::new(1, "1.txt", cx)])
@@ -3536,11 +3529,7 @@ mod tests {
             item.is_dirty = true;
         });
 
-        workspace
-            .update(cx, |workspace, cx| {
-                let pane = workspace.active_pane().clone();
-                Pane::close_items(workspace, pane, cx, move |id| id == item_id)
-            })
+        pane.update(cx, |pane, cx| pane.close_items(cx, move |id| id == item_id))
             .await
             .unwrap();
         assert!(!cx.has_pending_prompt(window_id));
@@ -3561,10 +3550,8 @@ mod tests {
         item.read_with(cx, |item, _| assert_eq!(item.save_count, 5));
 
         // Ensure autosave is prevented for deleted files also when closing the buffer.
-        let _close_items = workspace.update(cx, |workspace, cx| {
-            let pane = workspace.active_pane().clone();
-            Pane::close_items(workspace, pane, cx, move |id| id == item_id)
-        });
+        let _close_items =
+            pane.update(cx, |pane, cx| pane.close_items(cx, move |id| id == item_id));
         deterministic.run_until_parked();
         assert!(cx.has_pending_prompt(window_id));
         item.read_with(cx, |item, _| assert_eq!(item.save_count, 5));

crates/zed/src/zed.rs 🔗

@@ -734,6 +734,7 @@ mod tests {
             .unwrap()
             .downcast::<Workspace>()
             .unwrap();
+        let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
         let editor = workspace.read_with(cx, |workspace, cx| {
             workspace
                 .active_item(cx)
@@ -756,9 +757,9 @@ mod tests {
         assert!(cx.is_window_edited(workspace.window_id()));
 
         // Closing the item restores the window's edited state.
-        let close = workspace.update(cx, |workspace, cx| {
+        let close = pane.update(cx, |pane, cx| {
             drop(editor);
-            Pane::close_active_item(workspace, &Default::default(), cx).unwrap()
+            pane.close_active_item(&Default::default(), cx).unwrap()
         });
         executor.run_until_parked();
         cx.simulate_prompt_answer(workspace.window_id(), 1);
@@ -1384,6 +1385,7 @@ mod tests {
 
         let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
         let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
+        let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
 
         let entries = cx.read(|cx| workspace.file_project_paths(cx));
         let file1 = entries[0].clone();
@@ -1501,14 +1503,13 @@ mod tests {
 
         // Go forward to an item that has been closed, ensuring it gets re-opened at the same
         // location.
-        workspace
-            .update(cx, |workspace, cx| {
-                let editor3_id = editor3.id();
-                drop(editor3);
-                Pane::close_item_by_id(workspace, workspace.active_pane().clone(), editor3_id, cx)
-            })
-            .await
-            .unwrap();
+        pane.update(cx, |pane, cx| {
+            let editor3_id = editor3.id();
+            drop(editor3);
+            pane.close_item_by_id(editor3_id, cx)
+        })
+        .await
+        .unwrap();
         workspace
             .update(cx, |w, cx| Pane::go_forward(w, None, cx))
             .await
@@ -1537,14 +1538,13 @@ mod tests {
         );
 
         // Go back to an item that has been closed and removed from disk, ensuring it gets skipped.
-        workspace
-            .update(cx, |workspace, cx| {
-                let editor2_id = editor2.id();
-                drop(editor2);
-                Pane::close_item_by_id(workspace, workspace.active_pane().clone(), editor2_id, cx)
-            })
-            .await
-            .unwrap();
+        pane.update(cx, |pane, cx| {
+            let editor2_id = editor2.id();
+            drop(editor2);
+            pane.close_item_by_id(editor2_id, cx)
+        })
+        .await
+        .unwrap();
         app_state
             .fs
             .remove_file(Path::new("/root/a/file2"), Default::default())
@@ -1693,34 +1693,22 @@ mod tests {
         assert_eq!(active_path(&workspace, cx), Some(file4.clone()));
 
         // Close all the pane items in some arbitrary order.
-        workspace
-            .update(cx, |workspace, cx| {
-                Pane::close_item_by_id(workspace, pane.clone(), file1_item_id, cx)
-            })
+        pane.update(cx, |pane, cx| pane.close_item_by_id(file1_item_id, cx))
             .await
             .unwrap();
         assert_eq!(active_path(&workspace, cx), Some(file4.clone()));
 
-        workspace
-            .update(cx, |workspace, cx| {
-                Pane::close_item_by_id(workspace, pane.clone(), file4_item_id, cx)
-            })
+        pane.update(cx, |pane, cx| pane.close_item_by_id(file4_item_id, cx))
             .await
             .unwrap();
         assert_eq!(active_path(&workspace, cx), Some(file3.clone()));
 
-        workspace
-            .update(cx, |workspace, cx| {
-                Pane::close_item_by_id(workspace, pane.clone(), file2_item_id, cx)
-            })
+        pane.update(cx, |pane, cx| pane.close_item_by_id(file2_item_id, cx))
             .await
             .unwrap();
         assert_eq!(active_path(&workspace, cx), Some(file3.clone()));
 
-        workspace
-            .update(cx, |workspace, cx| {
-                Pane::close_item_by_id(workspace, pane.clone(), file3_item_id, cx)
-            })
+        pane.update(cx, |pane, cx| pane.close_item_by_id(file3_item_id, cx))
             .await
             .unwrap();
         assert_eq!(active_path(&workspace, cx), None);