diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index 7fcf050b3..959085645 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -1,18 +1,5 @@ package gui -import ( - "errors" - "fmt" - "strings" - - "github.com/jesseduffield/lazygit/pkg/commands/git_commands" - "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/jesseduffield/lazygit/pkg/gui/types" - "github.com/jesseduffield/lazygit/pkg/utils" -) - -// list panel functions - func (gui *Gui) branchesRenderToMain() error { var task updateTask branch := gui.State.Contexts.Branches.GetSelected() @@ -31,368 +18,3 @@ func (gui *Gui) branchesRenderToMain() error { }, }) } - -// specific functions - -func (gui *Gui) handleBranchPress() error { - branch := gui.State.Contexts.Branches.GetSelected() - if branch == nil { - return nil - } - - if branch == gui.getCheckedOutBranch() { - return gui.c.ErrorMsg(gui.c.Tr.AlreadyCheckedOutBranch) - } - - gui.c.LogAction(gui.c.Tr.Actions.CheckoutBranch) - return gui.helpers.Refs.CheckoutRef(branch.Name, types.CheckoutRefOptions{}) -} - -func (gui *Gui) handleCreatePullRequestPress() error { - branch := gui.State.Contexts.Branches.GetSelected() - return gui.createPullRequest(branch.Name, "") -} - -func (gui *Gui) handleCreatePullRequestMenu() error { - selectedBranch := gui.State.Contexts.Branches.GetSelected() - if selectedBranch == nil { - return nil - } - checkedOutBranch := gui.getCheckedOutBranch() - - return gui.createPullRequestMenu(selectedBranch, checkedOutBranch) -} - -func (gui *Gui) handleCopyPullRequestURLPress() error { - hostingServiceMgr := gui.getHostingServiceMgr() - - branch := gui.State.Contexts.Branches.GetSelected() - - branchExistsOnRemote := gui.git.Remote.CheckRemoteBranchExists(branch.Name) - - if !branchExistsOnRemote { - return gui.c.Error(errors.New(gui.c.Tr.NoBranchOnRemote)) - } - - url, err := hostingServiceMgr.GetPullRequestURL(branch.Name, "") - if err != nil { - return gui.c.Error(err) - } - gui.c.LogAction(gui.c.Tr.Actions.CopyPullRequestURL) - if err := gui.os.CopyToClipboard(url); err != nil { - return gui.c.Error(err) - } - - gui.c.Toast(gui.c.Tr.PullRequestURLCopiedToClipboard) - - return nil -} - -func (gui *Gui) handleGitFetch() error { - return gui.c.WithLoaderPanel(gui.c.Tr.FetchWait, func() error { - if err := gui.fetch(); err != nil { - _ = gui.c.Error(err) - } - return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) - }) -} - -func (gui *Gui) handleForceCheckout() error { - branch := gui.State.Contexts.Branches.GetSelected() - message := gui.c.Tr.SureForceCheckout - title := gui.c.Tr.ForceCheckoutBranch - - return gui.c.Ask(types.AskOpts{ - Title: title, - Prompt: message, - HandleConfirm: func() error { - gui.c.LogAction(gui.c.Tr.Actions.ForceCheckoutBranch) - if err := gui.git.Branch.Checkout(branch.Name, git_commands.CheckoutOptions{Force: true}); err != nil { - _ = gui.c.Error(err) - } - return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) - }, - }) -} - -func (gui *Gui) handleCheckoutByName() error { - return gui.c.Prompt(types.PromptOpts{ - Title: gui.c.Tr.BranchName + ":", - FindSuggestionsFunc: gui.helpers.Suggestions.GetRefsSuggestionsFunc(), - HandleConfirm: func(response string) error { - gui.c.LogAction("Checkout branch") - return gui.helpers.Refs.CheckoutRef(response, types.CheckoutRefOptions{ - OnRefNotFound: func(ref string) error { - return gui.c.Ask(types.AskOpts{ - Title: gui.c.Tr.BranchNotFoundTitle, - Prompt: fmt.Sprintf("%s %s%s", gui.c.Tr.BranchNotFoundPrompt, ref, "?"), - HandleConfirm: func() error { - return gui.createNewBranchWithName(ref) - }, - }) - }, - }) - }}, - ) -} - -func (gui *Gui) getCheckedOutBranch() *models.Branch { - if len(gui.State.Model.Branches) == 0 { - return nil - } - - return gui.State.Model.Branches[0] -} - -func (gui *Gui) createNewBranchWithName(newBranchName string) error { - branch := gui.State.Contexts.Branches.GetSelected() - if branch == nil { - return nil - } - - if err := gui.git.Branch.New(newBranchName, branch.Name); err != nil { - return gui.c.Error(err) - } - - gui.State.Contexts.Branches.SetSelectedLineIdx(0) - return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) -} - -func (gui *Gui) handleDeleteBranch() error { - return gui.deleteBranch(false) -} - -func (gui *Gui) deleteBranch(force bool) error { - selectedBranch := gui.State.Contexts.Branches.GetSelected() - if selectedBranch == nil { - return nil - } - checkedOutBranch := gui.getCheckedOutBranch() - if checkedOutBranch.Name == selectedBranch.Name { - return gui.c.ErrorMsg(gui.c.Tr.CantDeleteCheckOutBranch) - } - return gui.deleteNamedBranch(selectedBranch, force) -} - -func (gui *Gui) deleteNamedBranch(selectedBranch *models.Branch, force bool) error { - title := gui.c.Tr.DeleteBranch - var templateStr string - if force { - templateStr = gui.c.Tr.ForceDeleteBranchMessage - } else { - templateStr = gui.c.Tr.DeleteBranchMessage - } - message := utils.ResolvePlaceholderString( - templateStr, - map[string]string{ - "selectedBranchName": selectedBranch.Name, - }, - ) - - return gui.c.Ask(types.AskOpts{ - Title: title, - Prompt: message, - HandleConfirm: func() error { - gui.c.LogAction(gui.c.Tr.Actions.DeleteBranch) - if err := gui.git.Branch.Delete(selectedBranch.Name, force); err != nil { - errMessage := err.Error() - if !force && strings.Contains(errMessage, "git branch -D ") { - return gui.deleteNamedBranch(selectedBranch, true) - } - return gui.c.ErrorMsg(errMessage) - } - return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}}) - }, - }) -} - -func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error { - if gui.git.Branch.IsHeadDetached() { - return gui.c.ErrorMsg("Cannot merge branch in detached head state. You might have checked out a commit directly or a remote branch, in which case you should checkout the local branch you want to be on") - } - checkedOutBranchName := gui.getCheckedOutBranch().Name - if checkedOutBranchName == branchName { - return gui.c.ErrorMsg(gui.c.Tr.CantMergeBranchIntoItself) - } - prompt := utils.ResolvePlaceholderString( - gui.c.Tr.ConfirmMerge, - map[string]string{ - "checkedOutBranch": checkedOutBranchName, - "selectedBranch": branchName, - }, - ) - - return gui.c.Ask(types.AskOpts{ - Title: gui.c.Tr.MergingTitle, - Prompt: prompt, - HandleConfirm: func() error { - gui.c.LogAction(gui.c.Tr.Actions.Merge) - err := gui.git.Branch.Merge(branchName, git_commands.MergeOpts{}) - return gui.helpers.Rebase.CheckMergeOrRebase(err) - }, - }) -} - -func (gui *Gui) handleMerge() error { - selectedBranchName := gui.State.Contexts.Branches.GetSelected().Name - return gui.mergeBranchIntoCheckedOutBranch(selectedBranchName) -} - -func (gui *Gui) handleRebaseOntoLocalBranch() error { - selectedBranchName := gui.State.Contexts.Branches.GetSelected().Name - return gui.handleRebaseOntoBranch(selectedBranchName) -} - -func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error { - checkedOutBranch := gui.getCheckedOutBranch().Name - if selectedBranchName == checkedOutBranch { - return gui.c.ErrorMsg(gui.c.Tr.CantRebaseOntoSelf) - } - prompt := utils.ResolvePlaceholderString( - gui.c.Tr.ConfirmRebase, - map[string]string{ - "checkedOutBranch": checkedOutBranch, - "selectedBranch": selectedBranchName, - }, - ) - - return gui.c.Ask(types.AskOpts{ - Title: gui.c.Tr.RebasingTitle, - Prompt: prompt, - HandleConfirm: func() error { - gui.c.LogAction(gui.c.Tr.Actions.RebaseBranch) - err := gui.git.Rebase.RebaseBranch(selectedBranchName) - return gui.helpers.Rebase.CheckMergeOrRebase(err) - }, - }) -} - -func (gui *Gui) handleFastForward() error { - branch := gui.State.Contexts.Branches.GetSelected() - if branch == nil || !branch.IsRealBranch() { - return nil - } - - if !branch.IsTrackingRemote() { - return gui.c.ErrorMsg(gui.c.Tr.FwdNoUpstream) - } - if !branch.RemoteBranchStoredLocally() { - return gui.c.ErrorMsg(gui.c.Tr.FwdNoLocalUpstream) - } - if branch.HasCommitsToPush() { - return gui.c.ErrorMsg(gui.c.Tr.FwdCommitsToPush) - } - - action := gui.c.Tr.Actions.FastForwardBranch - - message := utils.ResolvePlaceholderString( - gui.c.Tr.Fetching, - map[string]string{ - "from": fmt.Sprintf("%s/%s", branch.UpstreamRemote, branch.UpstreamBranch), - "to": branch.Name, - }, - ) - - return gui.c.WithLoaderPanel(message, func() error { - if branch == gui.getCheckedOutBranch() { - gui.c.LogAction(action) - - err := gui.git.Sync.Pull( - git_commands.PullOptions{ - RemoteName: branch.UpstreamRemote, - BranchName: branch.Name, - FastForwardOnly: true, - }, - ) - if err != nil { - _ = gui.c.Error(err) - } - - return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) - } else { - gui.c.LogAction(action) - err := gui.git.Sync.FastForward(branch.Name, branch.UpstreamRemote, branch.UpstreamBranch) - if err != nil { - _ = gui.c.Error(err) - } - _ = gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}}) - } - - return nil - }) -} - -func (gui *Gui) handleCreateResetToBranchMenu() error { - branch := gui.State.Contexts.Branches.GetSelected() - if branch == nil { - return nil - } - - return gui.helpers.Refs.CreateGitResetMenu(branch.Name) -} - -func (gui *Gui) handleRenameBranch() error { - branch := gui.State.Contexts.Branches.GetSelected() - if branch == nil || !branch.IsRealBranch() { - return nil - } - - promptForNewName := func() error { - return gui.c.Prompt(types.PromptOpts{ - Title: gui.c.Tr.NewBranchNamePrompt + " " + branch.Name + ":", - InitialContent: branch.Name, - HandleConfirm: func(newBranchName string) error { - gui.c.LogAction(gui.c.Tr.Actions.RenameBranch) - if err := gui.git.Branch.Rename(branch.Name, newBranchName); err != nil { - return gui.c.Error(err) - } - - // need to find where the branch is now so that we can re-select it. That means we need to refetch the branches synchronously and then find our branch - gui.refreshBranches() - - // now that we've got our stuff again we need to find that branch and reselect it. - for i, newBranch := range gui.State.Model.Branches { - if newBranch.Name == newBranchName { - gui.State.Contexts.Branches.SetSelectedLineIdx(i) - if err := gui.State.Contexts.Branches.HandleRender(); err != nil { - return err - } - } - } - - return nil - }, - }) - } - - // I could do an explicit check here for whether the branch is tracking a remote branch - // but if we've selected it we'll already know that via Pullables and Pullables. - // Bit of a hack but I'm lazy. - if !branch.IsTrackingRemote() { - return promptForNewName() - } - - return gui.c.Ask(types.AskOpts{ - Title: gui.c.Tr.LcRenameBranch, - Prompt: gui.c.Tr.RenameBranchWarning, - HandleConfirm: promptForNewName, - }) -} - -func (gui *Gui) handleEnterBranch() error { - branch := gui.State.Contexts.Branches.GetSelected() - if branch == nil { - return nil - } - - return gui.switchToSubCommitsContext(branch.RefName()) -} - -func (gui *Gui) handleNewBranchOffBranch() error { - selectedBranch := gui.State.Contexts.Branches.GetSelected() - if selectedBranch == nil { - return nil - } - - return gui.helpers.Refs.NewBranch(selectedBranch.RefName(), selectedBranch.RefName(), "") -} diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index fbbedcb6f..8f1201ccb 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -85,7 +85,7 @@ func (gui *Gui) handleDiscardOldFileChange() error { return gui.c.WithWaitingStatus(gui.c.Tr.RebasingStatus, func() error { gui.c.LogAction(gui.c.Tr.Actions.DiscardOldFileChange) if err := gui.git.Rebase.DiscardOldFileChanges(gui.State.Model.Commits, gui.State.Contexts.BranchCommits.GetSelectedLineIdx(), fileName); err != nil { - if err := gui.helpers.Rebase.CheckMergeOrRebase(err); err != nil { + if err := gui.helpers.MergeAndRebase.CheckMergeOrRebase(err); err != nil { return err } } @@ -265,7 +265,7 @@ func (gui *Gui) SwitchToCommitFilesContext(opts controllers.SwitchToCommitFilesC 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) + gui.State.Contexts.CommitFiles.SetWindowName(opts.Context.GetWindowName()) if err := gui.refreshCommitFilesView(); err != nil { return err diff --git a/pkg/gui/context/branches_context.go b/pkg/gui/context/branches_context.go index 4b82844f4..146810a86 100644 --- a/pkg/gui/context/branches_context.go +++ b/pkg/gui/context/branches_context.go @@ -23,7 +23,7 @@ func NewBranchesContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *BranchesContext { viewModel := NewBranchesViewModel(getModel) diff --git a/pkg/gui/context/commit_files_context.go b/pkg/gui/context/commit_files_context.go index 1c555387b..8f9bd91f7 100644 --- a/pkg/gui/context/commit_files_context.go +++ b/pkg/gui/context/commit_files_context.go @@ -23,7 +23,7 @@ func NewCommitFilesContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *CommitFilesContext { viewModel := filetree.NewCommitFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree) diff --git a/pkg/gui/context/list_context_trait.go b/pkg/gui/context/list_context_trait.go index b716bb25e..6deb5dfc1 100644 --- a/pkg/gui/context/list_context_trait.go +++ b/pkg/gui/context/list_context_trait.go @@ -10,7 +10,7 @@ import ( type ListContextTrait struct { types.Context - c *types.ControllerCommon + c *types.HelperCommon list types.IList viewTrait *ViewTrait getDisplayStrings func(startIdx int, length int) [][]string diff --git a/pkg/gui/context/local_commits_context.go b/pkg/gui/context/local_commits_context.go index 533d97cb2..9da4721e3 100644 --- a/pkg/gui/context/local_commits_context.go +++ b/pkg/gui/context/local_commits_context.go @@ -23,7 +23,7 @@ func NewLocalCommitsContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *LocalCommitsContext { viewModel := NewLocalCommitsViewModel(getModel) @@ -61,8 +61,14 @@ func (self *LocalCommitsContext) GetSelectedItemId() string { type LocalCommitsViewModel struct { *traits.ListCursor + getModel func() []*models.Commit + + // If this is true we limit the amount of commits we load, for the sake of keeping things fast. + // If the user attempts to scroll past the end of the list, we will load more commits. limitCommits bool - getModel func() []*models.Commit + + // If this is true we'll use git log --all when fetching the commits. + showWholeGitGraph bool } func NewLocalCommitsViewModel(getModel func() []*models.Commit) *LocalCommitsViewModel { @@ -95,3 +101,11 @@ func (self *LocalCommitsViewModel) SetLimitCommits(value bool) { func (self *LocalCommitsViewModel) GetLimitCommits() bool { return self.limitCommits } + +func (self *LocalCommitsViewModel) SetShowWholeGitGraph(value bool) { + self.showWholeGitGraph = value +} + +func (self *LocalCommitsViewModel) GetShowWholeGitGraph() bool { + return self.showWholeGitGraph +} diff --git a/pkg/gui/context/menu_context.go b/pkg/gui/context/menu_context.go index 47c6b885f..2e75ba25a 100644 --- a/pkg/gui/context/menu_context.go +++ b/pkg/gui/context/menu_context.go @@ -21,7 +21,7 @@ func NewMenuContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, getOptionsMap func() map[string]string, ) *MenuContext { viewModel := NewMenuViewModel() diff --git a/pkg/gui/context/reflog_commits_context.go b/pkg/gui/context/reflog_commits_context.go index e3130c251..4a53fe393 100644 --- a/pkg/gui/context/reflog_commits_context.go +++ b/pkg/gui/context/reflog_commits_context.go @@ -23,7 +23,7 @@ func NewReflogCommitsContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *ReflogCommitsContext { viewModel := NewReflogCommitsViewModel(getModel) diff --git a/pkg/gui/context/remote_branches_context.go b/pkg/gui/context/remote_branches_context.go index 6ec5f887b..c851c96ac 100644 --- a/pkg/gui/context/remote_branches_context.go +++ b/pkg/gui/context/remote_branches_context.go @@ -23,7 +23,7 @@ func NewRemoteBranchesContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *RemoteBranchesContext { viewModel := NewRemoteBranchesViewModel(getModel) diff --git a/pkg/gui/context/remotes_context.go b/pkg/gui/context/remotes_context.go index 28d0db20a..2b6afdeb5 100644 --- a/pkg/gui/context/remotes_context.go +++ b/pkg/gui/context/remotes_context.go @@ -23,7 +23,7 @@ func NewRemotesContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *RemotesContext { viewModel := NewRemotesViewModel(getModel) diff --git a/pkg/gui/context/stash_context.go b/pkg/gui/context/stash_context.go index 9c22e7b06..95efeaef1 100644 --- a/pkg/gui/context/stash_context.go +++ b/pkg/gui/context/stash_context.go @@ -23,7 +23,7 @@ func NewStashContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *StashContext { viewModel := NewStashViewModel(getModel) diff --git a/pkg/gui/context/sub_commits_context.go b/pkg/gui/context/sub_commits_context.go index aed0e01a2..10c2cf41a 100644 --- a/pkg/gui/context/sub_commits_context.go +++ b/pkg/gui/context/sub_commits_context.go @@ -23,7 +23,7 @@ func NewSubCommitsContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *SubCommitsContext { viewModel := NewSubCommitsViewModel(getModel) diff --git a/pkg/gui/context/submodules_context.go b/pkg/gui/context/submodules_context.go index c58755985..2bf5fe274 100644 --- a/pkg/gui/context/submodules_context.go +++ b/pkg/gui/context/submodules_context.go @@ -23,7 +23,7 @@ func NewSubmodulesContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *SubmodulesContext { viewModel := NewSubmodulesViewModel(getModel) diff --git a/pkg/gui/context/suggestions_context.go b/pkg/gui/context/suggestions_context.go index 5320e40c6..6c565eedf 100644 --- a/pkg/gui/context/suggestions_context.go +++ b/pkg/gui/context/suggestions_context.go @@ -22,7 +22,7 @@ func NewSuggestionsContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *SuggestionsContext { viewModel := NewSuggestionsViewModel(getModel) diff --git a/pkg/gui/context/tags_context.go b/pkg/gui/context/tags_context.go index 169a4989d..aa6211f40 100644 --- a/pkg/gui/context/tags_context.go +++ b/pkg/gui/context/tags_context.go @@ -23,7 +23,7 @@ func NewTagsContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *TagsContext { viewModel := NewTagsViewModel(getModel) diff --git a/pkg/gui/context/working_tree_context.go b/pkg/gui/context/working_tree_context.go index c1021ba23..ae647afb3 100644 --- a/pkg/gui/context/working_tree_context.go +++ b/pkg/gui/context/working_tree_context.go @@ -23,7 +23,7 @@ func NewWorkingTreeContext( onRenderToMain func(...types.OnFocusOpts) error, onFocusLost func() error, - c *types.ControllerCommon, + c *types.HelperCommon, ) *WorkingTreeContext { viewModel := filetree.NewFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree) diff --git a/pkg/gui/controllers/bisect_controller.go b/pkg/gui/controllers/bisect_controller.go index 99ae9c2df..addcd8d80 100644 --- a/pkg/gui/controllers/bisect_controller.go +++ b/pkg/gui/controllers/bisect_controller.go @@ -4,7 +4,6 @@ import ( "fmt" "strings" - "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/context" @@ -13,33 +12,17 @@ import ( type BisectController struct { baseController - - c *types.ControllerCommon - context *context.LocalCommitsContext - git *commands.GitCommand - bisectHelper *BisectHelper - - getCommits func() []*models.Commit + *controllerCommon } var _ types.IController = &BisectController{} func NewBisectController( - c *types.ControllerCommon, - context *context.LocalCommitsContext, - git *commands.GitCommand, - bisectHelper *BisectHelper, - - getCommits func() []*models.Commit, + common *controllerCommon, ) *BisectController { return &BisectController{ - baseController: baseController{}, - c: c, - context: context, - git: git, - bisectHelper: bisectHelper, - - getCommits: getCommits, + baseController: baseController{}, + controllerCommon: common, } } @@ -119,7 +102,7 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c { DisplayString: self.c.Tr.Bisect.ResetOption, OnPress: func() error { - return self.bisectHelper.Reset() + return self.helpers.Bisect.Reset() }, }, } @@ -146,7 +129,7 @@ func (self *BisectController) openStartBisectMenu(info *git_commands.BisectInfo, return self.c.Error(err) } - return self.bisectHelper.PostBisectCommandRefresh() + return self.helpers.Bisect.PostBisectCommandRefresh() }, }, { @@ -161,7 +144,7 @@ func (self *BisectController) openStartBisectMenu(info *git_commands.BisectInfo, return self.c.Error(err) } - return self.bisectHelper.PostBisectCommandRefresh() + return self.helpers.Bisect.PostBisectCommandRefresh() }, }, }, @@ -188,7 +171,7 @@ func (self *BisectController) showBisectCompleteMessage(candidateShas []string) return self.c.Error(err) } - return self.bisectHelper.PostBisectCommandRefresh() + return self.helpers.Bisect.PostBisectCommandRefresh() }, }) } @@ -222,7 +205,7 @@ func (self *BisectController) afterBisectMarkRefresh(selectCurrent bool, waitToR } else { selectFn() - return self.bisectHelper.PostBisectCommandRefresh() + return self.helpers.Bisect.PostBisectCommandRefresh() } } @@ -230,10 +213,10 @@ func (self *BisectController) selectCurrentBisectCommit() { info := self.git.Bisect.GetInfo() if info.GetCurrentSha() != "" { // find index of commit with that sha, move cursor to that. - for i, commit := range self.getCommits() { + for i, commit := range self.model.Commits { if commit.Sha == info.GetCurrentSha() { - self.context.SetSelectedLineIdx(i) - _ = self.context.HandleFocus() + self.context().SetSelectedLineIdx(i) + _ = self.context().HandleFocus() break } } @@ -242,7 +225,7 @@ func (self *BisectController) selectCurrentBisectCommit() { func (self *BisectController) checkSelected(callback func(*models.Commit) error) func() error { return func() error { - commit := self.context.GetSelected() + commit := self.context().GetSelected() if commit == nil { return nil } @@ -252,5 +235,9 @@ func (self *BisectController) checkSelected(callback func(*models.Commit) error) } func (self *BisectController) Context() types.Context { - return self.context + return self.context() +} + +func (self *BisectController) context() *context.LocalCommitsContext { + return self.contexts.BranchCommits } diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go new file mode 100644 index 000000000..ff5989656 --- /dev/null +++ b/pkg/gui/controllers/branches_controller.go @@ -0,0 +1,475 @@ +package controllers + +import ( + "errors" + "fmt" + "strings" + + "github.com/jesseduffield/lazygit/pkg/commands/git_commands" + "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/gui/context" + "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/utils" +) + +type BranchesController struct { + baseController + *controllerCommon +} + +var _ types.IController = &BranchesController{} + +func NewBranchesController( + common *controllerCommon, +) *BranchesController { + return &BranchesController{ + baseController: baseController{}, + controllerCommon: common, + } +} + +func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding { + return []*types.Binding{ + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Universal.Select), + Handler: self.handleBranchPress, + Description: self.c.Tr.LcCheckout, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Branches.CreatePullRequest), + Handler: self.handleCreatePullRequestPress, + Description: self.c.Tr.LcCreatePullRequest, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Branches.ViewPullRequestOptions), + Handler: self.checkSelected(self.handleCreatePullRequestMenu), + Description: self.c.Tr.LcCreatePullRequestOptions, + OpensMenu: true, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Branches.CopyPullRequestURL), + Handler: self.handleCopyPullRequestURLPress, + Description: self.c.Tr.LcCopyPullRequestURL, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Branches.CheckoutBranchByName), + Handler: self.handleCheckoutByName, + Description: self.c.Tr.LcCheckoutByName, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Branches.ForceCheckoutBranch), + Handler: self.handleForceCheckout, + Description: self.c.Tr.LcForceCheckout, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Universal.New), + Handler: self.checkSelected(self.handleNewBranchOffBranch), + Description: self.c.Tr.LcNewBranch, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Universal.Remove), + Handler: self.checkSelectedAndReal(self.handleDeleteBranch), + Description: self.c.Tr.LcDeleteBranch, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Branches.RebaseBranch), + Handler: opts.Guards.OutsideFilterMode(self.handleRebaseOntoLocalBranch), + Description: self.c.Tr.LcRebaseBranch, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch), + Handler: opts.Guards.OutsideFilterMode(self.handleMerge), + Description: self.c.Tr.LcMergeIntoCurrentBranch, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Branches.FastForward), + Handler: self.checkSelectedAndReal(self.handleFastForward), + Description: self.c.Tr.FastForward, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Commits.ViewResetOptions), + Handler: self.checkSelected(self.handleCreateResetToBranchMenu), + Description: self.c.Tr.LcViewResetOptions, + OpensMenu: true, + }, + { + ViewName: "branches", + Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: opts.GetKey(opts.Config.Branches.RenameBranch), + Handler: self.checkSelectedAndReal(self.handleRenameBranch), + Description: self.c.Tr.LcRenameBranch, + }, + } +} + +func (self *BranchesController) Context() types.Context { + return self.context() +} + +func (self *BranchesController) context() *context.BranchesContext { + return self.contexts.Branches +} + +func (self *BranchesController) handleBranchPress() error { + branch := self.context().GetSelected() + if branch == nil { + return nil + } + + if branch == self.helpers.Refs.GetCheckedOutRef() { + return self.c.ErrorMsg(self.c.Tr.AlreadyCheckedOutBranch) + } + + self.c.LogAction(self.c.Tr.Actions.CheckoutBranch) + return self.helpers.Refs.CheckoutRef(branch.Name, types.CheckoutRefOptions{}) +} + +func (self *BranchesController) handleCreatePullRequestPress() error { + branch := self.context().GetSelected() + return self.createPullRequest(branch.Name, "") +} + +func (self *BranchesController) handleCreatePullRequestMenu(selectedBranch *models.Branch) error { + checkedOutBranch := self.helpers.Refs.GetCheckedOutRef() + + return self.createPullRequestMenu(selectedBranch, checkedOutBranch) +} + +func (self *BranchesController) handleCopyPullRequestURLPress() error { + branch := self.context().GetSelected() + + branchExistsOnRemote := self.git.Remote.CheckRemoteBranchExists(branch.Name) + + if !branchExistsOnRemote { + return self.c.Error(errors.New(self.c.Tr.NoBranchOnRemote)) + } + + url, err := self.helpers.Host.GetPullRequestURL(branch.Name, "") + if err != nil { + return self.c.Error(err) + } + self.c.LogAction(self.c.Tr.Actions.CopyPullRequestURL) + if err := self.os.CopyToClipboard(url); err != nil { + return self.c.Error(err) + } + + self.c.Toast(self.c.Tr.PullRequestURLCopiedToClipboard) + + return nil +} + +func (self *BranchesController) handleForceCheckout() error { + branch := self.context().GetSelected() + message := self.c.Tr.SureForceCheckout + title := self.c.Tr.ForceCheckoutBranch + + return self.c.Ask(types.AskOpts{ + Title: title, + Prompt: message, + HandleConfirm: func() error { + self.c.LogAction(self.c.Tr.Actions.ForceCheckoutBranch) + if err := self.git.Branch.Checkout(branch.Name, git_commands.CheckoutOptions{Force: true}); err != nil { + _ = self.c.Error(err) + } + return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) + }, + }) +} + +func (self *BranchesController) handleCheckoutByName() error { + return self.c.Prompt(types.PromptOpts{ + Title: self.c.Tr.BranchName + ":", + FindSuggestionsFunc: self.helpers.Suggestions.GetRefsSuggestionsFunc(), + HandleConfirm: func(response string) error { + self.c.LogAction("Checkout branch") + return self.helpers.Refs.CheckoutRef(response, types.CheckoutRefOptions{ + OnRefNotFound: func(ref string) error { + return self.c.Ask(types.AskOpts{ + Title: self.c.Tr.BranchNotFoundTitle, + Prompt: fmt.Sprintf("%s %s%s", self.c.Tr.BranchNotFoundPrompt, ref, "?"), + HandleConfirm: func() error { + return self.createNewBranchWithName(ref) + }, + }) + }, + }) + }}, + ) +} + +func (self *BranchesController) createNewBranchWithName(newBranchName string) error { + branch := self.context().GetSelected() + if branch == nil { + return nil + } + + if err := self.git.Branch.New(newBranchName, branch.Name); err != nil { + return self.c.Error(err) + } + + self.context().SetSelectedLineIdx(0) + return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) +} + +func (self *BranchesController) handleDeleteBranch(branch *models.Branch) error { + return self.deleteBranch(branch, false) +} + +func (self *BranchesController) deleteBranch(branch *models.Branch, force bool) error { + checkedOutBranch := self.helpers.Refs.GetCheckedOutRef() + if checkedOutBranch.Name == branch.Name { + return self.c.ErrorMsg(self.c.Tr.CantDeleteCheckOutBranch) + } + return self.deleteNamedBranch(branch, force) +} + +func (self *BranchesController) deleteNamedBranch(selectedBranch *models.Branch, force bool) error { + title := self.c.Tr.DeleteBranch + var templateStr string + if force { + templateStr = self.c.Tr.ForceDeleteBranchMessage + } else { + templateStr = self.c.Tr.DeleteBranchMessage + } + message := utils.ResolvePlaceholderString( + templateStr, + map[string]string{ + "selectedBranchName": selectedBranch.Name, + }, + ) + + return self.c.Ask(types.AskOpts{ + Title: title, + Prompt: message, + HandleConfirm: func() error { + self.c.LogAction(self.c.Tr.Actions.DeleteBranch) + if err := self.git.Branch.Delete(selectedBranch.Name, force); err != nil { + errMessage := err.Error() + if !force && strings.Contains(errMessage, "git branch -D ") { + return self.deleteNamedBranch(selectedBranch, true) + } + return self.c.ErrorMsg(errMessage) + } + return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}}) + }, + }) +} + +func (self *BranchesController) handleMerge() error { + selectedBranchName := self.context().GetSelected().Name + return self.helpers.MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranchName) +} + +func (self *BranchesController) handleRebaseOntoLocalBranch() error { + selectedBranchName := self.context().GetSelected().Name + return self.helpers.MergeAndRebase.RebaseOntoRef(selectedBranchName) +} + +func (self *BranchesController) handleFastForward(branch *models.Branch) error { + if !branch.IsTrackingRemote() { + return self.c.ErrorMsg(self.c.Tr.FwdNoUpstream) + } + if !branch.RemoteBranchStoredLocally() { + return self.c.ErrorMsg(self.c.Tr.FwdNoLocalUpstream) + } + if branch.HasCommitsToPush() { + return self.c.ErrorMsg(self.c.Tr.FwdCommitsToPush) + } + + action := self.c.Tr.Actions.FastForwardBranch + + message := utils.ResolvePlaceholderString( + self.c.Tr.Fetching, + map[string]string{ + "from": fmt.Sprintf("%s/%s", branch.UpstreamRemote, branch.UpstreamBranch), + "to": branch.Name, + }, + ) + + return self.c.WithLoaderPanel(message, func() error { + if branch == self.helpers.Refs.GetCheckedOutRef() { + self.c.LogAction(action) + + err := self.git.Sync.Pull( + git_commands.PullOptions{ + RemoteName: branch.UpstreamRemote, + BranchName: branch.Name, + FastForwardOnly: true, + }, + ) + if err != nil { + _ = self.c.Error(err) + } + + return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) + } else { + self.c.LogAction(action) + err := self.git.Sync.FastForward(branch.Name, branch.UpstreamRemote, branch.UpstreamBranch) + if err != nil { + _ = self.c.Error(err) + } + _ = self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}}) + } + + return nil + }) +} + +func (self *BranchesController) handleCreateResetToBranchMenu(selectedBranch *models.Branch) error { + return self.helpers.Refs.CreateGitResetMenu(selectedBranch.Name) +} + +func (self *BranchesController) handleRenameBranch(branch *models.Branch) error { + promptForNewName := func() error { + return self.c.Prompt(types.PromptOpts{ + Title: self.c.Tr.NewBranchNamePrompt + " " + branch.Name + ":", + InitialContent: branch.Name, + HandleConfirm: func(newBranchName string) error { + self.c.LogAction(self.c.Tr.Actions.RenameBranch) + if err := self.git.Branch.Rename(branch.Name, newBranchName); err != nil { + return self.c.Error(err) + } + + // need to find where the branch is now so that we can re-select it. That means we need to refetch the branches synchronously and then find our branch + _ = self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.BRANCHES}}) + + // now that we've got our stuff again we need to find that branch and reselect it. + for i, newBranch := range self.model.Branches { + if newBranch.Name == newBranchName { + self.context().SetSelectedLineIdx(i) + if err := self.context().HandleRender(); err != nil { + return err + } + } + } + + return nil + }, + }) + } + + // I could do an explicit check here for whether the branch is tracking a remote branch + // but if we've selected it we'll already know that via Pullables and Pullables. + // Bit of a hack but I'm lazy. + if !branch.IsTrackingRemote() { + return promptForNewName() + } + + return self.c.Ask(types.AskOpts{ + Title: self.c.Tr.LcRenameBranch, + Prompt: self.c.Tr.RenameBranchWarning, + HandleConfirm: promptForNewName, + }) +} + +func (self *BranchesController) handleNewBranchOffBranch(selectedBranch *models.Branch) error { + return self.helpers.Refs.NewBranch(selectedBranch.RefName(), selectedBranch.RefName(), "") +} + +func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Branch, checkedOutBranch *models.Branch) error { + menuItems := make([]*types.MenuItem, 0, 4) + + fromToDisplayStrings := func(from string, to string) []string { + return []string{fmt.Sprintf("%s → %s", from, to)} + } + + menuItemsForBranch := func(branch *models.Branch) []*types.MenuItem { + return []*types.MenuItem{ + { + DisplayStrings: fromToDisplayStrings(branch.Name, self.c.Tr.LcDefaultBranch), + OnPress: func() error { + return self.createPullRequest(branch.Name, "") + }, + }, + { + DisplayStrings: fromToDisplayStrings(branch.Name, self.c.Tr.LcSelectBranch), + OnPress: func() error { + return self.c.Prompt(types.PromptOpts{ + Title: branch.Name + " →", + FindSuggestionsFunc: self.helpers.Suggestions.GetBranchNameSuggestionsFunc(), + HandleConfirm: func(targetBranchName string) error { + return self.createPullRequest(branch.Name, targetBranchName) + }}, + ) + }, + }, + } + } + + if selectedBranch != checkedOutBranch { + menuItems = append(menuItems, + &types.MenuItem{ + DisplayStrings: fromToDisplayStrings(checkedOutBranch.Name, selectedBranch.Name), + OnPress: func() error { + return self.createPullRequest(checkedOutBranch.Name, selectedBranch.Name) + }, + }, + ) + menuItems = append(menuItems, menuItemsForBranch(checkedOutBranch)...) + } + + menuItems = append(menuItems, menuItemsForBranch(selectedBranch)...) + + return self.c.Menu(types.CreateMenuOptions{Title: fmt.Sprintf(self.c.Tr.CreatePullRequestOptions), Items: menuItems}) +} + +func (self *BranchesController) createPullRequest(from string, to string) error { + url, err := self.helpers.Host.GetPullRequestURL(from, to) + if err != nil { + return self.c.Error(err) + } + + self.c.LogAction(self.c.Tr.Actions.OpenPullRequest) + + if err := self.os.OpenLink(url); err != nil { + return self.c.Error(err) + } + + return nil +} + +func (self *BranchesController) checkSelected(callback func(*models.Branch) error) func() error { + return func() error { + selectedItem := self.context().GetSelected() + if selectedItem == nil { + return nil + } + + return callback(selectedItem) + } +} + +func (self *BranchesController) checkSelectedAndReal(callback func(*models.Branch) error) func() error { + return func() error { + selectedItem := self.context().GetSelected() + if selectedItem == nil || !selectedItem.IsRealBranch() { + return nil + } + + return callback(selectedItem) + } +} diff --git a/pkg/gui/controllers/common.go b/pkg/gui/controllers/common.go new file mode 100644 index 000000000..55ba4b176 --- /dev/null +++ b/pkg/gui/controllers/common.go @@ -0,0 +1,39 @@ +package controllers + +import ( + "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" + "github.com/jesseduffield/lazygit/pkg/gui/context" + "github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers" + "github.com/jesseduffield/lazygit/pkg/gui/types" +) + +type controllerCommon struct { + c *types.HelperCommon + os *oscommands.OSCommand + git *commands.GitCommand + helpers *helpers.Helpers + model *types.Model + contexts *context.ContextTree + modes *types.Modes +} + +func NewControllerCommon( + c *types.HelperCommon, + os *oscommands.OSCommand, + git *commands.GitCommand, + helpers *helpers.Helpers, + model *types.Model, + contexts *context.ContextTree, + modes *types.Modes, +) *controllerCommon { + return &controllerCommon{ + c: c, + os: os, + git: git, + helpers: helpers, + model: model, + contexts: contexts, + modes: modes, + } +} diff --git a/pkg/gui/controllers/files_controller.go b/pkg/gui/controllers/files_controller.go index de085607d..6868586e6 100644 --- a/pkg/gui/controllers/files_controller.go +++ b/pkg/gui/controllers/files_controller.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/jesseduffield/gocui" - "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/config" @@ -17,73 +17,33 @@ import ( ) type FilesController struct { - // I've said publicly that I'm against single-letter variable names but in this - // case I would actually prefer a _zero_ letter variable name in the form of - // struct embedding, but Go does not allow hiding public fields in an embedded struct - // to the client - c *types.ControllerCommon - context *context.WorkingTreeContext - model *types.Model - git *commands.GitCommand - os *oscommands.OSCommand + baseController + *controllerCommon - getSelectedFileNode func() *filetree.FileNode - contexts *context.ContextTree enterSubmodule func(submodule *models.SubmoduleConfig) error - getSubmodules func() []*models.SubmoduleConfig setCommitMessage func(message string) - getCheckedOutBranch func() *models.Branch withGpgHandling func(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error getFailedCommitMessage func() string - getSelectedPath func() string switchToMergeFn func(path string) error - suggestionsHelper ISuggestionsHelper - refsHelper IRefsHelper - filesHelper IFilesHelper - workingTreeHelper IWorkingTreeHelper } var _ types.IController = &FilesController{} func NewFilesController( - c *types.ControllerCommon, - context *context.WorkingTreeContext, - model *types.Model, - git *commands.GitCommand, - os *oscommands.OSCommand, - getSelectedFileNode func() *filetree.FileNode, - allContexts *context.ContextTree, + common *controllerCommon, enterSubmodule func(submodule *models.SubmoduleConfig) error, - getSubmodules func() []*models.SubmoduleConfig, setCommitMessage func(message string), withGpgHandling func(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error, getFailedCommitMessage func() string, - getSelectedPath func() string, switchToMergeFn func(path string) error, - suggestionsHelper ISuggestionsHelper, - refsHelper IRefsHelper, - filesHelper IFilesHelper, - workingTreeHelper IWorkingTreeHelper, ) *FilesController { return &FilesController{ - c: c, - context: context, - model: model, - git: git, - os: os, - getSelectedFileNode: getSelectedFileNode, - contexts: allContexts, + controllerCommon: common, enterSubmodule: enterSubmodule, - getSubmodules: getSubmodules, setCommitMessage: setCommitMessage, withGpgHandling: withGpgHandling, getFailedCommitMessage: getFailedCommitMessage, - getSelectedPath: getSelectedPath, switchToMergeFn: switchToMergeFn, - suggestionsHelper: suggestionsHelper, - refsHelper: refsHelper, - filesHelper: filesHelper, - workingTreeHelper: workingTreeHelper, } } @@ -96,7 +56,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types }, // { // Key: gocui.MouseLeft, - // Handler: func() error { return self.context.HandleClick(self.checkSelectedFileNode(self.press)) }, + // Handler: func() error { return self.context().HandleClick(self.checkSelectedFileNode(self.press)) }, // }, { Key: opts.GetKey(""), // TODO: softcode @@ -187,6 +147,11 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types Handler: self.OpenMergeTool, Description: self.c.Tr.LcOpenMergeTool, }, + { + Key: opts.GetKey(opts.Config.Files.Fetch), + Handler: self.fetch, + Description: self.c.Tr.LcFetch, + }, } } @@ -249,12 +214,12 @@ func (self *FilesController) press(node *filetree.FileNode) error { return err } - return self.context.HandleFocus() + return self.context().HandleFocus() } func (self *FilesController) checkSelectedFileNode(callback func(*filetree.FileNode) error) func() error { return func() error { - node := self.getSelectedFileNode() + node := self.context().GetSelectedFileNode() if node == nil { return nil } @@ -264,11 +229,15 @@ func (self *FilesController) checkSelectedFileNode(callback func(*filetree.FileN } func (self *FilesController) Context() types.Context { - return self.context + return self.context() +} + +func (self *FilesController) context() *context.WorkingTreeContext { + return self.contexts.Files } func (self *FilesController) getSelectedFile() *models.File { - node := self.getSelectedFileNode() + node := self.context().GetSelectedFileNode() if node == nil { return nil } @@ -280,7 +249,7 @@ func (self *FilesController) enter() error { } func (self *FilesController) EnterFile(opts types.OnFocusOpts) error { - node := self.getSelectedFileNode() + node := self.context().GetSelectedFileNode() if node == nil { return nil } @@ -291,7 +260,7 @@ func (self *FilesController) EnterFile(opts types.OnFocusOpts) error { file := node.File - submoduleConfigs := self.getSubmodules() + submoduleConfigs := self.model.Submodules if file.IsSubmodule(submoduleConfigs) { submoduleConfig := file.SubmoduleConfig(submoduleConfigs) return self.enterSubmodule(submoduleConfig) @@ -410,7 +379,7 @@ func (self *FilesController) commitPrefixConfigForRepo() *config.CommitPrefixCon } func (self *FilesController) prepareFilesForCommit() error { - noStagedFiles := !self.workingTreeHelper.AnyStagedFiles() + noStagedFiles := !self.helpers.WorkingTree.AnyStagedFiles() if noStagedFiles && self.c.UserConfig.Gui.SkipNoStagedFilesWarning { self.c.LogAction(self.c.Tr.Actions.StageAllFiles) err := self.git.WorkingTree.StageAll() @@ -442,7 +411,7 @@ func (self *FilesController) HandleCommitPress() error { return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) } - if !self.workingTreeHelper.AnyStagedFiles() { + if !self.helpers.WorkingTree.AnyStagedFiles() { return self.promptToStageAllAndRetry(self.HandleCommitPress) } @@ -458,7 +427,7 @@ func (self *FilesController) HandleCommitPress() error { if err != nil { return self.c.ErrorMsg(fmt.Sprintf("%s: %s", self.c.Tr.LcCommitPrefixPatternError, err.Error())) } - prefix := rgx.ReplaceAllString(self.getCheckedOutBranch().Name, prefixReplace) + prefix := rgx.ReplaceAllString(self.helpers.Refs.GetCheckedOutRef().Name, prefixReplace) self.setCommitMessage(prefix) } } @@ -493,7 +462,7 @@ func (self *FilesController) handleAmendCommitPress() error { return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) } - if !self.workingTreeHelper.AnyStagedFiles() { + if !self.helpers.WorkingTree.AnyStagedFiles() { return self.promptToStageAllAndRetry(self.handleAmendCommitPress) } @@ -519,7 +488,7 @@ func (self *FilesController) HandleCommitEditorPress() error { return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) } - if !self.workingTreeHelper.AnyStagedFiles() { + if !self.helpers.WorkingTree.AnyStagedFiles() { return self.promptToStageAllAndRetry(self.HandleCommitEditorPress) } @@ -556,8 +525,8 @@ func (self *FilesController) handleStatusFilterPressed() error { } func (self *FilesController) setStatusFiltering(filter filetree.FileTreeDisplayFilter) error { - self.context.FileTreeViewModel.SetFilter(filter) - return self.c.PostRefreshUpdate(self.context) + self.context().FileTreeViewModel.SetFilter(filter) + return self.c.PostRefreshUpdate(self.context()) } func (self *FilesController) edit(node *filetree.FileNode) error { @@ -565,16 +534,16 @@ func (self *FilesController) edit(node *filetree.FileNode) error { return self.c.ErrorMsg(self.c.Tr.ErrCannotEditDirectory) } - return self.filesHelper.EditFile(node.GetPath()) + return self.helpers.Files.EditFile(node.GetPath()) } func (self *FilesController) Open() error { - node := self.getSelectedFileNode() + node := self.context().GetSelectedFileNode() if node == nil { return nil } - return self.filesHelper.OpenFile(node.GetPath()) + return self.helpers.Files.OpenFile(node.GetPath()) } func (self *FilesController) switchToMerge() error { @@ -613,16 +582,16 @@ func (self *FilesController) stash() error { } func (self *FilesController) createResetMenu() error { - return self.refsHelper.CreateGitResetMenu("@{upstream}") + return self.helpers.Refs.CreateGitResetMenu("@{upstream}") } func (self *FilesController) handleToggleDirCollapsed() error { - node := self.getSelectedFileNode() + node := self.context().GetSelectedFileNode() if node == nil { return nil } - self.context.FileTreeViewModel.ToggleCollapsed(node.GetPath()) + self.context().FileTreeViewModel.ToggleCollapsed(node.GetPath()) if err := self.c.PostRefreshUpdate(self.contexts.Files); err != nil { self.c.Log.Error(err) @@ -632,9 +601,9 @@ func (self *FilesController) handleToggleDirCollapsed() error { } func (self *FilesController) toggleTreeView() error { - self.context.FileTreeViewModel.ToggleShowTree() + self.context().FileTreeViewModel.ToggleShowTree() - return self.c.PostRefreshUpdate(self.context) + return self.c.PostRefreshUpdate(self.context()) } func (self *FilesController) OpenMergeTool() error { @@ -654,7 +623,7 @@ func (self *FilesController) ResetSubmodule(submodule *models.SubmoduleConfig) e return self.c.WithWaitingStatus(self.c.Tr.LcResettingSubmoduleStatus, func() error { self.c.LogAction(self.c.Tr.Actions.ResetSubmodule) - file := self.workingTreeHelper.FileForSubmodule(submodule) + file := self.helpers.WorkingTree.FileForSubmodule(submodule) if file != nil { if err := self.git.WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil { return self.c.Error(err) @@ -673,7 +642,7 @@ func (self *FilesController) ResetSubmodule(submodule *models.SubmoduleConfig) e } func (self *FilesController) handleStashSave(stashFunc func(message string) error) error { - if !self.workingTreeHelper.IsWorkingTreeDirty() { + if !self.helpers.WorkingTree.IsWorkingTreeDirty() { return self.c.ErrorMsg(self.c.Tr.NoTrackedStagedFilesStash) } @@ -697,3 +666,25 @@ func (self *FilesController) onClickSecondary(opts gocui.ViewMouseBindingOpts) e clickedViewLineIdx := opts.Cy + opts.Oy return self.EnterFile(types.OnFocusOpts{ClickedViewName: "secondary", ClickedViewLineIdx: clickedViewLineIdx}) } + +func (self *FilesController) fetch() error { + return self.c.WithLoaderPanel(self.c.Tr.FetchWait, func() error { + if err := self.fetchAux(); err != nil { + _ = self.c.Error(err) + } + return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) + }) +} + +func (self *FilesController) fetchAux() (err error) { + self.c.LogAction("Fetch") + err = self.git.Sync.Fetch(git_commands.FetchOptions{}) + + if err != nil && strings.Contains(err.Error(), "exit status 128") { + _ = self.c.ErrorMsg(self.c.Tr.PassUnameWrong) + } + + _ = self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.BRANCHES, types.COMMITS, types.REMOTES, types.TAGS}, Mode: types.ASYNC}) + + return err +} diff --git a/pkg/gui/controllers/files_controller_remove.go b/pkg/gui/controllers/files_controller_remove.go index 42d1df8b0..cdebf8914 100644 --- a/pkg/gui/controllers/files_controller_remove.go +++ b/pkg/gui/controllers/files_controller_remove.go @@ -39,7 +39,7 @@ func (self *FilesController) remove(node *filetree.FileNode) error { } else { file := node.File - submodules := self.getSubmodules() + submodules := self.model.Submodules if file.IsSubmodule(submodules) { submodule := file.SubmoduleConfig(submodules) diff --git a/pkg/gui/controllers/global_controller.go b/pkg/gui/controllers/global_controller.go index dd0c8ea3b..487c1e10b 100644 --- a/pkg/gui/controllers/global_controller.go +++ b/pkg/gui/controllers/global_controller.go @@ -1,26 +1,22 @@ package controllers import ( - "github.com/jesseduffield/lazygit/pkg/commands/oscommands" + "github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" ) type GlobalController struct { baseController - - c *types.ControllerCommon - os *oscommands.OSCommand + *controllerCommon } func NewGlobalController( - c *types.ControllerCommon, - os *oscommands.OSCommand, + common *controllerCommon, ) *GlobalController { return &GlobalController{ - baseController: baseController{}, - c: c, - os: os, + baseController: baseController{}, + controllerCommon: common, } } @@ -63,7 +59,7 @@ func (self *GlobalController) GetCustomCommandsHistorySuggestionsFunc() func(str // reversing so that we display the latest command first history := utils.Reverse(self.c.GetAppState().CustomCommandsHistory) - return FuzzySearchFunc(history) + return helpers.FuzzySearchFunc(history) } func (self *GlobalController) Context() types.Context { diff --git a/pkg/gui/controllers/bisect_helper.go b/pkg/gui/controllers/helpers/bisect_helper.go similarity index 91% rename from pkg/gui/controllers/bisect_helper.go rename to pkg/gui/controllers/helpers/bisect_helper.go index 357407fb6..401d01b0c 100644 --- a/pkg/gui/controllers/bisect_helper.go +++ b/pkg/gui/controllers/helpers/bisect_helper.go @@ -1,4 +1,4 @@ -package controllers +package helpers import ( "github.com/jesseduffield/lazygit/pkg/commands" @@ -6,12 +6,12 @@ import ( ) type BisectHelper struct { - c *types.ControllerCommon + c *types.HelperCommon git *commands.GitCommand } func NewBisectHelper( - c *types.ControllerCommon, + c *types.HelperCommon, git *commands.GitCommand, ) *BisectHelper { return &BisectHelper{ diff --git a/pkg/gui/controllers/cherry_pick_helper.go b/pkg/gui/controllers/helpers/cherry_pick_helper.go similarity index 96% rename from pkg/gui/controllers/cherry_pick_helper.go rename to pkg/gui/controllers/helpers/cherry_pick_helper.go index 1f6665224..a0fd4ebca 100644 --- a/pkg/gui/controllers/cherry_pick_helper.go +++ b/pkg/gui/controllers/helpers/cherry_pick_helper.go @@ -1,4 +1,4 @@ -package controllers +package helpers import ( "github.com/jesseduffield/lazygit/pkg/commands" @@ -9,25 +9,25 @@ import ( ) type CherryPickHelper struct { - c *types.ControllerCommon + c *types.HelperCommon git *commands.GitCommand contexts *context.ContextTree getData func() *cherrypicking.CherryPicking - rebaseHelper *RebaseHelper + rebaseHelper *MergeAndRebaseHelper } // I'm using the analogy of copy+paste in the terminology here because it's intuitively what's going on, // even if in truth we're running git cherry-pick func NewCherryPickHelper( - c *types.ControllerCommon, + c *types.HelperCommon, git *commands.GitCommand, contexts *context.ContextTree, getData func() *cherrypicking.CherryPicking, - rebaseHelper *RebaseHelper, + rebaseHelper *MergeAndRebaseHelper, ) *CherryPickHelper { return &CherryPickHelper{ c: c, diff --git a/pkg/gui/controllers/files_helper.go b/pkg/gui/controllers/helpers/files_helper.go similarity index 94% rename from pkg/gui/controllers/files_helper.go rename to pkg/gui/controllers/helpers/files_helper.go index 35f388183..72be6e4e5 100644 --- a/pkg/gui/controllers/files_helper.go +++ b/pkg/gui/controllers/helpers/files_helper.go @@ -1,4 +1,4 @@ -package controllers +package helpers import ( "github.com/jesseduffield/lazygit/pkg/commands" @@ -14,13 +14,13 @@ type IFilesHelper interface { } type FilesHelper struct { - c *types.ControllerCommon + c *types.HelperCommon git *commands.GitCommand os *oscommands.OSCommand } func NewFilesHelper( - c *types.ControllerCommon, + c *types.HelperCommon, git *commands.GitCommand, os *oscommands.OSCommand, ) *FilesHelper { diff --git a/pkg/gui/controllers/helpers/helpers.go b/pkg/gui/controllers/helpers/helpers.go new file mode 100644 index 000000000..65f686ade --- /dev/null +++ b/pkg/gui/controllers/helpers/helpers.go @@ -0,0 +1,13 @@ +package helpers + +type Helpers struct { + Refs *RefsHelper + Bisect *BisectHelper + Suggestions *SuggestionsHelper + Files *FilesHelper + WorkingTree *WorkingTreeHelper + Tags *TagsHelper + MergeAndRebase *MergeAndRebaseHelper + CherryPick *CherryPickHelper + Host *HostHelper +} diff --git a/pkg/gui/controllers/helpers/host_helper.go b/pkg/gui/controllers/helpers/host_helper.go new file mode 100644 index 000000000..edc0bc7ba --- /dev/null +++ b/pkg/gui/controllers/helpers/host_helper.go @@ -0,0 +1,46 @@ +package helpers + +import ( + "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/hosting_service" + "github.com/jesseduffield/lazygit/pkg/gui/types" +) + +// this helper just wraps our hosting_service package + +type IHostHelper interface { + GetPullRequestURL(from string, to string) (string, error) + GetCommitURL(commitSha string) (string, error) +} + +type HostHelper struct { + c *types.HelperCommon + git *commands.GitCommand +} + +func NewHostHelper( + c *types.HelperCommon, + git *commands.GitCommand, +) *HostHelper { + return &HostHelper{ + c: c, + git: git, + } +} + +func (self *HostHelper) GetPullRequestURL(from string, to string) (string, error) { + return self.getHostingServiceMgr().GetPullRequestURL(from, to) +} + +func (self *HostHelper) GetCommitURL(commitSha string) (string, error) { + return self.getHostingServiceMgr().GetCommitURL(commitSha) +} + +// getting this on every request rather than storing it in state in case our remoteURL changes +// from one invocation to the next. Note however that we're currently caching config +// results so we might want to invalidate the cache here if it becomes a problem. +func (self *HostHelper) getHostingServiceMgr() *hosting_service.HostingServiceMgr { + remoteUrl := self.git.Config.GetRemoteURL() + configServices := self.c.UserConfig.Services + return hosting_service.NewHostingServiceMgr(self.c.Log, self.c.Tr, remoteUrl, configServices) +} diff --git a/pkg/gui/controllers/rebase_helper.go b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go similarity index 67% rename from pkg/gui/controllers/rebase_helper.go rename to pkg/gui/controllers/helpers/merge_and_rebase_helper.go index 036af31e0..477c5c64f 100644 --- a/pkg/gui/controllers/rebase_helper.go +++ b/pkg/gui/controllers/helpers/merge_and_rebase_helper.go @@ -1,33 +1,38 @@ -package controllers +package helpers import ( "fmt" "strings" "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/types/enums" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/utils" ) -type RebaseHelper struct { - c *types.ControllerCommon +type MergeAndRebaseHelper struct { + c *types.HelperCommon contexts *context.ContextTree git *commands.GitCommand takeOverMergeConflictScrolling func() + refsHelper *RefsHelper } -func NewRebaseHelper( - c *types.ControllerCommon, +func NewMergeAndRebaseHelper( + c *types.HelperCommon, contexts *context.ContextTree, git *commands.GitCommand, takeOverMergeConflictScrolling func(), -) *RebaseHelper { - return &RebaseHelper{ + refsHelper *RefsHelper, +) *MergeAndRebaseHelper { + return &MergeAndRebaseHelper{ c: c, contexts: contexts, git: git, takeOverMergeConflictScrolling: takeOverMergeConflictScrolling, + refsHelper: refsHelper, } } @@ -39,7 +44,7 @@ const ( REBASE_OPTION_SKIP string = "skip" ) -func (self *RebaseHelper) CreateRebaseOptionsMenu() error { +func (self *MergeAndRebaseHelper) CreateRebaseOptionsMenu() error { options := []string{REBASE_OPTION_CONTINUE, REBASE_OPTION_ABORT} if self.git.Status.WorkingTreeState() == enums.REBASE_MODE_REBASING { @@ -68,7 +73,7 @@ func (self *RebaseHelper) CreateRebaseOptionsMenu() error { return self.c.Menu(types.CreateMenuOptions{Title: title, Items: menuItems}) } -func (self *RebaseHelper) genericMergeCommand(command string) error { +func (self *MergeAndRebaseHelper) genericMergeCommand(command string) error { status := self.git.Status.WorkingTreeState() if status != enums.REBASE_MODE_MERGING && status != enums.REBASE_MODE_REBASING { @@ -120,7 +125,7 @@ func isMergeConflictErr(errStr string) bool { return false } -func (self *RebaseHelper) CheckMergeOrRebase(result error) error { +func (self *MergeAndRebaseHelper) CheckMergeOrRebase(result error) error { if err := self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}); err != nil { return err } @@ -154,7 +159,7 @@ func (self *RebaseHelper) CheckMergeOrRebase(result error) error { } } -func (self *RebaseHelper) AbortMergeOrRebaseWithConfirm() error { +func (self *MergeAndRebaseHelper) AbortMergeOrRebaseWithConfirm() error { // prompt user to confirm that they want to abort, then do it mode := self.workingTreeStateNoun() return self.c.Ask(types.AskOpts{ @@ -166,7 +171,7 @@ func (self *RebaseHelper) AbortMergeOrRebaseWithConfirm() error { }) } -func (self *RebaseHelper) workingTreeStateNoun() string { +func (self *MergeAndRebaseHelper) workingTreeStateNoun() string { workingTreeState := self.git.Status.WorkingTreeState() switch workingTreeState { case enums.REBASE_MODE_NONE: @@ -179,7 +184,7 @@ func (self *RebaseHelper) workingTreeStateNoun() string { } // PromptToContinueRebase asks the user if they want to continue the rebase/merge that's in progress -func (self *RebaseHelper) PromptToContinueRebase() error { +func (self *MergeAndRebaseHelper) PromptToContinueRebase() error { self.takeOverMergeConflictScrolling() return self.c.Ask(types.AskOpts{ @@ -190,3 +195,54 @@ func (self *RebaseHelper) PromptToContinueRebase() error { }, }) } + +func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error { + checkedOutBranch := self.refsHelper.GetCheckedOutRef().Name + if ref == checkedOutBranch { + return self.c.ErrorMsg(self.c.Tr.CantRebaseOntoSelf) + } + prompt := utils.ResolvePlaceholderString( + self.c.Tr.ConfirmRebase, + map[string]string{ + "checkedOutBranch": checkedOutBranch, + "selectedBranch": ref, + }, + ) + + return self.c.Ask(types.AskOpts{ + Title: self.c.Tr.RebasingTitle, + Prompt: prompt, + HandleConfirm: func() error { + self.c.LogAction(self.c.Tr.Actions.RebaseBranch) + err := self.git.Rebase.RebaseBranch(ref) + return self.CheckMergeOrRebase(err) + }, + }) +} + +func (self *MergeAndRebaseHelper) MergeRefIntoCheckedOutBranch(refName string) error { + if self.git.Branch.IsHeadDetached() { + return self.c.ErrorMsg("Cannot merge branch in detached head state. You might have checked out a commit directly or a remote branch, in which case you should checkout the local branch you want to be on") + } + checkedOutBranchName := self.refsHelper.GetCheckedOutRef().Name + if checkedOutBranchName == refName { + return self.c.ErrorMsg(self.c.Tr.CantMergeBranchIntoItself) + } + prompt := utils.ResolvePlaceholderString( + self.c.Tr.ConfirmMerge, + map[string]string{ + "checkedOutBranch": checkedOutBranchName, + "selectedBranch": refName, + }, + ) + + return self.c.Ask(types.AskOpts{ + Title: self.c.Tr.MergingTitle, + Prompt: prompt, + HandleConfirm: func() error { + self.c.LogAction(self.c.Tr.Actions.Merge) + err := self.git.Branch.Merge(refName, git_commands.MergeOpts{}) + return self.CheckMergeOrRebase(err) + }, + }) +} diff --git a/pkg/gui/controllers/refs_helper.go b/pkg/gui/controllers/helpers/refs_helper.go similarity index 93% rename from pkg/gui/controllers/refs_helper.go rename to pkg/gui/controllers/helpers/refs_helper.go index e6d9babfb..3b132a32f 100644 --- a/pkg/gui/controllers/refs_helper.go +++ b/pkg/gui/controllers/helpers/refs_helper.go @@ -1,4 +1,4 @@ -package controllers +package helpers import ( "fmt" @@ -6,6 +6,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" + "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/types" @@ -14,26 +15,30 @@ import ( type IRefsHelper interface { CheckoutRef(ref string, options types.CheckoutRefOptions) error + GetCheckedOutRef() *models.Branch CreateGitResetMenu(ref string) error ResetToRef(ref string, strength string, envVars []string) error NewBranch(from string, fromDescription string, suggestedBranchname string) error } type RefsHelper struct { - c *types.ControllerCommon + c *types.HelperCommon git *commands.GitCommand contexts *context.ContextTree + model *types.Model } func NewRefsHelper( - c *types.ControllerCommon, + c *types.HelperCommon, git *commands.GitCommand, contexts *context.ContextTree, + model *types.Model, ) *RefsHelper { return &RefsHelper{ c: c, git: git, contexts: contexts, + model: model, } } @@ -99,6 +104,14 @@ func (self *RefsHelper) CheckoutRef(ref string, options types.CheckoutRefOptions }) } +func (self *RefsHelper) GetCheckedOutRef() *models.Branch { + if len(self.model.Branches) == 0 { + return nil + } + + return self.model.Branches[0] +} + func (self *RefsHelper) ResetToRef(ref string, strength string, envVars []string) error { if err := self.git.Commit.ResetToCommit(ref, strength, envVars); err != nil { return self.c.Error(err) diff --git a/pkg/gui/controllers/suggestions_helper.go b/pkg/gui/controllers/helpers/suggestions_helper.go similarity index 98% rename from pkg/gui/controllers/suggestions_helper.go rename to pkg/gui/controllers/helpers/suggestions_helper.go index e696fdd8e..a48e325b1 100644 --- a/pkg/gui/controllers/suggestions_helper.go +++ b/pkg/gui/controllers/helpers/suggestions_helper.go @@ -1,4 +1,4 @@ -package controllers +package helpers import ( "fmt" @@ -30,7 +30,7 @@ type ISuggestionsHelper interface { } type SuggestionsHelper struct { - c *types.ControllerCommon + c *types.HelperCommon model *types.Model refreshSuggestionsFn func() @@ -39,7 +39,7 @@ type SuggestionsHelper struct { var _ ISuggestionsHelper = &SuggestionsHelper{} func NewSuggestionsHelper( - c *types.ControllerCommon, + c *types.HelperCommon, model *types.Model, refreshSuggestionsFn func(), ) *SuggestionsHelper { diff --git a/pkg/gui/controllers/tags_helper.go b/pkg/gui/controllers/helpers/tags_helper.go similarity index 94% rename from pkg/gui/controllers/tags_helper.go rename to pkg/gui/controllers/helpers/tags_helper.go index 6cec4fe4d..d2e92cd24 100644 --- a/pkg/gui/controllers/tags_helper.go +++ b/pkg/gui/controllers/helpers/tags_helper.go @@ -1,4 +1,4 @@ -package controllers +package helpers import ( "github.com/jesseduffield/lazygit/pkg/commands" @@ -10,11 +10,11 @@ import ( // and the commits context. type TagsHelper struct { - c *types.ControllerCommon + c *types.HelperCommon git *commands.GitCommand } -func NewTagsHelper(c *types.ControllerCommon, git *commands.GitCommand) *TagsHelper { +func NewTagsHelper(c *types.HelperCommon, git *commands.GitCommand) *TagsHelper { return &TagsHelper{ c: c, git: git, diff --git a/pkg/gui/controllers/working_tree_helper.go b/pkg/gui/controllers/helpers/working_tree_helper.go similarity index 98% rename from pkg/gui/controllers/working_tree_helper.go rename to pkg/gui/controllers/helpers/working_tree_helper.go index 894d278be..273748d6b 100644 --- a/pkg/gui/controllers/working_tree_helper.go +++ b/pkg/gui/controllers/helpers/working_tree_helper.go @@ -1,4 +1,4 @@ -package controllers +package helpers import ( "github.com/jesseduffield/lazygit/pkg/commands/models" diff --git a/pkg/gui/controllers/list_controller.go b/pkg/gui/controllers/list_controller.go index 8473fad83..5b1d2e04a 100644 --- a/pkg/gui/controllers/list_controller.go +++ b/pkg/gui/controllers/list_controller.go @@ -6,10 +6,10 @@ import ( ) type ListControllerFactory struct { - c *types.ControllerCommon + c *types.HelperCommon } -func NewListControllerFactory(c *types.ControllerCommon) *ListControllerFactory { +func NewListControllerFactory(c *types.HelperCommon) *ListControllerFactory { return &ListControllerFactory{ c: c, } @@ -25,7 +25,7 @@ func (self *ListControllerFactory) Create(context types.IListContext) *ListContr type ListController struct { baseController - c *types.ControllerCommon + c *types.HelperCommon context types.IListContext } diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index bb06a2314..0a7d51ae6 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -4,80 +4,37 @@ import ( "fmt" "github.com/jesseduffield/gocui" - "github.com/jesseduffield/lazygit/pkg/commands" - "github.com/jesseduffield/lazygit/pkg/commands/hosting_service" "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" ) type ( - CheckoutRefFn func(refName string, opts types.CheckoutRefOptions) error - CreateGitResetMenuFn func(refName string) error SwitchToCommitFilesContextFn func(SwitchToCommitFilesContextOpts) error - GetHostingServiceMgrFn func() *hosting_service.HostingServiceMgr PullFilesFn func() error - CheckMergeOrRebase func(error) error ) type LocalCommitsController struct { baseController - c *types.ControllerCommon - context *context.LocalCommitsContext - os *oscommands.OSCommand - git *commands.GitCommand - tagsHelper *TagsHelper - refsHelper IRefsHelper - cherryPickHelper *CherryPickHelper - rebaseHelper *RebaseHelper + *controllerCommon - model *types.Model - CheckMergeOrRebase CheckMergeOrRebase pullFiles PullFilesFn - getHostingServiceMgr GetHostingServiceMgrFn switchToCommitFilesContext SwitchToCommitFilesContextFn - getShowWholeGitGraph func() bool - setShowWholeGitGraph func(bool) } var _ types.IController = &LocalCommitsController{} func NewLocalCommitsController( - c *types.ControllerCommon, - context *context.LocalCommitsContext, - os *oscommands.OSCommand, - git *commands.GitCommand, - tagsHelper *TagsHelper, - refsHelper IRefsHelper, - cherryPickHelper *CherryPickHelper, - rebaseHelper *RebaseHelper, - model *types.Model, - CheckMergeOrRebase CheckMergeOrRebase, + common *controllerCommon, pullFiles PullFilesFn, - getHostingServiceMgr GetHostingServiceMgrFn, switchToCommitFilesContext SwitchToCommitFilesContextFn, - getShowWholeGitGraph func() bool, - setShowWholeGitGraph func(bool), ) *LocalCommitsController { return &LocalCommitsController{ baseController: baseController{}, - c: c, - context: context, - os: os, - git: git, - tagsHelper: tagsHelper, - refsHelper: refsHelper, - cherryPickHelper: cherryPickHelper, - rebaseHelper: rebaseHelper, - model: model, - CheckMergeOrRebase: CheckMergeOrRebase, + controllerCommon: common, pullFiles: pullFiles, - getHostingServiceMgr: getHostingServiceMgr, switchToCommitFilesContext: switchToCommitFilesContext, - getShowWholeGitGraph: getShowWholeGitGraph, - setShowWholeGitGraph: setShowWholeGitGraph, } } @@ -185,7 +142,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [ }, // { // Key: gocui.MouseLeft, - // Handler: func() error { return self.context.HandleClick(self.checkSelected(self.enter)) }, + // Handler: func() error { return self.context().HandleClick(self.checkSelected(self.enter)) }, // }, } @@ -305,7 +262,7 @@ func (self *LocalCommitsController) reword(commit *models.Commit) error { InitialContent: message, HandleConfirm: func(response string) error { self.c.LogAction(self.c.Tr.Actions.RewordCommit) - if err := self.git.Rebase.RewordCommit(self.model.Commits, self.context.GetSelectedLineIdx(), response); err != nil { + if err := self.git.Rebase.RewordCommit(self.model.Commits, self.context().GetSelectedLineIdx(), response); err != nil { return self.c.Error(err) } @@ -325,7 +282,7 @@ func (self *LocalCommitsController) rewordEditor() error { self.c.LogAction(self.c.Tr.Actions.RewordCommit) subProcess, err := self.git.Rebase.RewordCommitInEditor( - self.model.Commits, self.context.GetSelectedLineIdx(), + self.model.Commits, self.context().GetSelectedLineIdx(), ) if err != nil { return self.c.Error(err) @@ -388,15 +345,15 @@ func (self *LocalCommitsController) pick() error { } func (self *LocalCommitsController) interactiveRebase(action string) error { - err := self.git.Rebase.InteractiveRebase(self.model.Commits, self.context.GetSelectedLineIdx(), action) - return self.CheckMergeOrRebase(err) + err := self.git.Rebase.InteractiveRebase(self.model.Commits, self.context().GetSelectedLineIdx(), action) + return self.helpers.MergeAndRebase.CheckMergeOrRebase(err) } // handleMidRebaseCommand sees if the selected commit is in fact a rebasing // commit meaning you are trying to edit the todo file rather than actually // begin a rebase. It then updates the todo file with that action func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool, error) { - selectedCommit := self.context.GetSelected() + selectedCommit := self.context().GetSelected() if selectedCommit.Status != "rebasing" { return false, nil } @@ -416,7 +373,7 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool, ) if err := self.git.Rebase.EditRebaseTodo( - self.context.GetSelectedLineIdx(), action, + self.context().GetSelectedLineIdx(), action, ); err != nil { return false, self.c.Error(err) } @@ -427,7 +384,7 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool, } func (self *LocalCommitsController) handleCommitMoveDown() error { - index := self.context.GetSelectedLineIdx() + index := self.context().GetSelectedLineIdx() commits := self.model.Commits selectedCommit := self.model.Commits[index] if selectedCommit.Status == "rebasing" { @@ -443,7 +400,7 @@ func (self *LocalCommitsController) handleCommitMoveDown() error { if err := self.git.Rebase.MoveTodoDown(index); err != nil { return self.c.Error(err) } - self.context.MoveSelectedLine(1) + self.context().MoveSelectedLine(1) return self.c.Refresh(types.RefreshOptions{ Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS}, }) @@ -453,14 +410,14 @@ func (self *LocalCommitsController) handleCommitMoveDown() error { self.c.LogAction(self.c.Tr.Actions.MoveCommitDown) err := self.git.Rebase.MoveCommitDown(self.model.Commits, index) if err == nil { - self.context.MoveSelectedLine(1) + self.context().MoveSelectedLine(1) } - return self.CheckMergeOrRebase(err) + return self.helpers.MergeAndRebase.CheckMergeOrRebase(err) }) } func (self *LocalCommitsController) handleCommitMoveUp() error { - index := self.context.GetSelectedLineIdx() + index := self.context().GetSelectedLineIdx() if index == 0 { return nil } @@ -478,7 +435,7 @@ func (self *LocalCommitsController) handleCommitMoveUp() error { if err := self.git.Rebase.MoveTodoDown(index - 1); err != nil { return self.c.Error(err) } - self.context.MoveSelectedLine(-1) + self.context().MoveSelectedLine(-1) return self.c.Refresh(types.RefreshOptions{ Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS}, }) @@ -488,9 +445,9 @@ func (self *LocalCommitsController) handleCommitMoveUp() error { self.c.LogAction(self.c.Tr.Actions.MoveCommitUp) err := self.git.Rebase.MoveCommitDown(self.model.Commits, index-1) if err == nil { - self.context.MoveSelectedLine(-1) + self.context().MoveSelectedLine(-1) } - return self.CheckMergeOrRebase(err) + return self.helpers.MergeAndRebase.CheckMergeOrRebase(err) }) } @@ -501,8 +458,8 @@ func (self *LocalCommitsController) handleCommitAmendTo() error { HandleConfirm: func() error { return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func() error { self.c.LogAction(self.c.Tr.Actions.AmendCommit) - err := self.git.Rebase.AmendTo(self.context.GetSelected().Sha) - return self.CheckMergeOrRebase(err) + err := self.git.Rebase.AmendTo(self.context().GetSelected().Sha) + return self.helpers.MergeAndRebase.CheckMergeOrRebase(err) }) }, }) @@ -556,7 +513,7 @@ func (self *LocalCommitsController) createRevertMergeCommitMenu(commit *models.C } func (self *LocalCommitsController) afterRevertCommit() error { - self.context.MoveSelectedLine(1) + self.context().MoveSelectedLine(1) return self.c.Refresh(types.RefreshOptions{ Mode: types.BLOCK_UI, Scope: []types.RefreshableView{types.COMMITS, types.BRANCHES}, }) @@ -564,10 +521,9 @@ func (self *LocalCommitsController) afterRevertCommit() error { func (self *LocalCommitsController) enter(commit *models.Commit) error { return self.switchToCommitFilesContext(SwitchToCommitFilesContextOpts{ - RefName: commit.Sha, - CanRebase: true, - Context: self.context, - WindowName: "commits", + RefName: commit.Sha, + CanRebase: true, + Context: self.context(), }) } @@ -608,14 +564,14 @@ func (self *LocalCommitsController) handleSquashAllAboveFixupCommits(commit *mod return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func() error { self.c.LogAction(self.c.Tr.Actions.SquashAllAboveFixupCommits) err := self.git.Rebase.SquashAllAboveFixupCommits(commit.Sha) - return self.CheckMergeOrRebase(err) + return self.helpers.MergeAndRebase.CheckMergeOrRebase(err) }) }, }) } func (self *LocalCommitsController) handleTagCommit(commit *models.Commit) error { - return self.tagsHelper.CreateTagMenu(commit.Sha, func() {}) + return self.helpers.Tags.CreateTagMenu(commit.Sha, func() {}) } func (self *LocalCommitsController) handleCheckoutCommit(commit *models.Commit) error { @@ -624,19 +580,19 @@ func (self *LocalCommitsController) handleCheckoutCommit(commit *models.Commit) Prompt: self.c.Tr.SureCheckoutThisCommit, HandleConfirm: func() error { self.c.LogAction(self.c.Tr.Actions.CheckoutCommit) - return self.refsHelper.CheckoutRef(commit.Sha, types.CheckoutRefOptions{}) + return self.helpers.Refs.CheckoutRef(commit.Sha, types.CheckoutRefOptions{}) }, }) } func (self *LocalCommitsController) handleCreateCommitResetMenu(commit *models.Commit) error { - return self.refsHelper.CreateGitResetMenu(commit.Sha) + return self.helpers.Refs.CreateGitResetMenu(commit.Sha) } func (self *LocalCommitsController) openSearch() error { // we usually lazyload these commits but now that we're searching we need to load them now - if self.context.GetLimitCommits() { - self.context.SetLimitCommits(false) + if self.context().GetLimitCommits() { + self.context().SetLimitCommits(false) if err := self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.COMMITS}}); err != nil { return err } @@ -649,14 +605,14 @@ func (self *LocalCommitsController) openSearch() error { func (self *LocalCommitsController) gotoBottom() error { // we usually lazyload these commits but now that we're jumping to the bottom we need to load them now - if self.context.GetLimitCommits() { - self.context.SetLimitCommits(false) + if self.context().GetLimitCommits() { + self.context().SetLimitCommits(false) if err := self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.COMMITS}}); err != nil { return err } } - self.context.SetSelectedLineIdx(self.context.GetItemsLength() - 1) + self.context().SetSelectedLineIdx(self.context().GetItemsLength() - 1) return nil } @@ -684,10 +640,10 @@ func (self *LocalCommitsController) handleOpenLogMenu() error { { DisplayString: self.c.Tr.ToggleShowGitGraphAll, OnPress: func() error { - self.setShowWholeGitGraph(!self.getShowWholeGitGraph()) + self.context().SetShowWholeGitGraph(!self.context().GetShowWholeGitGraph()) - if self.getShowWholeGitGraph() { - self.context.SetLimitCommits(false) + if self.context().GetShowWholeGitGraph() { + self.context().SetLimitCommits(false) } return self.c.WithWaitingStatus(self.c.Tr.LcLoadingCommits, func() error { @@ -761,9 +717,7 @@ func (self *LocalCommitsController) handleOpenLogMenu() error { } func (self *LocalCommitsController) handleOpenCommitInBrowser(commit *models.Commit) error { - hostingServiceMgr := self.getHostingServiceMgr() - - url, err := hostingServiceMgr.GetCommitURL(commit.Sha) + url, err := self.helpers.Host.GetCommitURL(commit.Sha) if err != nil { return self.c.Error(err) } @@ -778,7 +732,7 @@ func (self *LocalCommitsController) handleOpenCommitInBrowser(commit *models.Com func (self *LocalCommitsController) checkSelected(callback func(*models.Commit) error) func() error { return func() error { - commit := self.context.GetSelected() + commit := self.context().GetSelected() if commit == nil { return nil } @@ -788,21 +742,25 @@ func (self *LocalCommitsController) checkSelected(callback func(*models.Commit) } func (self *LocalCommitsController) Context() types.Context { - return self.context + return self.context() +} + +func (self *LocalCommitsController) context() *context.LocalCommitsContext { + return self.contexts.BranchCommits } func (self *LocalCommitsController) newBranch(commit *models.Commit) error { - return self.refsHelper.NewBranch(commit.RefName(), commit.Description(), "") + return self.helpers.Refs.NewBranch(commit.RefName(), commit.Description(), "") } func (self *LocalCommitsController) copy(commit *models.Commit) error { - return self.cherryPickHelper.Copy(commit, self.model.Commits, self.context) + return self.helpers.CherryPick.Copy(commit, self.model.Commits, self.context()) } func (self *LocalCommitsController) copyRange(*models.Commit) error { - return self.cherryPickHelper.CopyRange(self.context.GetSelectedLineIdx(), self.model.Commits, self.context) + return self.helpers.CherryPick.CopyRange(self.context().GetSelectedLineIdx(), self.model.Commits, self.context()) } func (self *LocalCommitsController) paste() error { - return self.cherryPickHelper.Paste() + return self.helpers.CherryPick.Paste() } diff --git a/pkg/gui/controllers/menu_controller.go b/pkg/gui/controllers/menu_controller.go index 392fe3da6..91e85dec5 100644 --- a/pkg/gui/controllers/menu_controller.go +++ b/pkg/gui/controllers/menu_controller.go @@ -7,22 +7,17 @@ import ( type MenuController struct { baseController - - c *types.ControllerCommon - context *context.MenuContext + *controllerCommon } var _ types.IController = &MenuController{} func NewMenuController( - c *types.ControllerCommon, - context *context.MenuContext, + common *controllerCommon, ) *MenuController { return &MenuController{ - baseController: baseController{}, - - c: c, - context: context, + baseController: baseController{}, + controllerCommon: common, } } @@ -50,7 +45,7 @@ func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types. } func (self *MenuController) press() error { - selectedItem := self.context.GetSelected() + selectedItem := self.context().GetSelected() if err := self.c.PopContext(); err != nil { return err @@ -64,5 +59,9 @@ func (self *MenuController) press() error { } func (self *MenuController) Context() types.Context { - return self.context + return self.context() +} + +func (self *MenuController) context() *context.MenuContext { + return self.contexts.Menu } diff --git a/pkg/gui/controllers/remotes_controller.go b/pkg/gui/controllers/remotes_controller.go index 12d2e7459..489454f89 100644 --- a/pkg/gui/controllers/remotes_controller.go +++ b/pkg/gui/controllers/remotes_controller.go @@ -1,7 +1,6 @@ package controllers import ( - "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" @@ -10,30 +9,22 @@ import ( type RemotesController struct { baseController - - c *types.ControllerCommon + *controllerCommon context *context.RemotesContext - git *commands.GitCommand setRemoteBranches func([]*models.RemoteBranch) - contexts *context.ContextTree } var _ types.IController = &RemotesController{} func NewRemotesController( - c *types.ControllerCommon, - context *context.RemotesContext, - git *commands.GitCommand, - contexts *context.ContextTree, + common *controllerCommon, setRemoteBranches func([]*models.RemoteBranch), ) *RemotesController { return &RemotesController{ baseController: baseController{}, - c: c, - git: git, - contexts: contexts, - context: context, + controllerCommon: common, + context: common.contexts.Remotes, setRemoteBranches: setRemoteBranches, } } diff --git a/pkg/gui/controllers/sub_commits_switch_controller.go b/pkg/gui/controllers/sub_commits_switch_controller.go index dbd6ab135..cbc9ce137 100644 --- a/pkg/gui/controllers/sub_commits_switch_controller.go +++ b/pkg/gui/controllers/sub_commits_switch_controller.go @@ -1,19 +1,14 @@ package controllers import ( - "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/loaders" "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" ) type SubCommitsSwitchControllerFactory struct { - c *types.ControllerCommon - subCommitsContext *context.SubCommitsContext - git *commands.GitCommand - modes *types.Modes - setSubCommits func([]*models.Commit) + controllerCommon *controllerCommon + setSubCommits func([]*models.Commit) } var _ types.IController = &SubCommitsSwitchController{} @@ -25,40 +20,28 @@ type ContextWithRefName interface { type SubCommitsSwitchController struct { baseController + *controllerCommon + context ContextWithRefName - c *types.ControllerCommon - context ContextWithRefName - subCommitsContext *context.SubCommitsContext - git *commands.GitCommand - modes *types.Modes - setSubCommits func([]*models.Commit) + setSubCommits func([]*models.Commit) } func NewSubCommitsSwitchControllerFactory( - c *types.ControllerCommon, - subCommitsContext *context.SubCommitsContext, - git *commands.GitCommand, - modes *types.Modes, + common *controllerCommon, setSubCommits func([]*models.Commit), ) *SubCommitsSwitchControllerFactory { return &SubCommitsSwitchControllerFactory{ - c: c, - subCommitsContext: subCommitsContext, - git: git, - modes: modes, - setSubCommits: setSubCommits, + controllerCommon: common, + setSubCommits: setSubCommits, } } func (self *SubCommitsSwitchControllerFactory) Create(context ContextWithRefName) *SubCommitsSwitchController { return &SubCommitsSwitchController{ - baseController: baseController{}, - c: self.c, - context: context, - subCommitsContext: self.subCommitsContext, - git: self.git, - modes: self.modes, - setSubCommits: self.setSubCommits, + baseController: baseController{}, + controllerCommon: self.controllerCommon, + context: context, + setSubCommits: self.setSubCommits, } } @@ -94,10 +77,10 @@ func (self *SubCommitsSwitchController) viewCommits() error { } self.setSubCommits(commits) - self.subCommitsContext.SetSelectedLineIdx(0) - self.subCommitsContext.SetParentContext(self.context) + self.contexts.SubCommits.SetSelectedLineIdx(0) + self.contexts.SubCommits.SetParentContext(self.context) - return self.c.PushContext(self.subCommitsContext) + return self.c.PushContext(self.contexts.SubCommits) } func (self *SubCommitsSwitchController) Context() types.Context { diff --git a/pkg/gui/controllers/submodules_controller.go b/pkg/gui/controllers/submodules_controller.go index 2eba02953..408536960 100644 --- a/pkg/gui/controllers/submodules_controller.go +++ b/pkg/gui/controllers/submodules_controller.go @@ -5,7 +5,6 @@ import ( "path/filepath" "strings" - "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/style" @@ -14,10 +13,7 @@ import ( type SubmodulesController struct { baseController - - c *types.ControllerCommon - context *context.SubmodulesContext - git *commands.GitCommand + *controllerCommon enterSubmodule func(submodule *models.SubmoduleConfig) error } @@ -25,17 +21,13 @@ type SubmodulesController struct { var _ types.IController = &SubmodulesController{} func NewSubmodulesController( - c *types.ControllerCommon, - context *context.SubmodulesContext, - git *commands.GitCommand, + controllerCommon *controllerCommon, enterSubmodule func(submodule *models.SubmoduleConfig) error, ) *SubmodulesController { return &SubmodulesController{ - baseController: baseController{}, - c: c, - context: context, - git: git, - enterSubmodule: enterSubmodule, + baseController: baseController{}, + controllerCommon: controllerCommon, + enterSubmodule: enterSubmodule, } } @@ -79,7 +71,7 @@ func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []* }, // { // Key: gocui.MouseLeft, - // Handler: func() error { return self.context.HandleClick(self.checkSelected(self.enter)) }, + // Handler: func() error { return self.context().HandleClick(self.checkSelected(self.enter)) }, // }, } } @@ -227,7 +219,7 @@ func (self *SubmodulesController) remove(submodule *models.SubmoduleConfig) erro func (self *SubmodulesController) checkSelected(callback func(*models.SubmoduleConfig) error) func() error { return func() error { - submodule := self.context.GetSelected() + submodule := self.context().GetSelected() if submodule == nil { return nil } @@ -237,5 +229,9 @@ func (self *SubmodulesController) checkSelected(callback func(*models.SubmoduleC } func (self *SubmodulesController) Context() types.Context { - return self.context + return self.context() +} + +func (self *SubmodulesController) context() *context.SubmodulesContext { + return self.contexts.Submodules } diff --git a/pkg/gui/controllers/sync_controller.go b/pkg/gui/controllers/sync_controller.go index f3f2894b0..74db3d527 100644 --- a/pkg/gui/controllers/sync_controller.go +++ b/pkg/gui/controllers/sync_controller.go @@ -4,7 +4,6 @@ import ( "fmt" "strings" - "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/types" @@ -12,35 +11,22 @@ import ( type SyncController struct { baseController + *controllerCommon - c *types.ControllerCommon - git *commands.GitCommand - - getCheckedOutBranch func() *models.Branch - suggestionsHelper ISuggestionsHelper - getSuggestedRemote func() string - CheckMergeOrRebase func(error) error + getSuggestedRemote func() string } var _ types.IController = &SyncController{} func NewSyncController( - c *types.ControllerCommon, - git *commands.GitCommand, - getCheckedOutBranch func() *models.Branch, - suggestionsHelper ISuggestionsHelper, + common *controllerCommon, getSuggestedRemote func() string, - CheckMergeOrRebase func(error) error, ) *SyncController { return &SyncController{ - baseController: baseController{}, - c: c, - git: git, + baseController: baseController{}, + controllerCommon: common, - getCheckedOutBranch: getCheckedOutBranch, - suggestionsHelper: suggestionsHelper, - getSuggestedRemote: getSuggestedRemote, - CheckMergeOrRebase: CheckMergeOrRebase, + getSuggestedRemote: getSuggestedRemote, } } @@ -75,7 +61,7 @@ func (self *SyncController) HandlePull() error { func (self *SyncController) branchCheckedOut(f func(*models.Branch) error) func() error { return func() error { - currentBranch := self.getCheckedOutBranch() + currentBranch := self.helpers.Refs.GetCheckedOutRef() if currentBranch == nil { // need to wait for branches to refresh return nil @@ -160,7 +146,7 @@ func (self *SyncController) promptForUpstream(currentBranch *models.Branch, onCo return self.c.Prompt(types.PromptOpts{ Title: self.c.Tr.EnterUpstream, InitialContent: suggestedRemote + " " + currentBranch.Name, - FindSuggestionsFunc: self.suggestionsHelper.GetRemoteBranchesSuggestionsFunc(" "), + FindSuggestionsFunc: self.helpers.Suggestions.GetRemoteBranchesSuggestionsFunc(" "), HandleConfirm: onConfirm, }) } @@ -189,7 +175,7 @@ func (self *SyncController) pullWithLock(opts PullFilesOptions) error { }, ) - return self.CheckMergeOrRebase(err) + return self.helpers.MergeAndRebase.CheckMergeOrRebase(err) } type pushOpts struct { diff --git a/pkg/gui/controllers/tags_controller.go b/pkg/gui/controllers/tags_controller.go index e819c1973..0ec153025 100644 --- a/pkg/gui/controllers/tags_controller.go +++ b/pkg/gui/controllers/tags_controller.go @@ -1,7 +1,6 @@ package controllers import ( - "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" @@ -10,43 +9,17 @@ import ( type TagsController struct { baseController - - c *types.ControllerCommon - context *context.TagsContext - git *commands.GitCommand - contexts *context.ContextTree - tagsHelper *TagsHelper - - refsHelper IRefsHelper - suggestionsHelper ISuggestionsHelper - - switchToSubCommitsContext func(string) error + *controllerCommon } var _ types.IController = &TagsController{} func NewTagsController( - c *types.ControllerCommon, - context *context.TagsContext, - git *commands.GitCommand, - contexts *context.ContextTree, - tagsHelper *TagsHelper, - refsHelper IRefsHelper, - suggestionsHelper ISuggestionsHelper, - - switchToSubCommitsContext func(string) error, + common *controllerCommon, ) *TagsController { return &TagsController{ - baseController: baseController{}, - c: c, - context: context, - git: git, - contexts: contexts, - tagsHelper: tagsHelper, - refsHelper: refsHelper, - suggestionsHelper: suggestionsHelper, - - switchToSubCommitsContext: switchToSubCommitsContext, + baseController: baseController{}, + controllerCommon: common, } } @@ -85,7 +58,7 @@ func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types. func (self *TagsController) checkout(tag *models.Tag) error { self.c.LogAction(self.c.Tr.Actions.CheckoutTag) - if err := self.refsHelper.CheckoutRef(tag.Name, types.CheckoutRefOptions{}); err != nil { + if err := self.helpers.Refs.CheckoutRef(tag.Name, types.CheckoutRefOptions{}); err != nil { return err } return self.c.PushContext(self.contexts.Branches) @@ -123,7 +96,7 @@ func (self *TagsController) push(tag *models.Tag) error { return self.c.Prompt(types.PromptOpts{ Title: title, InitialContent: "origin", - FindSuggestionsFunc: self.suggestionsHelper.GetRemoteSuggestionsFunc(), + FindSuggestionsFunc: self.helpers.Suggestions.GetRemoteSuggestionsFunc(), HandleConfirm: func(response string) error { return self.c.WithWaitingStatus(self.c.Tr.PushingTagStatus, func() error { self.c.LogAction(self.c.Tr.Actions.PushTag) @@ -139,17 +112,17 @@ func (self *TagsController) push(tag *models.Tag) error { } func (self *TagsController) createResetMenu(tag *models.Tag) error { - return self.refsHelper.CreateGitResetMenu(tag.Name) + return self.helpers.Refs.CreateGitResetMenu(tag.Name) } func (self *TagsController) create() error { // leaving commit SHA blank so that we're just creating the tag for the current commit - return self.tagsHelper.CreateTagMenu("", func() { self.context.SetSelectedLineIdx(0) }) + return self.helpers.Tags.CreateTagMenu("", func() { self.context().SetSelectedLineIdx(0) }) } func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func() error { return func() error { - tag := self.context.GetSelected() + tag := self.context().GetSelected() if tag == nil { return nil } @@ -159,5 +132,9 @@ func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func( } func (self *TagsController) Context() types.Context { - return self.context + return self.context() +} + +func (self *TagsController) context() *context.TagsContext { + return self.contexts.Tags } diff --git a/pkg/gui/controllers/types.go b/pkg/gui/controllers/types.go index ecd02536c..9783ca3b7 100644 --- a/pkg/gui/controllers/types.go +++ b/pkg/gui/controllers/types.go @@ -6,8 +6,7 @@ import ( // all fields mandatory (except `CanRebase` because it's boolean) type SwitchToCommitFilesContextOpts struct { - RefName string - CanRebase bool - Context types.Context - WindowName string + RefName string + CanRebase bool + Context types.Context } diff --git a/pkg/gui/controllers/undo_controller.go b/pkg/gui/controllers/undo_controller.go index 683fb2b84..bfd6dc444 100644 --- a/pkg/gui/controllers/undo_controller.go +++ b/pkg/gui/controllers/undo_controller.go @@ -1,8 +1,6 @@ package controllers import ( - "github.com/jesseduffield/lazygit/pkg/commands" - "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/types/enums" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" @@ -20,34 +18,17 @@ import ( type UndoController struct { baseController - - c *types.ControllerCommon - git *commands.GitCommand - - refsHelper IRefsHelper - workingTreeHelper IWorkingTreeHelper - - getFilteredReflogCommits func() []*models.Commit + *controllerCommon } var _ types.IController = &UndoController{} func NewUndoController( - c *types.ControllerCommon, - git *commands.GitCommand, - refsHelper IRefsHelper, - workingTreeHelper IWorkingTreeHelper, - - getFilteredReflogCommits func() []*models.Commit, + common *controllerCommon, ) *UndoController { return &UndoController{ - baseController: baseController{}, - c: c, - git: git, - refsHelper: refsHelper, - workingTreeHelper: workingTreeHelper, - - getFilteredReflogCommits: getFilteredReflogCommits, + baseController: baseController{}, + controllerCommon: common, } } @@ -109,7 +90,7 @@ func (self *UndoController) reflogUndo() error { }) case CHECKOUT: self.c.LogAction(self.c.Tr.Actions.Undo) - return true, self.refsHelper.CheckoutRef(action.from, types.CheckoutRefOptions{ + return true, self.helpers.Refs.CheckoutRef(action.from, types.CheckoutRefOptions{ EnvVars: undoEnvVars, WaitingStatus: undoingStatus, }) @@ -147,7 +128,7 @@ func (self *UndoController) reflogRedo() error { }) case CHECKOUT: self.c.LogAction(self.c.Tr.Actions.Redo) - return true, self.refsHelper.CheckoutRef(action.to, types.CheckoutRefOptions{ + return true, self.helpers.Refs.CheckoutRef(action.to, types.CheckoutRefOptions{ EnvVars: redoEnvVars, WaitingStatus: redoingStatus, }) @@ -168,7 +149,7 @@ func (self *UndoController) reflogRedo() error { // Though we might support this later, hence the use of the CURRENT_REBASE action kind. func (self *UndoController) parseReflogForActions(onUserAction func(counter int, action reflogAction) (bool, error)) error { counter := 0 - reflogCommits := self.getFilteredReflogCommits() + reflogCommits := self.model.FilteredReflogCommits rebaseFinishCommitSha := "" var action *reflogAction for reflogCommitIdx, reflogCommit := range reflogCommits { @@ -222,14 +203,14 @@ type hardResetOptions struct { // only to be used in the undo flow for now (does an autostash) func (self *UndoController) hardResetWithAutoStash(commitSha string, options hardResetOptions) error { reset := func() error { - if err := self.refsHelper.ResetToRef(commitSha, "hard", options.EnvVars); err != nil { + if err := self.helpers.Refs.ResetToRef(commitSha, "hard", options.EnvVars); err != nil { return self.c.Error(err) } return nil } // if we have any modified tracked files we need to ask the user if they want us to stash for them - dirtyWorkingTree := self.workingTreeHelper.IsWorkingTreeDirty() + dirtyWorkingTree := self.helpers.WorkingTree.IsWorkingTreeDirty() if dirtyWorkingTree { // offer to autostash changes return self.c.Ask(types.AskOpts{ diff --git a/pkg/gui/custom_commands.go b/pkg/gui/custom_commands.go index e32e5bb11..6bd659bd7 100644 --- a/pkg/gui/custom_commands.go +++ b/pkg/gui/custom_commands.go @@ -54,7 +54,7 @@ func (gui *Gui) resolveTemplate(templateStr string, promptResponses []string) (s SelectedCommitFile: gui.getSelectedCommitFile(), SelectedCommitFilePath: gui.getSelectedCommitFilePath(), SelectedSubCommit: gui.State.Contexts.SubCommits.GetSelected(), - CheckedOutBranch: gui.getCheckedOutBranch(), + CheckedOutBranch: gui.helpers.Refs.GetCheckedOutRef(), PromptResponses: promptResponses, } diff --git a/pkg/gui/global_handlers.go b/pkg/gui/global_handlers.go index d14c5193d..d03723743 100644 --- a/pkg/gui/global_handlers.go +++ b/pkg/gui/global_handlers.go @@ -189,19 +189,6 @@ func (gui *Gui) handleMouseDownMain() error { return nil } -func (gui *Gui) fetch() (err error) { - gui.c.LogAction("Fetch") - err = gui.git.Sync.Fetch(git_commands.FetchOptions{}) - - if err != nil && strings.Contains(err.Error(), "exit status 128") { - _ = gui.c.ErrorMsg(gui.c.Tr.PassUnameWrong) - } - - _ = gui.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.BRANCHES, types.COMMITS, types.REMOTES, types.TAGS}, Mode: types.ASYNC}) - - return err -} - func (gui *Gui) backgroundFetch() (err error) { err = gui.git.Sync.Fetch(git_commands.FetchOptions{Background: true}) diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 93e5c5ff3..3966cd48f 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -20,6 +20,7 @@ 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/controllers/helpers" "github.com/jesseduffield/lazygit/pkg/gui/lbl" "github.com/jesseduffield/lazygit/pkg/gui/mergeconflicts" "github.com/jesseduffield/lazygit/pkg/gui/modes/cherrypicking" @@ -67,17 +68,6 @@ func NewContextManager(initialContext types.Context) ContextManager { } } -type Helpers struct { - Refs *controllers.RefsHelper - Bisect *controllers.BisectHelper - Suggestions *controllers.SuggestionsHelper - Files *controllers.FilesHelper - WorkingTree *controllers.WorkingTreeHelper - Tags *controllers.TagsHelper - Rebase *controllers.RebaseHelper - CherryPick *controllers.CherryPickHelper -} - type Repo string // Gui wraps the gocui Gui object which handles rendering and events @@ -144,9 +134,6 @@ type Gui struct { // flag as to whether or not the diff view should ignore whitespace IgnoreWhitespaceInDiffView bool - // if this is true, we'll load our commits using `git log --all` - ShowWholeGitGraph bool - // we use this to decide whether we'll return to the original directory that // lazygit was opened in, or if we'll retain the one we're currently in. RetainOriginalDir bool @@ -161,8 +148,8 @@ type Gui struct { // process InitialDir string - c *types.ControllerCommon - helpers *Helpers + c *types.HelperCommon + helpers *helpers.Helpers } // we keep track of some stuff from one render to the next to see if certain @@ -488,11 +475,11 @@ func NewGui( ) guiCommon := &guiCommon{gui: gui, IPopupHandler: gui.PopupHandler} - controllerCommon := &types.ControllerCommon{IGuiCommon: guiCommon, Common: cmn} + helperCommon := &types.HelperCommon{IGuiCommon: guiCommon, Common: cmn} // storing this stuff on the gui for now to ease refactoring // TODO: reset these controllers upon changing repos due to state changing - gui.c = controllerCommon + gui.c = helperCommon authors.SetCustomAuthors(gui.UserConfig.Gui.AuthorColors) presentation.SetCustomBranches(gui.UserConfig.Gui.BranchColors) @@ -503,21 +490,23 @@ func NewGui( func (gui *Gui) resetControllers() { controllerCommon := gui.c osCommand := gui.os - rebaseHelper := controllers.NewRebaseHelper(controllerCommon, gui.State.Contexts, gui.git, gui.takeOverMergeConflictScrolling) model := gui.State.Model - gui.helpers = &Helpers{ - Refs: controllers.NewRefsHelper( - controllerCommon, - gui.git, - gui.State.Contexts, - ), - Bisect: controllers.NewBisectHelper(controllerCommon, gui.git), - Suggestions: controllers.NewSuggestionsHelper(controllerCommon, model, gui.refreshSuggestions), - Files: controllers.NewFilesHelper(controllerCommon, gui.git, osCommand), - WorkingTree: controllers.NewWorkingTreeHelper(model), - Tags: controllers.NewTagsHelper(controllerCommon, gui.git), - Rebase: rebaseHelper, - CherryPick: controllers.NewCherryPickHelper( + refsHelper := helpers.NewRefsHelper( + controllerCommon, + gui.git, + gui.State.Contexts, + model, + ) + rebaseHelper := helpers.NewMergeAndRebaseHelper(controllerCommon, gui.State.Contexts, gui.git, gui.takeOverMergeConflictScrolling, refsHelper) + gui.helpers = &helpers.Helpers{ + Refs: refsHelper, + Bisect: helpers.NewBisectHelper(controllerCommon, gui.git), + Suggestions: helpers.NewSuggestionsHelper(controllerCommon, model, gui.refreshSuggestions), + Files: helpers.NewFilesHelper(controllerCommon, gui.git, osCommand), + WorkingTree: helpers.NewWorkingTreeHelper(model), + Tags: helpers.NewTagsHelper(controllerCommon, gui.git), + MergeAndRebase: rebaseHelper, + CherryPick: helpers.NewCherryPickHelper( controllerCommon, gui.git, gui.State.Contexts, @@ -526,109 +515,58 @@ func (gui *Gui) resetControllers() { ), } - syncController := controllers.NewSyncController( + common := controllers.NewControllerCommon( controllerCommon, + osCommand, gui.git, - gui.getCheckedOutBranch, - gui.helpers.Suggestions, + gui.helpers, + model, + gui.State.Contexts, + gui.State.Modes, + ) + + syncController := controllers.NewSyncController( + common, gui.getSuggestedRemote, - gui.helpers.Rebase.CheckMergeOrRebase, ) submodulesController := controllers.NewSubmodulesController( - controllerCommon, - gui.State.Contexts.Submodules, - gui.git, + common, gui.enterSubmodule, ) - bisectController := controllers.NewBisectController( - controllerCommon, - gui.State.Contexts.BranchCommits, - gui.git, - gui.helpers.Bisect, - func() []*models.Commit { return gui.State.Model.Commits }, - ) + bisectController := controllers.NewBisectController(common) gui.Controllers = Controllers{ Submodules: submodulesController, - Global: controllers.NewGlobalController( - controllerCommon, - osCommand, - ), + Global: controllers.NewGlobalController(common), Files: controllers.NewFilesController( - controllerCommon, - gui.State.Contexts.Files, - model, - gui.git, - osCommand, - gui.getSelectedFileNode, - gui.State.Contexts, + common, gui.enterSubmodule, - func() []*models.SubmoduleConfig { return gui.State.Model.Submodules }, gui.getSetTextareaTextFn(func() *gocui.View { return gui.Views.CommitMessage }), gui.withGpgHandling, func() string { return gui.State.failedCommitMessage }, - gui.getSelectedPath, gui.switchToMerge, - gui.helpers.Suggestions, - gui.helpers.Refs, - gui.helpers.Files, - gui.helpers.WorkingTree, - ), - Tags: controllers.NewTagsController( - controllerCommon, - gui.State.Contexts.Tags, - gui.git, - gui.State.Contexts, - gui.helpers.Tags, - gui.helpers.Refs, - gui.helpers.Suggestions, - gui.switchToSubCommitsContext, ), + Tags: controllers.NewTagsController(common), LocalCommits: controllers.NewLocalCommitsController( - controllerCommon, - gui.State.Contexts.BranchCommits, - osCommand, - gui.git, - gui.helpers.Tags, - gui.helpers.Refs, - gui.helpers.CherryPick, - gui.helpers.Rebase, - model, - gui.helpers.Rebase.CheckMergeOrRebase, + common, syncController.HandlePull, - gui.getHostingServiceMgr, gui.SwitchToCommitFilesContext, - func() bool { return gui.ShowWholeGitGraph }, - func(value bool) { gui.ShowWholeGitGraph = value }, ), Remotes: controllers.NewRemotesController( - controllerCommon, - gui.State.Contexts.Remotes, - gui.git, - gui.State.Contexts, + common, func(branches []*models.RemoteBranch) { gui.State.Model.RemoteBranches = branches }, ), - Menu: controllers.NewMenuController( - controllerCommon, - gui.State.Contexts.Menu, - ), - Undo: controllers.NewUndoController( - controllerCommon, - gui.git, - gui.helpers.Refs, - gui.helpers.WorkingTree, - func() []*models.Commit { return gui.State.Model.FilteredReflogCommits }, - ), + Menu: controllers.NewMenuController(common), + Undo: controllers.NewUndoController(common), Sync: syncController, } + branchesController := controllers.NewBranchesController(common) + switchToSubCommitsControllerFactory := controllers.NewSubCommitsSwitchControllerFactory( - controllerCommon, - gui.State.Contexts.SubCommits, - gui.git, - gui.State.Modes, + common, func(commits []*models.Commit) { gui.State.Model.SubCommits = commits }, ) @@ -640,6 +578,7 @@ func (gui *Gui) resetControllers() { controllers.AttachControllers(context, switchToSubCommitsControllerFactory.Create(context)) } + controllers.AttachControllers(gui.State.Contexts.Branches, branchesController) controllers.AttachControllers(gui.State.Contexts.Files, gui.Controllers.Files) controllers.AttachControllers(gui.State.Contexts.Tags, gui.Controllers.Tags) controllers.AttachControllers(gui.State.Contexts.Submodules, gui.Controllers.Submodules) diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 4b66281fc..25433eca5 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -194,593 +194,500 @@ func (gui *Gui) noPopupPanel(f func() error) func() error { } } -func (gui *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBinding) { - config := gui.c.UserConfig.Keybinding +// renaming receiver to 'self' to aid refactoring. Will probably end up moving all Gui handlers to this pattern eventually. +func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBinding) { + config := self.c.UserConfig.Keybinding guards := types.KeybindingGuards{ - OutsideFilterMode: gui.outsideFilterMode, - NoPopupPanel: gui.noPopupPanel, + OutsideFilterMode: self.outsideFilterMode, + NoPopupPanel: self.noPopupPanel, + } + + opts := types.KeybindingsOpts{ + GetKey: self.getKey, + Config: config, + Guards: guards, } bindings := []*types.Binding{ { ViewName: "", - Key: gui.getKey(config.Universal.Quit), + Key: opts.GetKey(opts.Config.Universal.Quit), Modifier: gocui.ModNone, - Handler: gui.handleQuit, + Handler: self.handleQuit, }, { ViewName: "", - Key: gui.getKey(config.Universal.QuitWithoutChangingDirectory), + Key: opts.GetKey(opts.Config.Universal.QuitWithoutChangingDirectory), Modifier: gocui.ModNone, - Handler: gui.handleQuitWithoutChangingDirectory, + Handler: self.handleQuitWithoutChangingDirectory, }, { ViewName: "", - Key: gui.getKey(config.Universal.QuitAlt1), + Key: opts.GetKey(opts.Config.Universal.QuitAlt1), Modifier: gocui.ModNone, - Handler: gui.handleQuit, + Handler: self.handleQuit, }, { ViewName: "", - Key: gui.getKey(config.Universal.Return), + Key: opts.GetKey(opts.Config.Universal.Return), Modifier: gocui.ModNone, - Handler: gui.handleTopLevelReturn, + Handler: self.handleTopLevelReturn, }, { ViewName: "", - Key: gui.getKey(config.Universal.OpenRecentRepos), - Handler: gui.handleCreateRecentReposMenu, + Key: opts.GetKey(opts.Config.Universal.OpenRecentRepos), + Handler: self.handleCreateRecentReposMenu, Alternative: "", - Description: gui.c.Tr.SwitchRepo, + Description: self.c.Tr.SwitchRepo, }, { ViewName: "", - Key: gui.getKey(config.Universal.ScrollUpMain), - Handler: gui.scrollUpMain, + Key: opts.GetKey(opts.Config.Universal.ScrollUpMain), + Handler: self.scrollUpMain, Alternative: "fn+up", - Description: gui.c.Tr.LcScrollUpMainPanel, + Description: self.c.Tr.LcScrollUpMainPanel, }, { ViewName: "", - Key: gui.getKey(config.Universal.ScrollDownMain), - Handler: gui.scrollDownMain, + Key: opts.GetKey(opts.Config.Universal.ScrollDownMain), + Handler: self.scrollDownMain, Alternative: "fn+down", - Description: gui.c.Tr.LcScrollDownMainPanel, + Description: self.c.Tr.LcScrollDownMainPanel, }, { ViewName: "", - Key: gui.getKey(config.Universal.ScrollUpMainAlt1), + Key: opts.GetKey(opts.Config.Universal.ScrollUpMainAlt1), Modifier: gocui.ModNone, - Handler: gui.scrollUpMain, + Handler: self.scrollUpMain, }, { ViewName: "", - Key: gui.getKey(config.Universal.ScrollDownMainAlt1), + Key: opts.GetKey(opts.Config.Universal.ScrollDownMainAlt1), Modifier: gocui.ModNone, - Handler: gui.scrollDownMain, + Handler: self.scrollDownMain, }, { ViewName: "", - Key: gui.getKey(config.Universal.ScrollUpMainAlt2), + Key: opts.GetKey(opts.Config.Universal.ScrollUpMainAlt2), Modifier: gocui.ModNone, - Handler: gui.scrollUpMain, + Handler: self.scrollUpMain, }, { ViewName: "", - Key: gui.getKey(config.Universal.ScrollDownMainAlt2), + Key: opts.GetKey(opts.Config.Universal.ScrollDownMainAlt2), Modifier: gocui.ModNone, - Handler: gui.scrollDownMain, + Handler: self.scrollDownMain, }, { ViewName: "", - Key: gui.getKey(config.Universal.CreateRebaseOptionsMenu), - Handler: gui.helpers.Rebase.CreateRebaseOptionsMenu, - Description: gui.c.Tr.ViewMergeRebaseOptions, + Key: opts.GetKey(opts.Config.Universal.CreateRebaseOptionsMenu), + Handler: self.helpers.MergeAndRebase.CreateRebaseOptionsMenu, + Description: self.c.Tr.ViewMergeRebaseOptions, OpensMenu: true, }, { ViewName: "", - Key: gui.getKey(config.Universal.CreatePatchOptionsMenu), - Handler: gui.handleCreatePatchOptionsMenu, - Description: gui.c.Tr.ViewPatchOptions, + Key: opts.GetKey(opts.Config.Universal.CreatePatchOptionsMenu), + Handler: self.handleCreatePatchOptionsMenu, + Description: self.c.Tr.ViewPatchOptions, OpensMenu: true, }, { ViewName: "", - Key: gui.getKey(config.Universal.Refresh), - Handler: gui.handleRefresh, - Description: gui.c.Tr.LcRefresh, + Key: opts.GetKey(opts.Config.Universal.Refresh), + Handler: self.handleRefresh, + Description: self.c.Tr.LcRefresh, }, { ViewName: "", - Key: gui.getKey(config.Universal.OptionMenu), - Handler: gui.handleCreateOptionsMenu, - Description: gui.c.Tr.LcOpenMenu, + Key: opts.GetKey(opts.Config.Universal.OptionMenu), + Handler: self.handleCreateOptionsMenu, + Description: self.c.Tr.LcOpenMenu, OpensMenu: true, }, { ViewName: "", - Key: gui.getKey(config.Universal.OptionMenuAlt1), + Key: opts.GetKey(opts.Config.Universal.OptionMenuAlt1), Modifier: gocui.ModNone, - Handler: gui.handleCreateOptionsMenu, + Handler: self.handleCreateOptionsMenu, }, { ViewName: "status", - Key: gui.getKey(config.Universal.Edit), - Handler: gui.handleEditConfig, - Description: gui.c.Tr.EditConfig, + Key: opts.GetKey(opts.Config.Universal.Edit), + Handler: self.handleEditConfig, + Description: self.c.Tr.EditConfig, }, { ViewName: "", - Key: gui.getKey(config.Universal.NextScreenMode), - Handler: gui.nextScreenMode, - Description: gui.c.Tr.LcNextScreenMode, + Key: opts.GetKey(opts.Config.Universal.NextScreenMode), + Handler: self.nextScreenMode, + Description: self.c.Tr.LcNextScreenMode, }, { ViewName: "", - Key: gui.getKey(config.Universal.PrevScreenMode), - Handler: gui.prevScreenMode, - Description: gui.c.Tr.LcPrevScreenMode, + Key: opts.GetKey(opts.Config.Universal.PrevScreenMode), + Handler: self.prevScreenMode, + Description: self.c.Tr.LcPrevScreenMode, }, { ViewName: "status", - Key: gui.getKey(config.Universal.OpenFile), - Handler: gui.handleOpenConfig, - Description: gui.c.Tr.OpenConfig, + Key: opts.GetKey(opts.Config.Universal.OpenFile), + Handler: self.handleOpenConfig, + Description: self.c.Tr.OpenConfig, }, { ViewName: "status", - Key: gui.getKey(config.Status.CheckForUpdate), - Handler: gui.handleCheckForUpdate, - Description: gui.c.Tr.LcCheckForUpdate, + Key: opts.GetKey(opts.Config.Status.CheckForUpdate), + Handler: self.handleCheckForUpdate, + Description: self.c.Tr.LcCheckForUpdate, }, { ViewName: "status", - Key: gui.getKey(config.Status.RecentRepos), - Handler: gui.handleCreateRecentReposMenu, - Description: gui.c.Tr.SwitchRepo, + Key: opts.GetKey(opts.Config.Status.RecentRepos), + Handler: self.handleCreateRecentReposMenu, + Description: self.c.Tr.SwitchRepo, }, { ViewName: "status", - Key: gui.getKey(config.Status.AllBranchesLogGraph), - Handler: gui.handleShowAllBranchLogs, - Description: gui.c.Tr.LcAllBranchesLogGraph, + Key: opts.GetKey(opts.Config.Status.AllBranchesLogGraph), + Handler: self.handleShowAllBranchLogs, + Description: self.c.Tr.LcAllBranchesLogGraph, }, { ViewName: "files", Contexts: []string{string(context.FILES_CONTEXT_KEY)}, - Key: gui.getKey(config.Files.ViewResetOptions), - Handler: gui.handleCreateResetMenu, - Description: gui.c.Tr.LcViewResetOptions, + Key: opts.GetKey(opts.Config.Files.ViewResetOptions), + Handler: self.handleCreateResetMenu, + Description: self.c.Tr.LcViewResetOptions, OpensMenu: true, }, { ViewName: "files", Contexts: []string{string(context.FILES_CONTEXT_KEY)}, - Key: gui.getKey(config.Files.Fetch), - Handler: gui.handleGitFetch, - Description: gui.c.Tr.LcFetch, - }, - { - ViewName: "files", - Contexts: []string{string(context.FILES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.CopyToClipboard), - Handler: gui.handleCopySelectedSideContextItemToClipboard, - Description: gui.c.Tr.LcCopyFileNameToClipboard, + Key: opts.GetKey(opts.Config.Universal.CopyToClipboard), + Handler: self.handleCopySelectedSideContextItemToClipboard, + Description: self.c.Tr.LcCopyFileNameToClipboard, }, { ViewName: "branches", Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Select), - Handler: gui.handleBranchPress, - Description: gui.c.Tr.LcCheckout, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.CreatePullRequest), - Handler: gui.handleCreatePullRequestPress, - Description: gui.c.Tr.LcCreatePullRequest, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.ViewPullRequestOptions), - Handler: gui.handleCreatePullRequestMenu, - Description: gui.c.Tr.LcCreatePullRequestOptions, + Key: opts.GetKey(opts.Config.Branches.ViewGitFlowOptions), + Handler: self.handleCreateGitFlowMenu, + Description: self.c.Tr.LcGitFlowOptions, OpensMenu: true, }, { ViewName: "branches", Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.CopyPullRequestURL), - Handler: gui.handleCopyPullRequestURLPress, - Description: gui.c.Tr.LcCopyPullRequestURL, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.CheckoutBranchByName), - Handler: gui.handleCheckoutByName, - Description: gui.c.Tr.LcCheckoutByName, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.ForceCheckoutBranch), - Handler: gui.handleForceCheckout, - Description: gui.c.Tr.LcForceCheckout, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.New), - Handler: gui.handleNewBranchOffBranch, - Description: gui.c.Tr.LcNewBranch, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Remove), - Handler: gui.handleDeleteBranch, - Description: gui.c.Tr.LcDeleteBranch, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.RebaseBranch), - Handler: guards.OutsideFilterMode(gui.handleRebaseOntoLocalBranch), - Description: gui.c.Tr.LcRebaseBranch, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.MergeIntoCurrentBranch), - Handler: guards.OutsideFilterMode(gui.handleMerge), - Description: gui.c.Tr.LcMergeIntoCurrentBranch, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.ViewGitFlowOptions), - Handler: gui.handleCreateGitFlowMenu, - Description: gui.c.Tr.LcGitFlowOptions, - OpensMenu: true, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.FastForward), - Handler: gui.handleFastForward, - Description: gui.c.Tr.FastForward, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.ViewResetOptions), - Handler: gui.handleCreateResetToBranchMenu, - Description: gui.c.Tr.LcViewResetOptions, - OpensMenu: true, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.RenameBranch), - Handler: gui.handleRenameBranch, - Description: gui.c.Tr.LcRenameBranch, - }, - { - ViewName: "branches", - Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.CopyToClipboard), - Handler: gui.handleCopySelectedSideContextItemToClipboard, - Description: gui.c.Tr.LcCopyBranchNameToClipboard, + Key: opts.GetKey(opts.Config.Universal.CopyToClipboard), + Handler: self.handleCopySelectedSideContextItemToClipboard, + Description: self.c.Tr.LcCopyBranchNameToClipboard, }, { ViewName: "branches", Contexts: []string{string(context.REMOTE_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Return), - Handler: gui.handleRemoteBranchesEscape, - Description: gui.c.Tr.ReturnToRemotesList, + Key: opts.GetKey(opts.Config.Universal.Return), + Handler: self.handleRemoteBranchesEscape, + Description: self.c.Tr.ReturnToRemotesList, }, { ViewName: "branches", Contexts: []string{string(context.REMOTE_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.ViewResetOptions), - Handler: gui.handleCreateResetToRemoteBranchMenu, - Description: gui.c.Tr.LcViewResetOptions, + Key: opts.GetKey(opts.Config.Commits.ViewResetOptions), + Handler: self.handleCreateResetToRemoteBranchMenu, + Description: self.c.Tr.LcViewResetOptions, OpensMenu: true, }, { ViewName: "commits", Contexts: []string{string(context.BRANCH_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.CopyToClipboard), - Handler: gui.handleCopySelectedSideContextItemToClipboard, - Description: gui.c.Tr.LcCopyCommitShaToClipboard, + Key: opts.GetKey(opts.Config.Universal.CopyToClipboard), + Handler: self.handleCopySelectedSideContextItemToClipboard, + Description: self.c.Tr.LcCopyCommitShaToClipboard, }, { ViewName: "commits", Contexts: []string{string(context.BRANCH_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.ResetCherryPick), - Handler: gui.helpers.CherryPick.Reset, - Description: gui.c.Tr.LcResetCherryPick, + Key: opts.GetKey(opts.Config.Commits.ResetCherryPick), + Handler: self.helpers.CherryPick.Reset, + Description: self.c.Tr.LcResetCherryPick, }, { ViewName: "commits", Contexts: []string{string(context.REFLOG_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.GoInto), - Handler: gui.handleViewReflogCommitFiles, - Description: gui.c.Tr.LcViewCommitFiles, + Key: opts.GetKey(opts.Config.Universal.GoInto), + Handler: self.handleViewReflogCommitFiles, + Description: self.c.Tr.LcViewCommitFiles, }, { ViewName: "commits", Contexts: []string{string(context.REFLOG_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Select), - Handler: gui.CheckoutReflogCommit, - Description: gui.c.Tr.LcCheckoutCommit, + Key: opts.GetKey(opts.Config.Universal.Select), + Handler: self.CheckoutReflogCommit, + Description: self.c.Tr.LcCheckoutCommit, }, { ViewName: "commits", Contexts: []string{string(context.REFLOG_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.ViewResetOptions), - Handler: gui.handleCreateReflogResetMenu, - Description: gui.c.Tr.LcViewResetOptions, + Key: opts.GetKey(opts.Config.Commits.ViewResetOptions), + Handler: self.handleCreateReflogResetMenu, + Description: self.c.Tr.LcViewResetOptions, OpensMenu: true, }, { ViewName: "commits", Contexts: []string{string(context.REFLOG_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.CherryPickCopy), - Handler: guards.OutsideFilterMode(gui.handleCopyReflogCommit), - Description: gui.c.Tr.LcCherryPickCopy, + Key: opts.GetKey(opts.Config.Commits.CherryPickCopy), + Handler: opts.Guards.OutsideFilterMode(self.handleCopyReflogCommit), + Description: self.c.Tr.LcCherryPickCopy, }, { ViewName: "commits", Contexts: []string{string(context.REFLOG_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.CherryPickCopyRange), - Handler: guards.OutsideFilterMode(gui.handleCopyReflogCommitRange), - Description: gui.c.Tr.LcCherryPickCopyRange, + Key: opts.GetKey(opts.Config.Commits.CherryPickCopyRange), + Handler: opts.Guards.OutsideFilterMode(self.handleCopyReflogCommitRange), + Description: self.c.Tr.LcCherryPickCopyRange, }, { ViewName: "commits", Contexts: []string{string(context.REFLOG_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.ResetCherryPick), - Handler: gui.helpers.CherryPick.Reset, - Description: gui.c.Tr.LcResetCherryPick, + Key: opts.GetKey(opts.Config.Commits.ResetCherryPick), + Handler: self.helpers.CherryPick.Reset, + Description: self.c.Tr.LcResetCherryPick, }, { ViewName: "commits", Contexts: []string{string(context.REFLOG_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.CopyToClipboard), - Handler: gui.handleCopySelectedSideContextItemToClipboard, - Description: gui.c.Tr.LcCopyCommitShaToClipboard, + Key: opts.GetKey(opts.Config.Universal.CopyToClipboard), + Handler: self.handleCopySelectedSideContextItemToClipboard, + Description: self.c.Tr.LcCopyCommitShaToClipboard, }, { ViewName: "branches", Contexts: []string{string(context.SUB_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.GoInto), - Handler: gui.handleViewSubCommitFiles, - Description: gui.c.Tr.LcViewCommitFiles, + Key: opts.GetKey(opts.Config.Universal.GoInto), + Handler: self.handleViewSubCommitFiles, + Description: self.c.Tr.LcViewCommitFiles, }, { ViewName: "branches", Contexts: []string{string(context.SUB_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Select), - Handler: gui.handleCheckoutSubCommit, - Description: gui.c.Tr.LcCheckoutCommit, + Key: opts.GetKey(opts.Config.Universal.Select), + Handler: self.handleCheckoutSubCommit, + Description: self.c.Tr.LcCheckoutCommit, }, { ViewName: "branches", Contexts: []string{string(context.SUB_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.ViewResetOptions), - Handler: gui.handleCreateSubCommitResetMenu, - Description: gui.c.Tr.LcViewResetOptions, + Key: opts.GetKey(opts.Config.Commits.ViewResetOptions), + Handler: self.handleCreateSubCommitResetMenu, + Description: self.c.Tr.LcViewResetOptions, OpensMenu: true, }, { ViewName: "branches", Contexts: []string{string(context.SUB_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.New), - Handler: gui.handleNewBranchOffSubCommit, - Description: gui.c.Tr.LcNewBranch, + Key: opts.GetKey(opts.Config.Universal.New), + Handler: self.handleNewBranchOffSubCommit, + Description: self.c.Tr.LcNewBranch, }, { ViewName: "branches", Contexts: []string{string(context.SUB_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.CherryPickCopy), - Handler: gui.handleCopySubCommit, - Description: gui.c.Tr.LcCherryPickCopy, + Key: opts.GetKey(opts.Config.Commits.CherryPickCopy), + Handler: self.handleCopySubCommit, + Description: self.c.Tr.LcCherryPickCopy, }, { ViewName: "branches", Contexts: []string{string(context.SUB_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.CherryPickCopyRange), - Handler: gui.handleCopySubCommitRange, - Description: gui.c.Tr.LcCherryPickCopyRange, + Key: opts.GetKey(opts.Config.Commits.CherryPickCopyRange), + Handler: self.handleCopySubCommitRange, + Description: self.c.Tr.LcCherryPickCopyRange, }, { ViewName: "branches", Contexts: []string{string(context.SUB_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Commits.ResetCherryPick), - Handler: gui.helpers.CherryPick.Reset, - Description: gui.c.Tr.LcResetCherryPick, + Key: opts.GetKey(opts.Config.Commits.ResetCherryPick), + Handler: self.helpers.CherryPick.Reset, + Description: self.c.Tr.LcResetCherryPick, }, { ViewName: "branches", Contexts: []string{string(context.SUB_COMMITS_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.CopyToClipboard), - Handler: gui.handleCopySelectedSideContextItemToClipboard, - Description: gui.c.Tr.LcCopyCommitShaToClipboard, + Key: opts.GetKey(opts.Config.Universal.CopyToClipboard), + Handler: self.handleCopySelectedSideContextItemToClipboard, + Description: self.c.Tr.LcCopyCommitShaToClipboard, }, { ViewName: "stash", - Key: gui.getKey(config.Universal.GoInto), - Handler: gui.handleViewStashFiles, - Description: gui.c.Tr.LcViewStashFiles, + Key: opts.GetKey(opts.Config.Universal.GoInto), + Handler: self.handleViewStashFiles, + Description: self.c.Tr.LcViewStashFiles, }, { ViewName: "stash", - Key: gui.getKey(config.Universal.Select), - Handler: gui.handleStashApply, - Description: gui.c.Tr.LcApply, + Key: opts.GetKey(opts.Config.Universal.Select), + Handler: self.handleStashApply, + Description: self.c.Tr.LcApply, }, { ViewName: "stash", - Key: gui.getKey(config.Stash.PopStash), - Handler: gui.handleStashPop, - Description: gui.c.Tr.LcPop, + Key: opts.GetKey(opts.Config.Stash.PopStash), + Handler: self.handleStashPop, + Description: self.c.Tr.LcPop, }, { ViewName: "stash", - Key: gui.getKey(config.Universal.Remove), - Handler: gui.handleStashDrop, - Description: gui.c.Tr.LcDrop, + Key: opts.GetKey(opts.Config.Universal.Remove), + Handler: self.handleStashDrop, + Description: self.c.Tr.LcDrop, }, { ViewName: "stash", - Key: gui.getKey(config.Universal.New), - Handler: gui.handleNewBranchOffStashEntry, - Description: gui.c.Tr.LcNewBranch, + Key: opts.GetKey(opts.Config.Universal.New), + Handler: self.handleNewBranchOffStashEntry, + Description: self.c.Tr.LcNewBranch, }, { ViewName: "commitMessage", - Key: gui.getKey(config.Universal.SubmitEditorText), + Key: opts.GetKey(opts.Config.Universal.SubmitEditorText), Modifier: gocui.ModNone, - Handler: gui.handleCommitConfirm, + Handler: self.handleCommitConfirm, }, { ViewName: "commitMessage", - Key: gui.getKey(config.Universal.Return), + Key: opts.GetKey(opts.Config.Universal.Return), Modifier: gocui.ModNone, - Handler: gui.handleCommitClose, + Handler: self.handleCommitClose, }, { ViewName: "credentials", - Key: gui.getKey(config.Universal.Confirm), + Key: opts.GetKey(opts.Config.Universal.Confirm), Modifier: gocui.ModNone, - Handler: gui.handleSubmitCredential, + Handler: self.handleSubmitCredential, }, { ViewName: "credentials", - Key: gui.getKey(config.Universal.Return), + Key: opts.GetKey(opts.Config.Universal.Return), Modifier: gocui.ModNone, - Handler: gui.handleCloseCredentialsView, + Handler: self.handleCloseCredentialsView, }, { ViewName: "menu", - Key: gui.getKey(config.Universal.Return), - Handler: gui.handleMenuClose, - Description: gui.c.Tr.LcCloseMenu, + Key: opts.GetKey(opts.Config.Universal.Return), + Handler: self.handleMenuClose, + Description: self.c.Tr.LcCloseMenu, }, { ViewName: "information", Key: gocui.MouseLeft, Modifier: gocui.ModNone, - Handler: gui.handleInfoClick, + Handler: self.handleInfoClick, }, { ViewName: "commitFiles", - Key: gui.getKey(config.Universal.CopyToClipboard), - Handler: gui.handleCopySelectedSideContextItemToClipboard, - Description: gui.c.Tr.LcCopyCommitFileNameToClipboard, + Key: opts.GetKey(opts.Config.Universal.CopyToClipboard), + Handler: self.handleCopySelectedSideContextItemToClipboard, + Description: self.c.Tr.LcCopyCommitFileNameToClipboard, }, { ViewName: "commitFiles", - Key: gui.getKey(config.CommitFiles.CheckoutCommitFile), - Handler: gui.handleCheckoutCommitFile, - Description: gui.c.Tr.LcCheckoutCommitFile, + Key: opts.GetKey(opts.Config.CommitFiles.CheckoutCommitFile), + Handler: self.handleCheckoutCommitFile, + Description: self.c.Tr.LcCheckoutCommitFile, }, { ViewName: "commitFiles", - Key: gui.getKey(config.Universal.Remove), - Handler: gui.handleDiscardOldFileChange, - Description: gui.c.Tr.LcDiscardOldFileChange, + Key: opts.GetKey(opts.Config.Universal.Remove), + Handler: self.handleDiscardOldFileChange, + Description: self.c.Tr.LcDiscardOldFileChange, }, { ViewName: "commitFiles", - Key: gui.getKey(config.Universal.OpenFile), - Handler: gui.handleOpenOldCommitFile, - Description: gui.c.Tr.LcOpenFile, + Key: opts.GetKey(opts.Config.Universal.OpenFile), + Handler: self.handleOpenOldCommitFile, + Description: self.c.Tr.LcOpenFile, }, { ViewName: "commitFiles", - Key: gui.getKey(config.Universal.Edit), - Handler: gui.handleEditCommitFile, - Description: gui.c.Tr.LcEditFile, + Key: opts.GetKey(opts.Config.Universal.Edit), + Handler: self.handleEditCommitFile, + Description: self.c.Tr.LcEditFile, }, { ViewName: "commitFiles", - Key: gui.getKey(config.Universal.Select), - Handler: gui.handleToggleFileForPatch, - Description: gui.c.Tr.LcToggleAddToPatch, + Key: opts.GetKey(opts.Config.Universal.Select), + Handler: self.handleToggleFileForPatch, + Description: self.c.Tr.LcToggleAddToPatch, }, { ViewName: "commitFiles", - Key: gui.getKey(config.Universal.GoInto), - Handler: gui.handleEnterCommitFile, - Description: gui.c.Tr.LcEnterFile, + Key: opts.GetKey(opts.Config.Universal.GoInto), + Handler: self.handleEnterCommitFile, + Description: self.c.Tr.LcEnterFile, }, { ViewName: "commitFiles", - Key: gui.getKey(config.Files.ToggleTreeView), - Handler: gui.handleToggleCommitFileTreeView, - Description: gui.c.Tr.LcToggleTreeView, + Key: opts.GetKey(opts.Config.Files.ToggleTreeView), + Handler: self.handleToggleCommitFileTreeView, + Description: self.c.Tr.LcToggleTreeView, }, { ViewName: "", - Key: gui.getKey(config.Universal.FilteringMenu), - Handler: gui.handleCreateFilteringMenuPanel, - Description: gui.c.Tr.LcOpenFilteringMenu, + Key: opts.GetKey(opts.Config.Universal.FilteringMenu), + Handler: self.handleCreateFilteringMenuPanel, + Description: self.c.Tr.LcOpenFilteringMenu, OpensMenu: true, }, { ViewName: "", - Key: gui.getKey(config.Universal.DiffingMenu), - Handler: gui.handleCreateDiffingMenuPanel, - Description: gui.c.Tr.LcOpenDiffingMenu, + Key: opts.GetKey(opts.Config.Universal.DiffingMenu), + Handler: self.handleCreateDiffingMenuPanel, + Description: self.c.Tr.LcOpenDiffingMenu, OpensMenu: true, }, { ViewName: "", - Key: gui.getKey(config.Universal.DiffingMenuAlt), - Handler: gui.handleCreateDiffingMenuPanel, - Description: gui.c.Tr.LcOpenDiffingMenu, + Key: opts.GetKey(opts.Config.Universal.DiffingMenuAlt), + Handler: self.handleCreateDiffingMenuPanel, + Description: self.c.Tr.LcOpenDiffingMenu, OpensMenu: true, }, { ViewName: "", - Key: gui.getKey(config.Universal.ExtrasMenu), - Handler: gui.handleCreateExtrasMenuPanel, - Description: gui.c.Tr.LcOpenExtrasMenu, + Key: opts.GetKey(opts.Config.Universal.ExtrasMenu), + Handler: self.handleCreateExtrasMenuPanel, + Description: self.c.Tr.LcOpenExtrasMenu, OpensMenu: true, }, { ViewName: "secondary", Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, - Handler: gui.scrollUpSecondary, + Handler: self.scrollUpSecondary, }, { ViewName: "secondary", Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, - Handler: gui.scrollDownSecondary, + Handler: self.scrollDownSecondary, }, { ViewName: "main", Contexts: []string{string(context.MAIN_NORMAL_CONTEXT_KEY)}, Key: gocui.MouseWheelDown, - Handler: gui.scrollDownMain, - Description: gui.c.Tr.ScrollDown, + Handler: self.scrollDownMain, + Description: self.c.Tr.ScrollDown, Alternative: "fn+up", }, { ViewName: "main", Contexts: []string{string(context.MAIN_NORMAL_CONTEXT_KEY)}, Key: gocui.MouseWheelUp, - Handler: gui.scrollUpMain, - Description: gui.c.Tr.ScrollUp, + Handler: self.scrollUpMain, + Description: self.c.Tr.ScrollUp, Alternative: "fn+down", }, { @@ -788,556 +695,550 @@ func (gui *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBin Contexts: []string{string(context.MAIN_NORMAL_CONTEXT_KEY)}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, - Handler: gui.handleMouseDownMain, + Handler: self.handleMouseDownMain, }, { ViewName: "secondary", Contexts: []string{string(context.MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, - Handler: gui.handleTogglePanelClick, + Handler: self.handleTogglePanelClick, }, { ViewName: "main", Contexts: []string{string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Return), - Handler: gui.handleStagingEscape, - Description: gui.c.Tr.ReturnToFilesPanel, + Key: opts.GetKey(opts.Config.Universal.Return), + Handler: self.handleStagingEscape, + Description: self.c.Tr.ReturnToFilesPanel, }, { ViewName: "main", Contexts: []string{string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Select), - Handler: gui.handleToggleStagedSelection, - Description: gui.c.Tr.StageSelection, + Key: opts.GetKey(opts.Config.Universal.Select), + Handler: self.handleToggleStagedSelection, + Description: self.c.Tr.StageSelection, }, { ViewName: "main", Contexts: []string{string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Remove), - Handler: gui.handleResetSelection, - Description: gui.c.Tr.ResetSelection, + Key: opts.GetKey(opts.Config.Universal.Remove), + Handler: self.handleResetSelection, + Description: self.c.Tr.ResetSelection, }, { ViewName: "main", Contexts: []string{string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.TogglePanel), - Handler: gui.handleTogglePanel, - Description: gui.c.Tr.TogglePanel, + Key: opts.GetKey(opts.Config.Universal.TogglePanel), + Handler: self.handleTogglePanel, + Description: self.c.Tr.TogglePanel, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Return), - Handler: gui.handleEscapePatchBuildingPanel, - Description: gui.c.Tr.ExitLineByLineMode, + Key: opts.GetKey(opts.Config.Universal.Return), + Handler: self.handleEscapePatchBuildingPanel, + Description: self.c.Tr.ExitLineByLineMode, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.OpenFile), - Handler: gui.handleOpenFileAtLine, - Description: gui.c.Tr.LcOpenFile, + Key: opts.GetKey(opts.Config.Universal.OpenFile), + Handler: self.handleOpenFileAtLine, + Description: self.c.Tr.LcOpenFile, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevItem), - Handler: gui.handleSelectPrevLine, - Description: gui.c.Tr.PrevLine, + Key: opts.GetKey(opts.Config.Universal.PrevItem), + Handler: self.handleSelectPrevLine, + Description: self.c.Tr.PrevLine, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextItem), - Handler: gui.handleSelectNextLine, - Description: gui.c.Tr.NextLine, + Key: opts.GetKey(opts.Config.Universal.NextItem), + Handler: self.handleSelectNextLine, + Description: self.c.Tr.NextLine, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevItemAlt), + Key: opts.GetKey(opts.Config.Universal.PrevItemAlt), Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevLine, + Handler: self.handleSelectPrevLine, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextItemAlt), + Key: opts.GetKey(opts.Config.Universal.NextItemAlt), Modifier: gocui.ModNone, - Handler: gui.handleSelectNextLine, + Handler: self.handleSelectNextLine, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, - Handler: gui.scrollUpMain, + Handler: self.scrollUpMain, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, - Handler: gui.scrollDownMain, + Handler: self.scrollDownMain, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevBlock), - Handler: gui.handleSelectPrevHunk, - Description: gui.c.Tr.PrevHunk, + Key: opts.GetKey(opts.Config.Universal.PrevBlock), + Handler: self.handleSelectPrevHunk, + Description: self.c.Tr.PrevHunk, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevBlockAlt), + Key: opts.GetKey(opts.Config.Universal.PrevBlockAlt), Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevHunk, + Handler: self.handleSelectPrevHunk, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextBlock), - Handler: gui.handleSelectNextHunk, - Description: gui.c.Tr.NextHunk, + Key: opts.GetKey(opts.Config.Universal.NextBlock), + Handler: self.handleSelectNextHunk, + Description: self.c.Tr.NextHunk, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextBlockAlt), + Key: opts.GetKey(opts.Config.Universal.NextBlockAlt), Modifier: gocui.ModNone, - Handler: gui.handleSelectNextHunk, + Handler: self.handleSelectNextHunk, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.CopyToClipboard), + Key: opts.GetKey(opts.Config.Universal.CopyToClipboard), Modifier: gocui.ModNone, - Handler: gui.copySelectedToClipboard, - Description: gui.c.Tr.LcCopySelectedTexToClipboard, + Handler: self.copySelectedToClipboard, + Description: self.c.Tr.LcCopySelectedTexToClipboard, }, { ViewName: "main", Contexts: []string{string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Edit), - Handler: gui.handleLineByLineEdit, - Description: gui.c.Tr.LcEditFile, + Key: opts.GetKey(opts.Config.Universal.Edit), + Handler: self.handleLineByLineEdit, + Description: self.c.Tr.LcEditFile, }, { ViewName: "main", Contexts: []string{string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.OpenFile), - Handler: gui.Controllers.Files.Open, - Description: gui.c.Tr.LcOpenFile, + Key: opts.GetKey(opts.Config.Universal.OpenFile), + Handler: self.Controllers.Files.Open, + Description: self.c.Tr.LcOpenFile, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextPage), + Key: opts.GetKey(opts.Config.Universal.NextPage), Modifier: gocui.ModNone, - Handler: gui.handleLineByLineNextPage, - Description: gui.c.Tr.LcNextPage, + Handler: self.handleLineByLineNextPage, + Description: self.c.Tr.LcNextPage, Tag: "navigation", }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevPage), + Key: opts.GetKey(opts.Config.Universal.PrevPage), Modifier: gocui.ModNone, - Handler: gui.handleLineByLinePrevPage, - Description: gui.c.Tr.LcPrevPage, + Handler: self.handleLineByLinePrevPage, + Description: self.c.Tr.LcPrevPage, Tag: "navigation", }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.GotoTop), + Key: opts.GetKey(opts.Config.Universal.GotoTop), Modifier: gocui.ModNone, - Handler: gui.handleLineByLineGotoTop, - Description: gui.c.Tr.LcGotoTop, + Handler: self.handleLineByLineGotoTop, + Description: self.c.Tr.LcGotoTop, Tag: "navigation", }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.GotoBottom), + Key: opts.GetKey(opts.Config.Universal.GotoBottom), Modifier: gocui.ModNone, - Handler: gui.handleLineByLineGotoBottom, - Description: gui.c.Tr.LcGotoBottom, + Handler: self.handleLineByLineGotoBottom, + Description: self.c.Tr.LcGotoBottom, Tag: "navigation", }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.StartSearch), - Handler: func() error { return gui.handleOpenSearch("main") }, - Description: gui.c.Tr.LcStartSearch, + Key: opts.GetKey(opts.Config.Universal.StartSearch), + Handler: func() error { return self.handleOpenSearch("main") }, + Description: self.c.Tr.LcStartSearch, Tag: "navigation", }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Select), - Handler: gui.handleToggleSelectionForPatch, - Description: gui.c.Tr.ToggleSelectionForPatch, + Key: opts.GetKey(opts.Config.Universal.Select), + Handler: self.handleToggleSelectionForPatch, + Description: self.c.Tr.ToggleSelectionForPatch, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Main.ToggleDragSelect), - Handler: gui.handleToggleSelectRange, - Description: gui.c.Tr.ToggleDragSelect, + Key: opts.GetKey(opts.Config.Main.ToggleDragSelect), + Handler: self.handleToggleSelectRange, + Description: self.c.Tr.ToggleDragSelect, }, // Alias 'V' -> 'v' { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Main.ToggleDragSelectAlt), - Handler: gui.handleToggleSelectRange, - Description: gui.c.Tr.ToggleDragSelect, + Key: opts.GetKey(opts.Config.Main.ToggleDragSelectAlt), + Handler: self.handleToggleSelectRange, + Description: self.c.Tr.ToggleDragSelect, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Main.ToggleSelectHunk), - Handler: gui.handleToggleSelectHunk, - Description: gui.c.Tr.ToggleSelectHunk, + Key: opts.GetKey(opts.Config.Main.ToggleSelectHunk), + Handler: self.handleToggleSelectHunk, + Description: self.c.Tr.ToggleSelectHunk, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, - Handler: gui.handleLBLMouseDown, + Handler: self.handleLBLMouseDown, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseLeft, Modifier: gocui.ModMotion, - Handler: gui.handleMouseDrag, + Handler: self.handleMouseDrag, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, - Handler: gui.scrollUpMain, + Handler: self.scrollUpMain, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, - Handler: gui.scrollDownMain, + Handler: self.scrollDownMain, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY), string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.ScrollLeft), - Handler: gui.scrollLeftMain, - Description: gui.c.Tr.LcScrollLeft, + Key: opts.GetKey(opts.Config.Universal.ScrollLeft), + Handler: self.scrollLeftMain, + Description: self.c.Tr.LcScrollLeft, }, { ViewName: "main", Contexts: []string{string(context.MAIN_PATCH_BUILDING_CONTEXT_KEY), string(context.MAIN_STAGING_CONTEXT_KEY), string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.ScrollRight), - Handler: gui.scrollRightMain, - Description: gui.c.Tr.LcScrollRight, + Key: opts.GetKey(opts.Config.Universal.ScrollRight), + Handler: self.scrollRightMain, + Description: self.c.Tr.LcScrollRight, }, { ViewName: "main", Contexts: []string{string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Files.CommitChanges), - Handler: gui.Controllers.Files.HandleCommitPress, - Description: gui.c.Tr.CommitChanges, + Key: opts.GetKey(opts.Config.Files.CommitChanges), + Handler: self.Controllers.Files.HandleCommitPress, + Description: self.c.Tr.CommitChanges, }, { ViewName: "main", Contexts: []string{string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Files.CommitChangesWithoutHook), - Handler: gui.Controllers.Files.HandleWIPCommitPress, - Description: gui.c.Tr.LcCommitChangesWithoutHook, + Key: opts.GetKey(opts.Config.Files.CommitChangesWithoutHook), + Handler: self.Controllers.Files.HandleWIPCommitPress, + Description: self.c.Tr.LcCommitChangesWithoutHook, }, { ViewName: "main", Contexts: []string{string(context.MAIN_STAGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Files.CommitChangesWithEditor), - Handler: gui.Controllers.Files.HandleCommitEditorPress, - Description: gui.c.Tr.CommitChangesWithEditor, + Key: opts.GetKey(opts.Config.Files.CommitChangesWithEditor), + Handler: self.Controllers.Files.HandleCommitEditorPress, + Description: self.c.Tr.CommitChangesWithEditor, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Return), - Handler: gui.handleEscapeMerge, - Description: gui.c.Tr.ReturnToFilesPanel, + Key: opts.GetKey(opts.Config.Universal.Return), + Handler: self.handleEscapeMerge, + Description: self.c.Tr.ReturnToFilesPanel, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Files.OpenMergeTool), - Handler: gui.Controllers.Files.OpenMergeTool, - Description: gui.c.Tr.LcOpenMergeTool, + Key: opts.GetKey(opts.Config.Files.OpenMergeTool), + Handler: self.Controllers.Files.OpenMergeTool, + Description: self.c.Tr.LcOpenMergeTool, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Select), - Handler: gui.handlePickHunk, - Description: gui.c.Tr.PickHunk, + Key: opts.GetKey(opts.Config.Universal.Select), + Handler: self.handlePickHunk, + Description: self.c.Tr.PickHunk, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Main.PickBothHunks), - Handler: gui.handlePickAllHunks, - Description: gui.c.Tr.PickAllHunks, + Key: opts.GetKey(opts.Config.Main.PickBothHunks), + Handler: self.handlePickAllHunks, + Description: self.c.Tr.PickAllHunks, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevBlock), - Handler: gui.handleSelectPrevConflict, - Description: gui.c.Tr.PrevConflict, + Key: opts.GetKey(opts.Config.Universal.PrevBlock), + Handler: self.handleSelectPrevConflict, + Description: self.c.Tr.PrevConflict, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextBlock), - Handler: gui.handleSelectNextConflict, - Description: gui.c.Tr.NextConflict, + Key: opts.GetKey(opts.Config.Universal.NextBlock), + Handler: self.handleSelectNextConflict, + Description: self.c.Tr.NextConflict, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevItem), - Handler: gui.handleSelectPrevConflictHunk, - Description: gui.c.Tr.SelectPrevHunk, + Key: opts.GetKey(opts.Config.Universal.PrevItem), + Handler: self.handleSelectPrevConflictHunk, + Description: self.c.Tr.SelectPrevHunk, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextItem), - Handler: gui.handleSelectNextConflictHunk, - Description: gui.c.Tr.SelectNextHunk, + Key: opts.GetKey(opts.Config.Universal.NextItem), + Handler: self.handleSelectNextConflictHunk, + Description: self.c.Tr.SelectNextHunk, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevBlockAlt), + Key: opts.GetKey(opts.Config.Universal.PrevBlockAlt), Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevConflict, + Handler: self.handleSelectPrevConflict, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextBlockAlt), + Key: opts.GetKey(opts.Config.Universal.NextBlockAlt), Modifier: gocui.ModNone, - Handler: gui.handleSelectNextConflict, + Handler: self.handleSelectNextConflict, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevItemAlt), + Key: opts.GetKey(opts.Config.Universal.PrevItemAlt), Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevConflictHunk, + Handler: self.handleSelectPrevConflictHunk, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextItemAlt), + Key: opts.GetKey(opts.Config.Universal.NextItemAlt), Modifier: gocui.ModNone, - Handler: gui.handleSelectNextConflictHunk, + Handler: self.handleSelectNextConflictHunk, }, { ViewName: "main", Contexts: []string{string(context.MAIN_MERGING_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Undo), - Handler: gui.handleMergeConflictUndo, - Description: gui.c.Tr.LcUndo, + Key: opts.GetKey(opts.Config.Universal.Undo), + Handler: self.handleMergeConflictUndo, + Description: self.c.Tr.LcUndo, }, { ViewName: "branches", Contexts: []string{string(context.REMOTE_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Select), + Key: opts.GetKey(opts.Config.Universal.Select), // gonna use the exact same handler as the 'n' keybinding because everybody wants this to happen when they checkout a remote branch - Handler: gui.handleNewBranchOffRemoteBranch, - Description: gui.c.Tr.LcCheckout, + Handler: self.handleNewBranchOffRemoteBranch, + Description: self.c.Tr.LcCheckout, }, { ViewName: "branches", Contexts: []string{string(context.REMOTE_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.New), - Handler: gui.handleNewBranchOffRemoteBranch, - Description: gui.c.Tr.LcNewBranch, + Key: opts.GetKey(opts.Config.Universal.New), + Handler: self.handleNewBranchOffRemoteBranch, + Description: self.c.Tr.LcNewBranch, }, { ViewName: "branches", Contexts: []string{string(context.REMOTE_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.MergeIntoCurrentBranch), - Handler: guards.OutsideFilterMode(gui.handleMergeRemoteBranch), - Description: gui.c.Tr.LcMergeIntoCurrentBranch, + Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch), + Handler: opts.Guards.OutsideFilterMode(self.handleMergeRemoteBranch), + Description: self.c.Tr.LcMergeIntoCurrentBranch, }, { ViewName: "branches", Contexts: []string{string(context.REMOTE_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.Remove), - Handler: gui.handleDeleteRemoteBranch, - Description: gui.c.Tr.LcDeleteBranch, + Key: opts.GetKey(opts.Config.Universal.Remove), + Handler: self.handleDeleteRemoteBranch, + Description: self.c.Tr.LcDeleteBranch, }, { ViewName: "branches", Contexts: []string{string(context.REMOTE_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.RebaseBranch), - Handler: guards.OutsideFilterMode(gui.handleRebaseOntoRemoteBranch), - Description: gui.c.Tr.LcRebaseBranch, + Key: opts.GetKey(opts.Config.Branches.RebaseBranch), + Handler: opts.Guards.OutsideFilterMode(self.handleRebaseOntoRemoteBranch), + Description: self.c.Tr.LcRebaseBranch, }, { ViewName: "branches", Contexts: []string{string(context.REMOTE_BRANCHES_CONTEXT_KEY)}, - Key: gui.getKey(config.Branches.SetUpstream), - Handler: gui.handleSetBranchUpstream, - Description: gui.c.Tr.LcSetUpstream, + Key: opts.GetKey(opts.Config.Branches.SetUpstream), + Handler: self.handleSetBranchUpstream, + Description: self.c.Tr.LcSetUpstream, }, { ViewName: "status", Key: gocui.MouseLeft, Modifier: gocui.ModNone, - Handler: gui.handleStatusClick, + Handler: self.handleStatusClick, }, { ViewName: "search", - Key: gui.getKey(config.Universal.Confirm), + Key: opts.GetKey(opts.Config.Universal.Confirm), Modifier: gocui.ModNone, - Handler: gui.handleSearch, + Handler: self.handleSearch, }, { ViewName: "search", - Key: gui.getKey(config.Universal.Return), + Key: opts.GetKey(opts.Config.Universal.Return), Modifier: gocui.ModNone, - Handler: gui.handleSearchEscape, + Handler: self.handleSearchEscape, }, { ViewName: "confirmation", - Key: gui.getKey(config.Universal.PrevItem), + Key: opts.GetKey(opts.Config.Universal.PrevItem), Modifier: gocui.ModNone, - Handler: gui.scrollUpConfirmationPanel, + Handler: self.scrollUpConfirmationPanel, }, { ViewName: "confirmation", - Key: gui.getKey(config.Universal.NextItem), + Key: opts.GetKey(opts.Config.Universal.NextItem), Modifier: gocui.ModNone, - Handler: gui.scrollDownConfirmationPanel, + Handler: self.scrollDownConfirmationPanel, }, { ViewName: "confirmation", - Key: gui.getKey(config.Universal.PrevItemAlt), + Key: opts.GetKey(opts.Config.Universal.PrevItemAlt), Modifier: gocui.ModNone, - Handler: gui.scrollUpConfirmationPanel, + Handler: self.scrollUpConfirmationPanel, }, { ViewName: "confirmation", - Key: gui.getKey(config.Universal.NextItemAlt), + Key: opts.GetKey(opts.Config.Universal.NextItemAlt), Modifier: gocui.ModNone, - Handler: gui.scrollDownConfirmationPanel, + Handler: self.scrollDownConfirmationPanel, }, { ViewName: "files", Contexts: []string{string(context.SUBMODULES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.CopyToClipboard), - Handler: gui.handleCopySelectedSideContextItemToClipboard, - Description: gui.c.Tr.LcCopySubmoduleNameToClipboard, + Key: opts.GetKey(opts.Config.Universal.CopyToClipboard), + Handler: self.handleCopySelectedSideContextItemToClipboard, + Description: self.c.Tr.LcCopySubmoduleNameToClipboard, }, { ViewName: "files", Contexts: []string{string(context.FILES_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.ToggleWhitespaceInDiffView), - Handler: gui.toggleWhitespaceInDiffView, - Description: gui.c.Tr.ToggleWhitespaceInDiffView, + Key: opts.GetKey(opts.Config.Universal.ToggleWhitespaceInDiffView), + Handler: self.toggleWhitespaceInDiffView, + Description: self.c.Tr.ToggleWhitespaceInDiffView, }, { ViewName: "", - Key: gui.getKey(config.Universal.IncreaseContextInDiffView), - Handler: gui.IncreaseContextInDiffView, - Description: gui.c.Tr.IncreaseContextInDiffView, + Key: opts.GetKey(opts.Config.Universal.IncreaseContextInDiffView), + Handler: self.IncreaseContextInDiffView, + Description: self.c.Tr.IncreaseContextInDiffView, }, { ViewName: "", - Key: gui.getKey(config.Universal.DecreaseContextInDiffView), - Handler: gui.DecreaseContextInDiffView, - Description: gui.c.Tr.DecreaseContextInDiffView, + Key: opts.GetKey(opts.Config.Universal.DecreaseContextInDiffView), + Handler: self.DecreaseContextInDiffView, + Description: self.c.Tr.DecreaseContextInDiffView, }, { ViewName: "extras", Key: gocui.MouseWheelUp, - Handler: gui.scrollUpExtra, + Handler: self.scrollUpExtra, }, { ViewName: "extras", Key: gocui.MouseWheelDown, - Handler: gui.scrollDownExtra, + Handler: self.scrollDownExtra, }, { ViewName: "extras", - Key: gui.getKey(config.Universal.ExtrasMenu), - Handler: gui.handleCreateExtrasMenuPanel, - Description: gui.c.Tr.LcOpenExtrasMenu, + Key: opts.GetKey(opts.Config.Universal.ExtrasMenu), + Handler: self.handleCreateExtrasMenuPanel, + Description: self.c.Tr.LcOpenExtrasMenu, OpensMenu: true, }, { ViewName: "extras", Tag: "navigation", Contexts: []string{string(context.COMMAND_LOG_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevItemAlt), + Key: opts.GetKey(opts.Config.Universal.PrevItemAlt), Modifier: gocui.ModNone, - Handler: gui.scrollUpExtra, + Handler: self.scrollUpExtra, }, { ViewName: "extras", Tag: "navigation", Contexts: []string{string(context.COMMAND_LOG_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.PrevItem), + Key: opts.GetKey(opts.Config.Universal.PrevItem), Modifier: gocui.ModNone, - Handler: gui.scrollUpExtra, + Handler: self.scrollUpExtra, }, { ViewName: "extras", Tag: "navigation", Contexts: []string{string(context.COMMAND_LOG_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextItem), + Key: opts.GetKey(opts.Config.Universal.NextItem), Modifier: gocui.ModNone, - Handler: gui.scrollDownExtra, + Handler: self.scrollDownExtra, }, { ViewName: "extras", Tag: "navigation", Contexts: []string{string(context.COMMAND_LOG_CONTEXT_KEY)}, - Key: gui.getKey(config.Universal.NextItemAlt), + Key: opts.GetKey(opts.Config.Universal.NextItemAlt), Modifier: gocui.ModNone, - Handler: gui.scrollDownExtra, + Handler: self.scrollDownExtra, }, { ViewName: "extras", Tag: "navigation", Key: gocui.MouseLeft, Modifier: gocui.ModNone, - Handler: gui.handleFocusCommandLog, + Handler: self.handleFocusCommandLog, }, } - keybindingsOpts := types.KeybindingsOpts{ - GetKey: gui.getKey, - Config: config, - Guards: guards, - } - mouseKeybindings := []*gocui.ViewMouseBinding{} - for _, c := range gui.State.Contexts.Flatten() { + for _, c := range self.State.Contexts.Flatten() { viewName := c.GetViewName() contextKey := c.GetKey() - for _, binding := range c.GetKeybindings(keybindingsOpts) { + for _, binding := range c.GetKeybindings(opts) { // TODO: move all mouse keybindings into the mouse keybindings approach below if !gocui.IsMouseKey(binding.Key) && contextKey != context.GLOBAL_CONTEXT_KEY { binding.Contexts = []string{string(contextKey)} @@ -1346,7 +1247,7 @@ func (gui *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBin bindings = append(bindings, binding) } - for _, binding := range c.GetMouseKeybindings(keybindingsOpts) { + for _, binding := range c.GetMouseKeybindings(opts) { if contextKey != context.GLOBAL_CONTEXT_KEY { binding.FromContext = string(contextKey) } @@ -1356,12 +1257,12 @@ func (gui *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBin for _, viewName := range []string{"status", "branches", "files", "commits", "commitFiles", "stash", "menu"} { bindings = append(bindings, []*types.Binding{ - {ViewName: viewName, Key: gui.getKey(config.Universal.PrevBlock), Modifier: gocui.ModNone, Handler: gui.previousSideWindow}, - {ViewName: viewName, Key: gui.getKey(config.Universal.NextBlock), Modifier: gocui.ModNone, Handler: gui.nextSideWindow}, - {ViewName: viewName, Key: gui.getKey(config.Universal.PrevBlockAlt), Modifier: gocui.ModNone, Handler: gui.previousSideWindow}, - {ViewName: viewName, Key: gui.getKey(config.Universal.NextBlockAlt), Modifier: gocui.ModNone, Handler: gui.nextSideWindow}, - {ViewName: viewName, Key: gui.getKey(config.Universal.PrevBlockAlt2), Modifier: gocui.ModNone, Handler: gui.previousSideWindow}, - {ViewName: viewName, Key: gui.getKey(config.Universal.NextBlockAlt2), Modifier: gocui.ModNone, Handler: gui.nextSideWindow}, + {ViewName: viewName, Key: opts.GetKey(opts.Config.Universal.PrevBlock), Modifier: gocui.ModNone, Handler: self.previousSideWindow}, + {ViewName: viewName, Key: opts.GetKey(opts.Config.Universal.NextBlock), Modifier: gocui.ModNone, Handler: self.nextSideWindow}, + {ViewName: viewName, Key: opts.GetKey(opts.Config.Universal.PrevBlockAlt), Modifier: gocui.ModNone, Handler: self.previousSideWindow}, + {ViewName: viewName, Key: opts.GetKey(opts.Config.Universal.NextBlockAlt), Modifier: gocui.ModNone, Handler: self.nextSideWindow}, + {ViewName: viewName, Key: opts.GetKey(opts.Config.Universal.PrevBlockAlt2), Modifier: gocui.ModNone, Handler: self.previousSideWindow}, + {ViewName: viewName, Key: opts.GetKey(opts.Config.Universal.NextBlockAlt2), Modifier: gocui.ModNone, Handler: self.nextSideWindow}, }...) } @@ -1374,26 +1275,26 @@ func (gui *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBin for i, window := range windows { bindings = append(bindings, &types.Binding{ ViewName: "", - Key: gui.getKey(config.Universal.JumpToBlock[i]), + Key: opts.GetKey(opts.Config.Universal.JumpToBlock[i]), Modifier: gocui.ModNone, - Handler: gui.goToSideWindow(window)}) + Handler: self.goToSideWindow(window)}) } } - for viewName := range gui.State.Contexts.InitialViewTabContextMap() { + for viewName := range self.State.Contexts.InitialViewTabContextMap() { bindings = append(bindings, []*types.Binding{ { ViewName: viewName, - Key: gui.getKey(config.Universal.NextTab), - Handler: gui.handleNextTab, - Description: gui.c.Tr.LcNextTab, + Key: opts.GetKey(opts.Config.Universal.NextTab), + Handler: self.handleNextTab, + Description: self.c.Tr.LcNextTab, Tag: "navigation", }, { ViewName: viewName, - Key: gui.getKey(config.Universal.PrevTab), - Handler: gui.handlePrevTab, - Description: gui.c.Tr.LcPrevTab, + Key: opts.GetKey(opts.Config.Universal.PrevTab), + Handler: self.handlePrevTab, + Description: self.c.Tr.LcPrevTab, Tag: "navigation", }, }...) diff --git a/pkg/gui/modes.go b/pkg/gui/modes.go index 6424c8540..882e6d863 100644 --- a/pkg/gui/modes.go +++ b/pkg/gui/modes.go @@ -73,7 +73,7 @@ func (gui *Gui) modeStatuses() []modeStatus { formatWorkingTreeState(workingTreeState), style.FgYellow, ) }, - reset: gui.helpers.Rebase.AbortMergeOrRebaseWithConfirm, + reset: gui.helpers.MergeAndRebase.AbortMergeOrRebaseWithConfirm, }, { isActive: func() bool { diff --git a/pkg/gui/patch_options_panel.go b/pkg/gui/patch_options_panel.go index d69dbda27..81d232da2 100644 --- a/pkg/gui/patch_options_panel.go +++ b/pkg/gui/patch_options_panel.go @@ -102,7 +102,7 @@ func (gui *Gui) handleDeletePatchFromCommit() error { commitIndex := gui.getPatchCommitIndex() gui.c.LogAction(gui.c.Tr.Actions.RemovePatchFromCommit) err := gui.git.Patch.DeletePatchesFromCommit(gui.State.Model.Commits, commitIndex) - return gui.helpers.Rebase.CheckMergeOrRebase(err) + return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err) }) } @@ -119,7 +119,7 @@ func (gui *Gui) handleMovePatchToSelectedCommit() error { commitIndex := gui.getPatchCommitIndex() gui.c.LogAction(gui.c.Tr.Actions.MovePatchToSelectedCommit) err := gui.git.Patch.MovePatchToSelectedCommit(gui.State.Model.Commits, commitIndex, gui.State.Contexts.BranchCommits.GetSelectedLineIdx()) - return gui.helpers.Rebase.CheckMergeOrRebase(err) + return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err) }) } @@ -137,7 +137,7 @@ func (gui *Gui) handleMovePatchIntoWorkingTree() error { commitIndex := gui.getPatchCommitIndex() gui.c.LogAction(gui.c.Tr.Actions.MovePatchIntoIndex) err := gui.git.Patch.MovePatchIntoIndex(gui.State.Model.Commits, commitIndex, stash) - return gui.helpers.Rebase.CheckMergeOrRebase(err) + return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err) }) } @@ -167,7 +167,7 @@ func (gui *Gui) handlePullPatchIntoNewCommit() error { commitIndex := gui.getPatchCommitIndex() gui.c.LogAction(gui.c.Tr.Actions.MovePatchIntoNewCommit) err := gui.git.Patch.PullPatchIntoNewCommit(gui.State.Model.Commits, commitIndex) - return gui.helpers.Rebase.CheckMergeOrRebase(err) + return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err) }) } diff --git a/pkg/gui/pull_request_menu_panel.go b/pkg/gui/pull_request_menu_panel.go deleted file mode 100644 index 1f63c6306..000000000 --- a/pkg/gui/pull_request_menu_panel.go +++ /dev/null @@ -1,78 +0,0 @@ -package gui - -import ( - "fmt" - - "github.com/jesseduffield/lazygit/pkg/commands/hosting_service" - "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/jesseduffield/lazygit/pkg/gui/types" -) - -func (gui *Gui) createPullRequestMenu(selectedBranch *models.Branch, checkedOutBranch *models.Branch) error { - menuItems := make([]*types.MenuItem, 0, 4) - - fromToDisplayStrings := func(from string, to string) []string { - return []string{fmt.Sprintf("%s → %s", from, to)} - } - - menuItemsForBranch := func(branch *models.Branch) []*types.MenuItem { - return []*types.MenuItem{ - { - DisplayStrings: fromToDisplayStrings(branch.Name, gui.c.Tr.LcDefaultBranch), - OnPress: func() error { - return gui.createPullRequest(branch.Name, "") - }, - }, - { - DisplayStrings: fromToDisplayStrings(branch.Name, gui.c.Tr.LcSelectBranch), - OnPress: func() error { - return gui.c.Prompt(types.PromptOpts{ - Title: branch.Name + " →", - FindSuggestionsFunc: gui.helpers.Suggestions.GetBranchNameSuggestionsFunc(), - HandleConfirm: func(targetBranchName string) error { - return gui.createPullRequest(branch.Name, targetBranchName) - }}, - ) - }, - }, - } - } - - if selectedBranch != checkedOutBranch { - menuItems = append(menuItems, - &types.MenuItem{ - DisplayStrings: fromToDisplayStrings(checkedOutBranch.Name, selectedBranch.Name), - OnPress: func() error { - return gui.createPullRequest(checkedOutBranch.Name, selectedBranch.Name) - }, - }, - ) - menuItems = append(menuItems, menuItemsForBranch(checkedOutBranch)...) - } - - menuItems = append(menuItems, menuItemsForBranch(selectedBranch)...) - - return gui.c.Menu(types.CreateMenuOptions{Title: fmt.Sprintf(gui.c.Tr.CreatePullRequestOptions), Items: menuItems}) -} - -func (gui *Gui) createPullRequest(from string, to string) error { - hostingServiceMgr := gui.getHostingServiceMgr() - url, err := hostingServiceMgr.GetPullRequestURL(from, to) - if err != nil { - return gui.c.Error(err) - } - - gui.c.LogAction(gui.c.Tr.Actions.OpenPullRequest) - - if err := gui.os.OpenLink(url); err != nil { - return gui.c.Error(err) - } - - return nil -} - -func (gui *Gui) getHostingServiceMgr() *hosting_service.HostingServiceMgr { - remoteUrl := gui.git.Config.GetRemoteURL() - configServices := gui.c.UserConfig.Services - return hosting_service.NewHostingServiceMgr(gui.Log, gui.Tr, remoteUrl, configServices) -} diff --git a/pkg/gui/reflog_panel.go b/pkg/gui/reflog_panel.go index 472c073cd..97fd1dd4f 100644 --- a/pkg/gui/reflog_panel.go +++ b/pkg/gui/reflog_panel.go @@ -65,10 +65,9 @@ func (gui *Gui) handleViewReflogCommitFiles() error { } return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{ - RefName: commit.Sha, - CanRebase: false, - Context: gui.State.Contexts.ReflogCommits, - WindowName: "commits", + RefName: commit.Sha, + CanRebase: false, + Context: gui.State.Contexts.ReflogCommits, }) } diff --git a/pkg/gui/refresh.go b/pkg/gui/refresh.go index 84d58d815..215028609 100644 --- a/pkg/gui/refresh.go +++ b/pkg/gui/refresh.go @@ -215,7 +215,7 @@ func (gui *Gui) refreshCommitsWithLimit() error { FilterPath: gui.State.Modes.Filtering.GetPath(), IncludeRebaseCommits: true, RefName: gui.refForLog(), - All: gui.ShowWholeGitGraph, + All: gui.State.Contexts.BranchCommits.GetShowWholeGitGraph(), }, ) if err != nil { @@ -408,7 +408,7 @@ func (gui *Gui) refreshStateFiles() error { } if gui.git.Status.WorkingTreeState() != enums.REBASE_MODE_NONE && conflictFileCount == 0 && prevConflictFileCount > 0 { - gui.OnUIThread(func() error { return gui.helpers.Rebase.PromptToContinueRebase() }) + gui.OnUIThread(func() error { return gui.helpers.MergeAndRebase.PromptToContinueRebase() }) } fileTreeViewModel.RWMutex.Lock() @@ -526,7 +526,7 @@ func (gui *Gui) refreshStatus() { gui.Mutexes.RefreshingStatusMutex.Lock() defer gui.Mutexes.RefreshingStatusMutex.Unlock() - currentBranch := gui.getCheckedOutBranch() + currentBranch := gui.helpers.Refs.GetCheckedOutRef() if currentBranch == nil { // need to wait for branches to refresh return diff --git a/pkg/gui/remote_branches_panel.go b/pkg/gui/remote_branches_panel.go index 243a7ca4d..eeed4cd13 100644 --- a/pkg/gui/remote_branches_panel.go +++ b/pkg/gui/remote_branches_panel.go @@ -34,7 +34,7 @@ func (gui *Gui) handleRemoteBranchesEscape() error { func (gui *Gui) handleMergeRemoteBranch() error { selectedBranchName := gui.State.Contexts.RemoteBranches.GetSelected().FullName() - return gui.mergeBranchIntoCheckedOutBranch(selectedBranchName) + return gui.helpers.MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranchName) } func (gui *Gui) handleDeleteRemoteBranch() error { @@ -63,12 +63,12 @@ func (gui *Gui) handleDeleteRemoteBranch() error { func (gui *Gui) handleRebaseOntoRemoteBranch() error { selectedBranchName := gui.State.Contexts.RemoteBranches.GetSelected().FullName() - return gui.handleRebaseOntoBranch(selectedBranchName) + return gui.helpers.MergeAndRebase.RebaseOntoRef(selectedBranchName) } func (gui *Gui) handleSetBranchUpstream() error { selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected() - checkedOutBranch := gui.getCheckedOutBranch() + checkedOutBranch := gui.helpers.Refs.GetCheckedOutRef() message := utils.ResolvePlaceholderString( gui.c.Tr.SetUpstreamMessage, @@ -101,15 +101,6 @@ func (gui *Gui) handleCreateResetToRemoteBranchMenu() error { return gui.helpers.Refs.CreateGitResetMenu(selectedBranch.FullName()) } -func (gui *Gui) handleEnterRemoteBranch() error { - selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected() - if selectedBranch == nil { - return nil - } - - return gui.switchToSubCommitsContext(selectedBranch.RefName()) -} - func (gui *Gui) handleNewBranchOffRemoteBranch() error { selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected() if selectedBranch == nil { diff --git a/pkg/gui/stash_panel.go b/pkg/gui/stash_panel.go index e51fcc054..6da862004 100644 --- a/pkg/gui/stash_panel.go +++ b/pkg/gui/stash_panel.go @@ -37,8 +37,6 @@ func (gui *Gui) handleStashApply() error { return nil } - skipStashWarning := gui.c.UserConfig.Gui.SkipStashWarning - apply := func() error { gui.c.LogAction(gui.c.Tr.Actions.Stash) err := gui.git.Stash.Apply(stashEntry.Index) @@ -49,7 +47,7 @@ func (gui *Gui) handleStashApply() error { return nil } - if skipStashWarning { + if gui.c.UserConfig.Gui.SkipStashWarning { return apply() } @@ -68,8 +66,6 @@ func (gui *Gui) handleStashPop() error { return nil } - skipStashWarning := gui.c.UserConfig.Gui.SkipStashWarning - pop := func() error { gui.c.LogAction(gui.c.Tr.Actions.Stash) err := gui.git.Stash.Pop(stashEntry.Index) @@ -80,7 +76,7 @@ func (gui *Gui) handleStashPop() error { return nil } - if skipStashWarning { + if gui.c.UserConfig.Gui.SkipStashWarning { return pop() } @@ -125,10 +121,9 @@ func (gui *Gui) handleViewStashFiles() error { } return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{ - RefName: stashEntry.RefName(), - CanRebase: false, - Context: gui.State.Contexts.Stash, - WindowName: "stash", + RefName: stashEntry.RefName(), + CanRebase: false, + Context: gui.State.Contexts.Stash, }) } diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go index fd1d75133..072f41da9 100644 --- a/pkg/gui/status_panel.go +++ b/pkg/gui/status_panel.go @@ -30,7 +30,7 @@ func (gui *Gui) handleCheckForUpdate() error { func (gui *Gui) handleStatusClick() error { // TODO: move into some abstraction (status is currently not a listViewContext where a lot of this code lives) - currentBranch := gui.getCheckedOutBranch() + currentBranch := gui.helpers.Refs.GetCheckedOutRef() if currentBranch == nil { // need to wait for branches to refresh return nil @@ -48,7 +48,7 @@ func (gui *Gui) handleStatusClick() error { case enums.REBASE_MODE_REBASING, enums.REBASE_MODE_MERGING: workingTreeStatus := fmt.Sprintf("(%s)", formatWorkingTreeState(workingTreeState)) if cursorInSubstring(cx, upstreamStatus+" ", workingTreeStatus) { - return gui.helpers.Rebase.CreateRebaseOptionsMenu() + return gui.helpers.MergeAndRebase.CreateRebaseOptionsMenu() } if cursorInSubstring(cx, upstreamStatus+" "+workingTreeStatus+" ", repoName) { return gui.handleCreateRecentReposMenu() @@ -74,7 +74,6 @@ func formatWorkingTreeState(rebaseMode enums.RebaseMode) string { } func (gui *Gui) statusRenderToMain() error { - // TODO: move into some abstraction (status is currently not a listViewContext where a lot of this code lives) dashboardString := strings.Join( []string{ lazygitTitle(), @@ -114,9 +113,8 @@ func (gui *Gui) askForConfigFile(action func(file string) error) error { } } return gui.c.Menu(types.CreateMenuOptions{ - Title: gui.c.Tr.SelectConfigFile, - Items: menuItems, - HideCancel: true, + Title: gui.c.Tr.SelectConfigFile, + Items: menuItems, }) } } diff --git a/pkg/gui/sub_commits_panel.go b/pkg/gui/sub_commits_panel.go index ddcb8f096..5b5637edc 100644 --- a/pkg/gui/sub_commits_panel.go +++ b/pkg/gui/sub_commits_panel.go @@ -63,10 +63,9 @@ func (gui *Gui) handleViewSubCommitFiles() error { } return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{ - RefName: commit.Sha, - CanRebase: false, - Context: gui.State.Contexts.SubCommits, - WindowName: "branches", + RefName: commit.Sha, + CanRebase: false, + Context: gui.State.Contexts.SubCommits, }) } diff --git a/pkg/gui/types/common.go b/pkg/gui/types/common.go index 748a2484b..9c13dcd67 100644 --- a/pkg/gui/types/common.go +++ b/pkg/gui/types/common.go @@ -9,7 +9,7 @@ import ( "gopkg.in/ozeidan/fuzzy-patricia.v3/patricia" ) -type ControllerCommon struct { +type HelperCommon struct { *common.Common IGuiCommon }