jesseduffield_lazygit/pkg/gui/context/reflog_commits_context.go
Stefan Haller 84be082fb5 Draw only visible part of the reflogs panel
Since the reflog can get very long, this saves some memory but especially some
UI thread lag. In one of my repos I had over 11'000 reflog entries (I guess I
should prune them more regularly...), and rendering them took ~600ms; since this
happens on the UI thread, there was an annoying stall for half a second after
every background fetch, for example.
2025-12-23 16:20:32 +01:00

103 lines
2.7 KiB
Go

package context
import (
"time"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
type ReflogCommitsContext struct {
*FilteredListViewModel[*models.Commit]
*ListContextTrait
}
var (
_ types.IListContext = (*ReflogCommitsContext)(nil)
_ types.DiffableContext = (*ReflogCommitsContext)(nil)
)
func NewReflogCommitsContext(c *ContextCommon) *ReflogCommitsContext {
viewModel := NewFilteredListViewModel(
func() []*models.Commit { return c.Model().FilteredReflogCommits },
func(commit *models.Commit) []string {
return []string{commit.ShortHash(), commit.Name}
},
)
getDisplayStrings := func(startIdx int, endIdx int) [][]string {
commits := viewModel.GetItems()
if startIdx >= len(commits) {
return nil
}
return presentation.GetReflogCommitListDisplayStrings(
commits[startIdx:endIdx],
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
c.Modes().CherryPicking.SelectedHashSet(),
c.Modes().Diffing.Ref,
time.Now(),
c.UserConfig().Gui.TimeFormat,
c.UserConfig().Gui.ShortTimeFormat,
c.UserConfig().Git.ParseEmoji,
)
}
return &ReflogCommitsContext{
FilteredListViewModel: viewModel,
ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
View: c.Views().ReflogCommits,
WindowName: "commits",
Key: REFLOG_COMMITS_CONTEXT_KEY,
Kind: types.SIDE_CONTEXT,
Focusable: true,
NeedsRerenderOnWidthChange: types.NEEDS_RERENDER_ON_WIDTH_CHANGE_WHEN_SCREEN_MODE_CHANGES,
NeedsRerenderOnHeightChange: true,
})),
ListRenderer: ListRenderer{
list: viewModel,
getDisplayStrings: getDisplayStrings,
},
c: c,
renderOnlyVisibleLines: true,
},
}
}
func (self *ReflogCommitsContext) CanRebase() bool {
return false
}
func (self *ReflogCommitsContext) GetSelectedRef() models.Ref {
commit := self.GetSelected()
if commit == nil {
return nil
}
return commit
}
func (self *ReflogCommitsContext) GetSelectedRefRangeForDiffFiles() *types.RefRange {
// It doesn't make much sense to show a range diff between two reflog entries.
return nil
}
func (self *ReflogCommitsContext) GetCommits() []*models.Commit {
return self.getModel()
}
func (self *ReflogCommitsContext) GetDiffTerminals() []string {
itemId := self.GetSelectedItemId()
return []string{itemId}
}
func (self *ReflogCommitsContext) RefForAdjustingLineNumberInDiff() string {
return self.GetSelectedItemId()
}
func (self *ReflogCommitsContext) ShowBranchHeadsInSubCommits() bool {
return false
}