mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-23 12:18:51 +02:00
When exiting filtering mode, we currently keep the selection index the same in the commits panel. This doesn't make sense at all, since the index in the filtered view has no relation to the index in the unfiltered view. I often use filtering mode (either by path or by author) to find a given commit faster than I would otherwise be able to. When exiting filtering mode, it's useful to keep the same commit selected, so that I can look at the surrounding commits, see which branch it was a part of, etc. So reselect the commit again after exiting filtering mode. Sometimes this is not possible, most likely when the commit is so long ago that it's outside of the initial 300 range. In that case, at least select the commit again that was selected before I entered filtering; this is still better than arbitrarily keeping the same selection index.
190 lines
5.1 KiB
Go
190 lines
5.1 KiB
Go
package helpers
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
|
"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() != enums.REBASE_MODE_NONE
|
|
},
|
|
Description: func() string {
|
|
workingTreeState := self.c.Git().Status.WorkingTreeState()
|
|
return self.withResetButton(
|
|
presentation.FormatWorkingTreeStateTitle(self.c.Tr, workingTreeState), 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)
|
|
}
|
|
|
|
return 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())
|
|
}
|
|
},
|
|
})
|
|
}
|
|
|
|
func (self *ModeHelper) SetSuppressRebasingMode(value bool) {
|
|
self.suppressRebasingMode = value
|
|
}
|