1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-07-03 00:57:52 +02:00
Files
lazygit/pkg/gui/controllers/helpers/mode_helper.go
Stefan Haller d82852a909 Change Refresh to not return an error
Refresh is one of those functions that shouldn't require error handling (similar
to triggering a redraw of the UI, see
https://github.com/jesseduffield/lazygit/issues/3887).

As far as I see, the only reason why Refresh can currently return an error is
that the Then function returns one. The actual refresh errors, e.g. from the git
calls that are made to fetch data, are already logged and swallowed. Most of the
Then functions do only UI stuff such as selecting a list item, and always return
nil; there's only one that can return an error (updating the rebase todo file in
LocalCommitsController.startInteractiveRebaseWithEdit); it's not a critical
error if this fails, it is only used for setting rebase todo items to "edit"
when you start an interactive rebase by pressing 'e' on a range selection of
commits. We simply log this error instead of returning it.
2025-07-02 16:09:42 +02:00

189 lines
4.9 KiB
Go

package helpers
import (
"fmt"
"strings"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/samber/lo"
)
type ModeHelper struct {
c *HelperCommon
diffHelper *DiffHelper
patchBuildingHelper *PatchBuildingHelper
cherryPickHelper *CherryPickHelper
mergeAndRebaseHelper *MergeAndRebaseHelper
bisectHelper *BisectHelper
suppressRebasingMode bool
}
func NewModeHelper(
c *HelperCommon,
diffHelper *DiffHelper,
patchBuildingHelper *PatchBuildingHelper,
cherryPickHelper *CherryPickHelper,
mergeAndRebaseHelper *MergeAndRebaseHelper,
bisectHelper *BisectHelper,
) *ModeHelper {
return &ModeHelper{
c: c,
diffHelper: diffHelper,
patchBuildingHelper: patchBuildingHelper,
cherryPickHelper: cherryPickHelper,
mergeAndRebaseHelper: mergeAndRebaseHelper,
bisectHelper: bisectHelper,
}
}
type ModeStatus struct {
IsActive func() bool
Description func() string
Reset func() error
}
func (self *ModeHelper) Statuses() []ModeStatus {
return []ModeStatus{
{
IsActive: self.c.Modes().Diffing.Active,
Description: func() string {
return self.withResetButton(
fmt.Sprintf(
"%s %s",
self.c.Tr.ShowingGitDiff,
"git diff "+strings.Join(self.diffHelper.DiffArgs(), " "),
),
style.FgMagenta,
)
},
Reset: self.diffHelper.ExitDiffMode,
},
{
IsActive: self.c.Git().Patch.PatchBuilder.Active,
Description: func() string {
return self.withResetButton(self.c.Tr.BuildingPatch, style.FgYellow.SetBold())
},
Reset: self.patchBuildingHelper.Reset,
},
{
IsActive: self.c.Modes().Filtering.Active,
Description: func() string {
filterContent := lo.Ternary(self.c.Modes().Filtering.GetPath() != "", self.c.Modes().Filtering.GetPath(), self.c.Modes().Filtering.GetAuthor())
return self.withResetButton(
fmt.Sprintf(
"%s '%s'",
self.c.Tr.FilteringBy,
filterContent,
),
style.FgRed,
)
},
Reset: self.ExitFilterMode,
},
{
IsActive: self.c.Modes().MarkedBaseCommit.Active,
Description: func() string {
return self.withResetButton(
self.c.Tr.MarkedBaseCommitStatus,
style.FgCyan,
)
},
Reset: self.mergeAndRebaseHelper.ResetMarkedBaseCommit,
},
{
IsActive: self.c.Modes().CherryPicking.Active,
Description: func() string {
copiedCount := len(self.c.Modes().CherryPicking.CherryPickedCommits)
text := self.c.Tr.CommitsCopied
if copiedCount == 1 {
text = self.c.Tr.CommitCopied
}
return self.withResetButton(
fmt.Sprintf(
"%d %s",
copiedCount,
text,
),
style.FgCyan,
)
},
Reset: self.cherryPickHelper.Reset,
},
{
IsActive: func() bool {
return !self.suppressRebasingMode && self.c.Git().Status.WorkingTreeState().Any()
},
Description: func() string {
workingTreeState := self.c.Git().Status.WorkingTreeState()
return self.withResetButton(
workingTreeState.Title(self.c.Tr), style.FgYellow,
)
},
Reset: self.mergeAndRebaseHelper.AbortMergeOrRebaseWithConfirm,
},
{
IsActive: func() bool {
return self.c.Model().BisectInfo.Started()
},
Description: func() string {
return self.withResetButton(self.c.Tr.Bisect.Bisecting, style.FgGreen)
},
Reset: self.bisectHelper.Reset,
},
}
}
func (self *ModeHelper) withResetButton(content string, textStyle style.TextStyle) string {
return textStyle.Sprintf(
"%s %s",
content,
style.AttrUnderline.Sprint(self.c.Tr.ResetInParentheses),
)
}
func (self *ModeHelper) GetActiveMode() (ModeStatus, bool) {
return lo.Find(self.Statuses(), func(mode ModeStatus) bool {
return mode.IsActive()
})
}
func (self *ModeHelper) IsAnyModeActive() bool {
return lo.SomeBy(self.Statuses(), func(mode ModeStatus) bool {
return mode.IsActive()
})
}
func (self *ModeHelper) ExitFilterMode() error {
return self.ClearFiltering()
}
func (self *ModeHelper) ClearFiltering() error {
selectedCommitHash := self.c.Contexts().LocalCommits.GetSelectedCommitHash()
self.c.Modes().Filtering.Reset()
if self.c.State().GetRepoState().GetScreenMode() == types.SCREEN_HALF {
self.c.State().GetRepoState().SetScreenMode(types.SCREEN_NORMAL)
}
self.c.Refresh(types.RefreshOptions{
Scope: []types.RefreshableView{types.COMMITS},
Then: func() {
// Find the commit that was last selected in filtering mode, and select it again after refreshing
if !self.c.Contexts().LocalCommits.SelectCommitByHash(selectedCommitHash) {
// If we couldn't find it (either because no commit was selected
// in filtering mode, or because the commit is outside the
// initial 300 range), go back to the commit that was selected
// before we entered filtering
self.c.Contexts().LocalCommits.SelectCommitByHash(self.c.Modes().Filtering.GetSelectedCommitHash())
}
},
})
return nil
}
func (self *ModeHelper) SetSuppressRebasingMode(value bool) {
self.suppressRebasingMode = value
}