1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2026-04-24 20:56:17 +02:00
Files
lazygit/pkg/gui/filetree/commit_file_tree.go
Stefan Haller b8d23dd5a5 Make file sort order and case sensitivity configurable
Set the sort order's default from the former foldersFirst to mixed, so this is a
change in behavior. I find this useful because it now matches git's order, so if
you look at the diff of a commit, the TOC at the top has the same order as the
file tree you see when entering the commit.
2026-03-30 17:53:25 +02:00

163 lines
4.3 KiB
Go

package filetree
import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/common"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/samber/lo"
)
type ICommitFileTree interface {
ITree[models.CommitFile]
Get(index int) *CommitFileNode
GetFile(path string) *models.CommitFile
GetAllItems() []*CommitFileNode
GetAllFiles() []*models.CommitFile
GetRoot() *CommitFileNode
SetTextFilter(filter string, useFuzzySearch bool)
GetTextFilter() string
}
type CommitFileTree struct {
getFiles func() []*models.CommitFile
tree *Node[models.CommitFile]
showTree bool
common *common.Common
collapsedPaths *CollapsedPaths
textFilter string
useFuzzySearch bool
}
func (self *CommitFileTree) CollapseAll() {
dirPaths := lo.FilterMap(self.GetAllItems(), func(file *CommitFileNode, index int) (string, bool) {
return file.path, !file.IsFile()
})
for _, path := range dirPaths {
self.collapsedPaths.Collapse(path)
}
}
func (self *CommitFileTree) ExpandAll() {
self.collapsedPaths.ExpandAll()
}
var _ ICommitFileTree = &CommitFileTree{}
func NewCommitFileTree(getFiles func() []*models.CommitFile, common *common.Common, showTree bool) *CommitFileTree {
return &CommitFileTree{
getFiles: getFiles,
common: common,
showTree: showTree,
collapsedPaths: NewCollapsedPaths(),
}
}
func (self *CommitFileTree) ExpandToPath(path string) {
self.collapsedPaths.ExpandToPath(path)
}
func (self *CommitFileTree) ToggleShowTree() {
self.showTree = !self.showTree
self.SetTree()
}
func (self *CommitFileTree) Get(index int) *CommitFileNode {
// need to traverse the three depth first until we get to the index.
return NewCommitFileNode(self.tree.GetNodeAtIndex(index+1, self.collapsedPaths)) // ignoring root
}
func (self *CommitFileTree) GetIndexForPath(path string) (int, bool) {
index, found := self.tree.GetIndexForPath(path, self.collapsedPaths)
return index - 1, found
}
func (self *CommitFileTree) GetAllItems() []*CommitFileNode {
if self.tree == nil {
return nil
}
// ignoring root
return lo.Map(self.tree.Flatten(self.collapsedPaths)[1:], func(node *Node[models.CommitFile], _ int) *CommitFileNode {
return NewCommitFileNode(node)
})
}
func (self *CommitFileTree) Len() int {
return self.tree.Size(self.collapsedPaths) - 1 // ignoring root
}
func (self *CommitFileTree) GetItem(index int) types.HasUrn {
// Unimplemented because we don't yet need to show inlines statuses in commit file views
return nil
}
func (self *CommitFileTree) GetAllFiles() []*models.CommitFile {
return self.getFiles()
}
func (self *CommitFileTree) getFilesForDisplay() []*models.CommitFile {
files := self.getFiles()
if self.textFilter != "" {
files = filterCommitFilesByText(files, self.textFilter, self.useFuzzySearch)
}
return files
}
func (self *CommitFileTree) SetTree() {
filesForDisplay := self.getFilesForDisplay()
guiConfig := self.common.UserConfig().Gui
showRootItem := guiConfig.ShowRootItemInFileTree
cmp := NodeSortComparator[models.CommitFile](guiConfig.FileTreeSortOrder, guiConfig.FileTreeSortCaseSensitive)
if self.showTree {
self.tree = BuildTreeFromCommitFiles(filesForDisplay, showRootItem, cmp)
} else {
self.tree = BuildFlatTreeFromCommitFiles(filesForDisplay, showRootItem, cmp)
}
}
func (self *CommitFileTree) SetTextFilter(filter string, useFuzzySearch bool) {
self.textFilter = filter
self.useFuzzySearch = useFuzzySearch
self.SetTree()
}
func (self *CommitFileTree) GetTextFilter() string {
return self.textFilter
}
func (self *CommitFileTree) IsCollapsed(path string) bool {
return self.collapsedPaths.IsCollapsed(path)
}
func (self *CommitFileTree) ToggleCollapsed(path string) {
self.collapsedPaths.ToggleCollapsed(path)
}
func (self *CommitFileTree) GetRoot() *CommitFileNode {
return NewCommitFileNode(self.tree)
}
func (self *CommitFileTree) CollapsedPaths() *CollapsedPaths {
return self.collapsedPaths
}
func (self *CommitFileTree) GetFile(path string) *models.CommitFile {
for _, file := range self.getFiles() {
if file.Path == path {
return file
}
}
return nil
}
func (self *CommitFileTree) GetVisualDepth(index int) int {
return self.tree.GetVisualDepthAtIndex(index+1, self.collapsedPaths) // +1 to skip root
}
func (self *CommitFileTree) InTreeMode() bool {
return self.showTree
}