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:
parent
da6fe01eca
commit
1183f68e19
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user