Use read-only access methods for read-only entity operations (#31479)

Another follow-up to #31254

Release Notes:

- N/A
This commit is contained in:
Joseph T. Lyons 2025-05-26 23:04:31 -04:00 committed by GitHub
parent 4a577fff4a
commit c208532693
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
79 changed files with 319 additions and 306 deletions

View file

@ -1762,7 +1762,7 @@ impl Pane {
return Ok(true);
}
let Some(item_ix) = pane
.update(cx, |pane, _| pane.index_for_item(item))
.read_with(cx, |pane, _| pane.index_for_item(item))
.ok()
.flatten()
else {
@ -2017,7 +2017,8 @@ impl Pane {
let pane = cx.entity().clone();
window.defer(cx, move |window, cx| {
let Ok(status_bar) = workspace.update(cx, |workspace, _| workspace.status_bar.clone())
let Ok(status_bar) =
workspace.read_with(cx, |workspace, _| workspace.status_bar.clone())
else {
return;
};
@ -3760,7 +3761,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
pane.update_in(cx, |pane, window, cx| {
assert!(
@ -3785,7 +3786,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
for i in 0..7 {
add_labeled_item(&pane, format!("{}", i).as_str(), false, cx);
@ -3834,7 +3835,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
// 1. Add with a destination index
// a. Add before the active item
@ -3917,7 +3918,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
// 1. Add with a destination index
// 1a. Add before the active item
@ -3993,7 +3994,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
// singleton view
pane.update_in(cx, |pane, window, cx| {
@ -4098,7 +4099,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
add_labeled_item(&pane, "A", false, cx);
add_labeled_item(&pane, "B", false, cx);
@ -4191,7 +4192,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
add_labeled_item(&pane, "A", false, cx);
add_labeled_item(&pane, "B", false, cx);
@ -4284,7 +4285,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
add_labeled_item(&pane, "A", false, cx);
add_labeled_item(&pane, "B", false, cx);
@ -4377,7 +4378,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx);
@ -4405,7 +4406,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
add_labeled_item(&pane, "A", true, cx);
add_labeled_item(&pane, "B", false, cx);
@ -4437,7 +4438,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx);
@ -4464,7 +4465,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx);
@ -4491,7 +4492,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let item_a = add_labeled_item(&pane, "A", false, cx);
add_labeled_item(&pane, "B", false, cx);
@ -4596,7 +4597,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let a = cx.update(|_, cx| TestProjectItem::new_dirty(1, "A.txt", cx));
let b = cx.update(|_, cx| TestProjectItem::new_dirty(1, "B.txt", cx));
@ -4640,7 +4641,7 @@ mod tests {
let project = Project::test(fs, None, cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let item_a = add_labeled_item(&pane, "A", false, cx);
add_labeled_item(&pane, "B", false, cx);
@ -4674,7 +4675,7 @@ mod tests {
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
// Non-pinned tabs in same pane
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
add_labeled_item(&pane, "A", false, cx);
add_labeled_item(&pane, "B", false, cx);
add_labeled_item(&pane, "C", false, cx);
@ -4705,7 +4706,7 @@ mod tests {
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
// No non-pinned tabs in same pane, non-pinned tabs in another pane
let pane1 = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane1 = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let pane2 = workspace.update_in(cx, |workspace, window, cx| {
workspace.split_pane(pane1.clone(), SplitDirection::Right, window, cx)
});

View file

@ -410,7 +410,10 @@ impl SerializedPaneGroup {
.await
.log_err()?;
if pane.update(cx, |pane, _| pane.items_len() != 0).log_err()? {
if pane
.read_with(cx, |pane, _| pane.items_len() != 0)
.log_err()?
{
let pane = pane.upgrade()?;
Some((
Member::Pane(pane.clone()),

View file

@ -2519,7 +2519,7 @@ impl Workspace {
});
cx.spawn(async move |cx| {
let (worktree, path) = entry.await?;
let worktree_id = worktree.update(cx, |t, _| t.id())?;
let worktree_id = worktree.read_with(cx, |t, _| t.id())?;
Ok((
worktree,
ProjectPath {
@ -5147,7 +5147,7 @@ impl Workspace {
cx: &mut Context<Workspace>,
) -> Task<Result<Vec<Option<Box<dyn ItemHandle>>>>> {
cx.spawn_in(window, async move |workspace, cx| {
let project = workspace.update(cx, |workspace, _| workspace.project().clone())?;
let project = workspace.read_with(cx, |workspace, _| workspace.project().clone())?;
let mut center_group = None;
let mut center_items = None;
@ -6836,7 +6836,7 @@ pub fn create_and_open_local_file(
default_content: impl 'static + Send + FnOnce() -> Rope,
) -> Task<Result<Box<dyn ItemHandle>>> {
cx.spawn_in(window, async move |workspace, cx| {
let fs = workspace.update(cx, |workspace, _| workspace.app_state().fs.clone())?;
let fs = workspace.read_with(cx, |workspace, _| workspace.app_state().fs.clone())?;
if !fs.is_file(path).await {
fs.create_file(path, Default::default()).await?;
fs.save(path, &default_content(), Default::default())
@ -7647,7 +7647,7 @@ mod tests {
workspace.update_in(cx, |workspace, window, cx| {
workspace.add_item_to_active_pane(Box::new(item1.clone()), None, true, window, cx);
});
item1.update(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(0)));
item1.read_with(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(0)));
// Adding an item that creates ambiguity increases the level of detail on
// both tabs.
@ -7659,8 +7659,8 @@ mod tests {
workspace.update_in(cx, |workspace, window, cx| {
workspace.add_item_to_active_pane(Box::new(item2.clone()), None, true, window, cx);
});
item1.update(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(1)));
item2.update(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(1)));
item1.read_with(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(1)));
item2.read_with(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(1)));
// Adding an item that creates ambiguity increases the level of detail only
// on the ambiguous tabs. In this case, the ambiguity can't be resolved so
@ -7673,9 +7673,9 @@ mod tests {
workspace.update_in(cx, |workspace, window, cx| {
workspace.add_item_to_active_pane(Box::new(item3.clone()), None, true, window, cx);
});
item1.update(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(1)));
item2.update(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(3)));
item3.update(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(3)));
item1.read_with(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(1)));
item2.read_with(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(3)));
item3.read_with(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(3)));
}
#[gpui::test]
@ -7702,7 +7702,7 @@ mod tests {
let project = Project::test(fs, ["root1".as_ref()], cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let worktree_id = project.update(cx, |project, cx| {
project.worktrees(cx).next().unwrap().read(cx).id()
});
@ -8099,7 +8099,7 @@ mod tests {
cx.executor().run_until_parked();
close.await.unwrap();
right_pane.update(cx, |pane, _| {
right_pane.read_with(cx, |pane, _| {
assert_eq!(pane.items_len(), 0);
});
}
@ -8112,7 +8112,7 @@ mod tests {
let project = Project::test(fs, [], cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let item = cx.new(|cx| {
TestItem::new(cx).with_project_items(&[TestProjectItem::new(1, "1.txt", cx)])
@ -8134,12 +8134,12 @@ mod tests {
// Deactivating the window saves the file.
cx.deactivate_window();
item.update(cx, |item, _| assert_eq!(item.save_count, 1));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 1));
// Re-activating the window doesn't save the file.
cx.update(|window, _| window.activate_window());
cx.executor().run_until_parked();
item.update(cx, |item, _| assert_eq!(item.save_count, 1));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 1));
// Autosave on focus change.
item.update_in(cx, |item, window, cx| {
@ -8155,7 +8155,7 @@ mod tests {
// Blurring the item saves the file.
item.update_in(cx, |_, window, _| window.blur());
cx.executor().run_until_parked();
item.update(cx, |item, _| assert_eq!(item.save_count, 2));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 2));
// Deactivating the window still saves the file.
item.update_in(cx, |item, window, cx| {
@ -8178,11 +8178,11 @@ mod tests {
// Delay hasn't fully expired, so the file is still dirty and unsaved.
cx.executor().advance_clock(Duration::from_millis(250));
item.update(cx, |item, _| assert_eq!(item.save_count, 3));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 3));
// After delay expires, the file is saved.
cx.executor().advance_clock(Duration::from_millis(250));
item.update(cx, |item, _| assert_eq!(item.save_count, 4));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 4));
// Autosave on focus change, ensuring closing the tab counts as such.
item.update(cx, |item, cx| {
@ -8203,7 +8203,7 @@ mod tests {
.await
.unwrap();
assert!(!cx.has_pending_prompt());
item.update(cx, |item, _| assert_eq!(item.save_count, 5));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 5));
// Add the item again, ensuring autosave is prevented if the underlying file has been deleted.
workspace.update_in(cx, |workspace, window, cx| {
@ -8217,7 +8217,7 @@ mod tests {
window.blur();
});
cx.run_until_parked();
item.update(cx, |item, _| assert_eq!(item.save_count, 5));
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 = pane.update_in(cx, |pane, window, cx| {
@ -8225,7 +8225,7 @@ mod tests {
});
cx.run_until_parked();
assert!(cx.has_pending_prompt());
item.update(cx, |item, _| assert_eq!(item.save_count, 5));
item.read_with(cx, |item, _| assert_eq!(item.save_count, 5));
}
#[gpui::test]
@ -8241,8 +8241,8 @@ mod tests {
let item = cx.new(|cx| {
TestItem::new(cx).with_project_items(&[TestProjectItem::new(1, "1.txt", cx)])
});
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let toolbar = pane.update(cx, |pane, _| pane.toolbar().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let toolbar = pane.read_with(cx, |pane, _| pane.toolbar().clone());
let toolbar_notify_count = Rc::new(RefCell::new(0));
workspace.update_in(cx, |workspace, window, cx| {
@ -8254,7 +8254,7 @@ mod tests {
.detach();
});
pane.update(cx, |pane, _| {
pane.read_with(cx, |pane, _| {
assert!(!pane.can_navigate_backward());
assert!(!pane.can_navigate_forward());
});
@ -8266,7 +8266,7 @@ mod tests {
// Toolbar must be notified to re-render the navigation buttons
assert_eq!(*toolbar_notify_count.borrow(), 1);
pane.update(cx, |pane, _| {
pane.read_with(cx, |pane, _| {
assert!(pane.can_navigate_backward());
assert!(!pane.can_navigate_forward());
});
@ -8279,7 +8279,7 @@ mod tests {
.unwrap();
assert_eq!(*toolbar_notify_count.borrow(), 2);
pane.update(cx, |pane, _| {
pane.read_with(cx, |pane, _| {
assert!(!pane.can_navigate_backward());
assert!(pane.can_navigate_forward());
});
@ -8305,7 +8305,7 @@ mod tests {
panel
});
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
pane.update_in(cx, |pane, window, cx| {
let item = cx.new(TestItem::new);
pane.add_item(Box::new(item), true, true, None, window, cx);
@ -8871,7 +8871,7 @@ mod tests {
// Emitting a ZoomIn event shows the panel as zoomed.
panel_1.update(cx, |_, cx| cx.emit(PanelEvent::ZoomIn));
workspace.update(cx, |workspace, _| {
workspace.read_with(cx, |workspace, _| {
assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
assert_eq!(workspace.zoomed_position, Some(DockPosition::Left));
});
@ -8880,7 +8880,7 @@ mod tests {
panel_1.update_in(cx, |panel, window, cx| {
panel.set_position(DockPosition::Right, window, cx)
});
workspace.update(cx, |workspace, _| {
workspace.read_with(cx, |workspace, _| {
assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
@ -8907,7 +8907,7 @@ mod tests {
// If focus is transferred to another view that's not a panel or another pane, we still show
// the panel as zoomed.
focus_other_view(cx);
workspace.update(cx, |workspace, _| {
workspace.read_with(cx, |workspace, _| {
assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
});
@ -8916,7 +8916,7 @@ mod tests {
workspace.update_in(cx, |_workspace, window, cx| {
cx.focus_self(window);
});
workspace.update(cx, |workspace, _| {
workspace.read_with(cx, |workspace, _| {
assert_eq!(workspace.zoomed, None);
assert_eq!(workspace.zoomed_position, None);
});
@ -8924,21 +8924,21 @@ mod tests {
// If focus is transferred again to another view that's not a panel or a pane, we won't
// show the panel as zoomed because it wasn't zoomed before.
focus_other_view(cx);
workspace.update(cx, |workspace, _| {
workspace.read_with(cx, |workspace, _| {
assert_eq!(workspace.zoomed, None);
assert_eq!(workspace.zoomed_position, None);
});
// When the panel is activated, it is zoomed again.
cx.dispatch_action(ToggleRightDock);
workspace.update(cx, |workspace, _| {
workspace.read_with(cx, |workspace, _| {
assert_eq!(workspace.zoomed, Some(panel_1.to_any().downgrade()));
assert_eq!(workspace.zoomed_position, Some(DockPosition::Right));
});
// Emitting a ZoomOut event unzooms the panel.
panel_1.update(cx, |_, cx| cx.emit(PanelEvent::ZoomOut));
workspace.update(cx, |workspace, _| {
workspace.read_with(cx, |workspace, _| {
assert_eq!(workspace.zoomed, None);
assert_eq!(workspace.zoomed_position, None);
});
@ -8961,7 +8961,7 @@ mod tests {
let project = Project::test(fs, [], cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let dirty_regular_buffer = cx.new(|cx| {
TestItem::new(cx)
@ -9109,7 +9109,7 @@ mod tests {
let project = Project::test(fs, [], cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let dirty_regular_buffer = cx.new(|cx| {
TestItem::new(cx)
@ -9199,7 +9199,7 @@ mod tests {
let project = Project::test(fs, [], cx).await;
let (workspace, cx) =
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
let pane = workspace.update(cx, |workspace, _| workspace.active_pane().clone());
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
let dirty_regular_buffer = cx.new(|cx| {
TestItem::new(cx)