mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-03 13:21:56 +02:00
d5b4f7bb3e
Situations where a view's width changes: - changing screen modes - enter staging or patch building - resizing the terminal window For the first of these we currently have special code to force a rerender, since some views render different content depending on whether they are in full-screen mode. We'll be able to remove that code now, since this new generic mechanism takes care of that too. But we will need this more general mechanism for cases where views truncate their content to the view width; we'll add one example for that later in this branch.
216 lines
5.5 KiB
Go
216 lines
5.5 KiB
Go
package context
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
|
"github.com/samber/lo"
|
|
)
|
|
|
|
type SubCommitsContext struct {
|
|
c *ContextCommon
|
|
|
|
*SubCommitsViewModel
|
|
*ListContextTrait
|
|
*DynamicTitleBuilder
|
|
*SearchTrait
|
|
}
|
|
|
|
var (
|
|
_ types.IListContext = (*SubCommitsContext)(nil)
|
|
_ types.DiffableContext = (*SubCommitsContext)(nil)
|
|
)
|
|
|
|
func NewSubCommitsContext(
|
|
c *ContextCommon,
|
|
) *SubCommitsContext {
|
|
viewModel := &SubCommitsViewModel{
|
|
ListViewModel: NewListViewModel(
|
|
func() []*models.Commit { return c.Model().SubCommits },
|
|
),
|
|
ref: nil,
|
|
limitCommits: true,
|
|
}
|
|
|
|
getDisplayStrings := func(startIdx int, endIdx int) [][]string {
|
|
// This can happen if a sub-commits view is asked to be rerendered while
|
|
// it is invisble; for example when switching screen modes, which
|
|
// rerenders all views.
|
|
if viewModel.GetRef() == nil {
|
|
return [][]string{}
|
|
}
|
|
|
|
selectedCommitSha := ""
|
|
if c.CurrentContext().GetKey() == SUB_COMMITS_CONTEXT_KEY {
|
|
selectedCommit := viewModel.GetSelected()
|
|
if selectedCommit != nil {
|
|
selectedCommitSha = selectedCommit.Sha
|
|
}
|
|
}
|
|
branches := []*models.Branch{}
|
|
if viewModel.GetShowBranchHeads() {
|
|
branches = c.Model().Branches
|
|
}
|
|
showBranchMarkerForHeadCommit := c.Git().Config.GetRebaseUpdateRefs()
|
|
return presentation.GetCommitListDisplayStrings(
|
|
c.Common,
|
|
c.Model().SubCommits,
|
|
branches,
|
|
viewModel.GetRef().RefName(),
|
|
showBranchMarkerForHeadCommit,
|
|
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
|
|
c.Modes().CherryPicking.SelectedShaSet(),
|
|
c.Modes().Diffing.Ref,
|
|
"",
|
|
c.UserConfig.Gui.TimeFormat,
|
|
c.UserConfig.Gui.ShortTimeFormat,
|
|
time.Now(),
|
|
c.UserConfig.Git.ParseEmoji,
|
|
selectedCommitSha,
|
|
startIdx,
|
|
endIdx,
|
|
// Don't show the graph in the left/right view; we'd like to, but
|
|
// it's too complicated:
|
|
shouldShowGraph(c) && viewModel.GetRefToShowDivergenceFrom() == "",
|
|
git_commands.NewNullBisectInfo(),
|
|
false,
|
|
)
|
|
}
|
|
|
|
getNonModelItems := func() []*NonModelItem {
|
|
result := []*NonModelItem{}
|
|
if viewModel.GetRefToShowDivergenceFrom() != "" {
|
|
_, upstreamIdx, found := lo.FindIndexOf(
|
|
c.Model().SubCommits, func(c *models.Commit) bool { return c.Divergence == models.DivergenceRight })
|
|
if !found {
|
|
upstreamIdx = 0
|
|
}
|
|
result = append(result, &NonModelItem{
|
|
Index: upstreamIdx,
|
|
Content: fmt.Sprintf("--- %s ---", c.Tr.DivergenceSectionHeaderRemote),
|
|
})
|
|
|
|
_, localIdx, found := lo.FindIndexOf(
|
|
c.Model().SubCommits, func(c *models.Commit) bool { return c.Divergence == models.DivergenceLeft })
|
|
if !found {
|
|
localIdx = len(c.Model().SubCommits)
|
|
}
|
|
result = append(result, &NonModelItem{
|
|
Index: localIdx,
|
|
Content: fmt.Sprintf("--- %s ---", c.Tr.DivergenceSectionHeaderLocal),
|
|
})
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
ctx := &SubCommitsContext{
|
|
c: c,
|
|
SubCommitsViewModel: viewModel,
|
|
SearchTrait: NewSearchTrait(c),
|
|
DynamicTitleBuilder: NewDynamicTitleBuilder(c.Tr.SubCommitsDynamicTitle),
|
|
ListContextTrait: &ListContextTrait{
|
|
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
|
View: c.Views().SubCommits,
|
|
WindowName: "branches",
|
|
Key: SUB_COMMITS_CONTEXT_KEY,
|
|
Kind: types.SIDE_CONTEXT,
|
|
Focusable: true,
|
|
Transient: true,
|
|
NeedsRerenderOnWidthChange: true,
|
|
})),
|
|
ListRenderer: ListRenderer{
|
|
list: viewModel,
|
|
getDisplayStrings: getDisplayStrings,
|
|
getNonModelItems: getNonModelItems,
|
|
},
|
|
c: c,
|
|
refreshViewportOnChange: true,
|
|
},
|
|
}
|
|
|
|
ctx.GetView().SetOnSelectItem(ctx.SearchTrait.onSelectItemWrapper(func(selectedLineIdx int) error {
|
|
ctx.GetList().SetSelectedLineIdx(selectedLineIdx)
|
|
return ctx.HandleFocus(types.OnFocusOpts{})
|
|
}))
|
|
|
|
return ctx
|
|
}
|
|
|
|
type SubCommitsViewModel struct {
|
|
// name of the ref that the sub-commits are shown for
|
|
ref types.Ref
|
|
refToShowDivergenceFrom string
|
|
*ListViewModel[*models.Commit]
|
|
|
|
limitCommits bool
|
|
showBranchHeads bool
|
|
}
|
|
|
|
func (self *SubCommitsViewModel) SetRef(ref types.Ref) {
|
|
self.ref = ref
|
|
}
|
|
|
|
func (self *SubCommitsViewModel) GetRef() types.Ref {
|
|
return self.ref
|
|
}
|
|
|
|
func (self *SubCommitsViewModel) SetRefToShowDivergenceFrom(ref string) {
|
|
self.refToShowDivergenceFrom = ref
|
|
}
|
|
|
|
func (self *SubCommitsViewModel) GetRefToShowDivergenceFrom() string {
|
|
return self.refToShowDivergenceFrom
|
|
}
|
|
|
|
func (self *SubCommitsViewModel) SetShowBranchHeads(value bool) {
|
|
self.showBranchHeads = value
|
|
}
|
|
|
|
func (self *SubCommitsViewModel) GetShowBranchHeads() bool {
|
|
return self.showBranchHeads
|
|
}
|
|
|
|
func (self *SubCommitsContext) GetSelectedItemId() string {
|
|
item := self.GetSelected()
|
|
if item == nil {
|
|
return ""
|
|
}
|
|
|
|
return item.ID()
|
|
}
|
|
|
|
func (self *SubCommitsContext) CanRebase() bool {
|
|
return false
|
|
}
|
|
|
|
func (self *SubCommitsContext) GetSelectedRef() types.Ref {
|
|
commit := self.GetSelected()
|
|
if commit == nil {
|
|
return nil
|
|
}
|
|
return commit
|
|
}
|
|
|
|
func (self *SubCommitsContext) GetCommits() []*models.Commit {
|
|
return self.getModel()
|
|
}
|
|
|
|
func (self *SubCommitsContext) SetLimitCommits(value bool) {
|
|
self.limitCommits = value
|
|
}
|
|
|
|
func (self *SubCommitsContext) GetLimitCommits() bool {
|
|
return self.limitCommits
|
|
}
|
|
|
|
func (self *SubCommitsContext) GetDiffTerminals() []string {
|
|
itemId := self.GetSelectedItemId()
|
|
|
|
return []string{itemId}
|
|
}
|