1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-05-13 22:17:05 +02:00
This commit is contained in:
Jesse Duffield 2021-03-21 10:46:43 +11:00
parent 1b94462410
commit 2b8302bced
8 changed files with 38 additions and 65 deletions

View File

@ -13,6 +13,7 @@ type FileChangeNode struct {
File *File File *File
Path string // e.g. '/path/to/mydir' Path string // e.g. '/path/to/mydir'
Collapsed bool Collapsed bool
CompressionLevel int // equal to the number of forward slashes you'll see in the path when it's rendered
} }
func (s *FileChangeNode) GetHasUnstagedChanges() bool { func (s *FileChangeNode) GetHasUnstagedChanges() bool {
@ -186,8 +187,10 @@ func (s *FileChangeNode) compressAux() *FileChangeNode {
for i := range s.Children { for i := range s.Children {
for s.Children[i].HasExactlyOneChild() { for s.Children[i].HasExactlyOneChild() {
prevCompressionLevel := s.Children[i].CompressionLevel
grandchild := s.Children[i].Children[0] grandchild := s.Children[i].Children[0]
s.Children[i] = grandchild s.Children[i] = grandchild
s.Children[i].CompressionLevel = prevCompressionLevel + 1
} }
} }
@ -241,6 +244,19 @@ func (s *FileChangeNode) ForEachFile(cb func(*File) error) error {
return nil return nil
} }
func (s *FileChangeNode) GetLeaves() []*FileChangeNode {
if s.IsLeaf() {
return []*FileChangeNode{s}
}
output := []*FileChangeNode{}
for _, child := range s.Children {
output = append(output, child.GetLeaves()...)
}
return output
}
func (s *FileChangeNode) NameAtDepth(depth int) string { func (s *FileChangeNode) NameAtDepth(depth int) string {
splitName := strings.Split(s.Path, string(os.PathSeparator)) splitName := strings.Split(s.Path, string(os.PathSeparator))
name := filepath.Join(splitName[depth:]...) name := filepath.Join(splitName[depth:]...)

View File

@ -20,61 +20,53 @@ func TestCompress(t *testing.T) {
{ {
name: "leaf node", name: "leaf node",
root: &FileChangeNode{ root: &FileChangeNode{
Name: "", Path: "",
Children: []*FileChangeNode{ Children: []*FileChangeNode{
{File: &File{Name: "test", ShortStatus: " M", HasStagedChanges: true}, Name: "test"}, {File: &File{Name: "test", ShortStatus: " M", HasStagedChanges: true}, Path: "test"},
}, },
}, },
expected: &FileChangeNode{ expected: &FileChangeNode{
Name: "", Path: "",
Children: []*FileChangeNode{ Children: []*FileChangeNode{
{File: &File{Name: "test", ShortStatus: " M", HasStagedChanges: true}, Name: "test"}, {File: &File{Name: "test", ShortStatus: " M", HasStagedChanges: true}, Path: "test"},
}, },
}, },
}, },
{ {
name: "big example", name: "big example",
root: &FileChangeNode{ root: &FileChangeNode{
Name: "", Path: "",
Children: []*FileChangeNode{ Children: []*FileChangeNode{
{ {
Name: "dir1",
Path: "dir1", Path: "dir1",
Children: []*FileChangeNode{ Children: []*FileChangeNode{
{ {
File: &File{Name: "file2", ShortStatus: "M ", HasUnstagedChanges: true}, File: &File{Name: "file2", ShortStatus: "M ", HasUnstagedChanges: true},
Name: "file2",
Path: "dir1/file2", Path: "dir1/file2",
}, },
}, },
}, },
{ {
Name: "dir2",
Path: "dir2", Path: "dir2",
Children: []*FileChangeNode{ Children: []*FileChangeNode{
{ {
File: &File{Name: "file3", ShortStatus: " M", HasStagedChanges: true}, File: &File{Name: "file3", ShortStatus: " M", HasStagedChanges: true},
Name: "file3",
Path: "dir2/file3", Path: "dir2/file3",
}, },
{ {
File: &File{Name: "file4", ShortStatus: "M ", HasUnstagedChanges: true}, File: &File{Name: "file4", ShortStatus: "M ", HasUnstagedChanges: true},
Name: "file4",
Path: "dir2/file4", Path: "dir2/file4",
}, },
}, },
}, },
{ {
Name: "dir3",
Path: "dir3", Path: "dir3",
Children: []*FileChangeNode{ Children: []*FileChangeNode{
{ {
Name: "dir3-1",
Path: "dir3/dir3-1", Path: "dir3/dir3-1",
Children: []*FileChangeNode{ Children: []*FileChangeNode{
{ {
File: &File{Name: "file5", ShortStatus: "M ", HasUnstagedChanges: true}, File: &File{Name: "file5", ShortStatus: "M ", HasUnstagedChanges: true},
Name: "file5",
Path: "dir3/dir3-1/file5", Path: "dir3/dir3-1/file5",
}, },
}, },
@ -83,43 +75,36 @@ func TestCompress(t *testing.T) {
}, },
{ {
File: &File{Name: "file1", ShortStatus: "M ", HasUnstagedChanges: true}, File: &File{Name: "file1", ShortStatus: "M ", HasUnstagedChanges: true},
Name: "file1",
Path: "file1", Path: "file1",
}, },
}, },
}, },
expected: &FileChangeNode{ expected: &FileChangeNode{
Name: "", Path: "",
Children: []*FileChangeNode{ Children: []*FileChangeNode{
{ {
Name: "dir1/file2",
File: &File{Name: "file2", ShortStatus: "M ", HasUnstagedChanges: true},
Path: "dir1/file2", Path: "dir1/file2",
File: &File{Name: "file2", ShortStatus: "M ", HasUnstagedChanges: true},
}, },
{ {
Name: "dir2",
Path: "dir2", Path: "dir2",
Children: []*FileChangeNode{ Children: []*FileChangeNode{
{ {
File: &File{Name: "file3", ShortStatus: " M", HasStagedChanges: true}, File: &File{Name: "file3", ShortStatus: " M", HasStagedChanges: true},
Name: "file3",
Path: "dir2/file3", Path: "dir2/file3",
}, },
{ {
File: &File{Name: "file4", ShortStatus: "M ", HasUnstagedChanges: true}, File: &File{Name: "file4", ShortStatus: "M ", HasUnstagedChanges: true},
Name: "file4",
Path: "dir2/file4", Path: "dir2/file4",
}, },
}, },
}, },
{ {
Name: "dir3/dir3-1/file5",
File: &File{Name: "file5", ShortStatus: "M ", HasUnstagedChanges: true},
Path: "dir3/dir3-1/file5", Path: "dir3/dir3-1/file5",
File: &File{Name: "file5", ShortStatus: "M ", HasUnstagedChanges: true},
}, },
{ {
File: &File{Name: "file1", ShortStatus: "M ", HasUnstagedChanges: true}, File: &File{Name: "file1", ShortStatus: "M ", HasUnstagedChanges: true},
Name: "file1",
Path: "file1", Path: "file1",
}, },
}, },

View File

@ -63,7 +63,7 @@ func (m *FileChangeManager) SetFiles(files []*models.File) {
func (m *FileChangeManager) SetTree() { func (m *FileChangeManager) SetTree() {
if m.ShowTree { if m.ShowTree {
m.Tree = GetTreeFromStatusFiles(m.Files, m.Log) m.Tree = GetTreeFromStatusFiles(m.Files)
} else { } else {
m.Tree = GetFlatTreeFromStatusFiles(m.Files) m.Tree = GetFlatTreeFromStatusFiles(m.Files)
} }
@ -93,7 +93,7 @@ func (m *FileChangeManager) renderAux(s *models.FileChangeNode, prefix string, d
} }
getLine := func() string { getLine := func() string {
return prefix + presentation.GetStatusNodeLine(s.GetHasUnstagedChanges(), s.GetHasStagedChanges(), s.NameAtDepth(depth), diffName, submoduleConfigs, s.File) return prefix + presentation.GetFileLine(s.GetHasUnstagedChanges(), s.GetHasStagedChanges(), s.NameAtDepth(depth), diffName, submoduleConfigs, s.File)
} }
if s.IsLeaf() { if s.IsLeaf() {
@ -131,7 +131,7 @@ func (m *FileChangeManager) renderAux(s *models.FileChangeNode, prefix string, d
childPrefix = newPrefix + INNER_ITEM childPrefix = newPrefix + INNER_ITEM
} }
arr = append(arr, m.renderAux(child, childPrefix, depth+1, diffName, submoduleConfigs)...) arr = append(arr, m.renderAux(child, childPrefix, depth+1+s.CompressionLevel, diffName, submoduleConfigs)...)
} }
return arr return arr

View File

@ -277,9 +277,6 @@ func (gui *Gui) filesListContext() *ListContext {
} }
return mappedLines return mappedLines
// TODO: Fix this up
return presentation.GetFileListDisplayStrings(gui.State.FileChangeManager.GetAllFiles(), gui.State.Modes.Diffing.Ref, gui.State.Submodules)
}, },
SelectedItem: func() (ListItem, bool) { SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedStatusNode() item := gui.getSelectedStatusNode()

View File

@ -7,24 +7,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
) )
func GetFileListDisplayStrings(files []*models.File, diffName string, submoduleConfigs []*models.SubmoduleConfig) [][]string { func GetFileLine(hasUnstagedChanges bool, hasStagedChanges bool, name string, diffName string, submoduleConfigs []*models.SubmoduleConfig, file *models.File) string {
lines := make([][]string, len(files))
for i := range files {
lines[i] = getFileDisplayStrings(files[i], diffName, submoduleConfigs)
}
return lines
}
// getFileDisplayStrings returns the display string of branch
func getFileDisplayStrings(f *models.File, diffName string, submoduleConfigs []*models.SubmoduleConfig) []string {
output := GetStatusNodeLine(f.HasUnstagedChanges, f.HasStagedChanges, f.Name, diffName, submoduleConfigs, f)
return []string{output}
}
func GetStatusNodeLine(hasUnstagedChanges bool, hasStagedChanges bool, name string, diffName string, submoduleConfigs []*models.SubmoduleConfig, file *models.File) string {
// potentially inefficient to be instantiating these color // potentially inefficient to be instantiating these color
// objects with each render // objects with each render
red := color.New(color.FgRed) red := color.New(color.FgRed)

View File

@ -7,10 +7,9 @@ import (
"strings" "strings"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/sirupsen/logrus"
) )
func GetTreeFromStatusFiles(files []*models.File, log *logrus.Entry) *models.FileChangeNode { func GetTreeFromStatusFiles(files []*models.File) *models.FileChangeNode {
root := &models.FileChangeNode{} root := &models.FileChangeNode{}
var curr *models.FileChangeNode var curr *models.FileChangeNode
@ -51,21 +50,14 @@ func GetTreeFromStatusFiles(files []*models.File, log *logrus.Entry) *models.Fil
} }
func GetFlatTreeFromStatusFiles(files []*models.File) *models.FileChangeNode { func GetFlatTreeFromStatusFiles(files []*models.File) *models.FileChangeNode {
root := &models.FileChangeNode{} rootAux := GetTreeFromStatusFiles(files)
for _, file := range files { sortedFiles := rootAux.GetLeaves()
root.Children = append(root.Children, &models.FileChangeNode{
Path: file.GetPath(),
File: file,
})
}
root.Sort()
// Move merge conflicts to top. This is the one way in which sorting // Move merge conflicts to top. This is the one way in which sorting
// differs between flat mode and tree mode // differs between flat mode and tree mode
sort.SliceStable(root.Children, func(i, j int) bool { sort.SliceStable(sortedFiles, func(i, j int) bool {
return root.Children[i].File != nil && root.Children[i].File.HasMergeConflicts && !(root.Children[j].File != nil && root.Children[j].File.HasMergeConflicts) return sortedFiles[i].File != nil && sortedFiles[i].File.HasMergeConflicts && !(sortedFiles[j].File != nil && sortedFiles[j].File.HasMergeConflicts)
}) })
return root return &models.FileChangeNode{Children: sortedFiles}
} }