summaryrefslogtreecommitdiffstats
path: root/pkg/gui/context
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2022-02-05 17:04:10 +1100
committerJesse Duffield <jessedduffield@gmail.com>2022-03-17 19:13:40 +1100
commitd82f175e79f18756769d91de94458b095130297c (patch)
tree63c0c5b17a698a5a202a85b930edd0cf9e85ebf7 /pkg/gui/context
parent145c69d9ae32ec8fbdd6d1e6116efec466a0a709 (diff)
refactor contexts
Diffstat (limited to 'pkg/gui/context')
-rw-r--r--pkg/gui/context/branches_context.go86
-rw-r--r--pkg/gui/context/commit_files_context.go58
-rw-r--r--pkg/gui/context/context.go32
-rw-r--r--pkg/gui/context/list_context_trait.go192
-rw-r--r--pkg/gui/context/local_commits_context.go87
-rw-r--r--pkg/gui/context/menu_context.go108
-rw-r--r--pkg/gui/context/reflog_commits_context.go86
-rw-r--r--pkg/gui/context/remote_branches_context.go86
-rw-r--r--pkg/gui/context/remotes_context.go86
-rw-r--r--pkg/gui/context/simple_context.go73
-rw-r--r--pkg/gui/context/stash_context.go86
-rw-r--r--pkg/gui/context/sub_commits_context.go87
-rw-r--r--pkg/gui/context/submodules_context.go86
-rw-r--r--pkg/gui/context/suggestions_context.go85
-rw-r--r--pkg/gui/context/tags_context.go84
-rw-r--r--pkg/gui/context/view_trait.go46
-rw-r--r--pkg/gui/context/viewport_list_context_trait.go22
-rw-r--r--pkg/gui/context/working_tree_context.go56
18 files changed, 1118 insertions, 328 deletions
diff --git a/pkg/gui/context/branches_context.go b/pkg/gui/context/branches_context.go
new file mode 100644
index 000000000..0be6e1dce
--- /dev/null
+++ b/pkg/gui/context/branches_context.go
@@ -0,0 +1,86 @@
+package context
+
+import (
+ "github.com/jesseduffield/gocui"
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/gui/context/traits"
+ "github.com/jesseduffield/lazygit/pkg/gui/types"
+)
+
+type BranchesContext struct {
+ *BranchesViewModel
+ *ListContextTrait
+}
+
+var _ types.IListContext = (*BranchesContext)(nil)
+
+func NewBranchesContext(
+ getModel func() []*models.Branch,
+ view *gocui.View,
+ getDisplayStrings func(startIdx int, length int) [][]string,
+
+ onFocus func(...types.OnFocusOpts) error,
+ onRenderToMain func(...types.OnFocusOpts) error,
+ onFocusLost func() error,
+
+ c *types.ControllerCommon,
+) *BranchesContext {
+ viewModel := NewBranchesViewModel(getModel)
+
+ return &BranchesContext{
+ BranchesViewModel: viewModel,
+ ListContextTrait: &ListContextTrait{
+ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
+ ViewName: "branches",
+ WindowName: "branches",
+ Key: LOCAL_BRANCHES_CONTEXT_KEY,
+ Kind: types.SIDE_CONTEXT,
+ Focusable: true,
+ }), ContextCallbackOpts{
+ OnFocus: onFocus,
+ OnFocusLost: onFocusLost,
+ OnRenderToMain: onRenderToMain,
+ }),
+ list: viewModel,
+ viewTrait: NewViewTrait(view),
+ getDisplayStrings: getDisplayStrings,
+ c: c,
+ },
+ }
+}
+
+func (self *BranchesContext) GetSelectedItemId() string {
+ item := self.GetSelected()
+ if item == nil {
+ return ""
+ }
+
+ return item.ID()
+}
+
+type BranchesViewModel struct {
+ *traits.ListCursor
+ getModel func() []*models.Branch
+}
+
+func NewBranchesViewModel(getModel func() []*models.Branch) *BranchesViewModel {
+ self := &BranchesViewModel{
+ getModel: getModel,
+ }
+
+ self.ListCursor = traits.NewListCursor(self)
+
+ return self
+}
+
+func (self *BranchesViewModel) GetItemsLength() int {
+ return len(self.getModel())
+}
+
+func (self *BranchesViewModel) GetSelected() *models.Branch {
+ if self.GetItemsLength() == 0 {
+ return nil
+ }
+
+ return self.getModel()[self.GetSelectedLineIdx()]
+}
diff --git a/pkg/gui/context/commit_files_context.go b/pkg/gui/context/commit_files_context.go
index e729fb3c1..1c555387b 100644
--- a/pkg/gui/context/commit_files_context.go
+++ b/pkg/gui/context/commit_files_context.go
@@ -9,7 +9,6 @@ import (
type CommitFilesContext struct {
*filetree.CommitFileTreeViewModel
- *BaseContext
*ListContextTrait
}
@@ -17,7 +16,7 @@ var _ types.IListContext = (*CommitFilesContext)(nil)
func NewCommitFilesContext(
getModel func() []*models.CommitFile,
- getView func() *gocui.View,
+ view *gocui.View,
getDisplayStrings func(startIdx int, length int) [][]string,
onFocus func(...types.OnFocusOpts) error,
@@ -26,43 +25,30 @@ func NewCommitFilesContext(
c *types.ControllerCommon,
) *CommitFilesContext {
- baseContext := NewBaseContext(NewBaseContextOpts{
- ViewName: "commitFiles",
- WindowName: "commits",
- Key: COMMIT_FILES_CONTEXT_KEY,
- Kind: types.SIDE_CONTEXT,
- Focusable: true,
- })
-
- self := &CommitFilesContext{}
- takeFocus := func() error { return c.PushContext(self) }
-
viewModel := filetree.NewCommitFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree)
- viewTrait := NewViewTrait(getView)
- listContextTrait := &ListContextTrait{
- base: baseContext,
- list: viewModel,
- viewTrait: viewTrait,
-
- GetDisplayStrings: getDisplayStrings,
- OnFocus: onFocus,
- OnRenderToMain: onRenderToMain,
- OnFocusLost: onFocusLost,
- takeFocus: takeFocus,
-
- // TODO: handle this in a trait
- RenderSelection: false,
- c: c,
+ return &CommitFilesContext{
+ CommitFileTreeViewModel: viewModel,
+ ListContextTrait: &ListContextTrait{
+ Context: NewSimpleContext(
+ NewBaseContext(NewBaseContextOpts{
+ ViewName: "commitFiles",
+ WindowName: "commits",
+ Key: COMMIT_FILES_CONTEXT_KEY,
+ Kind: types.SIDE_CONTEXT,
+ Focusable: true,
+ }),
+ ContextCallbackOpts{
+ OnFocus: onFocus,
+ OnFocusLost: onFocusLost,
+ OnRenderToMain: onRenderToMain,
+ }),
+ list: viewModel,
+ viewTrait: NewViewTrait(view),
+ getDisplayStrings: getDisplayStrings,
+ c: c,
+ },
}
-
- baseContext.AddKeybindingsFn(listContextTrait.keybindings)
-
- self.BaseContext = baseContext
- self.ListContextTrait = listContextTrait
- self.CommitFileTreeViewModel = viewModel
-
- return self
}
func (self *CommitFilesContext) GetSelectedItemId() string {
diff --git a/pkg/gui/context/context.go b/pkg/gui/context/context.go
index 710e9a590..5f7c8f163 100644
--- a/pkg/gui/context/context.go
+++ b/pkg/gui/context/context.go
@@ -1,6 +1,10 @@
package context
-import "github.com/jesseduffield/lazygit/pkg/gui/types"
+import (
+ "sync"
+
+ "github.com/jesseduffield/lazygit/pkg/gui/types"
+)
const (
GLOBAL_CONTEXT_KEY types.ContextKey = "global"
@@ -60,18 +64,18 @@ type ContextTree struct {
Global types.Context
Status types.Context
Files *WorkingTreeContext
- Submodules types.IListContext
- Menu types.IListContext
- Branches types.IListContext
- Remotes types.IListContext
- RemoteBranches types.IListContext
+ Menu *MenuContext
+ Branches *BranchesContext
Tags *TagsContext
- BranchCommits types.IListContext
+ BranchCommits *LocalCommitsContext
CommitFiles *CommitFilesContext
- ReflogCommits types.IListContext
- SubCommits types.IListContext
- Stash types.IListContext
- Suggestions types.IListContext
+ Remotes *RemotesContext
+ Submodules *SubmodulesContext
+ RemoteBranches *RemoteBranchesContext
+ ReflogCommits *ReflogCommitsContext
+ SubCommits *SubCommitsContext
+ Stash *StashContext
+ Suggestions *SuggestionsContext
Normal types.Context
Staging types.Context
PatchBuilding types.Context
@@ -113,6 +117,7 @@ func (self *ContextTree) Flatten() []types.Context {
type ViewContextMap struct {
content map[string]types.Context
+ sync.RWMutex
}
func NewViewContextMap() *ViewContextMap {
@@ -120,10 +125,15 @@ func NewViewContextMap() *ViewContextMap {
}
func (self *ViewContextMap) Get(viewName string) types.Context {
+ self.RLock()
+ defer self.RUnlock()
+
return self.content[viewName]
}
func (self *ViewContextMap) Set(viewName string, context types.Context) {
+ self.Lock()
+ defer self.Unlock()
self.content[viewName] = context
}
diff --git a/pkg/gui/context/list_context_trait.go b/pkg/gui/context/list_context_trait.go
index 50a91b827..e4fab30bf 100644
--- a/pkg/gui/context/list_context_trait.go
+++ b/pkg/gui/context/list_context_trait.go
@@ -3,44 +3,35 @@ package context
import (
"fmt"
- "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
)
type ListContextTrait struct {
- base types.IBaseContext
- list types.IList
- viewTrait *ViewTrait
+ types.Context
- takeFocus func() error
-
- GetDisplayStrings func(startIdx int, length int) [][]string
- OnFocus func(...types.OnFocusOpts) error
- OnRenderToMain func(...types.OnFocusOpts) error
- OnFocusLost func() error
-
- // if this is true, we'll call GetDisplayStrings for just the visible part of the
- // view and re-render that. This is useful when you need to render different
- // content based on the selection (e.g. for showing the selected commit)
- RenderSelection bool
+ c *types.ControllerCommon
+ list types.IList
+ viewTrait *ViewTrait
+ getDisplayStrings func(startIdx int, length int) [][]string
+}
- c *types.ControllerCommon
+func (self *ListContextTrait) GetList() types.IList {
+ return self.list
}
+// TODO: remove
func (self *ListContextTrait) GetPanelState() types.IListPanelState {
return self.list
}
+func (self *ListContextTrait) GetViewTrait() types.IViewTrait {
+ return self.viewTrait
+}
+
func (self *ListContextTrait) FocusLine() {
// we need a way of knowing whether we've rendered to the view yet.
self.viewTrait.FocusPoint(self.list.GetSelectedLineIdx())
- if self.RenderSelection {
- min, max := self.viewTrait.ViewPortYBounds()
- displayStrings := self.GetDisplayStrings(min, max)
- content := utils.RenderDisplayStrings(displayStrings)
- self.viewTrait.SetViewPortContent(content)
- }
self.viewTrait.SetFooter(formatListFooter(self.list.GetSelectedLineIdx(), self.list.GetItemsLength()))
}
@@ -48,164 +39,29 @@ func formatListFooter(selectedLineIdx int, length int) string {
return fmt.Sprintf("%d of %d", selectedLineIdx+1, length)
}
-// OnFocus assumes that the content of the context has already been rendered to the view. OnRender is the function which actually renders the content to the view
-func (self *ListContextTrait) HandleRender() error {
- if self.GetDisplayStrings != nil {
- self.list.RefreshSelectedIdx()
- content := utils.RenderDisplayStrings(self.GetDisplayStrings(0, self.list.GetItemsLength()))
- self.viewTrait.SetContent(content)
- self.c.Render()
- }
-
- return nil
-}
-
-func (self *ListContextTrait) HandleFocusLost() error {
- if self.OnFocusLost != nil {
- return self.OnFocusLost()
- }
-
- self.viewTrait.SetOriginX(0)
-
- return nil
-}
-
func (self *ListContextTrait) HandleFocus(opts ...types.OnFocusOpts) error {
self.FocusLine()
- if self.OnFocus != nil {
- if err := self.OnFocus(opts...); err != nil {
- return err
- }
- }
-
- if self.OnRenderToMain != nil {
- if err := self.OnRenderToMain(opts...); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (self *ListContextTrait) HandlePrevLine() error {
- return self.handleLineChange(-1)
-}
-
-func (self *ListContextTrait) HandleNextLine() error {
- return self.handleLineChange(1)
-}
-
-func (self *ListContextTrait) HandleScrollLeft() error {
- return self.scroll(self.viewTrait.ScrollLeft)
-}
-
-func (self *ListContextTrait) HandleScrollRight() error {
- return self.scroll(self.viewTrait.ScrollRight)
+ return self.Context.HandleFocus(opts...)
}
-func (self *ListContextTrait) scroll(scrollFunc func()) error {
- scrollFunc()
+func (self *ListContextTrait) HandleFocusLost() error {
+ self.viewTrait.SetOriginX(0)
- return self.HandleFocus()
+ return self.Context.HandleFocus()
}
-func (self *ListContextTrait) handleLineChange(change int) error {
- before := self.list.GetSelectedLineIdx()
- self.list.MoveSelectedLine(change)
- after := self.list.GetSelectedLineIdx()
-
- // doing this check so that if we're holding the up key at the start of the list
- // we're not constantly re-rendering the main view.
- if before != after {
- return self.HandleFocus()
- }
+// OnFocus assumes that the content of the context has already been rendered to the view. OnRender is the function which actually renders the content to the view
+func (self *ListContextTrait) HandleRender() error {
+ self.list.RefreshSelectedIdx()
+ content := utils.RenderDisplayStrings(self.getDisplayStrings(0, self.list.GetItemsLength()))
+ self.viewTrait.SetContent(content)
+ self.c.Render()
return nil
}
-func (self *ListContextTrait) HandlePrevPage() error {
- return self.handleLineChange(-self.viewTrait.PageDelta())
-}
-
-func (self *ListContextTrait) HandleNextPage() error {
- return self.handleLineChange(self.viewTrait.PageDelta())
-}
-
-func (self *ListContextTrait) HandleGotoTop() error {
- return self.handleLineChange(-self.list.GetItemsLength())
-}
-
-func (self *ListContextTrait) HandleGotoBottom() error {
- return self.handleLineChange(self.list.GetItemsLength())
-}
-
-func (self *ListContextTrait) HandleClick(onClick func() error) error {
- prevSelectedLineIdx := self.list.GetSelectedLineIdx()
- // because we're handling a click, we need to determine the new line idx based
- // on the view itself.
- newSelectedLineIdx := self.viewTrait.SelectedLineIdx()
-
- currentContextKey := self.c.CurrentContext().GetKey()
- alreadyFocused := currentContextKey == self.base.GetKey()
-
- // we need to focus the view
- if !alreadyFocused {
- if err := self.takeFocus(); err != nil {
- return err
- }
- }
-
- if newSelectedLineIdx > self.list.GetItemsLength()-1 {
- return nil
- }
-
- self.list.SetSelectedLineIdx(newSelectedLineIdx)
-
- if prevSelectedLineIdx == newSelectedLineIdx && alreadyFocused && onClick != nil {
- return onClick()
- }
- return self.HandleFocus()
-}
-
func (self *ListContextTrait) OnSearchSelect(selectedLineIdx int) error {
- self.list.SetSelectedLineIdx(selectedLineIdx)
+ self.GetList().SetSelectedLineIdx(selectedLineIdx)
return self.HandleFocus()
}
-
-func (self *ListContextTrait) HandleRenderToMain() error {
- if self.OnRenderToMain != nil {
- return self.OnRenderToMain()
- }
-
- return nil
-}
-
-func (self *ListContextTrait) keybindings(opts types.KeybindingsOpts) []*types.Binding {
- return []*types.Binding{
- {Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
- {Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevItem), Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
- {Tag: "navigation", Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: self.HandlePrevLine},
- {Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: self.HandleNextLine},
- {Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextItem), Modifier: gocui.ModNone, Handler: self.HandleNextLine},
- {Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.PrevPage), Modifier: gocui.ModNone, Handler: self.HandlePrevPage, Description: self.c.Tr.LcPrevPage},
- {Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.NextPage), Modifier: gocui.ModNone, Handler: self.HandleNextPage, Description: self.c.Tr.LcNextPage},
- {Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.GotoTop), Modifier: gocui.ModNone, Handler: self.HandleGotoTop, Description: self.c.Tr.LcGotoTop},
- {Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: func() error { return self.HandleClick(nil) }},
- {Tag: "navigation", Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: self.HandleNextLine},
- {Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.ScrollLeft), Modifier: gocui.ModNone, Handler: self.HandleScrollLeft},
- {Tag: "navigation", Key: opts.GetKey(opts.Config.Universal.ScrollRight), Modifier: gocui.ModNone, Handler: self.HandleScrollRight},
- {
- Key: opts.GetKey(opts.Config.Universal.StartSearch),
- Handler: func() error { self.c.OpenSearch(); return nil },
- Description: self.c.Tr.LcStartSearch,
- Tag: "navigation",
- },
- {
- Key: opts.GetKey(opts.Config.Universal.GotoBottom),
- Description: self.c.Tr.LcGotoBottom,
- Handler: self.HandleGotoBottom,
- Tag: "navigation",
- },
- }
-}
diff --git a/pkg/gui/context/local_commits_context.go b/pkg/gui/context/local_commits_context.go
new file mode 100644
index 000000000..0345ecb81
--- /dev/null
+++ b/pkg/gui/context/local_commits_context.go
@@ -0,0 +1,87 @@
+package context
+
+import (
+ "github.com/jesseduffield/gocui"
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/gui/context/traits"
+ "github.com/jesseduffield/lazygit/pkg/gui/types"
+)
+
+type LocalCommitsContext struct {
+ *LocalCommitsViewModel
+ *ViewportListContextTrait
+}
+
+var _ types.IListContext = (*LocalCommitsContext)(nil)
+
+func NewLocalCommitsContext(
+ getModel func() []*models.Commit,
+ view *gocui.View,
+ getDisplayStrings func(startIdx int, length int) [][]string,
+
+ onFocus func(...types.OnFocusOpts) error,
+ onRenderToMain func(...types.OnFocusOpts) error,
+ onFocusLost func() error,
+
+ c *types.ControllerCommon,
+) *LocalCommitsContext {
+ viewModel := NewLocalCommitsViewModel(getModel)
+
+ return &LocalCommitsContext{
+ LocalCommitsViewModel: viewModel,
+ ViewportListContextTrait: &ViewportListContextTrait{
+ ListContextTrait: &ListContextTrait{
+ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
+ ViewName: "commits",
+ WindowName: "commits",
+ Key: BRANCH_COMMITS_CONTEXT_KEY,
+ Kind: types.SIDE_CONTEXT,
+ Focusable: true,
+ }), ContextCallbackOpts{
+ OnFocus: onFocus,
+ OnFocusLost: onFocusLost,
+ OnRenderToMain: onRenderToMain,
+ }),
+ list: viewModel,
+ viewTrait: NewViewTrait(view),
+ getDisplayStrings: getDisplayStrings,
+ c: c,
+ }},
+ }
+}
+
+func (self *LocalCommitsContext) GetSelectedItemId() string {
+ item := self.GetSelected()
+ if item == nil {
+ return ""
+ }
+
+ return item.ID()
+}
+
+type LocalCommitsViewModel struct {
+ *traits.ListCursor
+ getModel func() []*models.Commit
+}
+
+func NewLocalCommitsViewModel(getModel func() []*models.Commit) *LocalCommitsViewModel {
+ self := &LocalCommitsViewModel{
+ getModel: getModel,
+ }
+
+ self.ListCursor = traits.NewListCursor(self)
+
+ return self
+}
+
+func (self *LocalCommitsViewModel) GetItemsLength() int {
+ return len(self.getModel())
+}
+
+func (self *LocalCommitsViewModel) GetSelected() *models.Commit {
+ if self.GetItemsLength() == 0 {
+ return nil
+ }
+
+ return self.getModel()[self.GetSelectedLineIdx()]
+}
diff --git a/pkg/gui/context/menu_context.go b/pkg/gui/context/menu_context.go
new file mode 100644
index 000000000..47c6b885f
--- /dev/null
+++ b/pkg/gui/context/menu_context.go
@@ -0,0 +1,108 @@
+package context
+
+import (
+ "github.com/jesseduffield/gocui"
+ "github.com/jesseduffield/lazygit/pkg/gui/context/traits"
+ "github.com/jesseduffield/lazygit/pkg/gui/presentation"
+ "github.com/jesseduffield/lazygit/pkg/gui/types"
+)
+
+type MenuContext struct {
+ *MenuViewModel
+ *ListContextTrait
+}
+
+var _ types.IListContext = (*MenuContext)(nil)
+
+func NewMenuContext(
+ view *gocui.View,
+
+ onFocus func(...types.OnFocusOpts) error,
+ onRenderToMain func(...types.OnFocusOpts) error,
+ onFocusLost func() error,
+
+ c *types.ControllerCommon,
+ getOptionsMap func() map[string]string,
+) *MenuContext {
+ viewModel := NewMenuViewModel()
+
+ return &MenuContext{
+ MenuViewModel: viewModel,
+ ListContextTrait: &ListContextTrait{
+ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
+ ViewName: "menu",
+ Key: "menu",
+ Kind: types.PERSISTENT_POPUP,
+ OnGetOptionsMap: getOptionsMap,
+ Focusable: true,
+ }), ContextCallbackOpts{
+ OnFocus: onFocus,
+ OnFocusLost: onFocusLost,
+ OnRenderToMain: onRenderToMain,
+ }),
+ getDisplayStrings: viewModel.GetDisplayStrings,
+ list: viewModel,
+ viewTrait: NewViewTrait(view),
+ c: c,
+ },
+ }
+}
+
+// TODO: remove this thing.
+func (self *MenuContext) GetSelectedItemId() string {
+ item := self.GetSelected()
+ if item == nil {
+ return ""
+ }
+
+ return item.DisplayString
+}
+
+type MenuViewModel struct {
+ *traits.ListCursor
+ menuItems []*types.MenuItem
+}
+
+func NewMenuViewModel() *MenuViewModel {
+ self := &MenuViewModel{
+ menuItems: nil,
+ }
+
+ self.ListCursor = traits.NewListCursor(self)
+
+ return self
+}
+
+func (self *MenuViewModel) GetItemsLength() int {
+ return len(self.menuItems)
+}
+
+func (self *MenuViewModel) GetSelected() *types.MenuItem {
+ if self.GetItemsLength() == 0 {
+ return nil
+ }
+
+ return self.menuItems[self.GetSelectedLineIdx()]
+}
+
+func (self *MenuViewModel) SetMenuItems(items []*types.MenuItem) {
+ self.menuItems = items
+}
+
+// TODO: move into presentation package
+func (self *MenuViewModel) GetDisplayStrings(startIdx int, length int) [][]string {
+ stringArrays := make([][]string, len(self.menuItems))
+ for i, item := range self.menuItems {
+ if item.DisplayStrings == nil {
+ styledStr := item.DisplayString
+ if item.OpensMenu {
+ styledStr = presentation.OpensMenuStyle(styledStr)
+ }
+ stringArrays[i] = []string{styledStr}
+ } else {
+ stringArrays[i] = item.DisplayStrings
+ }
+ }
+
+ return stringArrays
+}
diff --git a/pkg/gui/context/reflog_commits_context.go b/pkg/gui/context/reflog_commits_context.go
new file mode 100644
index 000000000..e3130c251
--- /dev/null
+++ b/pkg/gui/context/reflog_commits_context.go
@@ -0,0 +1,86 @@
+package context
+
+import (
+ "github.com/jesseduffield/gocui"
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/gui/context/traits"
+ "github.com/jesseduffield/lazygit/pkg/gui/types"
+)
+
+type ReflogCommitsContext struct {
+ *ReflogCommitsViewModel
+ *ListContextTrait
+}
+
+var _ types.IListContext = (*ReflogCommitsContext)(nil)
+
+func NewReflogCommitsContext(
+ getModel func() []*models.Commit,
+ view *gocui.View,
+ getDisplayStrings func(startIdx int, length int) [][]string,
+
+ onFocus func(...types.OnFocusOpts) error,
+ onRenderToMain func(...types.OnFocusOpts) error,
+ onFocusLost func() error,
+
+ c *types.ControllerCommon,
+) *ReflogCommitsContext {
+ viewModel := NewReflogCommitsViewModel(getModel)
+
+ return &ReflogCommitsContext{
+ ReflogCommitsViewModel: viewModel,
+ ListContextTrait: &ListContextTrait{
+ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
+ ViewName: "commits",
+ WindowName: "commits",
+ Key: REFLOG_COMMITS_CONTEXT_KEY,
+ Kind: types.SIDE_CONTEXT,
+ Focusable: true,
+ }), ContextCallbackOpts{
+ OnFocus: onFocus,
+ OnFocusLost: onFocusLost,
+ OnRenderToMain: onRenderToMain,
+ }),
+ list: viewModel,
+ viewTrait: NewViewTrait(view),
+ getDisplayStrings: getDisplayStrings,
+ c: c,
+ },
+ }
+}
+
+func (self *ReflogCommitsContext) GetSelectedItemId() string {
+ item := self.GetSelected()
+ if item == nil {
+ return ""
+ }
+
+ return item.ID()
+}
+
+type ReflogCommitsViewModel struct {
+ *traits.ListCursor
+ getModel func() []*models.Commit
+}
+
+func NewReflogCommitsViewModel(getModel func() []*models.Commit) *ReflogCommitsViewModel {
+ self := &ReflogCommitsViewModel{
+ getModel: getModel,
+ }
+
+ self.ListCursor = traits.NewListCursor(self)
+
+ return self
+}
+
+func (self *ReflogCommitsViewModel) GetItemsLength() int {
+ return len(self.getModel())
+}
+
+func (self *ReflogCommitsViewModel) GetSelected() *models.Commit {
+ if self.GetItemsLength() == 0 {
+ return nil
+ }
+
+ return self.getModel()[self.GetSelectedLineIdx()]
+}
diff --git a/pkg/gui/context/remote_branches_context.go b/pkg/gui/context/remote_branches_context.go
new file mode 100644
index 000000000..e15e80261
--- /dev/null
+++ b/pkg/gui/context/remote_branches_context.go
@@ -0,0 +1,86 @@
+package context
+
+import (
+ "github.com/jesseduffield/gocui"
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/gui/context/traits"
+ "github.com/jesseduffield/lazygit/pkg/gui/types"
+)
+
+type RemoteBranchesContext struct {
+ *RemoteBranchesViewModel
+ *ListContextTrait
+}
+
+var _ types.IListContext = (*RemoteBranchesContext)(nil)
+
+func NewRemoteBranchesContext(
+ getModel func() []*models.RemoteBranch,
+ view *gocui.View,
+ getDisplayStrings func(startIdx int, length int) [][]string,
+
+ onFocus func(...types.OnFocusOpts) error,
+ onRenderToMain func(...types.OnFocusOpts) error,
+ onFocusLost func() error,
+
+ c *types.ControllerCommon,
+) *RemoteBranchesContext {
+ viewModel := NewRemoteBranchesViewModel(getModel)
+
+ return &RemoteBranchesContext{
+ RemoteBranchesViewModel: viewModel,
+ ListContextTrait: &ListContextTrait{
+ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
+ ViewName: "branches",
+ WindowName: "branches",
+ Key: REMOTE_BRANCHES_CONTEXT_KEY,
+ Kind: types.SIDE_CONTEXT,
+ Focusable: true,
+ }), ContextCallbackOpts{
+ OnFocus: onFocus,
+ OnFocusLost: onFocusLost,
+ OnRenderToMain: onRenderToMain,
+ }),
+ list: viewModel,
+ viewTrait: NewViewTrait(view),
+ getDisplayStrings: getDisplayStrings,
+ c: c,
+ },
+ }
+}
+