Cargo.lock 🔗
@@ -5677,6 +5677,7 @@ dependencies = [
"project",
"serde_json",
"theme",
+ "util",
]
[[package]]
Max Brunsfeld created
Cargo.lock | 1
crates/workspace/Cargo.toml | 1
crates/workspace/src/pane.rs | 77 +++++++++++++++++++++-----------
crates/workspace/src/workspace.rs | 44 +++++++++++-------
4 files changed, 78 insertions(+), 45 deletions(-)
@@ -5677,6 +5677,7 @@ dependencies = [
"project",
"serde_json",
"theme",
+ "util",
]
[[package]]
@@ -17,6 +17,7 @@ gpui = { path = "../gpui" }
language = { path = "../language" }
project = { path = "../project" }
theme = { path = "../theme" }
+util = { path = "../util" }
anyhow = "1.0.38"
log = "0.4"
parking_lot = "0.11.1"
@@ -12,6 +12,7 @@ use gpui::{
use postage::watch;
use project::ProjectPath;
use std::{any::Any, cell::RefCell, cmp, mem, rc::Rc};
+use util::TryFutureExt;
action!(Split, SplitDirection);
action!(ActivateItem, usize);
@@ -114,29 +115,51 @@ impl Pane {
cx.emit(Event::Activate);
}
- pub fn go_back(&mut self, _: &GoBack, cx: &mut ViewContext<Self>) {
- if self.navigation.0.borrow().backward_stack.is_empty() {
- return;
- }
-
- if let Some(item_view) = self.active_item() {
- self.navigation.0.borrow_mut().mode = NavigationHistoryMode::GoingBack;
- item_view.deactivated(cx);
- self.navigation.0.borrow_mut().mode = NavigationHistoryMode::Normal;
- }
+ pub fn go_back(workspace: &mut Workspace, _: &GoBack, cx: &mut ViewContext<Workspace>) {
+ let project_path = workspace.active_pane().update(cx, |pane, cx| {
+ let mut navigation = pane.navigation.0.borrow_mut();
+ if let Some(entry) = navigation.backward_stack.pop() {
+ if let Some(index) = entry
+ .item_view
+ .upgrade(cx)
+ .and_then(|v| pane.index_for_item_view(v.as_ref()))
+ {
+ if let Some(item_view) = pane.active_item() {
+ pane.navigation.0.borrow_mut().mode = NavigationHistoryMode::GoingBack;
+ item_view.deactivated(cx);
+ pane.navigation.0.borrow_mut().mode = NavigationHistoryMode::Normal;
+ }
- let mut navigation = self.navigation.0.borrow_mut();
- if let Some(entry) = navigation.backward_stack.pop() {
- if let Some(index) = entry
- .item_view
- .upgrade(cx)
- .and_then(|v| self.index_for_item_view(v.as_ref()))
- {
- self.active_item_index = index;
- drop(navigation);
- self.focus_active_item(cx);
- cx.notify();
+ pane.active_item_index = index;
+ drop(navigation);
+ pane.focus_active_item(cx);
+ cx.notify();
+ } else {
+ return navigation.paths_by_item.get(&entry.item_view.id()).cloned();
+ }
}
+
+ None
+ });
+
+ if let Some(project_path) = project_path {
+ let task = workspace.load_path(project_path, cx);
+ cx.spawn(|workspace, mut cx| {
+ async move {
+ let item = task.await?;
+ workspace.update(&mut cx, |workspace, cx| {
+ let pane = workspace.active_pane().clone();
+ pane.update(cx, |pane, cx| {
+ pane.navigation.0.borrow_mut().mode = NavigationHistoryMode::GoingBack;
+ pane.open_item(item, workspace, cx);
+ pane.navigation.0.borrow_mut().mode = NavigationHistoryMode::Normal;
+ });
+ });
+ Ok(())
+ }
+ .log_err()
+ })
+ .detach();
}
}
@@ -268,17 +291,17 @@ impl Pane {
pub fn close_item(&mut self, item_view_id: usize, cx: &mut ViewContext<Self>) {
let mut item_ix = 0;
- self.item_views.retain(|(item_id, item)| {
- if item.id() == item_view_id {
+ self.item_views.retain(|(_, item_view)| {
+ if item_view.id() == item_view_id {
let mut navigation = self.navigation.0.borrow_mut();
- if let Some(path) = item.project_path(cx) {
- navigation.paths_by_item.insert(*item_id, path);
+ if let Some(path) = item_view.project_path(cx) {
+ navigation.paths_by_item.insert(item_view.id(), path);
} else {
- navigation.paths_by_item.remove(item_id);
+ navigation.paths_by_item.remove(&item_view.id());
}
if item_ix == self.active_item_index {
- item.deactivated(cx);
+ item_view.deactivated(cx);
}
item_ix += 1;
false
@@ -227,6 +227,7 @@ pub trait ItemViewHandle {
}
pub trait WeakItemViewHandle {
+ fn id(&self) -> usize;
fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn ItemViewHandle>>;
}
@@ -418,6 +419,10 @@ impl Clone for Box<dyn ItemHandle> {
}
impl<T: ItemView> WeakItemViewHandle for WeakViewHandle<T> {
+ fn id(&self) -> usize {
+ self.id()
+ }
+
fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn ItemViewHandle>> {
self.upgrade(cx)
.map(|v| Box::new(v) as Box<dyn ItemViewHandle>)
@@ -747,46 +752,49 @@ impl Workspace {
}
}
- #[must_use]
pub fn open_path(
&mut self,
path: ProjectPath,
cx: &mut ViewContext<Self>,
) -> Task<Result<Box<dyn ItemViewHandle>, Arc<anyhow::Error>>> {
+ let load_task = self.load_path(path, cx);
+ let pane = self.active_pane().clone().downgrade();
+ cx.spawn(|this, mut cx| async move {
+ let item = load_task.await?;
+ this.update(&mut cx, |this, cx| {
+ let pane = pane
+ .upgrade(&cx)
+ .ok_or_else(|| anyhow!("could not upgrade pane reference"))?;
+ Ok(this.open_item_in_pane(item, &pane, cx))
+ })
+ })
+ }
+
+ pub fn load_path(
+ &mut self,
+ path: ProjectPath,
+ cx: &mut ViewContext<Self>,
+ ) -> Task<Result<Box<dyn ItemHandle>>> {
if let Some(existing_item) = self.item_for_path(&path, cx) {
- return Task::ready(Ok(self.open_item(existing_item, cx)));
+ return Task::ready(Ok(existing_item));
}
let worktree = match self.project.read(cx).worktree_for_id(path.worktree_id, cx) {
Some(worktree) => worktree,
None => {
- return Task::ready(Err(Arc::new(anyhow!(
- "worktree {} does not exist",
- path.worktree_id
- ))));
+ return Task::ready(Err(anyhow!("worktree {} does not exist", path.worktree_id)));
}
};
let project_path = path.clone();
let path_openers = self.path_openers.clone();
- let open_task = worktree.update(cx, |worktree, cx| {
+ worktree.update(cx, |worktree, cx| {
for opener in path_openers.iter() {
if let Some(task) = opener.open(worktree, project_path.clone(), cx) {
return task;
}
}
Task::ready(Err(anyhow!("no opener found for path {:?}", project_path)))
- });
-
- let pane = self.active_pane().clone().downgrade();
- cx.spawn(|this, mut cx| async move {
- let item = open_task.await?;
- this.update(&mut cx, |this, cx| {
- let pane = pane
- .upgrade(&cx)
- .ok_or_else(|| anyhow!("could not upgrade pane reference"))?;
- Ok(this.open_item_in_pane(item, &pane, cx))
- })
})
}