Skip to content

Commit

Permalink
follow cursor when staging and unstaging a file rename
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseduffield committed Aug 7, 2020
1 parent 469ac11 commit 660cc2f
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 7 deletions.
20 changes: 18 additions & 2 deletions pkg/commands/file.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package commands

import "strings"
import (
"strings"

"github.com/jesseduffield/lazygit/pkg/utils"
)

// File : A file from git status
// duplicating this for now
Expand All @@ -17,6 +21,18 @@ type File struct {
ShortStatus string // e.g. 'AD', ' A', 'M ', '??'
}

const RENAME_SEPARATOR = " -> "

func (f *File) IsRename() bool {
return strings.Contains(f.Name, " -> ")
return strings.Contains(f.Name, RENAME_SEPARATOR)
}

// Names returns an array containing just the filename, or in the case of a rename, the after filename and the before filename
func (f *File) Names() []string {
return strings.Split(f.Name, RENAME_SEPARATOR)
}

// returns true if the file names are the same or if a a file rename includes the filename of the other
func (f *File) Matches(f2 *File) bool {
return utils.StringArraysOverlap(f.Names(), f2.Names())
}
11 changes: 8 additions & 3 deletions pkg/commands/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func (c *GitCommand) StashSave(message string) error {
}

// MergeStatusFiles merge status files
func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []*File) []*File {
func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []*File, selectedFile *File) []*File {
if len(oldFiles) == 0 {
return newFiles
}
Expand All @@ -290,10 +290,15 @@ func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []*File) []*File {
result := []*File{}
for _, oldFile := range oldFiles {
for newIndex, newFile := range newFiles {
if oldFile.Name == newFile.Name {
if 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)
break
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/commands/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ func TestGitCommandMergeStatusFiles(t *testing.T) {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommand()

s.test(gitCmd.MergeStatusFiles(s.oldFiles, s.newFiles))
s.test(gitCmd.MergeStatusFiles(s.oldFiles, s.newFiles, nil))
})
}
}
Expand Down
15 changes: 14 additions & 1 deletion pkg/gui/files_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,14 +410,27 @@ func (gui *Gui) handleRefreshFiles(g *gocui.Gui, v *gocui.View) error {
}

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()

// get files to stage
files := gui.GitCommand.GetStatusFiles(commands.GetStatusFileOptions{})
gui.State.Files = gui.GitCommand.MergeStatusFiles(gui.State.Files, files)
gui.State.Files = gui.GitCommand.MergeStatusFiles(gui.State.Files, files, selectedFile)

if err := gui.fileWatcher.addFilesToFileWatcher(files); err != nil {
return err
}

// let's try to find our file again and move the cursor to that
for idx, f := range gui.State.Files {
if selectedFile != nil && f.Matches(selectedFile) {
gui.State.Panels.Files.SelectedLine = idx
break
}
}

gui.refreshSelectedLine(&gui.State.Panels.Files.SelectedLine, len(gui.State.Files))
return nil
}
Expand Down
12 changes: 12 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,15 @@ func FindStringSubmatch(str string, regexpStr string) (bool, []string) {
match := re.FindStringSubmatch(str)
return len(match) > 0, match
}

func StringArraysOverlap(strArrA []string, strArrB []string) bool {
for _, first := range strArrA {
for _, second := range strArrB {
if first == second {
return true
}
}
}

return false
}

0 comments on commit 660cc2f

Please sign in to comment.