Skip to content

Commit

Permalink
Collapse/uncollapse all files in tree
Browse files Browse the repository at this point in the history
Seems like this feature is highly requested #4095 #3554

Did a quick wip pr. I got the core functionality working with files and
had some questions on what can be improved in order to polish it more.
I.e. What keymaps if any to add to these, should the functionality be to
toggle vs collapse and uncollapse separately, and if this should be
added anywhere else (right now it's just for the file tree)

Once I figure this out I can add the tests, documentations and anything
else that's missing. I'm also pretty new to the language so if there's a
way I can structure this better please let me know
  • Loading branch information
mtrajano committed Jan 10, 2025
1 parent 2c32101 commit a9ec232
Show file tree
Hide file tree
Showing 18 changed files with 207 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/Config.md
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,8 @@ keybinding:
openMergeTool: M
openStatusFilter: <c-b>
copyFileInfoToClipboard: "y"
collapseAll: '-'
expandAll: =
branches:
createPullRequest: o
viewPullRequestOptions: O
Expand Down
4 changes: 4 additions & 0 deletions docs/keybindings/Keybindings_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` a `` | Toggle all files | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
| `` <enter> `` | Enter file / Toggle directory collapsed | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
| `` ` `` | Toggle file tree view | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | Search the current view by text | |

## Commit summary
Expand Down Expand Up @@ -147,6 +149,8 @@ If you would instead like to start an interactive rebase from the selected commi
| `` <c-t> `` | Open external diff tool (git difftool) | |
| `` M `` | Open external merge tool | Run `git mergetool`. |
| `` f `` | Fetch | Fetch changes from remote. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | Search the current view by text | |

## Local branches
Expand Down
4 changes: 4 additions & 0 deletions docs/keybindings/Keybindings_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ If you would instead like to start an interactive rebase from the selected commi
| `` a `` | Toggle all files | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
| `` <enter> `` | Enter file / Toggle directory collapsed | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
| `` ` `` | ファイルツリーの表示を切り替え | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | 検索を開始 | |

## コミットメッセージ
Expand Down Expand Up @@ -218,6 +220,8 @@ If you would instead like to start an interactive rebase from the selected commi
| `` <c-t> `` | Open external diff tool (git difftool) | |
| `` M `` | Git mergetoolを開く | Run `git mergetool`. |
| `` f `` | Fetch | Fetch changes from remote. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | 検索を開始 | |

## ブランチ
Expand Down
4 changes: 4 additions & 0 deletions docs/keybindings/Keybindings_ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ If you would instead like to start an interactive rebase from the selected commi
| `` a `` | Toggle all files included in patch | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
| `` <enter> `` | Enter file to add selected lines to the patch (or toggle directory collapsed) | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
| `` ` `` | 파일 트리뷰로 전환 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | 검색 시작 | |

## 커밋메시지
Expand Down Expand Up @@ -359,6 +361,8 @@ If you would instead like to start an interactive rebase from the selected commi
| `` <c-t> `` | Open external diff tool (git difftool) | |
| `` M `` | Git mergetool를 열기 | Run `git mergetool`. |
| `` f `` | Fetch | Fetch changes from remote. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | 검색 시작 | |

## 확인 패널
Expand Down
4 changes: 4 additions & 0 deletions docs/keybindings/Keybindings_nl.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` <c-t> `` | Open external diff tool (git difftool) | |
| `` M `` | Open external merge tool | Run `git mergetool`. |
| `` f `` | Fetch | Fetch changes from remote. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | Start met zoeken | |

## Bevestigingspaneel
Expand Down Expand Up @@ -136,6 +138,8 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` a `` | Toggle all files | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
| `` <enter> `` | Enter bestand om geselecteerde regels toe te voegen aan de patch | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
| `` ` `` | Toggle bestandsboom weergave | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | Start met zoeken | |

## Commits
Expand Down
4 changes: 4 additions & 0 deletions docs/keybindings/Keybindings_pl.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ Jeśli chcesz zamiast tego rozpocząć interaktywny rebase od wybranego commita,
| `` <c-t> `` | Otwórz zewnętrzne narzędzie różnic (git difftool) | |
| `` M `` | Otwórz zewnętrzne narzędzie scalania | Uruchom `git mergetool`. |
| `` f `` | Pobierz | Pobierz zmiany ze zdalnego serwera. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | Szukaj w bieżącym widoku po tekście | |

## Pliki commita
Expand All @@ -245,6 +247,8 @@ Jeśli chcesz zamiast tego rozpocząć interaktywny rebase od wybranego commita,
| `` a `` | Przełącz wszystkie pliki | Dodaj/usuń wszystkie pliki commita do niestandardowej łatki. Zobacz https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
| `` <enter> `` | Wejdź do pliku / Przełącz zwiń katalog | Jeśli plik jest wybrany, wejdź do pliku, aby móc dodawać/usuwać poszczególne linie do niestandardowej łatki. Jeśli wybrany jest katalog, przełącz katalog. |
| `` ` `` | Przełącz widok drzewa plików | Przełącz widok plików między płaskim a drzewem. Płaski układ pokazuje wszystkie ścieżki plików na jednej liście, układ drzewa grupuje pliki według katalogów. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | Szukaj w bieżącym widoku po tekście | |

## Podsumowanie commita
Expand Down
4 changes: 4 additions & 0 deletions docs/keybindings/Keybindings_ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ If you would instead like to start an interactive rebase from the selected commi
| `` a `` | Переключить все файлы, включённые в патч | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
| `` <enter> `` | Введите файл, чтобы добавить выбранные строки в патч (или свернуть каталог переключения) | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
| `` ` `` | Переключить вид дерева файлов | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | Найти | |

## Статус
Expand Down Expand Up @@ -353,6 +355,8 @@ If you would instead like to start an interactive rebase from the selected commi
| `` <c-t> `` | Open external diff tool (git difftool) | |
| `` M `` | Открыть внешний инструмент слияния (git mergetool) | Run `git mergetool`. |
| `` f `` | Получить изменения | Fetch changes from remote. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | Найти | |

## Хранилище
Expand Down
4 changes: 4 additions & 0 deletions docs/keybindings/Keybindings_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ _图例:`<c-b>` 意味着ctrl+b, `<a-b>意味着Alt+b, `B` 意味着shift+b_
| `` a `` | 操作所有文件 | 添加或删除所有提交中的文件到自定义的补丁中。请参阅 https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches。 |
| `` <enter> `` | 输入文件以将所选行添加到补丁中(或切换目录折叠) | 如果已选择一个文件,则Enter进入该文件,以便您可以向自定义补丁添加/删除单独的行。如果选择了目录,则切换目录。 |
| `` ` `` | 切换文件树视图 | 在平铺部署与树布局之间切换文件视图。平铺布局在一个列表中展示所有文件路径,树布局则根据目录分组展示。 |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | 开始搜索 | |

## 文件
Expand Down Expand Up @@ -225,6 +227,8 @@ _图例:`<c-b>` 意味着ctrl+b, `<a-b>意味着Alt+b, `B` 意味着shift+b_
| `` <c-t> `` | 使用外部差异比较工具(git difftool) | |
| `` M `` | 打开外部合并工具(git mergetool) | 执行 `git mergetool`. |
| `` f `` | 抓取 | 从远程获取变更 |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | 开始搜索 | |

## 构建补丁中
Expand Down
4 changes: 4 additions & 0 deletions docs/keybindings/Keybindings_zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ If you would instead like to start an interactive rebase from the selected commi
| `` a `` | 切換所有檔案是否包含在補丁中 | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
| `` <enter> `` | 輸入檔案以將選定的行添加至補丁(或切換目錄折疊) | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
| `` ` `` | 顯示檔案樹狀視圖 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | 搜尋 | |

## 收藏 (Stash)
Expand Down Expand Up @@ -320,6 +322,8 @@ If you would instead like to start an interactive rebase from the selected commi
| `` <c-t> `` | 開啟外部差異工具 (git difftool) | |
| `` M `` | 開啟外部合併工具 | 執行 `git mergetool`|
| `` f `` | 擷取 | 同步遠端異動 |
| `` - `` | Collapse all files | Collapse all entries in the files tree |
| `` = `` | Expand all files | Expand all entries in the file tree |
| `` / `` | 搜尋 | |

## 狀態
Expand Down
4 changes: 4 additions & 0 deletions pkg/config/user_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ type KeybindingFilesConfig struct {
OpenMergeTool string `yaml:"openMergeTool"`
OpenStatusFilter string `yaml:"openStatusFilter"`
CopyFileInfoToClipboard string `yaml:"copyFileInfoToClipboard"`
CollapseAll string `yaml:"collapseAll"`
ExpandAll string `yaml:"expandAll"`
}

type KeybindingBranchesConfig struct {
Expand Down Expand Up @@ -895,6 +897,8 @@ func GetDefaultConfig() *UserConfig {
OpenStatusFilter: "<c-b>",
ConfirmDiscard: "x",
CopyFileInfoToClipboard: "y",
CollapseAll: "-",
ExpandAll: "=",
},
Branches: KeybindingBranchesConfig{
CopyPullRequestURL: "<c-y>",
Expand Down
40 changes: 40 additions & 0 deletions pkg/gui/controllers/commits_files_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,18 @@ func (self *CommitFilesController) GetKeybindings(opts types.KeybindingsOpts) []
Description: self.c.Tr.ToggleTreeView,
Tooltip: self.c.Tr.ToggleTreeViewTooltip,
},
{
Key: opts.GetKey(opts.Config.Files.CollapseAll),
Handler: self.collapseAll,
Description: self.c.Tr.CollapseAll,
Tooltip: self.c.Tr.CollapseAllTooltip,
},
{
Key: opts.GetKey(opts.Config.Files.ExpandAll),
Handler: self.expandAll,
Description: self.c.Tr.ExpandAll,
Tooltip: self.c.Tr.ExpandAllTooltip,
},
}

return bindings
Expand Down Expand Up @@ -401,6 +413,34 @@ func (self *CommitFilesController) toggleTreeView() error {
return nil
}

func (self *CommitFilesController) collapseAll() error {
nodes := self.context().GetAllItems()

dirPaths := lo.FilterMap(nodes, func(file *filetree.CommitFileNode, index int) (string, bool) {
return file.Path, !file.IsFile()
})

self.context().CommitFileTreeViewModel.CollapseAll(dirPaths)

self.c.PostRefreshUpdate(self.context())

return nil
}

func (self *CommitFilesController) expandAll() error {
files := self.context().GetAllFiles()

filePaths := lo.Map(files, func(file *models.CommitFile, index int) string {
return file.GetPath()
})

self.context().CommitFileTreeViewModel.UncollapseAll(filePaths)

self.c.PostRefreshUpdate(self.context())

return nil
}

// NOTE: these functions are identical to those in files_controller.go (except for types) and
// could also be cleaned up with some generics
func normalisedSelectedCommitFileNodes(selectedNodes []*filetree.CommitFileNode) []*filetree.CommitFileNode {
Expand Down
40 changes: 40 additions & 0 deletions pkg/gui/controllers/files_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,18 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
Description: self.c.Tr.Fetch,
Tooltip: self.c.Tr.FetchTooltip,
},
{
Key: opts.GetKey(opts.Config.Files.CollapseAll),
Handler: self.collapseAll,
Description: self.c.Tr.CollapseAll,
Tooltip: self.c.Tr.CollapseAllTooltip,
},
{
Key: opts.GetKey(opts.Config.Files.ExpandAll),
Handler: self.expandAll,
Description: self.c.Tr.ExpandAll,
Tooltip: self.c.Tr.ExpandAllTooltip,
},
}
}

Expand Down Expand Up @@ -478,6 +490,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.context())

return nil
}

func (self *FilesController) expandAll() 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.context())

return nil
}

func (self *FilesController) EnterFile(opts types.OnFocusOpts) error {
node := self.context().GetSelected()
if node == nil {
Expand Down
12 changes: 12 additions & 0 deletions pkg/gui/filetree/commit_file_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ type CommitFileTree struct {
collapsedPaths *CollapsedPaths
}

func (self *CommitFileTree) CollapseAll(paths []string) {
for _, path := range paths {
self.collapsedPaths.Collapse(path)
}
}

func (self *CommitFileTree) UncollapseAll(paths []string) {
for _, path := range paths {
self.collapsedPaths.ExpandToPath(path)
}
}

var _ ICommitFileTree = &CommitFileTree{}

func NewCommitFileTree(getFiles func() []*models.CommitFile, log *logrus.Entry, showTree bool) *CommitFileTree {
Expand Down
14 changes: 14 additions & 0 deletions pkg/gui/filetree/file_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type ITree[T any] interface {
IsCollapsed(path string) bool
ToggleCollapsed(path string)
CollapsedPaths() *CollapsedPaths
CollapseAll(paths []string)
UncollapseAll(paths []string)
}

type IFileTree interface {
Expand Down Expand Up @@ -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)
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/i18n/english.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ type TranslationSet struct {
NoBranchOnRemote string
Fetch string
FetchTooltip string
CollapseAll string
CollapseAllTooltip string
ExpandAll string
ExpandAllTooltip string
FileEnter string
FileEnterTooltip string
FileStagingRequirements string
Expand Down Expand Up @@ -1258,6 +1262,10 @@ func EnglishTranslationSet() *TranslationSet {
NoBranchOnRemote: `This branch doesn't exist on remote. You need to push it to remote first.`,
Fetch: `Fetch`,
FetchTooltip: "Fetch changes from remote.",
CollapseAll: "Collapse all files",
CollapseAllTooltip: "Collapse all entries in the files tree",
ExpandAll: "Expand all files",
ExpandAllTooltip: "Expand all entries in the file tree",
FileEnter: `Stage lines / Collapse directory`,
FileEnterTooltip: "If the selected item is a file, focus the staging view so you can stage individual hunks/lines. If the selected item is a directory, collapse/expand it.",
FileStagingRequirements: `Can only stage individual lines for tracked files`,
Expand Down
46 changes: 46 additions & 0 deletions pkg/integration/tests/file/collapse_expand.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package file

import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)

var CollapseExpand = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Collapsing and expanding all files in the file tree",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {
},
SetupRepo: func(shell *Shell) {
shell.CreateDir("dir")
shell.CreateFile("dir/file-one", "original content\n")
shell.CreateDir("dir2")
shell.CreateFile("dir2/file-two", "original content\n")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Files().
IsFocused().
Lines(
Contains("dir").IsSelected(),
Contains("??").Contains("file-one"),
Contains("dir2"),
Contains("??").Contains("file-two"),
)

t.Views().Files().
Press(keys.Files.CollapseAll).
Lines(
Contains("dir"),
Contains("dir2"),
)

t.Views().Files().
Press(keys.Files.ExpandAll).
Lines(
Contains("dir").IsSelected(),
Contains("??").Contains("file-one"),
Contains("dir2"),
Contains("??").Contains("file-two"),
)
},
})
Loading

0 comments on commit a9ec232

Please sign in to comment.