Remove methods taking &mut Workspace from Pane (#2540)

This pull request simplifies the `Pane` struct by replacing methods like
`Pane::add_item` that would previously take a `&mut Workspace` with
methods that take a `&mut self`. When access to the workspace is needed,
we now either emit an event from the `Pane` or directly move the method
to the `Workspace` struct.
This commit is contained in:
Antonio Scandurra 2023-05-30 15:01:35 +02:00 committed by GitHub
commit 1fc9103b61
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 556 additions and 663 deletions

View file

@ -6608,7 +6608,7 @@ async fn test_basic_following(
// When client A navigates back and forth, client B does so as well. // When client A navigates back and forth, client B does so as well.
workspace_a workspace_a
.update(cx_a, |workspace, cx| { .update(cx_a, |workspace, cx| {
workspace::Pane::go_back(workspace, None, cx) workspace.go_back(workspace.active_pane().downgrade(), cx)
}) })
.await .await
.unwrap(); .unwrap();
@ -6619,7 +6619,7 @@ async fn test_basic_following(
workspace_a workspace_a
.update(cx_a, |workspace, cx| { .update(cx_a, |workspace, cx| {
workspace::Pane::go_back(workspace, None, cx) workspace.go_back(workspace.active_pane().downgrade(), cx)
}) })
.await .await
.unwrap(); .unwrap();
@ -6630,7 +6630,7 @@ async fn test_basic_following(
workspace_a workspace_a
.update(cx_a, |workspace, cx| { .update(cx_a, |workspace, cx| {
workspace::Pane::go_forward(workspace, None, cx) workspace.go_forward(workspace.active_pane().downgrade(), cx)
}) })
.await .await
.unwrap(); .unwrap();

View file

@ -4931,12 +4931,12 @@ impl Editor {
} }
fn push_to_nav_history( fn push_to_nav_history(
&self, &mut self,
cursor_anchor: Anchor, cursor_anchor: Anchor,
new_position: Option<Point>, new_position: Option<Point>,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) { ) {
if let Some(nav_history) = &self.nav_history { if let Some(nav_history) = self.nav_history.as_mut() {
let buffer = self.buffer.read(cx).read(cx); let buffer = self.buffer.read(cx).read(cx);
let cursor_position = cursor_anchor.to_point(&buffer); let cursor_position = cursor_anchor.to_point(&buffer);
let scroll_state = self.scroll_manager.anchor(); let scroll_state = self.scroll_manager.anchor();

View file

@ -5264,6 +5264,20 @@ impl Project {
Some(ProjectPath { worktree_id, path }) Some(ProjectPath { worktree_id, path })
} }
pub fn absolute_path(&self, project_path: &ProjectPath, cx: &AppContext) -> Option<PathBuf> {
let workspace_root = self
.worktree_for_id(project_path.worktree_id, cx)?
.read(cx)
.abs_path();
let project_path = project_path.path.as_ref();
Some(if project_path == Path::new("") {
workspace_root.to_path_buf()
} else {
workspace_root.join(project_path)
})
}
// RPC message handlers // RPC message handlers
async fn handle_unshare_project( async fn handle_unshare_project(

View file

@ -50,6 +50,7 @@ impl TerminalPanel {
let window_id = cx.window_id(); let window_id = cx.window_id();
let mut pane = Pane::new( let mut pane = Pane::new(
workspace.weak_handle(), workspace.weak_handle(),
workspace.project().clone(),
workspace.app_state().background_actions, workspace.app_state().background_actions,
Default::default(), Default::default(),
cx, cx,
@ -176,8 +177,9 @@ impl TerminalPanel {
(panel, pane, items) (panel, pane, items)
})?; })?;
let pane = pane.downgrade();
let items = futures::future::join_all(items).await; let items = futures::future::join_all(items).await;
workspace.update(&mut cx, |workspace, cx| { pane.update(&mut cx, |pane, cx| {
let active_item_id = serialized_panel let active_item_id = serialized_panel
.as_ref() .as_ref()
.and_then(|panel| panel.active_item_id); .and_then(|panel| panel.active_item_id);
@ -185,17 +187,15 @@ impl TerminalPanel {
for item in items { for item in items {
if let Some(item) = item.log_err() { if let Some(item) = item.log_err() {
let item_id = item.id(); let item_id = item.id();
Pane::add_item(workspace, &pane, Box::new(item), false, false, None, cx); pane.add_item(Box::new(item), false, false, None, cx);
if Some(item_id) == active_item_id { if Some(item_id) == active_item_id {
active_ix = Some(pane.read(cx).items_len() - 1); active_ix = Some(pane.items_len() - 1);
} }
} }
} }
if let Some(active_ix) = active_ix { if let Some(active_ix) = active_ix {
pane.update(cx, |pane, cx| { pane.activate_item(active_ix, false, false, cx)
pane.activate_item(active_ix, false, false, cx)
});
} }
})?; })?;
@ -240,8 +240,10 @@ impl TerminalPanel {
Box::new(cx.add_view(|cx| { Box::new(cx.add_view(|cx| {
TerminalView::new(terminal, workspace.database_id(), cx) TerminalView::new(terminal, workspace.database_id(), cx)
})); }));
let focus = pane.read(cx).has_focus(); pane.update(cx, |pane, cx| {
Pane::add_item(workspace, &pane, terminal, true, focus, None, cx); let focus = pane.has_focus();
pane.add_item(terminal, true, focus, None, cx);
});
} }
})?; })?;
this.update(&mut cx, |this, cx| this.serialize(cx))?; this.update(&mut cx, |this, cx| this.serialize(cx))?;

File diff suppressed because it is too large Load diff

View file

@ -183,7 +183,7 @@ pub fn handle_dropped_item<V: View>(
.zip(pane.upgrade(cx)) .zip(pane.upgrade(cx))
{ {
workspace.update(cx, |workspace, cx| { workspace.update(cx, |workspace, cx| {
Pane::move_item(workspace, from, to, item_id, index, cx); workspace.move_item(from, to, item_id, index, cx);
}) })
} }
}); });

View file

@ -1,5 +1,5 @@
use crate::{item::ItemHandle, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId}; use crate::{item::ItemHandle, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId};
use anyhow::{anyhow, Context, Result}; use anyhow::{Context, Result};
use async_recursion::async_recursion; use async_recursion::async_recursion;
use db::sqlez::{ use db::sqlez::{
bindable::{Bind, Column, StaticColumnCount}, bindable::{Bind, Column, StaticColumnCount},
@ -230,7 +230,7 @@ impl SerializedPane {
pub async fn deserialize_to( pub async fn deserialize_to(
&self, &self,
project: &ModelHandle<Project>, project: &ModelHandle<Project>,
pane_handle: &WeakViewHandle<Pane>, pane: &WeakViewHandle<Pane>,
workspace_id: WorkspaceId, workspace_id: WorkspaceId,
workspace: &WeakViewHandle<Workspace>, workspace: &WeakViewHandle<Workspace>,
cx: &mut AsyncAppContext, cx: &mut AsyncAppContext,
@ -239,7 +239,7 @@ impl SerializedPane {
let mut active_item_index = None; let mut active_item_index = None;
for (index, item) in self.children.iter().enumerate() { for (index, item) in self.children.iter().enumerate() {
let project = project.clone(); let project = project.clone();
let item_handle = pane_handle let item_handle = pane
.update(cx, |_, cx| { .update(cx, |_, cx| {
if let Some(deserializer) = cx.global::<ItemDeserializers>().get(&item.kind) { if let Some(deserializer) = cx.global::<ItemDeserializers>().get(&item.kind) {
deserializer(project, workspace.clone(), workspace_id, item.item_id, cx) deserializer(project, workspace.clone(), workspace_id, item.item_id, cx)
@ -256,13 +256,9 @@ impl SerializedPane {
items.push(item_handle.clone()); items.push(item_handle.clone());
if let Some(item_handle) = item_handle { if let Some(item_handle) = item_handle {
workspace.update(cx, |workspace, cx| { pane.update(cx, |pane, cx| {
let pane_handle = pane_handle pane.add_item(item_handle.clone(), true, true, None, cx);
.upgrade(cx) })?;
.ok_or_else(|| anyhow!("pane was dropped"))?;
Pane::add_item(workspace, &pane_handle, item_handle, true, true, None, cx);
anyhow::Ok(())
})??;
} }
if item.active { if item.active {
@ -271,7 +267,7 @@ impl SerializedPane {
} }
if let Some(active_item_index) = active_item_index { if let Some(active_item_index) = active_item_index {
pane_handle.update(cx, |pane, cx| { pane.update(cx, |pane, cx| {
pane.activate_item(active_item_index, false, false, cx); pane.activate_item(active_item_index, false, false, cx);
})?; })?;
} }

View file

@ -99,7 +99,7 @@ impl Item for SharedScreen {
Some(format!("{}'s screen", self.user.github_login).into()) Some(format!("{}'s screen", self.user.github_login).into())
} }
fn deactivated(&mut self, cx: &mut ViewContext<Self>) { fn deactivated(&mut self, cx: &mut ViewContext<Self>) {
if let Some(nav_history) = self.nav_history.as_ref() { if let Some(nav_history) = self.nav_history.as_mut() {
nav_history.push::<()>(None, cx); nav_history.push::<()>(None, cx);
} }
} }

View file

@ -153,14 +153,13 @@ impl View for Toolbar {
let pane = pane.clone(); let pane = pane.clone();
cx.window_context().defer(move |cx| { cx.window_context().defer(move |cx| {
workspace.update(cx, |workspace, cx| { workspace.update(cx, |workspace, cx| {
Pane::go_back(workspace, Some(pane.clone()), cx) workspace.go_back(pane.clone(), cx).detach_and_log_err(cx);
.detach_and_log_err(cx);
}); });
}) })
} }
} }
}, },
super::GoBack { pane: None }, super::GoBack,
"Go Back", "Go Back",
cx, cx,
)); ));
@ -182,14 +181,15 @@ impl View for Toolbar {
let pane = pane.clone(); let pane = pane.clone();
cx.window_context().defer(move |cx| { cx.window_context().defer(move |cx| {
workspace.update(cx, |workspace, cx| { workspace.update(cx, |workspace, cx| {
Pane::go_forward(workspace, Some(pane.clone()), cx) workspace
.go_forward(pane.clone(), cx)
.detach_and_log_err(cx); .detach_and_log_err(cx);
}); });
}); });
} }
} }
}, },
super::GoForward { pane: None }, super::GoForward,
"Go Forward", "Go Forward",
cx, cx,
)); ));

View file

@ -278,6 +278,19 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
workspace.toggle_dock(DockPosition::Bottom, action.focus, cx); workspace.toggle_dock(DockPosition::Bottom, action.focus, cx);
}); });
cx.add_action(Workspace::activate_pane_at_index); cx.add_action(Workspace::activate_pane_at_index);
cx.add_action(|workspace: &mut Workspace, _: &ReopenClosedItem, cx| {
workspace.reopen_closed_item(cx).detach();
});
cx.add_action(|workspace: &mut Workspace, _: &GoBack, cx| {
workspace
.go_back(workspace.active_pane().downgrade(), cx)
.detach();
});
cx.add_action(|workspace: &mut Workspace, _: &GoForward, cx| {
workspace
.go_forward(workspace.active_pane().downgrade(), cx)
.detach();
});
cx.add_action(|_: &mut Workspace, _: &install_cli::Install, cx| { cx.add_action(|_: &mut Workspace, _: &install_cli::Install, cx| {
cx.spawn(|workspace, mut cx| async move { cx.spawn(|workspace, mut cx| async move {
@ -583,6 +596,7 @@ impl Workspace {
let center_pane = cx.add_view(|cx| { let center_pane = cx.add_view(|cx| {
Pane::new( Pane::new(
weak_handle.clone(), weak_handle.clone(),
project.clone(),
app_state.background_actions, app_state.background_actions,
pane_history_timestamp.clone(), pane_history_timestamp.clone(),
cx, cx,
@ -999,6 +1013,115 @@ impl Workspace {
.collect() .collect()
} }
fn navigate_history(
&mut self,
pane: WeakViewHandle<Pane>,
mode: NavigationMode,
cx: &mut ViewContext<Workspace>,
) -> Task<Result<()>> {
let to_load = if let Some(pane) = pane.upgrade(cx) {
cx.focus(&pane);
pane.update(cx, |pane, cx| {
loop {
// Retrieve the weak item handle from the history.
let entry = pane.nav_history_mut().pop(mode, cx)?;
// If the item is still present in this pane, then activate it.
if let Some(index) = entry
.item
.upgrade(cx)
.and_then(|v| pane.index_for_item(v.as_ref()))
{
let prev_active_item_index = pane.active_item_index();
pane.nav_history_mut().set_mode(mode);
pane.activate_item(index, true, true, cx);
pane.nav_history_mut().set_mode(NavigationMode::Normal);
let mut navigated = prev_active_item_index != pane.active_item_index();
if let Some(data) = entry.data {
navigated |= pane.active_item()?.navigate(data, cx);
}
if navigated {
break None;
}
}
// If the item is no longer present in this pane, then retrieve its
// project path in order to reopen it.
else {
break pane
.nav_history()
.path_for_item(entry.item.id())
.map(|(project_path, _)| (project_path, entry));
}
}
})
} else {
None
};
if let Some((project_path, entry)) = to_load {
// If the item was no longer present, then load it again from its previous path.
let task = self.load_path(project_path, cx);
cx.spawn(|workspace, mut cx| async move {
let task = task.await;
let mut navigated = false;
if let Some((project_entry_id, build_item)) = task.log_err() {
let prev_active_item_id = pane.update(&mut cx, |pane, _| {
pane.nav_history_mut().set_mode(mode);
pane.active_item().map(|p| p.id())
})?;
pane.update(&mut cx, |pane, cx| {
let item = pane.open_item(project_entry_id, true, cx, build_item);
navigated |= Some(item.id()) != prev_active_item_id;
pane.nav_history_mut().set_mode(NavigationMode::Normal);
if let Some(data) = entry.data {
navigated |= item.navigate(data, cx);
}
})?;
}
if !navigated {
workspace
.update(&mut cx, |workspace, cx| {
Self::navigate_history(workspace, pane, mode, cx)
})?
.await?;
}
Ok(())
})
} else {
Task::ready(Ok(()))
}
}
pub fn go_back(
&mut self,
pane: WeakViewHandle<Pane>,
cx: &mut ViewContext<Workspace>,
) -> Task<Result<()>> {
self.navigate_history(pane, NavigationMode::GoingBack, cx)
}
pub fn go_forward(
&mut self,
pane: WeakViewHandle<Pane>,
cx: &mut ViewContext<Workspace>,
) -> Task<Result<()>> {
self.navigate_history(pane, NavigationMode::GoingForward, cx)
}
pub fn reopen_closed_item(&mut self, cx: &mut ViewContext<Workspace>) -> Task<Result<()>> {
self.navigate_history(
self.active_pane().downgrade(),
NavigationMode::ReopeningClosedItem,
cx,
)
}
pub fn client(&self) -> &Client { pub fn client(&self) -> &Client {
&self.app_state.client &self.app_state.client
} }
@ -1307,22 +1430,6 @@ impl Workspace {
}) })
} }
pub fn absolute_path(&self, project_path: &ProjectPath, cx: &AppContext) -> Option<PathBuf> {
let workspace_root = self
.project()
.read(cx)
.worktree_for_id(project_path.worktree_id, cx)?
.read(cx)
.abs_path();
let project_path = project_path.path.as_ref();
Some(if project_path == Path::new("") {
workspace_root.to_path_buf()
} else {
workspace_root.join(project_path)
})
}
fn add_folder_to_project(&mut self, _: &AddFolderToProject, cx: &mut ViewContext<Self>) { fn add_folder_to_project(&mut self, _: &AddFolderToProject, cx: &mut ViewContext<Self>) {
let mut paths = cx.prompt_for_paths(PathPromptOptions { let mut paths = cx.prompt_for_paths(PathPromptOptions {
files: false, files: false,
@ -1588,6 +1695,7 @@ impl Workspace {
let pane = cx.add_view(|cx| { let pane = cx.add_view(|cx| {
Pane::new( Pane::new(
self.weak_handle(), self.weak_handle(),
self.project.clone(),
self.app_state.background_actions, self.app_state.background_actions,
self.pane_history_timestamp.clone(), self.pane_history_timestamp.clone(),
cx, cx,
@ -1607,7 +1715,7 @@ impl Workspace {
) -> bool { ) -> bool {
if let Some(center_pane) = self.last_active_center_pane.clone() { if let Some(center_pane) = self.last_active_center_pane.clone() {
if let Some(center_pane) = center_pane.upgrade(cx) { if let Some(center_pane) = center_pane.upgrade(cx) {
Pane::add_item(self, &center_pane, item, true, true, None, cx); center_pane.update(cx, |pane, cx| pane.add_item(item, true, true, None, cx));
true true
} else { } else {
false false
@ -1618,8 +1726,8 @@ impl Workspace {
} }
pub fn add_item(&mut self, item: Box<dyn ItemHandle>, cx: &mut ViewContext<Self>) { pub fn add_item(&mut self, item: Box<dyn ItemHandle>, cx: &mut ViewContext<Self>) {
let active_pane = self.active_pane().clone(); self.active_pane
Pane::add_item(self, &active_pane, item, true, true, None, cx); .update(cx, |pane, cx| pane.add_item(item, true, true, None, cx));
} }
pub fn open_abs_path( pub fn open_abs_path(
@ -1669,13 +1777,10 @@ impl Workspace {
}); });
let task = self.load_path(path.into(), cx); let task = self.load_path(path.into(), cx);
cx.spawn(|this, mut cx| async move { cx.spawn(|_, mut cx| async move {
let (project_entry_id, build_item) = task.await?; let (project_entry_id, build_item) = task.await?;
let pane = pane pane.update(&mut cx, |pane, cx| {
.upgrade(&cx) pane.open_item(project_entry_id, focus_item, cx, build_item)
.ok_or_else(|| anyhow!("pane was closed"))?;
this.update(&mut cx, |this, cx| {
Pane::open_item(this, pane, project_entry_id, focus_item, cx, build_item)
}) })
}) })
} }
@ -1732,8 +1837,9 @@ impl Workspace {
pub fn open_shared_screen(&mut self, peer_id: PeerId, cx: &mut ViewContext<Self>) { pub fn open_shared_screen(&mut self, peer_id: PeerId, cx: &mut ViewContext<Self>) {
if let Some(shared_screen) = self.shared_screen_for_peer(peer_id, &self.active_pane, cx) { if let Some(shared_screen) = self.shared_screen_for_peer(peer_id, &self.active_pane, cx) {
let pane = self.active_pane.clone(); self.active_pane.update(cx, |pane, cx| {
Pane::add_item(self, &pane, Box::new(shared_screen), false, true, None, cx); pane.add_item(Box::new(shared_screen), false, true, None, cx)
});
} }
} }
@ -1820,6 +1926,7 @@ impl Workspace {
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) { ) {
match event { match event {
pane::Event::AddItem { item } => item.added_to_pane(self, pane, cx),
pane::Event::Split(direction) => { pane::Event::Split(direction) => {
self.split_pane(pane, *direction, cx); self.split_pane(pane, *direction, cx);
} }
@ -1874,7 +1981,7 @@ impl Workspace {
let item = pane.read(cx).active_item()?; let item = pane.read(cx).active_item()?;
let maybe_pane_handle = if let Some(clone) = item.clone_on_split(self.database_id(), cx) { let maybe_pane_handle = if let Some(clone) = item.clone_on_split(self.database_id(), cx) {
let new_pane = self.add_pane(cx); let new_pane = self.add_pane(cx);
Pane::add_item(self, &new_pane, clone, true, true, None, cx); new_pane.update(cx, |pane, cx| pane.add_item(clone, true, true, None, cx));
self.center.split(&pane, &new_pane, direction).unwrap(); self.center.split(&pane, &new_pane, direction).unwrap();
Some(new_pane) Some(new_pane)
} else { } else {
@ -1896,7 +2003,7 @@ impl Workspace {
let Some(from) = from.upgrade(cx) else { return; }; let Some(from) = from.upgrade(cx) else { return; };
let new_pane = self.add_pane(cx); let new_pane = self.add_pane(cx);
Pane::move_item(self, from.clone(), new_pane.clone(), item_id_to_move, 0, cx); self.move_item(from.clone(), new_pane.clone(), item_id_to_move, 0, cx);
self.center self.center
.split(&pane_to_split, &new_pane, split_direction) .split(&pane_to_split, &new_pane, split_direction)
.unwrap(); .unwrap();
@ -1924,6 +2031,41 @@ impl Workspace {
})) }))
} }
pub fn move_item(
&mut self,
source: ViewHandle<Pane>,
destination: ViewHandle<Pane>,
item_id_to_move: usize,
destination_index: usize,
cx: &mut ViewContext<Self>,
) {
let item_to_move = source
.read(cx)
.items()
.enumerate()
.find(|(_, item_handle)| item_handle.id() == item_id_to_move);
if item_to_move.is_none() {
log::warn!("Tried to move item handle which was not in `from` pane. Maybe tab was closed during drop");
return;
}
let (item_ix, item_handle) = item_to_move.unwrap();
let item_handle = item_handle.clone();
if source != destination {
// Close item from previous pane
source.update(cx, |source, cx| {
source.remove_item(item_ix, false, cx);
});
}
// This automatically removes duplicate items in the pane
destination.update(cx, |destination, cx| {
destination.add_item(item_handle, true, true, Some(destination_index), cx);
cx.focus_self();
});
}
fn remove_pane(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) { fn remove_pane(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) {
if self.center.remove(&pane).unwrap() { if self.center.remove(&pane).unwrap() {
self.force_remove_pane(&pane, cx); self.force_remove_pane(&pane, cx);
@ -2527,7 +2669,9 @@ impl Workspace {
if let Some(index) = pane.update(cx, |pane, _| pane.index_for_item(item.as_ref())) { if let Some(index) = pane.update(cx, |pane, _| pane.index_for_item(item.as_ref())) {
pane.update(cx, |pane, cx| pane.activate_item(index, false, false, cx)); pane.update(cx, |pane, cx| pane.activate_item(index, false, false, cx));
} else { } else {
Pane::add_item(self, &pane, item.boxed_clone(), false, false, None, cx); pane.update(cx, |pane, cx| {
pane.add_item(item.boxed_clone(), false, false, None, cx)
});
} }
if pane_was_focused { if pane_was_focused {
@ -4016,9 +4160,7 @@ mod tests {
}); });
workspace workspace
.update(cx, |workspace, cx| { .update(cx, |workspace, cx| workspace.go_back(pane.downgrade(), cx))
Pane::go_back(workspace, Some(pane.downgrade()), cx)
})
.await .await
.unwrap(); .unwrap();

View file

@ -120,8 +120,8 @@ pub fn menus() -> Vec<Menu<'static>> {
Menu { Menu {
name: "Go", name: "Go",
items: vec![ items: vec![
MenuItem::action("Back", workspace::GoBack { pane: None }), MenuItem::action("Back", workspace::GoBack),
MenuItem::action("Forward", workspace::GoForward { pane: None }), MenuItem::action("Forward", workspace::GoForward),
MenuItem::separator(), MenuItem::separator(),
MenuItem::action("Go to File", file_finder::Toggle), MenuItem::action("Go to File", file_finder::Toggle),
MenuItem::action("Go to Symbol in Project", project_symbols::Toggle), MenuItem::action("Go to Symbol in Project", project_symbols::Toggle),

View file

@ -663,7 +663,7 @@ mod tests {
use util::http::FakeHttpClient; use util::http::FakeHttpClient;
use workspace::{ use workspace::{
item::{Item, ItemHandle}, item::{Item, ItemHandle},
open_new, open_paths, pane, NewFile, Pane, SplitDirection, WorkspaceHandle, open_new, open_paths, pane, NewFile, SplitDirection, WorkspaceHandle,
}; };
#[gpui::test] #[gpui::test]
@ -1488,7 +1488,7 @@ mod tests {
); );
workspace workspace
.update(cx, |w, cx| Pane::go_back(w, None, cx)) .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1497,7 +1497,7 @@ mod tests {
); );
workspace workspace
.update(cx, |w, cx| Pane::go_back(w, None, cx)) .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1506,7 +1506,7 @@ mod tests {
); );
workspace workspace
.update(cx, |w, cx| Pane::go_back(w, None, cx)) .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1515,7 +1515,7 @@ mod tests {
); );
workspace workspace
.update(cx, |w, cx| Pane::go_back(w, None, cx)) .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1525,7 +1525,7 @@ mod tests {
// Go back one more time and ensure we don't navigate past the first item in the history. // Go back one more time and ensure we don't navigate past the first item in the history.
workspace workspace
.update(cx, |w, cx| Pane::go_back(w, None, cx)) .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1534,7 +1534,7 @@ mod tests {
); );
workspace workspace
.update(cx, |w, cx| Pane::go_forward(w, None, cx)) .update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1543,7 +1543,7 @@ mod tests {
); );
workspace workspace
.update(cx, |w, cx| Pane::go_forward(w, None, cx)) .update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1561,7 +1561,7 @@ mod tests {
.await .await
.unwrap(); .unwrap();
workspace workspace
.update(cx, |w, cx| Pane::go_forward(w, None, cx)) .update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1570,7 +1570,7 @@ mod tests {
); );
workspace workspace
.update(cx, |w, cx| Pane::go_forward(w, None, cx)) .update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1579,7 +1579,7 @@ mod tests {
); );
workspace workspace
.update(cx, |w, cx| Pane::go_back(w, None, cx)) .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1601,7 +1601,7 @@ mod tests {
.await .await
.unwrap(); .unwrap();
workspace workspace
.update(cx, |w, cx| Pane::go_back(w, None, cx)) .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1609,7 +1609,7 @@ mod tests {
(file1.clone(), DisplayPoint::new(10, 0), 0.) (file1.clone(), DisplayPoint::new(10, 0), 0.)
); );
workspace workspace
.update(cx, |w, cx| Pane::go_forward(w, None, cx)) .update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1653,7 +1653,7 @@ mod tests {
}) })
}); });
workspace workspace
.update(cx, |w, cx| Pane::go_back(w, None, cx)) .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1661,7 +1661,7 @@ mod tests {
(file1.clone(), DisplayPoint::new(2, 0), 0.) (file1.clone(), DisplayPoint::new(2, 0), 0.)
); );
workspace workspace
.update(cx, |w, cx| Pane::go_back(w, None, cx)) .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
.await .await
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -1766,81 +1766,97 @@ mod tests {
// Reopen all the closed items, ensuring they are reopened in the same order // Reopen all the closed items, ensuring they are reopened in the same order
// in which they were closed. // in which they were closed.
workspace workspace
.update(cx, Pane::reopen_closed_item) .update(cx, Workspace::reopen_closed_item)
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file3.clone())); assert_eq!(active_path(&workspace, cx), Some(file3.clone()));
workspace workspace
.update(cx, Pane::reopen_closed_item) .update(cx, Workspace::reopen_closed_item)
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file2.clone())); assert_eq!(active_path(&workspace, cx), Some(file2.clone()));
workspace workspace
.update(cx, Pane::reopen_closed_item) .update(cx, Workspace::reopen_closed_item)
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file4.clone())); assert_eq!(active_path(&workspace, cx), Some(file4.clone()));
workspace workspace
.update(cx, Pane::reopen_closed_item) .update(cx, Workspace::reopen_closed_item)
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file1.clone())); assert_eq!(active_path(&workspace, cx), Some(file1.clone()));
// Reopening past the last closed item is a no-op. // Reopening past the last closed item is a no-op.
workspace workspace
.update(cx, Pane::reopen_closed_item) .update(cx, Workspace::reopen_closed_item)
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file1.clone())); assert_eq!(active_path(&workspace, cx), Some(file1.clone()));
// Reopening closed items doesn't interfere with navigation history. // Reopening closed items doesn't interfere with navigation history.
workspace workspace
.update(cx, |workspace, cx| Pane::go_back(workspace, None, cx)) .update(cx, |workspace, cx| {
workspace.go_back(workspace.active_pane().downgrade(), cx)
})
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file4.clone())); assert_eq!(active_path(&workspace, cx), Some(file4.clone()));
workspace workspace
.update(cx, |workspace, cx| Pane::go_back(workspace, None, cx)) .update(cx, |workspace, cx| {
workspace.go_back(workspace.active_pane().downgrade(), cx)
})
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file2.clone())); assert_eq!(active_path(&workspace, cx), Some(file2.clone()));
workspace workspace
.update(cx, |workspace, cx| Pane::go_back(workspace, None, cx)) .update(cx, |workspace, cx| {
workspace.go_back(workspace.active_pane().downgrade(), cx)
})
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file3.clone())); assert_eq!(active_path(&workspace, cx), Some(file3.clone()));
workspace workspace
.update(cx, |workspace, cx| Pane::go_back(workspace, None, cx)) .update(cx, |workspace, cx| {
workspace.go_back(workspace.active_pane().downgrade(), cx)
})
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file4.clone())); assert_eq!(active_path(&workspace, cx), Some(file4.clone()));
workspace workspace
.update(cx, |workspace, cx| Pane::go_back(workspace, None, cx)) .update(cx, |workspace, cx| {
workspace.go_back(workspace.active_pane().downgrade(), cx)
})
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file3.clone())); assert_eq!(active_path(&workspace, cx), Some(file3.clone()));
workspace workspace
.update(cx, |workspace, cx| Pane::go_back(workspace, None, cx)) .update(cx, |workspace, cx| {
workspace.go_back(workspace.active_pane().downgrade(), cx)
})
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file2.clone())); assert_eq!(active_path(&workspace, cx), Some(file2.clone()));
workspace workspace
.update(cx, |workspace, cx| Pane::go_back(workspace, None, cx)) .update(cx, |workspace, cx| {
workspace.go_back(workspace.active_pane().downgrade(), cx)
})
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file1.clone())); assert_eq!(active_path(&workspace, cx), Some(file1.clone()));
workspace workspace
.update(cx, |workspace, cx| Pane::go_back(workspace, None, cx)) .update(cx, |workspace, cx| {
workspace.go_back(workspace.active_pane().downgrade(), cx)
})
.await .await
.unwrap(); .unwrap();
assert_eq!(active_path(&workspace, cx), Some(file1.clone())); assert_eq!(active_path(&workspace, cx), Some(file1.clone()));