summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/gui/basic_context.go77
-rw-r--r--pkg/gui/branches_panel.go19
-rw-r--r--pkg/gui/cherry_picking.go3
-rw-r--r--pkg/gui/commit_files_panel.go7
-rw-r--r--pkg/gui/confirmation_panel.go74
-rw-r--r--pkg/gui/context/base_context.go67
-rw-r--r--pkg/gui/context/context.go2
-rw-r--r--pkg/gui/context/list_context_trait.go231
-rw-r--r--pkg/gui/context/list_trait.go32
-rw-r--r--pkg/gui/context/parent_context_mgr.go20
-rw-r--r--pkg/gui/context/tags_context.go107
-rw-r--r--pkg/gui/context/view_trait.go80
-rw-r--r--pkg/gui/context_config.go209
-rw-r--r--pkg/gui/controllers/bisect_controller.go17
-rw-r--r--pkg/gui/controllers/controller_common.go10
-rw-r--r--pkg/gui/controllers/files_controller.go25
-rw-r--r--pkg/gui/controllers/local_commits_controller.go41
-rw-r--r--pkg/gui/controllers/menu_controller.go9
-rw-r--r--pkg/gui/controllers/remotes_controller.go15
-rw-r--r--pkg/gui/controllers/submodules_controller.go19
-rw-r--r--pkg/gui/controllers/sync_controller.go11
-rw-r--r--pkg/gui/controllers/tags_controller.go28
-rw-r--r--pkg/gui/controllers/types.go22
-rw-r--r--pkg/gui/controllers/undo_controller.go7
-rw-r--r--pkg/gui/custom_commands.go17
-rw-r--r--pkg/gui/diffing.go13
-rw-r--r--pkg/gui/discard_changes_menu_panel.go15
-rw-r--r--pkg/gui/extras_panel.go6
-rw-r--r--pkg/gui/file_helper.go5
-rw-r--r--pkg/gui/files_panel.go3
-rw-r--r--pkg/gui/filtering.go3
-rw-r--r--pkg/gui/filtering_menu_panel.go14
-rw-r--r--pkg/gui/git_flow.go8
-rw-r--r--pkg/gui/gui.go21
-rw-r--r--pkg/gui/gui_common.go18
-rw-r--r--pkg/gui/keybindings.go28
-rw-r--r--pkg/gui/list_context.go13
-rw-r--r--pkg/gui/list_context_config.go109
-rw-r--r--pkg/gui/menu_panel.go8
-rw-r--r--pkg/gui/options_menu_panel.go7
-rw-r--r--pkg/gui/patch_options_panel.go11
-rw-r--r--pkg/gui/popup/popup_handler.go92
-rw-r--r--pkg/gui/pull_request_menu_panel.go14
-rw-r--r--pkg/gui/quitting.go4
-rw-r--r--pkg/gui/rebase_options_panel.go11
-rw-r--r--pkg/gui/recent_repos_panel.go8
-rw-r--r--pkg/gui/ref_helper.go13
-rw-r--r--pkg/gui/reflog_panel.go3
-rw-r--r--pkg/gui/remote_branches_panel.go5
-rw-r--r--pkg/gui/staging_panel.go3
-rw-r--r--pkg/gui/stash_panel.go7
-rw-r--r--pkg/gui/status_panel.go8
-rw-r--r--pkg/gui/sub_commits_panel.go3
-rw-r--r--pkg/gui/suggestions_helper.go4
-rw-r--r--pkg/gui/tags_panel.go16
-rw-r--r--pkg/gui/types/common.go94
-rw-r--r--pkg/gui/types/context.go26
-rw-r--r--pkg/gui/updates.go6
-rw-r--r--pkg/gui/view_helpers.go3
-rw-r--r--pkg/gui/workspace_reset_options_panel.go5
60 files changed, 1154 insertions, 602 deletions
diff --git a/pkg/gui/basic_context.go b/pkg/gui/basic_context.go
index 1043cca89..e9a3ca933 100644
--- a/pkg/gui/basic_context.go
+++ b/pkg/gui/basic_context.go
@@ -1,71 +1,48 @@
package gui
import (
+ "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
-type BasicContext struct {
+type SimpleContext struct {
OnFocus func(opts ...types.OnFocusOpts) error
OnFocusLost func() error
OnRender func() error
// this is for pushing some content to the main view
- OnRenderToMain func(opts ...types.OnFocusOpts) error
- Kind types.ContextKind
- Key types.ContextKey
- ViewName string
- WindowName string
- OnGetOptionsMap func() map[string]string
+ OnRenderToMain func(opts ...types.OnFocusOpts) error
- ParentContext types.Context
- // we can't know on the calling end whether a Context is actually a nil value without reflection, so we're storing this flag here to tell us. There has got to be a better way around this
- hasParent bool
+ *context.BaseContext
}
-var _ types.Context = &BasicContext{}
-
-func (self *BasicContext) GetOptionsMap() map[string]string {
- if self.OnGetOptionsMap != nil {
- return self.OnGetOptionsMap()
- }
- return nil
-}
-
-func (self *BasicContext) SetParentContext(context types.Context) {
- self.ParentContext = context
- self.hasParent = true
-}
-
-func (self *BasicContext) GetParentContext() (types.Context, bool) {
- return self.ParentContext, self.hasParent
-}
-
-func (self *BasicContext) SetWindowName(windowName string) {
- self.WindowName = windowName
+type NewSimpleContextOpts struct {
+ OnFocus func(opts ...types.OnFocusOpts) error
+ OnFocusLost func() error
+ OnRender func() error
+ // this is for pushing some content to the main view
+ OnRenderToMain func(opts ...types.OnFocusOpts) error
}
-func (self *BasicContext) GetWindowName() string {
- windowName := self.WindowName
-
- if windowName != "" {
- return windowName
+func NewSimpleContext(baseContext *context.BaseContext, opts NewSimpleContextOpts) *SimpleContext {
+ return &SimpleContext{
+ OnFocus: opts.OnFocus,
+ OnFocusLost: opts.OnFocusLost,
+ OnRender: opts.OnRender,
+ OnRenderToMain: opts.OnRenderToMain,
+ BaseContext: baseContext,
}
-
- // TODO: actually set this for everything so we don't default to the view name
- return self.ViewName
}
-func (self *BasicContext) HandleRender() error {
+var _ types.Context = &SimpleContext{}
+
+func (self *SimpleContext) HandleRender() error {
if self.OnRender != nil {
return self.OnRender()
}
return nil
}
-func (self *BasicContext) GetViewName() string {
- return self.ViewName
-}
-
-func (self *BasicContext) HandleFocus(opts ...types.OnFocusOpts) error {
+func (self *SimpleContext) HandleFocus(opts ...types.OnFocusOpts) error {
if self.OnFocus != nil {
if err := self.OnFocus(opts...); err != nil {
return err
@@ -81,25 +58,17 @@ func (self *BasicContext) HandleFocus(opts ...types.OnFocusOpts) error {
return nil
}
-func (self *BasicContext) HandleFocusLost() error {
+func (self *SimpleContext) HandleFocusLost() error {
if self.OnFocusLost != nil {
return self.OnFocusLost()
}
return nil
}
-func (self *BasicContext) HandleRenderToMain() error {
+func (self *SimpleContext) HandleRenderToMain() error {
if self.OnRenderToMain != nil {
return self.OnRenderToMain()
}
return nil
}
-
-func (self *BasicContext) GetKind() types.ContextKind {
- return self.Kind
-}
-
-func (self *BasicContext) GetKey() types.ContextKey {
- return self.Key
-}
diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go
index 18094b297..7b179e2ff 100644
--- a/pkg/gui/branches_panel.go
+++ b/pkg/gui/branches_panel.go
@@ -8,7 +8,6 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/controllers"
- "github.com/jesseduffield/lazygit/pkg/gui/popup"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
)
@@ -145,7 +144,7 @@ func (gui *Gui) handleForceCheckout() error {
message := gui.c.Tr.SureForceCheckout
title := gui.c.Tr.ForceCheckoutBranch
- return gui.c.Ask(popup.AskOpts{
+ return gui.c.Ask(types.AskOpts{
Title: title,
Prompt: message,
HandleConfirm: func() error {
@@ -159,14 +158,14 @@ func (gui *Gui) handleForceCheckout() error {
}
func (gui *Gui) handleCheckoutByName() error {
- return gui.c.Prompt(popup.PromptOpts{
+ return gui.c.Prompt(types.PromptOpts{
Title: gui.c.Tr.BranchName + ":",
FindSuggestionsFunc: gui.suggestionsHelper.GetRefsSuggestionsFunc(),
HandleConfirm: func(response string) error {
gui.c.LogAction("Checkout branch")
return gui.refHelper.CheckoutRef(response, types.CheckoutRefOptions{
OnRefNotFound: func(ref string) error {
- return gui.c.Ask(popup.AskOpts{
+ return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.BranchNotFoundTitle,
Prompt: fmt.Sprintf("%s %s%s", gui.c.Tr.BranchNotFoundPrompt, ref, "?"),
HandleConfirm: func() error {
@@ -232,7 +231,7 @@ func (gui *Gui) deleteNamedBranch(selectedBranch *models.Branch, force bool) err
},
)
- return gui.c.Ask(popup.AskOpts{
+ return gui.c.Ask(types.AskOpts{
Title: title,
Prompt: message,
HandleConfirm: func() error {
@@ -265,7 +264,7 @@ func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error {
},
)
- return gui.c.Ask(popup.AskOpts{
+ return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.MergingTitle,
Prompt: prompt,
HandleConfirm: func() error {
@@ -299,7 +298,7 @@ func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error {
},
)
- return gui.c.Ask(popup.AskOpts{
+ return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.RebasingTitle,
Prompt: prompt,
HandleConfirm: func() error {
@@ -368,7 +367,7 @@ func (gui *Gui) handleRenameBranch() error {
}
promptForNewName := func() error {
- return gui.c.Prompt(popup.PromptOpts{
+ return gui.c.Prompt(types.PromptOpts{
Title: gui.c.Tr.NewBranchNamePrompt + " " + branch.Name + ":",
InitialContent: branch.Name,
HandleConfirm: func(newBranchName string) error {
@@ -402,7 +401,7 @@ func (gui *Gui) handleRenameBranch() error {
return promptForNewName()
}
- return gui.c.Ask(popup.AskOpts{
+ return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.LcRenameBranch,
Prompt: gui.c.Tr.RenameBranchWarning,
HandleConfirm: promptForNewName,
@@ -430,7 +429,7 @@ func (gui *Gui) handleNewBranchOffCurrentItem() error {
prefilledName = strings.SplitAfterN(item.ID(), "/", 2)[1]
}
- return gui.c.Prompt(popup.PromptOpts{
+ return gui.c.Prompt(types.PromptOpts{
Title: message,
InitialContent: prefilledName,
HandleConfirm: func(response string) error {
diff --git a/pkg/gui/cherry_picking.go b/pkg/gui/cherry_picking.go
index 28554edce..be6fe379d 100644
--- a/pkg/gui/cherry_picking.go
+++ b/pkg/gui/cherry_picking.go
@@ -2,7 +2,6 @@ package gui
import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
- "github.com/jesseduffield/lazygit/pkg/gui/popup"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
@@ -135,7 +134,7 @@ func (gui *Gui) handleCopyCommitRange() error {
// HandlePasteCommits begins a cherry-pick rebase with the commits the user has copied
func (gui *Gui) HandlePasteCommits() error {
- return gui.c.Ask(popup.AskOpts{
+ return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.CherryPick,
Prompt: gui.c.Tr.SureCherryPick,
HandleConfirm: func() error {
diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go
index abae8196f..ef2c94bef 100644
--- a/pkg/gui/commit_files_panel.go
+++ b/pkg/gui/commit_files_panel.go
@@ -5,7 +5,6 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/patch"
"github.com/jesseduffield/lazygit/pkg/gui/controllers"
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
- "github.com/jesseduffield/lazygit/pkg/gui/popup"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
@@ -81,7 +80,7 @@ func (gui *Gui) handleDiscardOldFileChange() error {
fileName := gui.getSelectedCommitFileName()
- return gui.c.Ask(popup.AskOpts{
+ return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.DiscardFileChangesTitle,
Prompt: gui.c.Tr.DiscardFileChangesPrompt,
HandleConfirm: func() error {
@@ -181,7 +180,7 @@ func (gui *Gui) handleToggleFileForPatch() error {
}
if gui.git.Patch.PatchManager.Active() && gui.git.Patch.PatchManager.To != gui.State.CommitFileTreeViewModel.GetParent() {
- return gui.c.Ask(popup.AskOpts{
+ return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.DiscardPatch,
Prompt: gui.c.Tr.DiscardPatchConfirm,
HandleConfirm: func() error {
@@ -229,7 +228,7 @@ func (gui *Gui) enterCommitFile(opts types.OnFocusOpts) error {
}
if gui.git.Patch.PatchManager.Active() && gui.git.Patch.PatchManager.To != gui.State.CommitFileTreeViewModel.GetParent() {
- return gui.c.Ask(popup.AskOpts{
+ return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.DiscardPatch,
Prompt: gui.c.Tr.DiscardPatchConfirm,
HandleConfirm: func() error {
diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go
index 1d865348f..51c71b30b 100644
--- a/pkg/gui/confirmation_panel.go
+++ b/pkg/gui/confirmation_panel.go
@@ -191,12 +191,6 @@ func (gui *Gui) setKeyBindings(opts popup.CreatePopupPanelOpts) error {
onConfirm = gui.wrappedConfirmationFunction(opts.HandlersManageFocus, opts.HandleConfirm)
}
- type confirmationKeybinding struct {
- viewName string
- key interface{}
- handler func() error
- }
-
keybindingConfig := gui.c.UserConfig.Keybinding
onSuggestionConfirm := gui.wrappedPromptConfirmationFunction(
opts.HandlersManageFocus,
@@ -204,26 +198,30 @@ func (gui *Gui) setKeyBindings(opts popup.CreatePopupPanelOpts) error {
gui.getSelectedSuggestionValue,
)
- confirmationKeybindings := []confirmationKeybinding{
+ bindings := []*types.Binding{
{
- viewName: "confirmation",
- key: gui.getKey(keybindingConfig.Universal.Confirm),
- handler: onConfirm,
+ ViewName: "confirmation",
+ Contexts: []string{string(CONFIRMATION_CONTEXT_KEY)},
+ Key: gui.getKey(keybindingConfig.Universal.Confirm),
+ Handler: onConfirm,
},
{
- viewName: "confirmation",
- key: gui.getKey(keybindingConfig.Universal.ConfirmAlt1),
- handler: onConfirm,
+ ViewName: "confirmation",
+ Contexts: []string{string(CONFIRMATION_CONTEXT_KEY)},
+ Key: gui.getKey(keybindingConfig.Universal.ConfirmAlt1),
+ Handler: onConfirm,
},
{
- viewName: "confirmation",
- key: gui.getKey(keybindingConfig.Universal.Return),
- handler: gui.wrappedConfirmationFunction(opts.HandlersManageFocus, opts.HandleClose),
+ ViewName: "confirmation",
+ Contexts: []string{string(CONFIRMATION_CONTEXT_KEY)},
+ Key: gui.getKey(keybindingConfig.Universal.Return),
+ Handler: gui.wrappedConfirmationFunction(opts.HandlersManageFocus, opts.HandleClose),
},
{
- viewName: "confirmation",
- key: gui.getKey(keybindingConfig.Universal.TogglePanel),
- handler: func() error {
+ ViewName: "confirmation",
+ Contexts: []string{string(CONFIRMATION_CONTEXT_KEY)},
+ Key: gui.getKey(keybindingConfig.Universal.TogglePanel),
+ Handler: func() error {
if len(gui.State.Suggestions) > 0 {
return gui.replaceContext(gui.State.Contexts.Suggestions)
}
@@ -231,29 +229,33 @@ func (gui *Gui) setKeyBindings(opts popup.CreatePopupPanelOpts) error {
},
},
{
- viewName: "suggestions",
- key: gui.getKey(keybindingConfig.Universal.Confirm),
- handler: onSuggestionConfirm,
+ ViewName: "suggestions",
+ Contexts: []string{string(CONFIRMATION_CONTEXT_KEY)},
+ Key: gui.getKey(keybindingConfig.Universal.Confirm),
+ Handler: onSuggestionConfirm,
},
{
- viewName: "suggestions",
- key: gui.getKey(keybindingConfig.Universal.ConfirmAlt1),
- handler: onSuggestionConfirm,
+ ViewName: "suggestions",
+ Contexts: []string{string(CONFIRMATION_CONTEXT_KEY)},
+ Key: gui.getKey(keybindingConfig.Universal.ConfirmAlt1),
+ Handler: onSuggestionConfirm,
},
{
- viewName: "suggestions",
- key: gui.getKey(keybindingConfig.Universal.Return),
- handler: gui.wrappedConfirmationFunction(opts.HandlersManageFocus, opts.HandleClose),
+ ViewName: "suggestions",
+ Contexts: []string{string(CONFIRMATION_CONTEXT_KEY)},
+ Key: gui.getKey(keybindingConfig.Universal.Return),
+ Handler: gui.wrappedConfirmationFunction(opts.HandlersManageFocus, opts.HandleClose),
},
{
- viewName: "suggestions",
- key: gui.getKey(keybindingConfig.Universal.TogglePanel),
- handler: func() error { return gui.replaceContext(gui.State.Contexts.Confirmation) },
+ ViewName: "suggestions",
+ Contexts: []string{string(CONFIRMATION_CONTEXT_KEY)},
+ Key: gui.getKey(keybindingConfig.Universal.TogglePanel),
+ Handler: func() error { return gui.replaceContext(gui.State.Contexts.Confirmation) },
},
}
- for _, binding := range confirmationKeybindings {
- if err := gui.g.SetKeybinding(binding.viewName, nil, binding.key, gocui.ModNone, gui.wrappedHandler(binding.handler)); err != nil {
+ for _, binding := range bindings {
+ if err := gui.SetKeybinding(binding); err != nil {
return err
}
}
@@ -271,12 +273,6 @@ func (gui *Gui) clearConfirmationViewKeyBindings() {
_ = gui.g.DeleteKeybinding("suggestions", gui.getKey(keybindingConfig.Universal.Return), gocui.ModNone)
}
-func (gui *Gui) wrappedHandler(f func() error) func(g *gocui.Gui, v *gocui.View) error {
- return func(g *gocui.Gui, v *gocui.View) error {
- return f()
- }
-}
-
func (gui *Gui) refreshSuggestions() {
gui.suggestionsAsyncHandler.Do(func() func() {
suggestions := gui.findSuggestions(gui.c.GetPromptInput())
diff --git a/pkg/gui/context/base_context.go b/pkg/gui/context/base_context.go
new file mode 100644
index 000000000..e95b298a4
--- /dev/null
+++ b/pkg/gui/context/base_context.go
@@ -0,0 +1,67 @@
+package context
+
+import "github.com/jesseduffield/lazygit/pkg/gui/types"
+
+type BaseContext struct {
+ Kind types.ContextKind
+ Key types.ContextKey
+ ViewName string
+ WindowName string
+ OnGetOptionsMap func() map[string]string
+
+ *ParentContextMgr
+}
+
+func (self *BaseContext) GetOptionsMap() map[string]string {
+ if self.OnGetOptionsMap != nil {
+ return self.OnGetOptionsMap()
+ }
+ return nil
+}
+
+func (self *BaseContext) SetWindowName(windowName string) {
+ self.WindowName = windowName
+}
+
+func (self *BaseContext) GetWindowName() string {
+ windowName := self.WindowName
+
+ if windowName != "" {
+ return windowName
+ }
+
+ // TODO: actually set this for everything so we don't default to the view name
+ return self.ViewName
+}
+
+func (self *BaseContext) GetViewName() string {
+ return self.ViewName
+}
+
+func (self *BaseContext) GetKind() types.ContextKind {
+ return self.Kind
+}
+
+func (self *BaseContext) GetKey() types.ContextKey {
+ return self.Key
+}
+
+type NewBaseContextOpts struct {
+ Kind types.ContextKind
+ Key types.ContextKey
+ ViewName string
+ WindowName string
+
+ OnGetOptionsMap func() map[string]string
+}
+
+func NewBaseContext(opts NewBaseContextOpts) *BaseContext {
+ return &BaseContext{
+ Kind: opts.Kind,
+ Key: opts.Key,
+ ViewName: opts.ViewName,
+ WindowName: opts.WindowName,
+ OnGetOptionsMap: opts.OnGetOptionsMap,
+ ParentContextMgr: &ParentContextMgr{},
+ }
+}
diff --git a/pkg/gui/context/context.go b/pkg/gui/context/context.go
index 67de237ed..30030990f 100644
--- a/pkg/gui/context/context.go
+++ b/pkg/gui/context/context.go
@@ -10,7 +10,7 @@ type ContextTree struct {
Branches types.IListContext
Remotes types.IListContext
RemoteBranches types.IListContext
- Tags types.IListContext
+ Tags *TagsContext
BranchCommits types.IListContext
CommitFiles types.IListContext
ReflogCommits types.IListContext
diff --git a/pkg/gui/context/list_context_trait.go b/pkg/gui/context/list_context_trait.go
new file mode 100644
index 000000000..776056fad
--- /dev/null
+++ b/pkg/gui/context/list_context_trait.go
@@ -0,0 +1,231 @@
+package context
+
+import (
+ "fmt"
+
+ "github.com/jesseduffield/gocui"
+ "github.com/jesseduffield/lazygit/pkg/config"
+ "github.com/jesseduffield/lazygit/pkg/gui/types"
+ "github.com/jesseduffield/lazygit/pkg/utils"
+)
+
+type Thing interface {
+ // the boolean here tells us whether the item is nil. This is needed because you can't work it out on the calling end once the pointer is wrapped in an interface (unless you want to use reflection)
+ GetSelectedItem() (types.ListItem, bool)
+}
+
+type ListContextTrait struct {
+ base types.IBaseContext
+ thing Thing
+ listTrait *ListTrait
+ viewTrait *ViewTrait
+
+ 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
+}
+
+func (self *ListContextTrait) GetPanelState() types.IListPanelState {
+ return self.listTrait
+}
+
+func (self *ListContextTrait) FocusLine() {
+ // we need a way of knowing whether we've rendered to the view yet.
+ self.viewTrait.FocusPoint(self.listTrait.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.listTrait.GetSelectedLineIdx(), self.listTrait.GetItemsLength()))
+}
+
+func formatListFooter(selectedLineIdx int, length int) string {
+ return fmt.Sprintf("%d of %d", selectedLineIdx+1, length)
+}
+
+func (self *ListContextTrait) GetSelected