diff --git a/pkg/gui/controllers/files_controller.go b/pkg/gui/controllers/files_controller.go index 1ea20eeb218..20cd7775a79 100644 --- a/pkg/gui/controllers/files_controller.go +++ b/pkg/gui/controllers/files_controller.go @@ -186,6 +186,12 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types Description: self.c.Tr.Fetch, Tooltip: self.c.Tr.FetchTooltip, }, + { + Key: 'z', + Handler: self.collapseAll, + // GetDisabledReason: self.require(self.singleItemSelected()), + Description: "Collapse All directories", + }, } } @@ -478,6 +484,34 @@ func (self *FilesController) enter() error { return self.EnterFile(types.OnFocusOpts{ClickedWindowName: "", ClickedViewLineIdx: -1}) } +func (self *FilesController) collapseAll() error { + nodes := self.context().GetAllItems() + + dirPaths := lo.FilterMap(nodes, func(file *filetree.FileNode, index int) (string, bool) { + return file.Path, !file.IsFile() + }) + + self.context().FileTreeViewModel.CollapseAll(dirPaths) + + self.c.PostRefreshUpdate(self.c.Contexts().Files) + + return nil +} + +func (self *FilesController) uncollapseAll() error { + files := self.context().GetAllFiles() + + filePaths := lo.Map(files, func(file *models.File, index int) string { + return file.GetPath() + }) + + self.context().FileTreeViewModel.UncollapseAll(filePaths) + + self.c.PostRefreshUpdate(self.c.Contexts().Files) + + return nil +} + func (self *FilesController) EnterFile(opts types.OnFocusOpts) error { node := self.context().GetSelected() if node == nil { diff --git a/pkg/gui/filetree/collapsed_paths.go b/pkg/gui/filetree/collapsed_paths.go index 903999b37d0..039c431e1ea 100644 --- a/pkg/gui/filetree/collapsed_paths.go +++ b/pkg/gui/filetree/collapsed_paths.go @@ -29,10 +29,14 @@ func (self *CollapsedPaths) Collapse(path string) { self.collapsedPaths.Add(path) } +func (self *CollapsedPaths) Uncollapse(path string) { + self.collapsedPaths.Remove(path) +} + func (self *CollapsedPaths) ToggleCollapsed(path string) { - if self.collapsedPaths.Includes(path) { - self.collapsedPaths.Remove(path) + if self.IsCollapsed(path) { + self.Uncollapse(path) } else { - self.collapsedPaths.Add(path) + self.Collapse(path) } } diff --git a/pkg/gui/filetree/file_tree.go b/pkg/gui/filetree/file_tree.go index 12780e3ed3d..d12988daa47 100644 --- a/pkg/gui/filetree/file_tree.go +++ b/pkg/gui/filetree/file_tree.go @@ -44,6 +44,8 @@ type IFileTree interface { GetAllFiles() []*models.File GetFilter() FileTreeDisplayFilter GetRoot() *FileNode + CollapseAll(paths []string) + UncollapseAll(paths []string) } type FileTree struct { @@ -171,6 +173,18 @@ func (self *FileTree) ToggleCollapsed(path string) { self.collapsedPaths.ToggleCollapsed(path) } +func (self *FileTree) CollapseAll(paths []string) { + for _, path := range paths { + self.collapsedPaths.Collapse(path) + } +} + +func (self *FileTree) UncollapseAll(paths []string) { + for _, path := range paths { + self.collapsedPaths.ExpandToPath(path) + } +} + func (self *FileTree) Tree() *FileNode { return NewFileNode(self.tree) }