1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-25 12:24:47 +02:00

better handling of refreshed files

This commit is contained in:
Jesse Duffield 2021-03-21 09:06:15 +11:00
parent da6fe01eca
commit 1183f68e19
4 changed files with 23 additions and 127 deletions

View File

@ -461,87 +461,6 @@ func TestGitCommandCommitAmend(t *testing.T) {
assert.NoError(t, err)
}
// TestGitCommandMergeStatusFiles is a function.
func TestGitCommandMergeStatusFiles(t *testing.T) {
type scenario struct {
testName string
oldFiles []*models.File
newFiles []*models.File
test func([]*models.File)
}
scenarios := []scenario{
{
"Old file and new file are the same",
[]*models.File{},
[]*models.File{
{
Name: "new_file.txt",
},
},
func(files []*models.File) {
expected := []*models.File{
{
Name: "new_file.txt",
},
}
assert.Len(t, files, 1)
assert.EqualValues(t, expected, files)
},
},
{
"Several files to merge, with some identical",
[]*models.File{
{
Name: "new_file1.txt",
},
{
Name: "new_file2.txt",
},
{
Name: "new_file3.txt",
},
},
[]*models.File{
{
Name: "new_file4.txt",
},
{
Name: "new_file5.txt",
},
{
Name: "new_file1.txt",
},
},
func(files []*models.File) {
expected := []*models.File{
{
Name: "new_file1.txt",
},
{
Name: "new_file4.txt",
},
{
Name: "new_file5.txt",
},
}
assert.Len(t, files, 3)
assert.EqualValues(t, expected, files)
},
},
}
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommand()
s.test(gitCmd.MergeStatusFiles(s.oldFiles, s.newFiles, nil))
})
}
}
// TestGitCommandGetCommitDifferences is a function.
func TestGitCommandGetCommitDifferences(t *testing.T) {
type scenario struct {

View File

@ -102,38 +102,3 @@ func (c *GitCommand) GitStatus(opts GitStatusOptions) (string, error) {
return strings.Join(splitLines, "\n"), nil
}
// MergeStatusFiles merge status files
func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []*models.File, selectedFile *models.File) []*models.File {
if len(oldFiles) == 0 {
return newFiles
}
appendedIndexes := []int{}
// retain position of files we already could see
result := []*models.File{}
for _, oldFile := range oldFiles {
for newIndex, newFile := range newFiles {
if utils.IncludesInt(appendedIndexes, newIndex) {
continue
}
// if we just staged B and in doing so created 'A -> B' and we are currently have oldFile: A and newFile: 'A -> B', we want to wait until we come across B so the our cursor isn't jumping anywhere
waitForMatchingFile := selectedFile != nil && newFile.IsRename() && !selectedFile.IsRename() && newFile.Matches(selectedFile) && !oldFile.Matches(selectedFile)
if oldFile.Matches(newFile) && !waitForMatchingFile {
result = append(result, newFile)
appendedIndexes = append(appendedIndexes, newIndex)
}
}
}
// append any new files to the end
for index, newFile := range newFiles {
if !utils.IncludesInt(appendedIndexes, index) {
result = append(result, newFile)
}
}
return result
}

View File

@ -522,26 +522,36 @@ func (gui *Gui) refreshStateFiles() error {
// keep track of where the cursor is currently and the current file names
// when we refresh, go looking for a matching name
// move the cursor to there.
selectedFile := gui.getSelectedFile()
selectedNode := gui.getSelectedStatusNode()
getPaths := func(node *models.StatusLineNode) []string {
if node.File != nil && node.File.IsRename() {
return node.File.Names()
} else {
return []string{node.Path}
}
}
selectedPaths := getPaths(selectedNode)
prevSelectedLineIdx := gui.State.Panels.Files.SelectedLineIdx
// get files to stage
// noRenames := gui.State.StatusLineManager.TreeMode
files := gui.GitCommand.GetStatusFiles(commands.GetStatusFileOptions{})
gui.State.StatusLineManager.SetFiles(
gui.GitCommand.MergeStatusFiles(gui.State.StatusLineManager.GetAllFiles(), files, selectedFile),
)
gui.State.StatusLineManager.SetFiles(files)
if err := gui.fileWatcher.addFilesToFileWatcher(files); err != nil {
return err
}
// let's try to find our file again and move the cursor to that
if selectedFile != nil {
if selectedNode != nil {
for idx, node := range gui.State.StatusLineManager.GetAllItems() {
// TODO: check that this works
selectedFileHasMoved := node.File != nil && node.File.Matches(selectedFile) && idx != prevSelectedLineIdx
if selectedFileHasMoved {
paths := getPaths(node)
// If you started off with a rename selected, and now it's broken in two, we want you to jump to the new file, not the old file.
// This is because the new should be in the same position as the rename was meaning less cursor jumping
foundOldFileInRename := selectedNode.File != nil && selectedNode.File.IsRename() && node.Path == selectedNode.File.PreviousName
selectedNodeHasMoved := idx != prevSelectedLineIdx && utils.StringArraysOverlap(paths, selectedPaths) && !foundOldFileInRename
if selectedNodeHasMoved {
gui.State.Panels.Files.SelectedLineIdx = idx
break
}

View File

@ -54,11 +54,13 @@ func GetFlatTreeFromStatusFiles(files []*models.File) *models.StatusLineNode {
root := &models.StatusLineNode{}
for _, file := range files {
root.Children = append(root.Children, &models.StatusLineNode{
Name: file.Name,
Name: file.GetPath(),
Path: file.GetPath(),
File: file,
})
}
root.Sort()
return root
}