@@ -900,6 +900,8 @@
{
"context": "GitPanel && ChangesList",
"bindings": {
+ "left": "git_panel::CollapseSelectedEntry",
+ "right": "git_panel::ExpandSelectedEntry",
"up": "menu::SelectPrevious",
"down": "menu::SelectNext",
"enter": "menu::Confirm",
@@ -975,6 +975,8 @@
"context": "GitPanel && ChangesList",
"use_key_equivalents": true,
"bindings": {
+ "left": "git_panel::CollapseSelectedEntry",
+ "right": "git_panel::ExpandSelectedEntry",
"up": "menu::SelectPrevious",
"down": "menu::SelectNext",
"cmd-up": "menu::SelectFirst",
@@ -904,6 +904,8 @@
"context": "GitPanel && ChangesList",
"use_key_equivalents": true,
"bindings": {
+ "left": "git_panel::CollapseSelectedEntry",
+ "right": "git_panel::ExpandSelectedEntry",
"up": "menu::SelectPrevious",
"down": "menu::SelectNext",
"enter": "menu::Confirm",
@@ -98,6 +98,10 @@ actions!(
ToggleSortByPath,
/// Toggles showing entries in tree vs flat view.
ToggleTreeView,
+ /// Expands the selected entry to show its children.
+ ExpandSelectedEntry,
+ /// Collapses the selected entry to hide its children.
+ CollapseSelectedEntry,
]
);
@@ -896,6 +900,48 @@ impl GitPanel {
.position(|entry| entry.status_entry().is_some())
}
+ fn expand_selected_entry(
+ &mut self,
+ _: &ExpandSelectedEntry,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) {
+ let Some(entry) = self.get_selected_entry().cloned() else {
+ return;
+ };
+
+ if let GitListEntry::Directory(dir_entry) = entry {
+ if dir_entry.expanded {
+ self.select_next(&SelectNext, window, cx);
+ } else {
+ self.toggle_directory(&dir_entry.key, window, cx);
+ }
+ } else {
+ self.select_next(&SelectNext, window, cx);
+ }
+ }
+
+ fn collapse_selected_entry(
+ &mut self,
+ _: &CollapseSelectedEntry,
+ window: &mut Window,
+ cx: &mut Context<Self>,
+ ) {
+ let Some(entry) = self.get_selected_entry().cloned() else {
+ return;
+ };
+
+ if let GitListEntry::Directory(dir_entry) = entry {
+ if dir_entry.expanded {
+ self.toggle_directory(&dir_entry.key, window, cx);
+ } else {
+ self.select_previous(&SelectPrevious, window, cx);
+ }
+ } else {
+ self.select_previous(&SelectPrevious, window, cx);
+ }
+ }
+
fn select_first(&mut self, _: &SelectFirst, _window: &mut Window, cx: &mut Context<Self>) {
if let Some(first_entry) = self.first_status_entry_index() {
self.selected_entry = Some(first_entry);
@@ -5264,6 +5310,8 @@ impl Render for GitPanel {
.on_action(cx.listener(Self::stash_all))
.on_action(cx.listener(Self::stash_pop))
})
+ .on_action(cx.listener(Self::collapse_selected_entry))
+ .on_action(cx.listener(Self::expand_selected_entry))
.on_action(cx.listener(Self::select_first))
.on_action(cx.listener(Self::select_next))
.on_action(cx.listener(Self::select_previous))