From b5515da00b916bcf79f680b360d5c00e08932338 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sun, 30 Jan 2022 16:38:07 +1100 Subject: [PATCH] move commit files context into new structure --- pkg/gui/commit_files_panel.go | 50 +++---- pkg/gui/context/commit_files_context.go | 68 ++++++++++ pkg/gui/context/context.go | 2 +- .../controllers/local_commits_controller.go | 2 + pkg/gui/diffing.go | 2 +- pkg/gui/filetree/commit_file_tree.go | 107 +++++++++++++++ .../filetree/commit_file_tree_view_model.go | 128 ++++++++---------- pkg/gui/filetree/file_tree.go | 25 ++-- pkg/gui/gui.go | 50 +++---- pkg/gui/line_by_line_panel.go | 7 +- pkg/gui/list_context_config.go | 33 ++--- pkg/gui/patch_building_panel.go | 2 +- pkg/gui/presentation/files.go | 12 +- pkg/gui/refresh.go | 2 +- 14 files changed, 312 insertions(+), 178 deletions(-) create mode 100644 pkg/gui/context/commit_files_context.go create mode 100644 pkg/gui/filetree/commit_file_tree.go diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index 973273089..e4932d080 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -10,12 +10,7 @@ import ( ) func (gui *Gui) getSelectedCommitFileNode() *filetree.CommitFileNode { - selectedLine := gui.State.Panels.CommitFiles.SelectedLineIdx - if selectedLine == -1 || selectedLine > gui.State.CommitFileTreeViewModel.GetItemsLength()-1 { - return nil - } - - return gui.State.CommitFileTreeViewModel.GetItemAtIndex(selectedLine) + return gui.State.Contexts.CommitFiles.GetSelectedFileNode() } func (gui *Gui) getSelectedCommitFile() *models.CommitFile { @@ -45,7 +40,7 @@ func (gui *Gui) commitFilesRenderToMain() error { return nil } - to := gui.State.CommitFileTreeViewModel.GetParent() + to := gui.State.Contexts.CommitFiles.GetRefName() from, reverse := gui.getFromAndReverseArgsForDiff(to) 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) - 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) } @@ -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) files, err := gui.git.Loaders.CommitFiles.GetFilesInDiff(from, to, reverse) if err != nil { return gui.c.Error(err) } - gui.State.CommitFileTreeViewModel.SetParent(to) - gui.State.CommitFileTreeViewModel.SetFiles(files) + gui.State.CommitFiles = files + gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.SetTree() 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, // otherwise we'll remove everything 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 { @@ -180,7 +175,7 @@ func (gui *Gui) handleToggleFileForPatch() error { 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{ Title: gui.c.Tr.DiscardPatch, Prompt: gui.c.Tr.DiscardPatchConfirm, @@ -195,9 +190,11 @@ func (gui *Gui) handleToggleFileForPatch() 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) 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) } - 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{ Title: gui.c.Tr.DiscardPatch, Prompt: gui.c.Tr.DiscardPatchConfirm, @@ -248,7 +245,7 @@ func (gui *Gui) handleToggleCommitFileDirCollapsed() error { 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 { 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. gui.resetWindowForView(gui.Views.CommitFiles) - gui.State.Panels.CommitFiles.SelectedLineIdx = 0 - gui.State.Panels.CommitFiles.refName = opts.RefName - gui.State.Panels.CommitFiles.canRebase = opts.CanRebase + gui.State.Contexts.CommitFiles.SetSelectedLineIdx(0) + gui.State.Contexts.CommitFiles.SetRefName(opts.RefName) + gui.State.Contexts.CommitFiles.SetCanRebase(opts.CanRebase) gui.State.Contexts.CommitFiles.SetParentContext(opts.Context) 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 func (gui *Gui) handleToggleCommitFileTreeView() error { - path := gui.getSelectedCommitFilePath() - - 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) - } - } + gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.ToggleShowTree() return gui.c.PostRefreshUpdate(gui.State.Contexts.CommitFiles) } diff --git a/pkg/gui/context/commit_files_context.go b/pkg/gui/context/commit_files_context.go new file mode 100644 index 000000000..84a5cd67c --- /dev/null +++ b/pkg/gui/context/commit_files_context.go @@ -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 +} diff --git a/pkg/gui/context/context.go b/pkg/gui/context/context.go index 1bcefeadb..20d67a5a7 100644 --- a/pkg/gui/context/context.go +++ b/pkg/gui/context/context.go @@ -64,7 +64,7 @@ type ContextTree struct { RemoteBranches types.IListContext Tags *TagsContext BranchCommits types.IListContext - CommitFiles types.IListContext + CommitFiles *CommitFilesContext ReflogCommits types.IListContext SubCommits types.IListContext Stash types.IListContext diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index 8b4cddfaf..9e1cacca7 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -434,6 +434,7 @@ func (self *LocalCommitsController) handleCommitMoveDown() error { if err := self.git.Rebase.MoveTodoDown(index); err != nil { return self.c.Error(err) } + // TODO: use MoveSelectedLine _ = self.getContext().HandleNextLine() return self.c.Refresh(types.RefreshOptions{ 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) err := self.git.Rebase.MoveCommitDown(self.getCommits(), index) if err == nil { + // TODO: use MoveSelectedLine _ = self.getContext().HandleNextLine() } return self.checkMergeOrRebase(err) diff --git a/pkg/gui/diffing.go b/pkg/gui/diffing.go index 98833dfee..385139b76 100644 --- a/pkg/gui/diffing.go +++ b/pkg/gui/diffing.go @@ -40,7 +40,7 @@ func (gui *Gui) currentDiffTerminals() []string { // TODO: should we just return nil here? return []string{""} 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: // for our local branches we want to include both the branch and its upstream branch := gui.getSelectedBranch() diff --git a/pkg/gui/filetree/commit_file_tree.go b/pkg/gui/filetree/commit_file_tree.go new file mode 100644 index 000000000..d020aee21 --- /dev/null +++ b/pkg/gui/filetree/commit_file_tree.go @@ -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 +} diff --git a/pkg/gui/filetree/commit_file_tree_view_model.go b/pkg/gui/filetree/commit_file_tree_view_model.go index 301396462..86e7e864e 100644 --- a/pkg/gui/filetree/commit_file_tree_view_model.go +++ b/pkg/gui/filetree/commit_file_tree_view_model.go @@ -1,101 +1,93 @@ package filetree import ( + "sync" + "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" ) +type ICommitFileTreeViewModel interface { + ICommitFileTree + types.IListCursor + + GetRefName() string + SetRefName(string) + GetCanRebase() bool + SetCanRebase(bool) +} + type CommitFileTreeViewModel struct { - files []*models.CommitFile - tree *CommitFileNode - showTree bool - log *logrus.Entry - collapsedPaths CollapsedPaths - // 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}' - parent string + sync.RWMutex + ICommitFileTree + types.IListCursor + + // this is e.g. the commit SHA of the commit for which we're viewing the files + refName 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 { - return self.parent -} +var _ ICommitFileTreeViewModel = &CommitFileTreeViewModel{} -func (self *CommitFileTreeViewModel) SetParent(parent string) { - self.parent = parent -} - -func NewCommitFileTreeViewModel(files []*models.CommitFile, log *logrus.Entry, showTree bool) *CommitFileTreeViewModel { - viewModel := &CommitFileTreeViewModel{ - log: log, - showTree: showTree, - collapsedPaths: CollapsedPaths{}, +func NewCommitFileTreeViewModel(getFiles func() []*models.CommitFile, log *logrus.Entry, showTree bool) *CommitFileTreeViewModel { + fileTree := NewCommitFileTree(getFiles, log, showTree) + listCursor := traits.NewListCursor(fileTree) + return &CommitFileTreeViewModel{ + ICommitFileTree: fileTree, + IListCursor: listCursor, + refName: "", + canRebase: false, } - - viewModel.SetFiles(files) - - return viewModel } -func (self *CommitFileTreeViewModel) ExpandToPath(path string) { - self.collapsedPaths.ExpandToPath(path) +func (self *CommitFileTreeViewModel) GetRefName() string { + return self.refName } -func (self *CommitFileTreeViewModel) ToggleShowTree() { - self.showTree = !self.showTree - self.SetTree() +func (self *CommitFileTreeViewModel) SetRefName(refName string) { + self.refName = refName } -func (self *CommitFileTreeViewModel) 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 *CommitFileTreeViewModel) GetCanRebase() bool { + return self.canRebase } -func (self *CommitFileTreeViewModel) GetIndexForPath(path string) (int, bool) { - index, found := self.tree.GetIndexForPath(path, self.collapsedPaths) - return index - 1, found +func (self *CommitFileTreeViewModel) SetCanRebase(canRebase bool) { + self.canRebase = canRebase } -func (self *CommitFileTreeViewModel) GetAllItems() []*CommitFileNode { - if self.tree == nil { +func (self *CommitFileTreeViewModel) GetSelectedFileNode() *CommitFileNode { + if self.GetItemsLength() == 0 { return nil } - return self.tree.Flatten(self.collapsedPaths)[1:] // ignoring root + return self.GetItemAtIndex(self.GetSelectedLineIdx()) } -func (self *CommitFileTreeViewModel) GetItemsLength() int { - return self.tree.Size(self.collapsedPaths) - 1 // ignoring root -} +// duplicated from file_tree_view_model.go. Generics will help here +func (self *CommitFileTreeViewModel) ToggleShowTree() { + selectedNode := self.GetSelectedFileNode() -func (self *CommitFileTreeViewModel) GetAllFiles() []*models.CommitFile { - return self.files -} + self.ICommitFileTree.ToggleShowTree() -func (self *CommitFileTreeViewModel) SetFiles(files []*models.CommitFile) { - self.files = files + if selectedNode == nil { + 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() { - if self.showTree { - self.tree = BuildTreeFromCommitFiles(self.files) - } else { - self.tree = BuildFlatTreeFromCommitFiles(self.files) + index, found := self.GetIndexForPath(path) + if found { + self.SetSelectedLineIdx(index) } } - -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 -} diff --git a/pkg/gui/filetree/file_tree.go b/pkg/gui/filetree/file_tree.go index 504707b28..113027e59 100644 --- a/pkg/gui/filetree/file_tree.go +++ b/pkg/gui/filetree/file_tree.go @@ -2,7 +2,6 @@ package filetree import ( "fmt" - "sync" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/sirupsen/logrus" @@ -18,25 +17,28 @@ const ( DisplayConflicted ) -type IFileTree interface { +type ITree interface { InTreeMode() bool ExpandToPath(path string) - FilterFiles(test func(*models.File) bool) []*models.File - SetFilter(filter FileTreeDisplayFilter) ToggleShowTree() - - GetItemAtIndex(index int) *FileNode - GetFile(path string) *models.File GetIndexForPath(path string) (int, bool) - GetAllItems() []*FileNode GetItemsLength() int - GetAllFiles() []*models.File - SetTree() IsCollapsed(path string) bool ToggleCollapsed(path string) Tree() INode 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 } @@ -47,8 +49,6 @@ type FileTree struct { log *logrus.Entry filter FileTreeDisplayFilter collapsedPaths CollapsedPaths - - sync.RWMutex } 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, filter: DisplayAll, collapsedPaths: CollapsedPaths{}, - RWMutex: sync.RWMutex{}, } } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index bb515be4d..b80ef9656 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -20,7 +20,6 @@ import ( "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui/context" "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/mergeconflicts" "github.com/jesseduffield/lazygit/pkg/gui/modes/cherrypicking" @@ -173,18 +172,16 @@ type PrevLayout struct { } type GuiRepoState struct { - // the file panels (files and commit files) can render as a tree, so we have - // managers for them which handle rendering a flat list of files in tree form - CommitFileTreeViewModel *filetree.CommitFileTreeViewModel - Files []*models.File - Submodules []*models.SubmoduleConfig - Branches []*models.Branch - Commits []*models.Commit - StashEntries []*models.StashEntry - SubCommits []*models.Commit - Remotes []*models.Remote - RemoteBranches []*models.RemoteBranch - Tags []*models.Tag + CommitFiles []*models.CommitFile + Files []*models.File + Submodules []*models.SubmoduleConfig + Branches []*models.Branch + Commits []*models.Commit + StashEntries []*models.StashEntry + SubCommits []*models.Commit + Remotes []*models.Remote + RemoteBranches []*models.RemoteBranch + Tags []*models.Tag // FilteredReflogCommits are the ones that appear in the reflog panel. // when in filtering mode we only include the ones that match the given path FilteredReflogCommits []*models.Commit @@ -316,15 +313,6 @@ type menuPanelState struct { 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 { listPanelState } @@ -333,6 +321,8 @@ type suggestionsPanelState struct { 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 { Branches *branchPanelState Remotes *remotePanelState @@ -344,7 +334,6 @@ type panelStates struct { Menu *menuPanelState LineByLine *LblPanelState Merging *MergingPanelState - CommitFiles *commitFilesPanelState Submodules *submodulePanelState Suggestions *suggestionsPanelState } @@ -427,8 +416,6 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) { } } - showTree := gui.UserConfig.Gui.ShowFileTree - contexts := gui.contextTree() screenMode := SCREEN_NORMAL @@ -439,12 +426,12 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) { } gui.State = &GuiRepoState{ - CommitFileTreeViewModel: filetree.NewCommitFileTreeViewModel(make([]*models.CommitFile, 0), gui.Log, showTree), - Commits: make([]*models.Commit, 0), - FilteredReflogCommits: make([]*models.Commit, 0), - ReflogCommits: make([]*models.Commit, 0), - StashEntries: make([]*models.StashEntry, 0), - BisectInfo: git_commands.NewNullBisectInfo(), + Files: make([]*models.File, 0), + Commits: make([]*models.Commit, 0), + FilteredReflogCommits: make([]*models.Commit, 0), + ReflogCommits: make([]*models.Commit, 0), + StashEntries: make([]*models.StashEntry, 0), + BisectInfo: git_commands.NewNullBisectInfo(), 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 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}, ReflogCommits: &reflogCommitPanelState{listPanelState{SelectedLineIdx: 0}}, SubCommits: &subCommitPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, refName: ""}, - CommitFiles: &commitFilesPanelState{listPanelState: listPanelState{SelectedLineIdx: -1}, refName: ""}, Stash: &stashPanelState{listPanelState{SelectedLineIdx: -1}}, Menu: &menuPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, OnPress: nil}, Suggestions: &suggestionsPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}}, diff --git a/pkg/gui/line_by_line_panel.go b/pkg/gui/line_by_line_panel.go index f55b339a3..39c0597c4 100644 --- a/pkg/gui/line_by_line_panel.go +++ b/pkg/gui/line_by_line_panel.go @@ -121,9 +121,12 @@ func (gui *Gui) handleMouseDrag() error { } 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 { diff --git a/pkg/gui/list_context_config.go b/pkg/gui/list_context_config.go index 6f7203db0..8137ace82 100644 --- a/pkg/gui/list_context_config.go +++ b/pkg/gui/list_context_config.go @@ -293,25 +293,16 @@ func (gui *Gui) stashListContext() types.IListContext { } } -func (gui *Gui) commitFilesListContext() types.IListContext { - return &ListContext{ - BaseContext: context.NewBaseContext(context.NewBaseContextOpts{ - ViewName: "commitFiles", - WindowName: "commits", - Key: context.COMMIT_FILES_CONTEXT_KEY, - 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 { +func (gui *Gui) commitFilesListContext() *context.CommitFilesContext { + return context.NewCommitFilesContext( + func() []*models.CommitFile { return gui.State.CommitFiles }, + func() *gocui.View { return gui.Views.CommitFiles }, + func(startIdx int, length int) [][]string { + if gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.GetItemsLength() == 0 { 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)) for i, line := range lines { mappedLines[i] = []string{line} @@ -319,11 +310,11 @@ func (gui *Gui) commitFilesListContext() types.IListContext { return mappedLines }, - SelectedItem: func() (types.ListItem, bool) { - item := gui.getSelectedCommitFileNode() - return item, item != nil - }, - } + OnFocusWrapper(gui.onCommitFileFocus), + OnFocusWrapper(gui.withDiffModeCheck(gui.commitFilesRenderToMain)), + nil, + gui.c, + ) } func (gui *Gui) submodulesListContext() types.IListContext { diff --git a/pkg/gui/patch_building_panel.go b/pkg/gui/patch_building_panel.go index 865e1162c..ac09a898c 100644 --- a/pkg/gui/patch_building_panel.go +++ b/pkg/gui/patch_building_panel.go @@ -31,7 +31,7 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error { return nil } - to := gui.State.CommitFileTreeViewModel.GetParent() + to := gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.GetRefName() from, reverse := gui.getFromAndReverseArgsForDiff(to) diff, err := gui.git.WorkingTree.ShowFileDiff(from, to, reverse, node.GetPath(), true) if err != nil { diff --git a/pkg/gui/presentation/files.go b/pkg/gui/presentation/files.go index 88b9491d9..3efb8d29b 100644 --- a/pkg/gui/presentation/files.go +++ b/pkg/gui/presentation/files.go @@ -21,22 +21,22 @@ const NESTED = "│ " const NOTHING = " " func RenderFileTree( - fileMgr filetree.IFileTree, + tree filetree.IFileTree, diffName string, submoduleConfigs []*models.SubmoduleConfig, ) []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) return getFileLine(castN.GetHasUnstagedChanges(), castN.GetHasStagedChanges(), castN.NameAtDepth(depth), diffName, submoduleConfigs, castN.File) }) } func RenderCommitFileTree( - commitFileMgr *filetree.CommitFileTreeViewModel, + tree *filetree.CommitFileTreeViewModel, diffName string, patchManager *patch.PatchManager, ) []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) // 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 var status patch.PatchStatus 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 } 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 } else { diff --git a/pkg/gui/refresh.go b/pkg/gui/refresh.go index 481a7ad6a..2f08c57c5 100644 --- a/pkg/gui/refresh.go +++ b/pkg/gui/refresh.go @@ -195,7 +195,7 @@ func (gui *Gui) refreshCommits() { // For now the awkwardness remains. commit := gui.getSelectedLocalCommit() if commit != nil { - gui.State.Panels.CommitFiles.refName = commit.RefName() + gui.State.Contexts.CommitFiles.SetRefName(commit.RefName()) _ = gui.refreshCommitFilesView() } }