Add OpenExcerptsSplit (#8574)
I would like to keep diagnostics open on one side, and process them on the other. Release Notes: - Added `editor::OpenExcerptsSplit` (bound to `cmd-k enter`) to open the selected excerpts in the adjacent pane - vim: Added `ctrl-w d`, `ctrl-w shift-d` and `ctrl-w space` for `editor::GoTo{,Type}Definition` and `editor::OpenExcerptsSplit`
This commit is contained in:
parent
b7429bf29d
commit
778b6fb27b
20 changed files with 100 additions and 80 deletions
|
@ -1885,15 +1885,23 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_item(&mut self, item: Box<dyn ItemHandle>, cx: &mut WindowContext) {
|
||||
pub fn add_item_to_active_pane(&mut self, item: Box<dyn ItemHandle>, cx: &mut WindowContext) {
|
||||
self.add_item(self.active_pane.clone(), item, cx)
|
||||
}
|
||||
|
||||
pub fn add_item(
|
||||
&mut self,
|
||||
pane: View<Pane>,
|
||||
item: Box<dyn ItemHandle>,
|
||||
cx: &mut WindowContext,
|
||||
) {
|
||||
if let Some(text) = item.telemetry_event_text(cx) {
|
||||
self.client()
|
||||
.telemetry()
|
||||
.report_app_event(format!("{}: open", text));
|
||||
}
|
||||
|
||||
self.active_pane
|
||||
.update(cx, |pane, cx| pane.add_item(item, true, true, None, cx));
|
||||
pane.update(cx, |pane, cx| pane.add_item(item, true, true, None, cx));
|
||||
}
|
||||
|
||||
pub fn split_item(
|
||||
|
@ -1903,9 +1911,7 @@ impl Workspace {
|
|||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
let new_pane = self.split_pane(self.active_pane.clone(), split_direction, cx);
|
||||
new_pane.update(cx, move |new_pane, cx| {
|
||||
new_pane.add_item(item, true, true, None, cx)
|
||||
})
|
||||
self.add_item(new_pane, item, cx);
|
||||
}
|
||||
|
||||
pub fn open_abs_path(
|
||||
|
@ -2047,6 +2053,7 @@ impl Workspace {
|
|||
|
||||
pub fn open_project_item<T>(
|
||||
&mut self,
|
||||
pane: View<Pane>,
|
||||
project_item: Model<T::Item>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> View<T>
|
||||
|
@ -2057,7 +2064,7 @@ impl Workspace {
|
|||
|
||||
let entry_id = project_item.read(cx).entry_id(cx);
|
||||
if let Some(item) = entry_id
|
||||
.and_then(|entry_id| self.active_pane().read(cx).item_for_entry(entry_id, cx))
|
||||
.and_then(|entry_id| pane.read(cx).item_for_entry(entry_id, cx))
|
||||
.and_then(|item| item.downcast())
|
||||
{
|
||||
self.activate_item(&item, cx);
|
||||
|
@ -2065,31 +2072,7 @@ impl Workspace {
|
|||
}
|
||||
|
||||
let item = cx.new_view(|cx| T::for_project_item(self.project().clone(), project_item, cx));
|
||||
self.add_item(Box::new(item.clone()), cx);
|
||||
item
|
||||
}
|
||||
|
||||
pub fn split_project_item<T>(
|
||||
&mut self,
|
||||
project_item: Model<T::Item>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> View<T>
|
||||
where
|
||||
T: ProjectItem,
|
||||
{
|
||||
use project::Item as _;
|
||||
|
||||
let entry_id = project_item.read(cx).entry_id(cx);
|
||||
if let Some(item) = entry_id
|
||||
.and_then(|entry_id| self.active_pane().read(cx).item_for_entry(entry_id, cx))
|
||||
.and_then(|item| item.downcast())
|
||||
{
|
||||
self.activate_item(&item, cx);
|
||||
return item;
|
||||
}
|
||||
|
||||
let item = cx.new_view(|cx| T::for_project_item(self.project().clone(), project_item, cx));
|
||||
self.split_item(SplitDirection::Right, Box::new(item.clone()), cx);
|
||||
self.add_item(pane, Box::new(item.clone()), cx);
|
||||
item
|
||||
}
|
||||
|
||||
|
@ -2498,6 +2481,13 @@ impl Workspace {
|
|||
&self.active_pane
|
||||
}
|
||||
|
||||
pub fn adjacent_pane(&mut self, cx: &mut ViewContext<Self>) -> View<Pane> {
|
||||
self.find_pane_in_direction(SplitDirection::Right, cx)
|
||||
.or_else(|| self.find_pane_in_direction(SplitDirection::Left, cx))
|
||||
.unwrap_or_else(|| self.split_pane(self.active_pane.clone(), SplitDirection::Right, cx))
|
||||
.clone()
|
||||
}
|
||||
|
||||
pub fn pane_for(&self, handle: &dyn ItemHandle) -> Option<View<Pane>> {
|
||||
let weak_pane = self.panes_by_item.get(&handle.item_id())?;
|
||||
weak_pane.upgrade()
|
||||
|
@ -4702,7 +4692,7 @@ mod tests {
|
|||
item
|
||||
});
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item(Box::new(item1.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item1.clone()), cx);
|
||||
});
|
||||
item1.update(cx, |item, _| assert_eq!(item.tab_detail.get(), Some(0)));
|
||||
|
||||
|
@ -4714,7 +4704,7 @@ mod tests {
|
|||
item
|
||||
});
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item(Box::new(item2.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item2.clone()), 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)));
|
||||
|
@ -4728,7 +4718,7 @@ mod tests {
|
|||
item
|
||||
});
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item(Box::new(item3.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item3.clone()), 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)));
|
||||
|
@ -4771,7 +4761,9 @@ mod tests {
|
|||
});
|
||||
|
||||
// Add an item to an empty pane
|
||||
workspace.update(cx, |workspace, cx| workspace.add_item(Box::new(item1), cx));
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item_to_active_pane(Box::new(item1), cx)
|
||||
});
|
||||
project.update(cx, |project, cx| {
|
||||
assert_eq!(
|
||||
project.active_entry(),
|
||||
|
@ -4783,7 +4775,9 @@ mod tests {
|
|||
assert_eq!(cx.window_title().as_deref(), Some("one.txt — root1"));
|
||||
|
||||
// Add a second item to a non-empty pane
|
||||
workspace.update(cx, |workspace, cx| workspace.add_item(Box::new(item2), cx));
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item_to_active_pane(Box::new(item2), cx)
|
||||
});
|
||||
assert_eq!(cx.window_title().as_deref(), Some("two.txt — root1"));
|
||||
project.update(cx, |project, cx| {
|
||||
assert_eq!(
|
||||
|
@ -4836,7 +4830,9 @@ mod tests {
|
|||
|
||||
// When there are no dirty items, there's nothing to do.
|
||||
let item1 = cx.new_view(|cx| TestItem::new(cx));
|
||||
workspace.update(cx, |w, cx| w.add_item(Box::new(item1.clone()), cx));
|
||||
workspace.update(cx, |w, cx| {
|
||||
w.add_item_to_active_pane(Box::new(item1.clone()), cx)
|
||||
});
|
||||
let task = workspace.update(cx, |w, cx| w.prepare_to_close(false, cx));
|
||||
assert!(task.await.unwrap());
|
||||
|
||||
|
@ -4849,8 +4845,8 @@ mod tests {
|
|||
.with_project_items(&[TestProjectItem::new(1, "1.txt", cx)])
|
||||
});
|
||||
workspace.update(cx, |w, cx| {
|
||||
w.add_item(Box::new(item2.clone()), cx);
|
||||
w.add_item(Box::new(item3.clone()), cx);
|
||||
w.add_item_to_active_pane(Box::new(item2.clone()), cx);
|
||||
w.add_item_to_active_pane(Box::new(item3.clone()), cx);
|
||||
});
|
||||
let task = workspace.update(cx, |w, cx| w.prepare_to_close(false, cx));
|
||||
cx.executor().run_until_parked();
|
||||
|
@ -4894,10 +4890,10 @@ mod tests {
|
|||
.with_project_items(&[TestProjectItem::new_untitled(cx)])
|
||||
});
|
||||
let pane = workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item(Box::new(item1.clone()), cx);
|
||||
workspace.add_item(Box::new(item2.clone()), cx);
|
||||
workspace.add_item(Box::new(item3.clone()), cx);
|
||||
workspace.add_item(Box::new(item4.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item1.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item2.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item3.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item4.clone()), cx);
|
||||
workspace.active_pane().clone()
|
||||
});
|
||||
|
||||
|
@ -5019,9 +5015,9 @@ mod tests {
|
|||
// multi-entry items: (3, 4)
|
||||
let left_pane = workspace.update(cx, |workspace, cx| {
|
||||
let left_pane = workspace.active_pane().clone();
|
||||
workspace.add_item(Box::new(item_2_3.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item_2_3.clone()), cx);
|
||||
for item in single_entry_items {
|
||||
workspace.add_item(Box::new(item), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item), cx);
|
||||
}
|
||||
left_pane.update(cx, |pane, cx| {
|
||||
pane.activate_item(2, true, true, cx);
|
||||
|
@ -5092,7 +5088,7 @@ mod tests {
|
|||
});
|
||||
let item_id = item.entity_id();
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item(Box::new(item.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item.clone()), cx);
|
||||
});
|
||||
|
||||
// Autosave on window change.
|
||||
|
@ -5174,7 +5170,7 @@ mod tests {
|
|||
|
||||
// Add the item again, ensuring autosave is prevented if the underlying file has been deleted.
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item(Box::new(item.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item.clone()), cx);
|
||||
});
|
||||
item.update(cx, |item, cx| {
|
||||
item.project_items[0].update(cx, |item, _| {
|
||||
|
@ -5212,7 +5208,7 @@ mod tests {
|
|||
let toolbar_notify_count = Rc::new(RefCell::new(0));
|
||||
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
workspace.add_item(Box::new(item.clone()), cx);
|
||||
workspace.add_item_to_active_pane(Box::new(item.clone()), cx);
|
||||
let toolbar_notification_count = toolbar_notify_count.clone();
|
||||
cx.observe(&toolbar, move |_, _, _| {
|
||||
*toolbar_notification_count.borrow_mut() += 1
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue