1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-06-17 00:18:05 +02:00

move commit files context into new structure

This commit is contained in:
Jesse Duffield
2022-01-30 16:38:07 +11:00
parent c084abb378
commit b5515da00b
14 changed files with 312 additions and 178 deletions

View File

@ -10,12 +10,7 @@ import (
) )
func (gui *Gui) getSelectedCommitFileNode() *filetree.CommitFileNode { func (gui *Gui) getSelectedCommitFileNode() *filetree.CommitFileNode {
selectedLine := gui.State.Panels.CommitFiles.SelectedLineIdx return gui.State.Contexts.CommitFiles.GetSelectedFileNode()
if selectedLine == -1 || selectedLine > gui.State.CommitFileTreeViewModel.GetItemsLength()-1 {
return nil
}
return gui.State.CommitFileTreeViewModel.GetItemAtIndex(selectedLine)
} }
func (gui *Gui) getSelectedCommitFile() *models.CommitFile { func (gui *Gui) getSelectedCommitFile() *models.CommitFile {
@ -45,7 +40,7 @@ func (gui *Gui) commitFilesRenderToMain() error {
return nil return nil
} }
to := gui.State.CommitFileTreeViewModel.GetParent() to := gui.State.Contexts.CommitFiles.GetRefName()
from, reverse := gui.getFromAndReverseArgsForDiff(to) from, reverse := gui.getFromAndReverseArgsForDiff(to)
cmdObj := gui.git.WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false) cmdObj := gui.git.WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false)
@ -67,7 +62,7 @@ func (gui *Gui) handleCheckoutCommitFile() error {
} }
gui.c.LogAction(gui.c.Tr.Actions.CheckoutFile) gui.c.LogAction(gui.c.Tr.Actions.CheckoutFile)
if err := gui.git.WorkingTree.CheckoutFile(gui.State.CommitFileTreeViewModel.GetParent(), node.GetPath()); err != nil { if err := gui.git.WorkingTree.CheckoutFile(gui.State.Contexts.CommitFiles.GetRefName(), node.GetPath()); err != nil {
return gui.c.Error(err) return gui.c.Error(err)
} }
@ -107,15 +102,15 @@ func (gui *Gui) refreshCommitFilesView() error {
} }
} }
to := gui.State.Panels.CommitFiles.refName to := gui.State.Contexts.CommitFiles.GetRefName()
from, reverse := gui.getFromAndReverseArgsForDiff(to) from, reverse := gui.getFromAndReverseArgsForDiff(to)
files, err := gui.git.Loaders.CommitFiles.GetFilesInDiff(from, to, reverse) files, err := gui.git.Loaders.CommitFiles.GetFilesInDiff(from, to, reverse)
if err != nil { if err != nil {
return gui.c.Error(err) return gui.c.Error(err)
} }
gui.State.CommitFileTreeViewModel.SetParent(to) gui.State.CommitFiles = files
gui.State.CommitFileTreeViewModel.SetFiles(files) gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.SetTree()
return gui.c.PostRefreshUpdate(gui.State.Contexts.CommitFiles) return gui.c.PostRefreshUpdate(gui.State.Contexts.CommitFiles)
} }
@ -158,7 +153,7 @@ func (gui *Gui) handleToggleFileForPatch() error {
// if there is any file that hasn't been fully added we'll fully add everything, // if there is any file that hasn't been fully added we'll fully add everything,
// otherwise we'll remove everything // otherwise we'll remove everything
adding := node.AnyFile(func(file *models.CommitFile) bool { adding := node.AnyFile(func(file *models.CommitFile) bool {
return gui.git.Patch.PatchManager.GetFileStatus(file.Name, gui.State.CommitFileTreeViewModel.GetParent()) != patch.WHOLE return gui.git.Patch.PatchManager.GetFileStatus(file.Name, gui.State.Contexts.CommitFiles.GetRefName()) != patch.WHOLE
}) })
err := node.ForEachFile(func(file *models.CommitFile) error { err := node.ForEachFile(func(file *models.CommitFile) error {
@ -180,7 +175,7 @@ func (gui *Gui) handleToggleFileForPatch() error {
return gui.c.PostRefreshUpdate(gui.State.Contexts.CommitFiles) return gui.c.PostRefreshUpdate(gui.State.Contexts.CommitFiles)
} }
if gui.git.Patch.PatchManager.Active() && gui.git.Patch.PatchManager.To != gui.State.CommitFileTreeViewModel.GetParent() { if gui.git.Patch.PatchManager.Active() && gui.git.Patch.PatchManager.To != gui.State.Contexts.CommitFiles.GetRefName() {
return gui.c.Ask(types.AskOpts{ return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.DiscardPatch, Title: gui.c.Tr.DiscardPatch,
Prompt: gui.c.Tr.DiscardPatchConfirm, Prompt: gui.c.Tr.DiscardPatchConfirm,
@ -195,9 +190,11 @@ func (gui *Gui) handleToggleFileForPatch() error {
} }
func (gui *Gui) startPatchManager() error { func (gui *Gui) startPatchManager() error {
canRebase := gui.State.Panels.CommitFiles.canRebase commitFilesContext := gui.State.Contexts.CommitFiles
canRebase := commitFilesContext.GetCanRebase()
to := commitFilesContext.GetRefName()
to := gui.State.Panels.CommitFiles.refName
from, reverse := gui.getFromAndReverseArgsForDiff(to) from, reverse := gui.getFromAndReverseArgsForDiff(to)
gui.git.Patch.PatchManager.Start(from, to, reverse, canRebase) gui.git.Patch.PatchManager.Start(from, to, reverse, canRebase)
@ -228,7 +225,7 @@ func (gui *Gui) enterCommitFile(opts types.OnFocusOpts) error {
return gui.c.PushContext(gui.State.Contexts.PatchBuilding, opts) return gui.c.PushContext(gui.State.Contexts.PatchBuilding, opts)
} }
if gui.git.Patch.PatchManager.Active() && gui.git.Patch.PatchManager.To != gui.State.CommitFileTreeViewModel.GetParent() { if gui.git.Patch.PatchManager.Active() && gui.git.Patch.PatchManager.To != gui.State.Contexts.CommitFiles.GetRefName() {
return gui.c.Ask(types.AskOpts{ return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.DiscardPatch, Title: gui.c.Tr.DiscardPatch,
Prompt: gui.c.Tr.DiscardPatchConfirm, Prompt: gui.c.Tr.DiscardPatchConfirm,
@ -248,7 +245,7 @@ func (gui *Gui) handleToggleCommitFileDirCollapsed() error {
return nil return nil
} }
gui.State.CommitFileTreeViewModel.ToggleCollapsed(node.GetPath()) gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.ToggleCollapsed(node.GetPath())
if err := gui.c.PostRefreshUpdate(gui.State.Contexts.CommitFiles); err != nil { if err := gui.c.PostRefreshUpdate(gui.State.Contexts.CommitFiles); err != nil {
gui.c.Log.Error(err) gui.c.Log.Error(err)
@ -262,9 +259,9 @@ func (gui *Gui) SwitchToCommitFilesContext(opts controllers.SwitchToCommitFilesC
// no longer considers the commitFiles view as its main view. // no longer considers the commitFiles view as its main view.
gui.resetWindowForView(gui.Views.CommitFiles) gui.resetWindowForView(gui.Views.CommitFiles)
gui.State.Panels.CommitFiles.SelectedLineIdx = 0 gui.State.Contexts.CommitFiles.SetSelectedLineIdx(0)
gui.State.Panels.CommitFiles.refName = opts.RefName gui.State.Contexts.CommitFiles.SetRefName(opts.RefName)
gui.State.Panels.CommitFiles.canRebase = opts.CanRebase gui.State.Contexts.CommitFiles.SetCanRebase(opts.CanRebase)
gui.State.Contexts.CommitFiles.SetParentContext(opts.Context) gui.State.Contexts.CommitFiles.SetParentContext(opts.Context)
gui.State.Contexts.CommitFiles.SetWindowName(opts.WindowName) gui.State.Contexts.CommitFiles.SetWindowName(opts.WindowName)
@ -277,18 +274,7 @@ func (gui *Gui) SwitchToCommitFilesContext(opts controllers.SwitchToCommitFilesC
// NOTE: this is very similar to handleToggleFileTreeView, could be DRY'd with generics // NOTE: this is very similar to handleToggleFileTreeView, could be DRY'd with generics
func (gui *Gui) handleToggleCommitFileTreeView() error { func (gui *Gui) handleToggleCommitFileTreeView() error {
path := gui.getSelectedCommitFilePath() gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.ToggleShowTree()
gui.State.CommitFileTreeViewModel.ToggleShowTree()
// find that same node in the new format and move the cursor to it
if path != "" {
gui.State.CommitFileTreeViewModel.ExpandToPath(path)
index, found := gui.State.CommitFileTreeViewModel.GetIndexForPath(path)
if found {
gui.State.Contexts.CommitFiles.GetPanelState().SetSelectedLineIdx(index)
}
}
return gui.c.PostRefreshUpdate(gui.State.Contexts.CommitFiles) return gui.c.PostRefreshUpdate(gui.State.Contexts.CommitFiles)
} }

View File

@ -0,0 +1,68 @@
package context
import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
type CommitFilesContext struct {
*filetree.CommitFileTreeViewModel
*BaseContext
*ListContextTrait
}
var _ types.IListContext = (*CommitFilesContext)(nil)
func NewCommitFilesContext(
getModel func() []*models.CommitFile,
getView func() *gocui.View,
getDisplayStrings func(startIdx int, length int) [][]string,
onFocus func(...types.OnFocusOpts) error,
onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error,
c *types.ControllerCommon,
) *CommitFilesContext {
baseContext := NewBaseContext(NewBaseContextOpts{
ViewName: "commitFiles",
WindowName: "commits",
Key: COMMIT_FILES_CONTEXT_KEY,
Kind: types.SIDE_CONTEXT,
})
self := &CommitFilesContext{}
takeFocus := func() error { return c.PushContext(self) }
viewModel := filetree.NewCommitFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree)
viewTrait := NewViewTrait(getView)
listContextTrait := &ListContextTrait{
base: baseContext,
list: viewModel,
viewTrait: viewTrait,
GetDisplayStrings: getDisplayStrings,
OnFocus: onFocus,
OnRenderToMain: onRenderToMain,
OnFocusLost: onFocusLost,
takeFocus: takeFocus,
// TODO: handle this in a trait
RenderSelection: false,
c: c,
}
self.BaseContext = baseContext
self.ListContextTrait = listContextTrait
self.CommitFileTreeViewModel = viewModel
return self
}
func (self *CommitFilesContext) GetSelectedItem() (types.ListItem, bool) {
item := self.CommitFileTreeViewModel.GetSelectedFileNode()
return item, item != nil
}

View File

@ -64,7 +64,7 @@ type ContextTree struct {
RemoteBranches types.IListContext RemoteBranches types.IListContext
Tags *TagsContext Tags *TagsContext
BranchCommits types.IListContext BranchCommits types.IListContext
CommitFiles types.IListContext CommitFiles *CommitFilesContext
ReflogCommits types.IListContext ReflogCommits types.IListContext
SubCommits types.IListContext SubCommits types.IListContext
Stash types.IListContext Stash types.IListContext

View File

@ -434,6 +434,7 @@ func (self *LocalCommitsController) handleCommitMoveDown() error {
if err := self.git.Rebase.MoveTodoDown(index); err != nil { if err := self.git.Rebase.MoveTodoDown(index); err != nil {
return self.c.Error(err) return self.c.Error(err)
} }
// TODO: use MoveSelectedLine
_ = self.getContext().HandleNextLine() _ = self.getContext().HandleNextLine()
return self.c.Refresh(types.RefreshOptions{ return self.c.Refresh(types.RefreshOptions{
Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS}, Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS},
@ -444,6 +445,7 @@ func (self *LocalCommitsController) handleCommitMoveDown() error {
self.c.LogAction(self.c.Tr.Actions.MoveCommitDown) self.c.LogAction(self.c.Tr.Actions.MoveCommitDown)
err := self.git.Rebase.MoveCommitDown(self.getCommits(), index) err := self.git.Rebase.MoveCommitDown(self.getCommits(), index)
if err == nil { if err == nil {
// TODO: use MoveSelectedLine
_ = self.getContext().HandleNextLine() _ = self.getContext().HandleNextLine()
} }
return self.checkMergeOrRebase(err) return self.checkMergeOrRebase(err)

View File

@ -40,7 +40,7 @@ func (gui *Gui) currentDiffTerminals() []string {
// TODO: should we just return nil here? // TODO: should we just return nil here?
return []string{""} return []string{""}
case context.COMMIT_FILES_CONTEXT_KEY: case context.COMMIT_FILES_CONTEXT_KEY:
return []string{gui.State.Panels.CommitFiles.refName} return []string{gui.State.Contexts.CommitFiles.GetRefName()}
case context.LOCAL_BRANCHES_CONTEXT_KEY: case context.LOCAL_BRANCHES_CONTEXT_KEY:
// for our local branches we want to include both the branch and its upstream // for our local branches we want to include both the branch and its upstream
branch := gui.getSelectedBranch() branch := gui.getSelectedBranch()

View File

@ -0,0 +1,107 @@
package filetree
import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/sirupsen/logrus"
)
type ICommitFileTree interface {
ITree
GetItemAtIndex(index int) *CommitFileNode
GetFile(path string) *models.CommitFile
GetAllItems() []*CommitFileNode
GetAllFiles() []*models.CommitFile
}
type CommitFileTree struct {
getFiles func() []*models.CommitFile
tree *CommitFileNode
showTree bool
log *logrus.Entry
collapsedPaths CollapsedPaths
}
var _ ICommitFileTree = &CommitFileTree{}
func NewCommitFileTree(getFiles func() []*models.CommitFile, log *logrus.Entry, showTree bool) *CommitFileTree {
return &CommitFileTree{
getFiles: getFiles,
log: log,
showTree: showTree,
collapsedPaths: CollapsedPaths{},
}
}
func (self *CommitFileTree) ExpandToPath(path string) {
self.collapsedPaths.ExpandToPath(path)
}
func (self *CommitFileTree) ToggleShowTree() {
self.showTree = !self.showTree
self.SetTree()
}
func (self *CommitFileTree) GetItemAtIndex(index int) *CommitFileNode {
// need to traverse the three depth first until we get to the index.
return self.tree.GetNodeAtIndex(index+1, self.collapsedPaths) // ignoring root
}
func (self *CommitFileTree) GetIndexForPath(path string) (int, bool) {
index, found := self.tree.GetIndexForPath(path, self.collapsedPaths)
return index - 1, found
}
func (self *CommitFileTree) GetAllItems() []*CommitFileNode {
if self.tree == nil {
return nil
}
return self.tree.Flatten(self.collapsedPaths)[1:] // ignoring root
}
func (self *CommitFileTree) GetItemsLength() int {
return self.tree.Size(self.collapsedPaths) - 1 // ignoring root
}
func (self *CommitFileTree) GetAllFiles() []*models.CommitFile {
return self.getFiles()
}
func (self *CommitFileTree) SetTree() {
if self.showTree {
self.tree = BuildTreeFromCommitFiles(self.getFiles())
} else {
self.tree = BuildFlatTreeFromCommitFiles(self.getFiles())
}
}
func (self *CommitFileTree) IsCollapsed(path string) bool {
return self.collapsedPaths.IsCollapsed(path)
}
func (self *CommitFileTree) ToggleCollapsed(path string) {
self.collapsedPaths.ToggleCollapsed(path)
}
func (self *CommitFileTree) Tree() INode {
return self.tree
}
func (self *CommitFileTree) CollapsedPaths() CollapsedPaths {
return self.collapsedPaths
}
func (self *CommitFileTree) GetFile(path string) *models.CommitFile {
for _, file := range self.getFiles() {
if file.Name == path {
return file
}
}
return nil
}
func (self *CommitFileTree) InTreeMode() bool {
return self.showTree
}

View File

@ -1,101 +1,93 @@
package filetree package filetree
import ( import (
"sync"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
type ICommitFileTreeViewModel interface {
ICommitFileTree
types.IListCursor
GetRefName() string
SetRefName(string)
GetCanRebase() bool
SetCanRebase(bool)
}
type CommitFileTreeViewModel struct { type CommitFileTreeViewModel struct {
files []*models.CommitFile sync.RWMutex
tree *CommitFileNode ICommitFileTree
showTree bool types.IListCursor
log *logrus.Entry
collapsedPaths CollapsedPaths // this is e.g. the commit SHA of the commit for which we're viewing the files
// parent is the identifier of the parent object e.g. a commit SHA if this commit file is for a commit, or a stash entry ref like 'stash@{1}' refName string
parent string
// we set this to true when you're viewing the files within the checked-out branch's commits.
// If you're viewing the files of some random other branch we can't do any rebase stuff.
canRebase bool
} }
func (self *CommitFileTreeViewModel) GetParent() string { var _ ICommitFileTreeViewModel = &CommitFileTreeViewModel{}
return self.parent
}
func (self *CommitFileTreeViewModel) SetParent(parent string) { func NewCommitFileTreeViewModel(getFiles func() []*models.CommitFile, log *logrus.Entry, showTree bool) *CommitFileTreeViewModel {
self.parent = parent fileTree := NewCommitFileTree(getFiles, log, showTree)
} listCursor := traits.NewListCursor(fileTree)
return &CommitFileTreeViewModel{
func NewCommitFileTreeViewModel(files []*models.CommitFile, log *logrus.Entry, showTree bool) *CommitFileTreeViewModel { ICommitFileTree: fileTree,
viewModel := &CommitFileTreeViewModel{ IListCursor: listCursor,
log: log, refName: "",
showTree: showTree, canRebase: false,
collapsedPaths: CollapsedPaths{},
} }
viewModel.SetFiles(files)
return viewModel
} }
func (self *CommitFileTreeViewModel) ExpandToPath(path string) { func (self *CommitFileTreeViewModel) GetRefName() string {
self.collapsedPaths.ExpandToPath(path) return self.refName
} }
func (self *CommitFileTreeViewModel) ToggleShowTree() { func (self *CommitFileTreeViewModel) SetRefName(refName string) {
self.showTree = !self.showTree self.refName = refName
self.SetTree()
} }
func (self *CommitFileTreeViewModel) GetItemAtIndex(index int) *CommitFileNode { func (self *CommitFileTreeViewModel) GetCanRebase() bool {
// need to traverse the three depth first until we get to the index. return self.canRebase
return self.tree.GetNodeAtIndex(index+1, self.collapsedPaths) // ignoring root
} }
func (self *CommitFileTreeViewModel) GetIndexForPath(path string) (int, bool) { func (self *CommitFileTreeViewModel) SetCanRebase(canRebase bool) {
index, found := self.tree.GetIndexForPath(path, self.collapsedPaths) self.canRebase = canRebase
return index - 1, found
} }
func (self *CommitFileTreeViewModel) GetAllItems() []*CommitFileNode { func (self *CommitFileTreeViewModel) GetSelectedFileNode() *CommitFileNode {
if self.tree == nil { if self.GetItemsLength() == 0 {
return nil return nil
} }
return self.tree.Flatten(self.collapsedPaths)[1:] // ignoring root return self.GetItemAtIndex(self.GetSelectedLineIdx())
} }
func (self *CommitFileTreeViewModel) GetItemsLength() int { // duplicated from file_tree_view_model.go. Generics will help here
return self.tree.Size(self.collapsedPaths) - 1 // ignoring root func (self *CommitFileTreeViewModel) ToggleShowTree() {
} selectedNode := self.GetSelectedFileNode()
func (self *CommitFileTreeViewModel) GetAllFiles() []*models.CommitFile { self.ICommitFileTree.ToggleShowTree()
return self.files
}
func (self *CommitFileTreeViewModel) SetFiles(files []*models.CommitFile) { if selectedNode == nil {
self.files = files return
}
path := selectedNode.Path
self.SetTree() if self.InTreeMode() {
} self.ExpandToPath(path)
} else if len(selectedNode.Children) > 0 {
path = selectedNode.GetLeaves()[0].Path
}
func (self *CommitFileTreeViewModel) SetTree() { index, found := self.GetIndexForPath(path)
if self.showTree { if found {
self.tree = BuildTreeFromCommitFiles(self.files) self.SetSelectedLineIdx(index)
} else {
self.tree = BuildFlatTreeFromCommitFiles(self.files)
} }
} }
func (self *CommitFileTreeViewModel) IsCollapsed(path string) bool {
return self.collapsedPaths.IsCollapsed(path)
}
func (self *CommitFileTreeViewModel) ToggleCollapsed(path string) {
self.collapsedPaths.ToggleCollapsed(path)
}
func (self *CommitFileTreeViewModel) Tree() INode {
return self.tree
}
func (self *CommitFileTreeViewModel) CollapsedPaths() CollapsedPaths {
return self.collapsedPaths
}

View File

@ -2,7 +2,6 @@ package filetree
import ( import (
"fmt" "fmt"
"sync"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -18,25 +17,28 @@ const (
DisplayConflicted DisplayConflicted
) )
type IFileTree interface { type ITree interface {
InTreeMode() bool InTreeMode() bool
ExpandToPath(path string) ExpandToPath(path string)
FilterFiles(test func(*models.File) bool) []*models.File
SetFilter(filter FileTreeDisplayFilter)
ToggleShowTree() ToggleShowTree()
GetItemAtIndex(index int) *FileNode
GetFile(path string) *models.File
GetIndexForPath(path string) (int, bool) GetIndexForPath(path string) (int, bool)
GetAllItems() []*FileNode
GetItemsLength() int GetItemsLength() int
GetAllFiles() []*models.File
SetTree() SetTree()
IsCollapsed(path string) bool IsCollapsed(path string) bool
ToggleCollapsed(path string) ToggleCollapsed(path string)
Tree() INode Tree() INode
CollapsedPaths() CollapsedPaths CollapsedPaths() CollapsedPaths
}
type IFileTree interface {
ITree
FilterFiles(test func(*models.File) bool) []*models.File
SetFilter(filter FileTreeDisplayFilter)
GetItemAtIndex(index int) *FileNode
GetFile(path string) *models.File
GetAllItems() []*FileNode
GetAllFiles() []*models.File
GetFilter() FileTreeDisplayFilter GetFilter() FileTreeDisplayFilter
} }
@ -47,8 +49,6 @@ type FileTree struct {
log *logrus.Entry log *logrus.Entry
filter FileTreeDisplayFilter filter FileTreeDisplayFilter
collapsedPaths CollapsedPaths collapsedPaths CollapsedPaths
sync.RWMutex
} }
func NewFileTree(getFiles func() []*models.File, log *logrus.Entry, showTree bool) *FileTree { func NewFileTree(getFiles func() []*models.File, log *logrus.Entry, showTree bool) *FileTree {
@ -58,7 +58,6 @@ func NewFileTree(getFiles func() []*models.File, log *logrus.Entry, showTree boo
showTree: showTree, showTree: showTree,
filter: DisplayAll, filter: DisplayAll,
collapsedPaths: CollapsedPaths{}, collapsedPaths: CollapsedPaths{},
RWMutex: sync.RWMutex{},
} }
} }

View File

@ -20,7 +20,6 @@ import (
"github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers" "github.com/jesseduffield/lazygit/pkg/gui/controllers"
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
"github.com/jesseduffield/lazygit/pkg/gui/lbl" "github.com/jesseduffield/lazygit/pkg/gui/lbl"
"github.com/jesseduffield/lazygit/pkg/gui/mergeconflicts" "github.com/jesseduffield/lazygit/pkg/gui/mergeconflicts"
"github.com/jesseduffield/lazygit/pkg/gui/modes/cherrypicking" "github.com/jesseduffield/lazygit/pkg/gui/modes/cherrypicking"
@ -173,18 +172,16 @@ type PrevLayout struct {
} }
type GuiRepoState struct { type GuiRepoState struct {
// the file panels (files and commit files) can render as a tree, so we have CommitFiles []*models.CommitFile
// managers for them which handle rendering a flat list of files in tree form Files []*models.File
CommitFileTreeViewModel *filetree.CommitFileTreeViewModel Submodules []*models.SubmoduleConfig
Files []*models.File Branches []*models.Branch
Submodules []*models.SubmoduleConfig Commits []*models.Commit
Branches []*models.Branch StashEntries []*models.StashEntry
Commits []*models.Commit SubCommits []*models.Commit
StashEntries []*models.StashEntry Remotes []*models.Remote
SubCommits []*models.Commit RemoteBranches []*models.RemoteBranch
Remotes []*models.Remote Tags []*models.Tag
RemoteBranches []*models.RemoteBranch
Tags []*models.Tag
// FilteredReflogCommits are the ones that appear in the reflog panel. // FilteredReflogCommits are the ones that appear in the reflog panel.
// when in filtering mode we only include the ones that match the given path // when in filtering mode we only include the ones that match the given path
FilteredReflogCommits []*models.Commit FilteredReflogCommits []*models.Commit
@ -316,15 +313,6 @@ type menuPanelState struct {
OnPress func() error OnPress func() error
} }
type commitFilesPanelState struct {
listPanelState
// this is the SHA of the commit or the stash index of the stash.
// Not sure if ref is actually the right word here
refName string
canRebase bool
}
type submodulePanelState struct { type submodulePanelState struct {
listPanelState listPanelState
} }
@ -333,6 +321,8 @@ type suggestionsPanelState struct {
listPanelState listPanelState
} }
// as we move things to the new context approach we're going to eventually
// remove this struct altogether and store this state on the contexts.
type panelStates struct { type panelStates struct {
Branches *branchPanelState Branches *branchPanelState
Remotes *remotePanelState Remotes *remotePanelState
@ -344,7 +334,6 @@ type panelStates struct {
Menu *menuPanelState Menu *menuPanelState
LineByLine *LblPanelState LineByLine *LblPanelState
Merging *MergingPanelState Merging *MergingPanelState
CommitFiles *commitFilesPanelState
Submodules *submodulePanelState Submodules *submodulePanelState
Suggestions *suggestionsPanelState Suggestions *suggestionsPanelState
} }
@ -427,8 +416,6 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) {
} }
} }
showTree := gui.UserConfig.Gui.ShowFileTree
contexts := gui.contextTree() contexts := gui.contextTree()
screenMode := SCREEN_NORMAL screenMode := SCREEN_NORMAL
@ -439,12 +426,12 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) {
} }
gui.State = &GuiRepoState{ gui.State = &GuiRepoState{
CommitFileTreeViewModel: filetree.NewCommitFileTreeViewModel(make([]*models.CommitFile, 0), gui.Log, showTree), Files: make([]*models.File, 0),
Commits: make([]*models.Commit, 0), Commits: make([]*models.Commit, 0),
FilteredReflogCommits: make([]*models.Commit, 0), FilteredReflogCommits: make([]*models.Commit, 0),
ReflogCommits: make([]*models.Commit, 0), ReflogCommits: make([]*models.Commit, 0),
StashEntries: make([]*models.StashEntry, 0), StashEntries: make([]*models.StashEntry, 0),
BisectInfo: git_commands.NewNullBisectInfo(), BisectInfo: git_commands.NewNullBisectInfo(),
Panels: &panelStates{ Panels: &panelStates{
// TODO: work out why some of these are -1 and some are 0. Last time I checked there was a good reason but I'm less certain now // TODO: work out why some of these are -1 and some are 0. Last time I checked there was a good reason but I'm less certain now
Submodules: &submodulePanelState{listPanelState{SelectedLineIdx: -1}}, Submodules: &submodulePanelState{listPanelState{SelectedLineIdx: -1}},
@ -454,7 +441,6 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) {
Commits: &commitPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, LimitCommits: true}, Commits: &commitPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, LimitCommits: true},
ReflogCommits: &reflogCommitPanelState{listPanelState{SelectedLineIdx: 0}}, ReflogCommits: &reflogCommitPanelState{listPanelState{SelectedLineIdx: 0}},
SubCommits: &subCommitPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, refName: ""}, SubCommits: &subCommitPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, refName: ""},
CommitFiles: &commitFilesPanelState{listPanelState: listPanelState{SelectedLineIdx: -1}, refName: ""},
Stash: &stashPanelState{listPanelState{SelectedLineIdx: -1}}, Stash: &stashPanelState{listPanelState{SelectedLineIdx: -1}},
Menu: &menuPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, OnPress: nil}, Menu: &menuPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, OnPress: nil},
Suggestions: &suggestionsPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}}, Suggestions: &suggestionsPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}},

View File

@ -121,9 +121,12 @@ func (gui *Gui) handleMouseDrag() error {
} }
func (gui *Gui) getSelectedCommitFileName() string { func (gui *Gui) getSelectedCommitFileName() string {
idx := gui.State.Panels.CommitFiles.SelectedLineIdx node := gui.State.Contexts.CommitFiles.GetSelectedFileNode()
if node == nil {
return ""
}
return gui.State.CommitFileTreeViewModel.GetItemAtIndex(idx).GetPath() return node.Path
} }
func (gui *Gui) refreshMainViewForLineByLine(state *LblPanelState) error { func (gui *Gui) refreshMainViewForLineByLine(state *LblPanelState) error {

View File

@ -293,25 +293,16 @@ func (gui *Gui) stashListContext() types.IListContext {
} }
} }
func (gui *Gui) commitFilesListContext() types.IListContext { func (gui *Gui) commitFilesListContext() *context.CommitFilesContext {
return &ListContext{ return context.NewCommitFilesContext(
BaseContext: context.NewBaseContext(context.NewBaseContextOpts{ func() []*models.CommitFile { return gui.State.CommitFiles },
ViewName: "commitFiles", func() *gocui.View { return gui.Views.CommitFiles },
WindowName: "commits", func(startIdx int, length int) [][]string {
Key: context.COMMIT_FILES_CONTEXT_KEY, if gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.GetItemsLength() == 0 {
Kind: types.SIDE_CONTEXT,
}),
GetItemsLength: func() int { return gui.State.CommitFileTreeViewModel.GetItemsLength() },
OnGetPanelState: func() types.IListPanelState { return gui.State.Panels.CommitFiles },
OnFocus: OnFocusWrapper(gui.onCommitFileFocus),
OnRenderToMain: OnFocusWrapper(gui.withDiffModeCheck(gui.commitFilesRenderToMain)),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
if gui.State.CommitFileTreeViewModel.GetItemsLength() == 0 {
return [][]string{{style.FgRed.Sprint("(none)")}} return [][]string{{style.FgRed.Sprint("(none)")}}
} }
lines := presentation.RenderCommitFileTree(gui.State.CommitFileTreeViewModel, gui.State.Modes.Diffing.Ref, gui.git.Patch.PatchManager) lines := presentation.RenderCommitFileTree(gui.State.Contexts.CommitFiles.CommitFileTreeViewModel, gui.State.Modes.Diffing.Ref, gui.git.Patch.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}
@ -319,11 +310,11 @@ func (gui *Gui) commitFilesListContext() types.IListContext {
return mappedLines return mappedLines
}, },
SelectedItem: func() (types.ListItem, bool) { OnFocusWrapper(gui.onCommitFileFocus),
item := gui.getSelectedCommitFileNode() OnFocusWrapper(gui.withDiffModeCheck(gui.commitFilesRenderToMain)),
return item, item != nil nil,
}, gui.c,
} )
} }
func (gui *Gui) submodulesListContext() types.IListContext { func (gui *Gui) submodulesListContext() types.IListContext {

View File

@ -31,7 +31,7 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
return nil return nil
} }
to := gui.State.CommitFileTreeViewModel.GetParent() to := gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.GetRefName()
from, reverse := gui.getFromAndReverseArgsForDiff(to) from, reverse := gui.getFromAndReverseArgsForDiff(to)
diff, err := gui.git.WorkingTree.ShowFileDiff(from, to, reverse, node.GetPath(), true) diff, err := gui.git.WorkingTree.ShowFileDiff(from, to, reverse, node.GetPath(), true)
if err != nil { if err != nil {

View File

@ -21,22 +21,22 @@ const NESTED = "│ "
const NOTHING = " " const NOTHING = " "
func RenderFileTree( func RenderFileTree(
fileMgr filetree.IFileTree, tree filetree.IFileTree,
diffName string, diffName string,
submoduleConfigs []*models.SubmoduleConfig, submoduleConfigs []*models.SubmoduleConfig,
) []string { ) []string {
return renderAux(fileMgr.Tree(), fileMgr.CollapsedPaths(), "", -1, func(n filetree.INode, depth int) string { return renderAux(tree.Tree(), tree.CollapsedPaths(), "", -1, func(n filetree.INode, depth int) string {
castN := n.(*filetree.FileNode) castN := n.(*filetree.FileNode)
return getFileLine(castN.GetHasUnstagedChanges(), castN.GetHasStagedChanges(), castN.NameAtDepth(depth), diffName, submoduleConfigs, castN.File) return getFileLine(castN.GetHasUnstagedChanges(), castN.GetHasStagedChanges(), castN.NameAtDepth(depth), diffName, submoduleConfigs, castN.File)
}) })
} }
func RenderCommitFileTree( func RenderCommitFileTree(
commitFileMgr *filetree.CommitFileTreeViewModel, tree *filetree.CommitFileTreeViewModel,
diffName string, diffName string,
patchManager *patch.PatchManager, patchManager *patch.PatchManager,
) []string { ) []string {
return renderAux(commitFileMgr.Tree(), commitFileMgr.CollapsedPaths(), "", -1, func(n filetree.INode, depth int) string { return renderAux(tree.Tree(), tree.CollapsedPaths(), "", -1, func(n filetree.INode, depth int) string {
castN := n.(*filetree.CommitFileNode) castN := n.(*filetree.CommitFileNode)
// This is a little convoluted because we're dealing with either a leaf or a non-leaf. // This is a little convoluted because we're dealing with either a leaf or a non-leaf.
@ -45,11 +45,11 @@ func RenderCommitFileTree(
// based on the leaves of that subtree // based on the leaves of that subtree
var status patch.PatchStatus var status patch.PatchStatus
if castN.EveryFile(func(file *models.CommitFile) bool { if castN.EveryFile(func(file *models.CommitFile) bool {
return patchManager.GetFileStatus(file.Name, commitFileMgr.GetParent()) == patch.WHOLE return patchManager.GetFileStatus(file.Name, tree.GetRefName()) == patch.WHOLE
}) { }) {
status = patch.WHOLE status = patch.WHOLE
} else if castN.EveryFile(func(file *models.CommitFile) bool { } else if castN.EveryFile(func(file *models.CommitFile) bool {
return patchManager.GetFileStatus(file.Name, commitFileMgr.GetParent()) == patch.UNSELECTED return patchManager.GetFileStatus(file.Name, tree.GetRefName()) == patch.UNSELECTED
}) { }) {
status = patch.UNSELECTED status = patch.UNSELECTED
} else { } else {

View File

@ -195,7 +195,7 @@ func (gui *Gui) refreshCommits() {
// For now the awkwardness remains. // For now the awkwardness remains.
commit := gui.getSelectedLocalCommit() commit := gui.getSelectedLocalCommit()
if commit != nil { if commit != nil {
gui.State.Panels.CommitFiles.refName = commit.RefName() gui.State.Contexts.CommitFiles.SetRefName(commit.RefName())
_ = gui.refreshCommitFilesView() _ = gui.refreshCommitFilesView()
} }
} }