Open buffer when trying to expand a file

This commit is contained in:
Antonio Scandurra
2021-09-30 16:19:24 +02:00
parent e98731876c
commit 41fea2de1c
2 changed files with 75 additions and 49 deletions
+73 -38
View File
@@ -1,6 +1,7 @@
use crate::{
project::{self, Project},
theme,
workspace::Workspace,
worktree::{self, Worktree},
Settings,
};
@@ -14,7 +15,7 @@ use gpui::{
},
platform::CursorStyle,
AppContext, Element, ElementBox, Entity, ModelHandle, MutableAppContext, ReadModel, View,
ViewContext, WeakViewHandle,
ViewContext, ViewHandle, WeakViewHandle,
};
use postage::watch;
use std::{
@@ -51,7 +52,7 @@ struct EntryDetails {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ProjectEntry {
pub worktree_ix: usize,
pub worktree_id: usize,
pub entry_id: usize,
}
@@ -66,51 +67,73 @@ pub fn init(cx: &mut MutableAppContext) {
cx.add_action(ProjectPanel::toggle_expanded);
cx.add_action(ProjectPanel::select_prev);
cx.add_action(ProjectPanel::select_next);
cx.add_action(ProjectPanel::open_entry);
cx.add_bindings([
Binding::new("right", ExpandSelectedEntry, None),
Binding::new("left", CollapseSelectedEntry, None),
]);
}
pub enum Event {}
pub enum Event {
OpenedEntry { worktree_id: usize, entry_id: usize },
}
impl ProjectPanel {
pub fn new(
project: ModelHandle<Project>,
settings: watch::Receiver<Settings>,
cx: &mut ViewContext<Self>,
) -> Self {
cx.observe(&project, |this, _, cx| {
this.update_visible_entries(None, cx);
cx.notify();
})
.detach();
cx.subscribe(&project, |this, _, event, cx| match event {
project::Event::ActiveEntryChanged(Some((worktree_id, entry_id))) => {
this.expand_entry(*worktree_id, *entry_id, cx);
this.update_visible_entries(Some((*worktree_id, *entry_id)), cx);
cx.notify();
}
project::Event::WorktreeRemoved(id) => {
this.expanded_dir_ids.remove(id);
cx: &mut ViewContext<Workspace>,
) -> ViewHandle<Self> {
let project_panel = cx.add_view(|cx: &mut ViewContext<Self>| {
cx.observe(&project, |this, _, cx| {
this.update_visible_entries(None, cx);
cx.notify();
})
.detach();
cx.subscribe(&project, |this, _, event, cx| match event {
project::Event::ActiveEntryChanged(Some((worktree_id, entry_id))) => {
this.expand_entry(*worktree_id, *entry_id, cx);
this.update_visible_entries(Some((*worktree_id, *entry_id)), cx);
cx.notify();
}
project::Event::WorktreeRemoved(id) => {
this.expanded_dir_ids.remove(id);
this.update_visible_entries(None, cx);
cx.notify();
}
_ => {}
})
.detach();
let mut this = Self {
project: project.clone(),
settings,
list: Default::default(),
visible_entries: Default::default(),
expanded_dir_ids: Default::default(),
selection: None,
handle: cx.handle().downgrade(),
};
this.update_visible_entries(None, cx);
this
});
cx.subscribe(&project_panel, move |workspace, _, event, cx| match event {
Event::OpenedEntry {
worktree_id,
entry_id,
} => {
if let Some(worktree) = project.read(cx).worktree_for_id(*worktree_id) {
if let Some(entry) = worktree.read(cx).entry_for_id(*entry_id) {
workspace
.open_entry((worktree.id(), entry.path.clone()), cx)
.map(|t| t.detach());
}
}
}
_ => {}
})
.detach();
let mut this = Self {
project,
settings,
list: Default::default(),
visible_entries: Default::default(),
expanded_dir_ids: Default::default(),
selection: None,
handle: cx.handle().downgrade(),
};
this.update_visible_entries(None, cx);
this
project_panel
}
fn expand_selected_entry(&mut self, _: &ExpandSelectedEntry, cx: &mut ViewContext<Self>) {
@@ -132,6 +155,11 @@ impl ProjectPanel {
}
}
} else {
let event = Event::OpenedEntry {
worktree_id: worktree.id(),
entry_id: entry.id,
};
cx.emit(event);
}
}
}
@@ -169,10 +197,10 @@ impl ProjectPanel {
fn toggle_expanded(&mut self, action: &ToggleExpanded, cx: &mut ViewContext<Self>) {
let ProjectEntry {
worktree_ix,
worktree_id,
entry_id,
} = action.0;
let worktree_id = self.project.read(cx).worktrees()[worktree_ix].id();
if let Some(expanded_dir_ids) = self.expanded_dir_ids.get_mut(&worktree_id) {
match expanded_dir_ids.binary_search(&entry_id) {
Ok(ix) => {
@@ -203,6 +231,13 @@ impl ProjectPanel {
}
}
fn open_entry(&mut self, action: &Open, cx: &mut ViewContext<Self>) {
cx.emit(Event::OpenedEntry {
worktree_id: action.0.worktree_id,
entry_id: action.0.entry_id,
});
}
fn select_next(&mut self, _: &SelectNext, cx: &mut ViewContext<Self>) {
if let Some(selection) = self.selection {
let next_ix = selection.index + 1;
@@ -411,7 +446,7 @@ impl ProjectPanel {
}),
};
let entry = ProjectEntry {
worktree_ix,
worktree_id: worktree.id(),
entry_id: entry.id,
};
callback(entry, details, cx);
@@ -429,7 +464,7 @@ impl ProjectPanel {
) -> ElementBox {
let is_dir = details.is_dir;
MouseEventHandler::new::<Self, _, _, _>(
(entry.worktree_ix, entry.entry_id),
(entry.worktree_id, entry.entry_id),
cx,
|state, _| {
let style = if details.is_selected {
@@ -568,7 +603,8 @@ mod tests {
.read_with(&cx, |t, _| t.as_local().unwrap().scan_complete())
.await;
let (_, panel) = cx.add_window(|cx| ProjectPanel::new(project, settings, cx));
let (_, workspace) = cx.add_window(|cx| Workspace::new(&app_state, cx));
let panel = workspace.update(&mut cx, |_, cx| ProjectPanel::new(project, settings, cx));
assert_eq!(
visible_entry_details(&panel, 0..50, &mut cx),
&[
@@ -742,14 +778,13 @@ mod tests {
) {
let path = path.as_ref();
panel.update(cx, |panel, cx| {
for (worktree_ix, worktree) in panel.project.read(cx).worktrees().iter().enumerate()
{
for worktree in panel.project.read(cx).worktrees() {
let worktree = worktree.read(cx);
if let Ok(relative_path) = path.strip_prefix(worktree.root_name()) {
let entry_id = worktree.entry_for_path(relative_path).unwrap().id;
panel.toggle_expanded(
&ToggleExpanded(ProjectEntry {
worktree_ix,
worktree_id: worktree.id(),
entry_id,
}),
cx,
+2 -11
View File
@@ -8,7 +8,7 @@ use crate::{
fs::Fs,
people_panel::{JoinWorktree, LeaveWorktree, PeoplePanel, ShareWorktree, UnshareWorktree},
project::Project,
project_panel::{self, ProjectPanel},
project_panel::ProjectPanel,
rpc,
settings::Settings,
user,
@@ -54,14 +54,6 @@ pub fn init(cx: &mut MutableAppContext) {
cx.add_action(Workspace::save_active_item);
cx.add_action(Workspace::debug_elements);
cx.add_action(Workspace::open_new_file);
cx.add_action(|this: &mut Workspace, action: &project_panel::Open, cx| {
if let Some(worktree) = this.worktrees(cx).get(action.0.worktree_ix) {
if let Some(entry) = worktree.read(cx).entry_for_id(action.0.entry_id) {
this.open_entry((worktree.id(), entry.path.clone()), cx)
.map(|task| task.detach());
}
}
});
cx.add_action(Workspace::toggle_sidebar_item);
cx.add_action(Workspace::share_worktree);
cx.add_action(Workspace::unshare_worktree);
@@ -386,8 +378,7 @@ impl Workspace {
let mut left_sidebar = Sidebar::new(Side::Left);
left_sidebar.add_item(
"icons/folder-tree-16.svg",
cx.add_view(|cx| ProjectPanel::new(project.clone(), app_state.settings.clone(), cx))
.into(),
ProjectPanel::new(project.clone(), app_state.settings.clone(), cx).into(),
);
let mut right_sidebar = Sidebar::new(Side::Right);