Allow expanding/collapsing active entry using the keyboard

This commit is contained in:
Antonio Scandurra 2021-09-30 14:38:21 +02:00
parent 789d5dfaee
commit 19325fd3f1

View File

@ -8,6 +8,7 @@ use gpui::{
keymap::{
self,
menu::{SelectNext, SelectPrev},
Binding,
},
platform::CursorStyle,
AppContext, Element, ElementBox, Entity, ModelHandle, MutableAppContext, ReadModel, View,
@ -52,13 +53,21 @@ pub struct ProjectEntry {
pub entry_id: usize,
}
action!(ExpandActiveEntry);
action!(CollapseActiveEntry);
action!(ToggleExpanded, ProjectEntry);
action!(Open, ProjectEntry);
pub fn init(cx: &mut MutableAppContext) {
cx.add_action(ProjectPanel::expand_active_entry);
cx.add_action(ProjectPanel::collapse_active_entry);
cx.add_action(ProjectPanel::toggle_expanded);
cx.add_action(ProjectPanel::select_prev);
cx.add_action(ProjectPanel::select_next);
cx.add_bindings([
Binding::new("right", ExpandActiveEntry, None),
Binding::new("left", CollapseActiveEntry, None),
]);
}
pub enum Event {}
@ -77,7 +86,7 @@ impl ProjectPanel {
cx.subscribe(&project, |this, _, event, cx| match event {
project::Event::ActiveEntryChanged(entry) => {
if let Some((worktree_id, entry_id)) = *entry {
this.expand_active_entry(worktree_id, entry_id, cx);
this.expand_entry(worktree_id, entry_id, cx);
this.update_visible_entries(Some((worktree_id, entry_id)), cx);
cx.notify();
}
@ -103,6 +112,68 @@ impl ProjectPanel {
this
}
fn expand_active_entry(&mut self, _: &ExpandActiveEntry, cx: &mut ViewContext<Self>) {
if let Some(active_entry) = self.active_entry {
let project = self.project.read(cx);
if let Some(worktree) = project.worktree_for_id(active_entry.worktree_id) {
if let Some(entry) = worktree.read(cx).entry_for_id(active_entry.entry_id) {
if entry.is_dir() {
if let Some(expanded_dir_ids) =
self.expanded_dir_ids.get_mut(&active_entry.worktree_id)
{
match expanded_dir_ids.binary_search(&active_entry.entry_id) {
Ok(_) => self.select_next(&SelectNext, cx),
Err(ix) => {
expanded_dir_ids.insert(ix, active_entry.entry_id);
self.update_visible_entries(None, cx);
cx.notify();
}
}
}
} else {
}
}
}
}
}
fn collapse_active_entry(&mut self, _: &CollapseActiveEntry, cx: &mut ViewContext<Self>) {
if let Some(active_entry) = self.active_entry {
let project = self.project.read(cx);
if let Some(worktree) = project.worktree_for_id(active_entry.worktree_id) {
let worktree = worktree.read(cx);
if let Some(mut entry) = worktree.entry_for_id(active_entry.entry_id) {
if let Some(expanded_dir_ids) =
self.expanded_dir_ids.get_mut(&active_entry.worktree_id)
{
loop {
match expanded_dir_ids.binary_search(&entry.id) {
Ok(ix) => {
expanded_dir_ids.remove(ix);
self.update_visible_entries(
Some((active_entry.worktree_id, entry.id)),
cx,
);
cx.notify();
break;
}
Err(_) => {
if let Some(parent_entry) =
entry.path.parent().and_then(|p| worktree.entry_for_path(p))
{
entry = parent_entry;
} else {
break;
}
}
}
}
}
}
}
}
}
fn toggle_expanded(&mut self, action: &ToggleExpanded, cx: &mut ViewContext<Self>) {
let ProjectEntry {
worktree_ix,
@ -269,12 +340,7 @@ impl ProjectPanel {
self.autoscroll();
}
fn expand_active_entry(
&mut self,
worktree_id: usize,
entry_id: usize,
cx: &mut ViewContext<Self>,
) {
fn expand_entry(&mut self, worktree_id: usize, entry_id: usize, cx: &mut ViewContext<Self>) {
let project = self.project.read(cx);
if let Some((worktree, expanded_dir_ids)) = project
.worktree_for_id(worktree_id)