mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-04 23:37:41 +02:00
refactor
This commit is contained in:
parent
332a3c4cbf
commit
54910fdb76
@ -4,11 +4,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetFilesInDiff get the specified commit files
|
// GetFilesInDiff get the specified commit files
|
||||||
func (c *GitCommand) GetFilesInDiff(from string, to string, reverse bool, patchManager *patch.PatchManager) ([]*models.CommitFile, error) {
|
func (c *GitCommand) GetFilesInDiff(from string, to string, reverse bool) ([]*models.CommitFile, error) {
|
||||||
reverseFlag := ""
|
reverseFlag := ""
|
||||||
if reverse {
|
if reverse {
|
||||||
reverseFlag = " -R "
|
reverseFlag = " -R "
|
||||||
@ -19,11 +18,11 @@ func (c *GitCommand) GetFilesInDiff(from string, to string, reverse bool, patchM
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.getCommitFilesFromFilenames(filenames, to, patchManager), nil
|
return c.getCommitFilesFromFilenames(filenames), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// filenames string is something like "file1\nfile2\nfile3"
|
// filenames string is something like "file1\nfile2\nfile3"
|
||||||
func (c *GitCommand) getCommitFilesFromFilenames(filenames string, parent string, patchManager *patch.PatchManager) []*models.CommitFile {
|
func (c *GitCommand) getCommitFilesFromFilenames(filenames string) []*models.CommitFile {
|
||||||
commitFiles := make([]*models.CommitFile, 0)
|
commitFiles := make([]*models.CommitFile, 0)
|
||||||
|
|
||||||
lines := strings.Split(strings.TrimRight(filenames, "\x00"), "\x00")
|
lines := strings.Split(strings.TrimRight(filenames, "\x00"), "\x00")
|
||||||
@ -32,15 +31,10 @@ func (c *GitCommand) getCommitFilesFromFilenames(filenames string, parent string
|
|||||||
// typical result looks like 'A my_file' meaning my_file was added
|
// typical result looks like 'A my_file' meaning my_file was added
|
||||||
changeStatus := lines[i]
|
changeStatus := lines[i]
|
||||||
name := lines[i+1]
|
name := lines[i+1]
|
||||||
status := patch.UNSELECTED
|
|
||||||
if patchManager != nil && patchManager.To == parent {
|
|
||||||
status = patchManager.GetFileStatus(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
commitFiles = append(commitFiles, &models.CommitFile{
|
commitFiles = append(commitFiles, &models.CommitFile{
|
||||||
Name: name,
|
Name: name,
|
||||||
ChangeStatus: changeStatus,
|
ChangeStatus: changeStatus,
|
||||||
PatchStatus: status,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,6 @@ package models
|
|||||||
type CommitFile struct {
|
type CommitFile struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
// PatchStatus tells us whether the file has been wholly or partially added to a patch. We might want to pull this logic up into the gui package and make it a map like we do with cherry picked commits
|
|
||||||
PatchStatus int // one of 'WHOLE' 'PART' 'NONE'
|
|
||||||
|
|
||||||
ChangeStatus string // e.g. 'A' for added or 'M' for modified. This is based on the result from git diff --name-status
|
ChangeStatus string // e.g. 'A' for added or 'M' for modified. This is based on the result from git diff --name-status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package patch
|
package patch
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -9,9 +8,11 @@ import (
|
|||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PatchStatus int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// UNSELECTED is for when the commit file has not been added to the patch in any way
|
// UNSELECTED is for when the commit file has not been added to the patch in any way
|
||||||
UNSELECTED = iota
|
UNSELECTED PatchStatus = iota
|
||||||
// WHOLE is for when you want to add the whole diff of a file to the patch,
|
// WHOLE is for when you want to add the whole diff of a file to the patch,
|
||||||
// including e.g. if it was deleted
|
// including e.g. if it was deleted
|
||||||
WHOLE
|
WHOLE
|
||||||
@ -20,7 +21,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type fileInfo struct {
|
type fileInfo struct {
|
||||||
mode int // one of WHOLE/PART
|
mode PatchStatus
|
||||||
includedLineIndices []int
|
includedLineIndices []int
|
||||||
diff string
|
diff string
|
||||||
}
|
}
|
||||||
@ -81,20 +82,25 @@ func (p *PatchManager) removeFile(info *fileInfo) {
|
|||||||
info.includedLineIndices = nil
|
info.includedLineIndices = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PatchManager) ToggleFileWhole(filename string) error {
|
func (p *PatchManager) AddFileWhole(filename string) error {
|
||||||
info, err := p.getFileInfo(filename)
|
info, err := p.getFileInfo(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
switch info.mode {
|
|
||||||
case UNSELECTED, PART:
|
p.addFileWhole(info)
|
||||||
p.addFileWhole(info)
|
|
||||||
case WHOLE:
|
return nil
|
||||||
p.removeFile(info)
|
}
|
||||||
default:
|
|
||||||
return errors.New("unknown file mode")
|
func (p *PatchManager) RemoveFile(filename string) error {
|
||||||
|
info, err := p.getFileInfo(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.removeFile(info)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +222,7 @@ func (p *PatchManager) RenderAggregatedPatchColored(plain bool) string {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PatchManager) GetFileStatus(filename string) int {
|
func (p *PatchManager) GetFileStatus(filename string) PatchStatus {
|
||||||
info, ok := p.fileInfoMap[filename]
|
info, ok := p.fileInfoMap[filename]
|
||||||
if !ok {
|
if !ok {
|
||||||
return UNSELECTED
|
return UNSELECTED
|
||||||
|
@ -3,6 +3,7 @@ package gui
|
|||||||
import (
|
import (
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -104,7 +105,7 @@ func (gui *Gui) refreshCommitFilesView() error {
|
|||||||
to := gui.State.Panels.CommitFiles.refName
|
to := gui.State.Panels.CommitFiles.refName
|
||||||
from, reverse := gui.getFromAndReverseArgsForDiff(to)
|
from, reverse := gui.getFromAndReverseArgsForDiff(to)
|
||||||
|
|
||||||
files, err := gui.GitCommand.GetFilesInDiff(from, to, reverse, gui.GitCommand.PatchManager)
|
files, err := gui.GitCommand.GetFilesInDiff(from, to, reverse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gui.surfaceError(err)
|
return gui.surfaceError(err)
|
||||||
}
|
}
|
||||||
@ -137,8 +138,6 @@ func (gui *Gui) handleToggleFileForPatch(g *gocui.Gui, v *gocui.View) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: if file is nil, toggle all leaves underneath on/off
|
|
||||||
|
|
||||||
toggleTheFile := func() error {
|
toggleTheFile := func() error {
|
||||||
if !gui.GitCommand.PatchManager.Active() {
|
if !gui.GitCommand.PatchManager.Active() {
|
||||||
if err := gui.startPatchManager(); err != nil {
|
if err := gui.startPatchManager(); err != nil {
|
||||||
@ -146,15 +145,29 @@ func (gui *Gui) handleToggleFileForPatch(g *gocui.Gui, v *gocui.View) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := gui.GitCommand.PatchManager.ToggleFileWhole(node.GetPath()); err != nil {
|
// if there is any file that hasn't been fully added we'll fully add everything,
|
||||||
return err
|
// otherwise we'll remove everything
|
||||||
|
adding := node.AnyFile(func(file *models.CommitFile) bool {
|
||||||
|
return gui.GitCommand.PatchManager.GetFileStatus(file.Name) != patch.WHOLE
|
||||||
|
})
|
||||||
|
|
||||||
|
err := node.ForEachFile(func(file *models.CommitFile) error {
|
||||||
|
if adding {
|
||||||
|
return gui.GitCommand.PatchManager.AddFileWhole(file.Name)
|
||||||
|
} else {
|
||||||
|
return gui.GitCommand.PatchManager.RemoveFile(file.Name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return gui.surfaceError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if gui.GitCommand.PatchManager.IsEmpty() {
|
if gui.GitCommand.PatchManager.IsEmpty() {
|
||||||
gui.GitCommand.PatchManager.Reset()
|
gui.GitCommand.PatchManager.Reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
return gui.refreshCommitFilesView()
|
return gui.postRefreshUpdate(gui.Contexts.CommitFiles.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
if gui.GitCommand.PatchManager.Active() && gui.GitCommand.PatchManager.To != gui.State.CommitFileChangeManager.GetParent() {
|
if gui.GitCommand.PatchManager.Active() && gui.GitCommand.PatchManager.To != gui.State.CommitFileChangeManager.GetParent() {
|
||||||
|
@ -2,6 +2,7 @@ package filetree
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -87,9 +88,9 @@ func (m *CommitFileChangeManager) ToggleCollapsed(path string) {
|
|||||||
m.collapsedPaths.ToggleCollapsed(path)
|
m.collapsedPaths.ToggleCollapsed(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CommitFileChangeManager) Render(diffName string) []string {
|
func (m *CommitFileChangeManager) Render(diffName string, patchManager *patch.PatchManager) []string {
|
||||||
return renderAux(m.tree, m.collapsedPaths, "", -1, func(n INode, depth int) string {
|
return renderAux(m.tree, m.collapsedPaths, "", -1, func(n INode, depth int) string {
|
||||||
castN := n.(*CommitFileChangeNode)
|
castN := n.(*CommitFileChangeNode)
|
||||||
return presentation.GetCommitFileLine(castN.NameAtDepth(depth), diffName, castN.File)
|
return presentation.GetCommitFileLine(castN.NameAtDepth(depth), diffName, castN.File, patchManager)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,21 @@ func (s *CommitFileChangeNode) Any(test func(node *CommitFileChangeNode) bool) b
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *CommitFileChangeNode) Every(test func(node *CommitFileChangeNode) bool) bool {
|
||||||
|
return every(s, func(n INode) bool {
|
||||||
|
castNode := n.(*CommitFileChangeNode)
|
||||||
|
return test(castNode)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommitFileChangeNode) EveryFile(test func(file *models.CommitFile) bool) bool {
|
||||||
|
return every(s, func(n INode) bool {
|
||||||
|
castNode := n.(*CommitFileChangeNode)
|
||||||
|
|
||||||
|
return castNode.File == nil || test(castNode.File)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (n *CommitFileChangeNode) Flatten(collapsedPaths map[string]bool) []*CommitFileChangeNode {
|
func (n *CommitFileChangeNode) Flatten(collapsedPaths map[string]bool) []*CommitFileChangeNode {
|
||||||
results := flatten(n, collapsedPaths)
|
results := flatten(n, collapsedPaths)
|
||||||
nodes := make([]*CommitFileChangeNode, len(results))
|
nodes := make([]*CommitFileChangeNode, len(results))
|
||||||
|
@ -77,6 +77,20 @@ func any(node INode, test func(INode) bool) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func every(node INode, test func(INode) bool) bool {
|
||||||
|
if !test(node) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, child := range node.GetChildren() {
|
||||||
|
if !every(child, test) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func flatten(node INode, collapsedPaths map[string]bool) []INode {
|
func flatten(node INode, collapsedPaths map[string]bool) []INode {
|
||||||
result := []INode{}
|
result := []INode{}
|
||||||
result = append(result, node)
|
result = append(result, node)
|
||||||
|
@ -465,7 +465,7 @@ func (gui *Gui) commitFilesListContext() *ListContext {
|
|||||||
return [][]string{{utils.ColoredString("(none)", color.FgRed)}}
|
return [][]string{{utils.ColoredString("(none)", color.FgRed)}}
|
||||||
}
|
}
|
||||||
|
|
||||||
lines := gui.State.CommitFileChangeManager.Render(gui.State.Modes.Diffing.Ref)
|
lines := gui.State.CommitFileChangeManager.Render(gui.State.Modes.Diffing.Ref, gui.GitCommand.PatchManager)
|
||||||
mappedLines := make([][]string, len(lines))
|
mappedLines := make([][]string, len(lines))
|
||||||
for i, line := range lines {
|
for i, line := range lines {
|
||||||
mappedLines[i] = []string{line}
|
mappedLines[i] = []string{line}
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetCommitFileLine(name string, diffName string, commitFile *models.CommitFile) string {
|
func GetCommitFileLine(name string, diffName string, commitFile *models.CommitFile, patchManager *patch.PatchManager) string {
|
||||||
yellow := color.New(color.FgYellow)
|
yellow := color.New(color.FgYellow)
|
||||||
green := color.New(color.FgGreen)
|
green := color.New(color.FgGreen)
|
||||||
defaultColor := color.New(theme.DefaultTextColor)
|
defaultColor := color.New(theme.DefaultTextColor)
|
||||||
@ -22,7 +22,8 @@ func GetCommitFileLine(name string, diffName string, commitFile *models.CommitFi
|
|||||||
if diffName == name {
|
if diffName == name {
|
||||||
colour = diffTerminalColor
|
colour = diffTerminalColor
|
||||||
} else if commitFile != nil {
|
} else if commitFile != nil {
|
||||||
switch commitFile.PatchStatus {
|
status := patchManager.GetFileStatus(commitFile.Name)
|
||||||
|
switch status {
|
||||||
case patch.UNSELECTED:
|
case patch.UNSELECTED:
|
||||||
colour = defaultColor
|
colour = defaultColor
|
||||||
case patch.WHOLE:
|
case patch.WHOLE:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user