Restructure item closing to take the Workspace
instead of the Pane
This commit is contained in:
parent
939def42e3
commit
cac0dddb1b
3 changed files with 113 additions and 102 deletions
|
@ -1,5 +1,6 @@
|
||||||
use super::{ItemHandle, SplitDirection};
|
use super::{ItemHandle, SplitDirection};
|
||||||
use crate::{toolbar::Toolbar, Item, Settings, WeakItemHandle, Workspace};
|
use crate::{toolbar::Toolbar, Item, Settings, WeakItemHandle, Workspace};
|
||||||
|
use anyhow::Result;
|
||||||
use collections::{HashMap, VecDeque};
|
use collections::{HashMap, VecDeque};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
|
@ -8,10 +9,10 @@ use gpui::{
|
||||||
geometry::{rect::RectF, vector::vec2f},
|
geometry::{rect::RectF, vector::vec2f},
|
||||||
keymap::Binding,
|
keymap::Binding,
|
||||||
platform::{CursorStyle, NavigationDirection},
|
platform::{CursorStyle, NavigationDirection},
|
||||||
AppContext, Entity, ModelHandle, MutableAppContext, PromptLevel, Quad, RenderContext, Task,
|
AppContext, Entity, MutableAppContext, PromptLevel, Quad, RenderContext, Task, View,
|
||||||
View, ViewContext, ViewHandle, WeakViewHandle,
|
ViewContext, ViewHandle, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use project::{Project, ProjectEntryId, ProjectPath};
|
use project::{ProjectEntryId, ProjectPath};
|
||||||
use std::{any::Any, cell::RefCell, cmp, mem, path::Path, rc::Rc};
|
use std::{any::Any, cell::RefCell, cmp, mem, path::Path, rc::Rc};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
|
@ -21,10 +22,16 @@ action!(ActivatePrevItem);
|
||||||
action!(ActivateNextItem);
|
action!(ActivateNextItem);
|
||||||
action!(CloseActiveItem);
|
action!(CloseActiveItem);
|
||||||
action!(CloseInactiveItems);
|
action!(CloseInactiveItems);
|
||||||
action!(CloseItem, usize);
|
action!(CloseItem, CloseItemParams);
|
||||||
action!(GoBack, Option<WeakViewHandle<Pane>>);
|
action!(GoBack, Option<WeakViewHandle<Pane>>);
|
||||||
action!(GoForward, Option<WeakViewHandle<Pane>>);
|
action!(GoForward, Option<WeakViewHandle<Pane>>);
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CloseItemParams {
|
||||||
|
pub item_id: usize,
|
||||||
|
pub pane: WeakViewHandle<Pane>,
|
||||||
|
}
|
||||||
|
|
||||||
const MAX_NAVIGATION_HISTORY_LEN: usize = 1024;
|
const MAX_NAVIGATION_HISTORY_LEN: usize = 1024;
|
||||||
|
|
||||||
pub fn init(cx: &mut MutableAppContext) {
|
pub fn init(cx: &mut MutableAppContext) {
|
||||||
|
@ -37,14 +44,11 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||||
cx.add_action(|pane: &mut Pane, _: &ActivateNextItem, cx| {
|
cx.add_action(|pane: &mut Pane, _: &ActivateNextItem, cx| {
|
||||||
pane.activate_next_item(cx);
|
pane.activate_next_item(cx);
|
||||||
});
|
});
|
||||||
cx.add_action(|pane: &mut Pane, _: &CloseActiveItem, cx| {
|
cx.add_async_action(Pane::close_active_item);
|
||||||
pane.close_active_item(cx).detach();
|
cx.add_async_action(Pane::close_inactive_items);
|
||||||
});
|
cx.add_async_action(|workspace: &mut Workspace, action: &CloseItem, cx| {
|
||||||
cx.add_action(|pane: &mut Pane, _: &CloseInactiveItems, cx| {
|
let pane = action.0.pane.upgrade(cx)?;
|
||||||
pane.close_inactive_items(cx).detach();
|
Some(Pane::close_item(workspace, pane, action.0.item_id, cx))
|
||||||
});
|
|
||||||
cx.add_action(|pane: &mut Pane, action: &CloseItem, cx| {
|
|
||||||
pane.close_item(action.0, cx).detach();
|
|
||||||
});
|
});
|
||||||
cx.add_action(|pane: &mut Pane, action: &Split, cx| {
|
cx.add_action(|pane: &mut Pane, action: &Split, cx| {
|
||||||
pane.split(action.0, cx);
|
pane.split(action.0, cx);
|
||||||
|
@ -98,7 +102,6 @@ pub struct Pane {
|
||||||
active_item_index: usize,
|
active_item_index: usize,
|
||||||
nav_history: Rc<RefCell<NavHistory>>,
|
nav_history: Rc<RefCell<NavHistory>>,
|
||||||
toolbar: ViewHandle<Toolbar>,
|
toolbar: ViewHandle<Toolbar>,
|
||||||
project: ModelHandle<Project>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ItemNavHistory {
|
pub struct ItemNavHistory {
|
||||||
|
@ -134,13 +137,12 @@ pub struct NavigationEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pane {
|
impl Pane {
|
||||||
pub fn new(project: ModelHandle<Project>, cx: &mut ViewContext<Self>) -> Self {
|
pub fn new(cx: &mut ViewContext<Self>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
items: Vec::new(),
|
items: Vec::new(),
|
||||||
active_item_index: 0,
|
active_item_index: 0,
|
||||||
nav_history: Default::default(),
|
nav_history: Default::default(),
|
||||||
toolbar: cx.add_view(|_| Toolbar::new()),
|
toolbar: cx.add_view(|_| Toolbar::new()),
|
||||||
project,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,47 +412,75 @@ impl Pane {
|
||||||
self.activate_item(index, true, cx);
|
self.activate_item(index, true, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_active_item(&mut self, cx: &mut ViewContext<Self>) -> Task<()> {
|
fn close_active_item(
|
||||||
if self.items.is_empty() {
|
workspace: &mut Workspace,
|
||||||
Task::ready(())
|
_: &CloseActiveItem,
|
||||||
|
cx: &mut ViewContext<Workspace>,
|
||||||
|
) -> Option<Task<Result<()>>> {
|
||||||
|
let pane_handle = workspace.active_pane().clone();
|
||||||
|
let pane = pane_handle.read(cx);
|
||||||
|
if pane.items.is_empty() {
|
||||||
|
None
|
||||||
} else {
|
} else {
|
||||||
self.close_item(self.items[self.active_item_index].id(), cx)
|
let item_id_to_close = pane.items[pane.active_item_index].id();
|
||||||
|
Some(Self::close_items(
|
||||||
|
workspace,
|
||||||
|
pane_handle,
|
||||||
|
cx,
|
||||||
|
move |item_id| item_id == item_id_to_close,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_inactive_items(&mut self, cx: &mut ViewContext<Self>) -> Task<()> {
|
pub fn close_inactive_items(
|
||||||
if self.items.is_empty() {
|
workspace: &mut Workspace,
|
||||||
Task::ready(())
|
_: &CloseInactiveItems,
|
||||||
|
cx: &mut ViewContext<Workspace>,
|
||||||
|
) -> Option<Task<Result<()>>> {
|
||||||
|
let pane_handle = workspace.active_pane().clone();
|
||||||
|
let pane = pane_handle.read(cx);
|
||||||
|
if pane.items.is_empty() {
|
||||||
|
None
|
||||||
} else {
|
} else {
|
||||||
let active_item_id = self.items[self.active_item_index].id();
|
let active_item_id = pane.items[pane.active_item_index].id();
|
||||||
self.close_items(cx, move |id| id != active_item_id)
|
Some(Self::close_items(workspace, pane_handle, cx, move |id| {
|
||||||
|
id != active_item_id
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_item(&mut self, view_id_to_close: usize, cx: &mut ViewContext<Self>) -> Task<()> {
|
pub fn close_item(
|
||||||
self.close_items(cx, move |view_id| view_id == view_id_to_close)
|
workspace: &mut Workspace,
|
||||||
|
pane: ViewHandle<Pane>,
|
||||||
|
item_id_to_close: usize,
|
||||||
|
cx: &mut ViewContext<Workspace>,
|
||||||
|
) -> Task<Result<()>> {
|
||||||
|
Self::close_items(workspace, pane, cx, move |view_id| {
|
||||||
|
view_id == item_id_to_close
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_items(
|
pub fn close_items(
|
||||||
&mut self,
|
workspace: &mut Workspace,
|
||||||
cx: &mut ViewContext<Self>,
|
pane: ViewHandle<Pane>,
|
||||||
|
cx: &mut ViewContext<Workspace>,
|
||||||
should_close: impl 'static + Fn(usize) -> bool,
|
should_close: impl 'static + Fn(usize) -> bool,
|
||||||
) -> Task<()> {
|
) -> Task<Result<()>> {
|
||||||
const CONFLICT_MESSAGE: &'static str = "This file has changed on disk since you started editing it. Do you want to overwrite it?";
|
const CONFLICT_MESSAGE: &'static str = "This file has changed on disk since you started editing it. Do you want to overwrite it?";
|
||||||
const DIRTY_MESSAGE: &'static str =
|
const DIRTY_MESSAGE: &'static str =
|
||||||
"This file contains unsaved edits. Do you want to save it?";
|
"This file contains unsaved edits. Do you want to save it?";
|
||||||
|
|
||||||
let project = self.project.clone();
|
let project = workspace.project().clone();
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
while let Some(item_to_close_ix) = this.read_with(&cx, |this, _| {
|
while let Some(item_to_close_ix) = pane.read_with(&cx, |pane, _| {
|
||||||
this.items.iter().position(|item| should_close(item.id()))
|
pane.items.iter().position(|item| should_close(item.id()))
|
||||||
}) {
|
}) {
|
||||||
let item =
|
let item =
|
||||||
this.read_with(&cx, |this, _| this.items[item_to_close_ix].boxed_clone());
|
pane.read_with(&cx, |pane, _| pane.items[item_to_close_ix].boxed_clone());
|
||||||
if cx.read(|cx| item.is_dirty(cx)) {
|
if cx.read(|cx| item.is_dirty(cx)) {
|
||||||
if cx.read(|cx| item.can_save(cx)) {
|
if cx.read(|cx| item.can_save(cx)) {
|
||||||
let mut answer = this.update(&mut cx, |this, cx| {
|
let mut answer = pane.update(&mut cx, |pane, cx| {
|
||||||
this.activate_item(item_to_close_ix, true, cx);
|
pane.activate_item(item_to_close_ix, true, cx);
|
||||||
cx.prompt(
|
cx.prompt(
|
||||||
PromptLevel::Warning,
|
PromptLevel::Warning,
|
||||||
DIRTY_MESSAGE,
|
DIRTY_MESSAGE,
|
||||||
|
@ -460,21 +490,14 @@ impl Pane {
|
||||||
|
|
||||||
match answer.next().await {
|
match answer.next().await {
|
||||||
Some(0) => {
|
Some(0) => {
|
||||||
if cx
|
cx.update(|cx| item.save(project.clone(), cx)).await?;
|
||||||
.update(|cx| item.save(project.clone(), cx))
|
|
||||||
.await
|
|
||||||
.log_err()
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(1) => {}
|
Some(1) => {}
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
} else if cx.read(|cx| item.can_save_as(cx)) {
|
} else if cx.read(|cx| item.can_save_as(cx)) {
|
||||||
let mut answer = this.update(&mut cx, |this, cx| {
|
let mut answer = pane.update(&mut cx, |pane, cx| {
|
||||||
this.activate_item(item_to_close_ix, true, cx);
|
pane.activate_item(item_to_close_ix, true, cx);
|
||||||
cx.prompt(
|
cx.prompt(
|
||||||
PromptLevel::Warning,
|
PromptLevel::Warning,
|
||||||
DIRTY_MESSAGE,
|
DIRTY_MESSAGE,
|
||||||
|
@ -494,14 +517,8 @@ impl Pane {
|
||||||
let mut abs_path =
|
let mut abs_path =
|
||||||
cx.update(|cx| cx.prompt_for_new_path(&start_abs_path));
|
cx.update(|cx| cx.prompt_for_new_path(&start_abs_path));
|
||||||
if let Some(abs_path) = abs_path.next().await.flatten() {
|
if let Some(abs_path) = abs_path.next().await.flatten() {
|
||||||
if cx
|
cx.update(|cx| item.save_as(project.clone(), abs_path, cx))
|
||||||
.update(|cx| item.save_as(project.clone(), abs_path, cx))
|
.await?;
|
||||||
.await
|
|
||||||
.log_err()
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -511,8 +528,8 @@ impl Pane {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if cx.read(|cx| item.has_conflict(cx) && item.can_save(cx)) {
|
} else if cx.read(|cx| item.has_conflict(cx) && item.can_save(cx)) {
|
||||||
let mut answer = this.update(&mut cx, |this, cx| {
|
let mut answer = pane.update(&mut cx, |pane, cx| {
|
||||||
this.activate_item(item_to_close_ix, true, cx);
|
pane.activate_item(item_to_close_ix, true, cx);
|
||||||
cx.prompt(
|
cx.prompt(
|
||||||
PromptLevel::Warning,
|
PromptLevel::Warning,
|
||||||
CONFLICT_MESSAGE,
|
CONFLICT_MESSAGE,
|
||||||
|
@ -522,50 +539,36 @@ impl Pane {
|
||||||
|
|
||||||
match answer.next().await {
|
match answer.next().await {
|
||||||
Some(0) => {
|
Some(0) => {
|
||||||
if cx
|
cx.update(|cx| item.save(project.clone(), cx)).await?;
|
||||||
.update(|cx| item.save(project.clone(), cx))
|
|
||||||
.await
|
|
||||||
.log_err()
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(1) => {
|
Some(1) => {
|
||||||
if cx
|
cx.update(|cx| item.reload(project.clone(), cx)).await?;
|
||||||
.update(|cx| item.reload(project.clone(), cx))
|
|
||||||
.await
|
|
||||||
.log_err()
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.update(&mut cx, |this, cx| {
|
pane.update(&mut cx, |pane, cx| {
|
||||||
if let Some(item_ix) = this.items.iter().position(|i| i.id() == item.id()) {
|
if let Some(item_ix) = pane.items.iter().position(|i| i.id() == item.id()) {
|
||||||
if item_ix == this.active_item_index {
|
if item_ix == pane.active_item_index {
|
||||||
if item_ix + 1 < this.items.len() {
|
if item_ix + 1 < pane.items.len() {
|
||||||
this.activate_next_item(cx);
|
pane.activate_next_item(cx);
|
||||||
} else if item_ix > 0 {
|
} else if item_ix > 0 {
|
||||||
this.activate_prev_item(cx);
|
pane.activate_prev_item(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = this.items.remove(item_ix);
|
let item = pane.items.remove(item_ix);
|
||||||
if this.items.is_empty() {
|
if pane.items.is_empty() {
|
||||||
item.deactivated(cx);
|
item.deactivated(cx);
|
||||||
cx.emit(Event::Remove);
|
cx.emit(Event::Remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
if item_ix < this.active_item_index {
|
if item_ix < pane.active_item_index {
|
||||||
this.active_item_index -= 1;
|
pane.active_item_index -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut nav_history = this.nav_history.borrow_mut();
|
let mut nav_history = pane.nav_history.borrow_mut();
|
||||||
if let Some(path) = item.project_path(cx) {
|
if let Some(path) = item.project_path(cx) {
|
||||||
nav_history.paths_by_item.insert(item.id(), path);
|
nav_history.paths_by_item.insert(item.id(), path);
|
||||||
} else {
|
} else {
|
||||||
|
@ -576,6 +579,7 @@ impl Pane {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.update(&mut cx, |_, cx| cx.notify());
|
this.update(&mut cx, |_, cx| cx.notify());
|
||||||
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,6 +611,7 @@ impl Pane {
|
||||||
let theme = cx.global::<Settings>().theme.clone();
|
let theme = cx.global::<Settings>().theme.clone();
|
||||||
|
|
||||||
enum Tabs {}
|
enum Tabs {}
|
||||||
|
let pane = cx.handle();
|
||||||
let tabs = MouseEventHandler::new::<Tabs, _, _>(0, cx, |mouse_state, cx| {
|
let tabs = MouseEventHandler::new::<Tabs, _, _>(0, cx, |mouse_state, cx| {
|
||||||
let mut row = Flex::row();
|
let mut row = Flex::row();
|
||||||
for (ix, item) in self.items.iter().enumerate() {
|
for (ix, item) in self.items.iter().enumerate() {
|
||||||
|
@ -698,8 +703,14 @@ impl Pane {
|
||||||
)
|
)
|
||||||
.with_padding(Padding::uniform(4.))
|
.with_padding(Padding::uniform(4.))
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(move |cx| {
|
.on_click({
|
||||||
cx.dispatch_action(CloseItem(item_id))
|
let pane = pane.clone();
|
||||||
|
move |cx| {
|
||||||
|
cx.dispatch_action(CloseItem(CloseItemParams {
|
||||||
|
item_id,
|
||||||
|
pane: pane.clone(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.named("close-tab-icon")
|
.named("close-tab-icon")
|
||||||
} else {
|
} else {
|
||||||
|
@ -864,7 +875,8 @@ mod tests {
|
||||||
use crate::WorkspaceParams;
|
use crate::WorkspaceParams;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use gpui::TestAppContext;
|
use gpui::{ModelHandle, TestAppContext, ViewContext};
|
||||||
|
use project::Project;
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_close_items(cx: &mut TestAppContext) {
|
async fn test_close_items(cx: &mut TestAppContext) {
|
||||||
|
@ -908,15 +920,17 @@ mod tests {
|
||||||
workspace.active_pane().clone()
|
workspace.active_pane().clone()
|
||||||
});
|
});
|
||||||
|
|
||||||
let close_items = pane.update(cx, |pane, cx| {
|
let close_items = workspace.update(cx, |workspace, cx| {
|
||||||
pane.activate_item(1, true, cx);
|
pane.update(cx, |pane, cx| {
|
||||||
assert_eq!(pane.active_item().unwrap().id(), item2.id());
|
pane.activate_item(1, true, cx);
|
||||||
|
assert_eq!(pane.active_item().unwrap().id(), item2.id());
|
||||||
|
});
|
||||||
|
|
||||||
let item1_id = item1.id();
|
let item1_id = item1.id();
|
||||||
let item3_id = item3.id();
|
let item3_id = item3.id();
|
||||||
let item4_id = item4.id();
|
let item4_id = item4.id();
|
||||||
let item5_id = item5.id();
|
let item5_id = item5.id();
|
||||||
pane.close_items(cx, move |id| {
|
Pane::close_items(workspace, pane.clone(), cx, move |id| {
|
||||||
[item1_id, item3_id, item4_id, item5_id].contains(&id)
|
[item1_id, item3_id, item4_id, item5_id].contains(&id)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -960,7 +974,7 @@ mod tests {
|
||||||
cx.simulate_prompt_answer(window_id, 0);
|
cx.simulate_prompt_answer(window_id, 0);
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
cx.simulate_new_path_selection(|_| Some(Default::default()));
|
cx.simulate_new_path_selection(|_| Some(Default::default()));
|
||||||
close_items.await;
|
close_items.await.unwrap();
|
||||||
pane.read_with(cx, |pane, cx| {
|
pane.read_with(cx, |pane, cx| {
|
||||||
assert_eq!(item5.read(cx).save_count, 0);
|
assert_eq!(item5.read(cx).save_count, 0);
|
||||||
assert_eq!(item5.read(cx).save_as_count, 1);
|
assert_eq!(item5.read(cx).save_as_count, 1);
|
||||||
|
|
|
@ -497,8 +497,7 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if T::should_close_item_on_event(event) {
|
if T::should_close_item_on_event(event) {
|
||||||
pane.update(cx, |pane, cx| pane.close_item(item.id(), cx))
|
Pane::close_item(workspace, pane, item.id(), cx).detach_and_log_err(cx);
|
||||||
.detach();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,7 +737,7 @@ impl Workspace {
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
let pane = cx.add_view(|cx| Pane::new(params.project.clone(), cx));
|
let pane = cx.add_view(|cx| Pane::new(cx));
|
||||||
let pane_id = pane.id();
|
let pane_id = pane.id();
|
||||||
cx.observe(&pane, move |me, _, cx| {
|
cx.observe(&pane, move |me, _, cx| {
|
||||||
let active_entry = me.active_project_path(cx);
|
let active_entry = me.active_project_path(cx);
|
||||||
|
@ -1070,7 +1069,7 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_pane(&mut self, cx: &mut ViewContext<Self>) -> ViewHandle<Pane> {
|
fn add_pane(&mut self, cx: &mut ViewContext<Self>) -> ViewHandle<Pane> {
|
||||||
let pane = cx.add_view(|cx| Pane::new(self.project.clone(), cx));
|
let pane = cx.add_view(|cx| Pane::new(cx));
|
||||||
let pane_id = pane.id();
|
let pane_id = pane.id();
|
||||||
cx.observe(&pane, move |me, _, cx| {
|
cx.observe(&pane, move |me, _, cx| {
|
||||||
let active_entry = me.active_project_path(cx);
|
let active_entry = me.active_project_path(cx);
|
||||||
|
|
|
@ -878,11 +878,10 @@ mod tests {
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
let editor3_id = editor3.id();
|
let editor3_id = editor3.id();
|
||||||
drop(editor3);
|
drop(editor3);
|
||||||
workspace
|
Pane::close_item(workspace, workspace.active_pane().clone(), editor3_id, cx)
|
||||||
.active_pane()
|
|
||||||
.update(cx, |pane, cx| pane.close_item(editor3_id, cx))
|
|
||||||
})
|
})
|
||||||
.await;
|
.await
|
||||||
|
.unwrap();
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |w, cx| Pane::go_forward(w, None, cx))
|
.update(cx, |w, cx| Pane::go_forward(w, None, cx))
|
||||||
.await;
|
.await;
|
||||||
|
@ -896,11 +895,10 @@ mod tests {
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
let editor2_id = editor2.id();
|
let editor2_id = editor2.id();
|
||||||
drop(editor2);
|
drop(editor2);
|
||||||
workspace
|
Pane::close_item(workspace, workspace.active_pane().clone(), editor2_id, cx)
|
||||||
.active_pane()
|
|
||||||
.update(cx, |pane, cx| pane.close_item(editor2_id, cx))
|
|
||||||
})
|
})
|
||||||
.await;
|
.await
|
||||||
|
.unwrap();
|
||||||
app_state
|
app_state
|
||||||
.fs
|
.fs
|
||||||
.as_fake()
|
.as_fake()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue