1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-03-27 22:01:46 +02:00

lots of changes

This commit is contained in:
Jesse Duffield 2023-03-23 18:47:29 +11:00
parent 711674f6cd
commit db12853bbe
63 changed files with 1024 additions and 943 deletions

View File

@ -1,132 +0,0 @@
package gui
import (
"time"
"github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/sasha-s/go-deadlock"
)
// statusManager's job is to handle rendering of loading states and toast notifications
// that you see at the bottom left of the screen.
type statusManager struct {
statuses []appStatus
nextId int
mutex deadlock.Mutex
}
type appStatus struct {
message string
statusType string
id int
}
func (m *statusManager) removeStatus(id int) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.statuses = slices.Filter(m.statuses, func(status appStatus) bool {
return status.id != id
})
}
func (m *statusManager) addWaitingStatus(message string) int {
m.mutex.Lock()
defer m.mutex.Unlock()
m.nextId += 1
id := m.nextId
newStatus := appStatus{
message: message,
statusType: "waiting",
id: id,
}
m.statuses = append([]appStatus{newStatus}, m.statuses...)
return id
}
func (m *statusManager) addToastStatus(message string) int {
m.mutex.Lock()
defer m.mutex.Unlock()
m.nextId++
id := m.nextId
newStatus := appStatus{
message: message,
statusType: "toast",
id: id,
}
m.statuses = append([]appStatus{newStatus}, m.statuses...)
go func() {
time.Sleep(time.Second * 2)
m.removeStatus(id)
}()
return id
}
func (m *statusManager) getStatusString() string {
if len(m.statuses) == 0 {
return ""
}
topStatus := m.statuses[0]
if topStatus.statusType == "waiting" {
return topStatus.message + " " + utils.Loader()
}
return topStatus.message
}
func (m *statusManager) showStatus() bool {
return len(m.statuses) > 0
}
func (gui *Gui) toast(message string) {
gui.statusManager.addToastStatus(message)
gui.renderAppStatus()
}
func (gui *Gui) renderAppStatus() {
go utils.Safe(func() {
ticker := time.NewTicker(time.Millisecond * 50)
defer ticker.Stop()
for range ticker.C {
appStatus := gui.statusManager.getStatusString()
gui.c.OnUIThread(func() error {
gui.c.SetViewContent(gui.Views.AppStatus, appStatus)
return nil
})
if appStatus == "" {
return
}
}
})
}
// withWaitingStatus wraps a function and shows a waiting status while the function is still executing
func (gui *Gui) withWaitingStatus(message string, f func() error) error {
go utils.Safe(func() {
id := gui.statusManager.addWaitingStatus(message)
defer func() {
gui.statusManager.removeStatus(id)
}()
gui.renderAppStatus()
if err := f(); err != nil {
gui.c.OnUIThread(func() error {
return gui.c.Error(err)
})
}
})
return nil
}

View File

@ -3,6 +3,7 @@ package gui
import (
"github.com/jesseduffield/lazycore/pkg/boxlayout"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/mattn/go-runewidth"
@ -14,11 +15,28 @@ import (
const INFO_SECTION_PADDING = " "
type WindowArranger struct {
gui *Gui
c *helpers.HelperCommon
windowHelper *helpers.WindowHelper
modeHelper *helpers.ModeHelper
appStatusHelper *helpers.AppStatusHelper
}
func NewWindowArranger(
c *helpers.HelperCommon,
windowHelper *helpers.WindowHelper,
modeHelper *helpers.ModeHelper,
appStatusHelper *helpers.AppStatusHelper,
) *WindowArranger {
return &WindowArranger{
c: c,
windowHelper: windowHelper,
modeHelper: modeHelper,
appStatusHelper: appStatusHelper,
}
}
func (self *WindowArranger) getWindowDimensions(informationStr string, appStatus string) map[string]boxlayout.Dimensions {
width, height := self.gui.g.Size()
width, height := self.c.GocuiGui().Size()
sideSectionWeight, mainSectionWeight := self.getMidSectionWeights()
@ -35,7 +53,12 @@ func (self *WindowArranger) getWindowDimensions(informationStr string, appStatus
extrasWindowSize := self.getExtrasWindowSize(height)
showInfoSection := self.gui.c.UserConfig.Gui.ShowBottomLine || self.gui.State.Searching.isSearching || self.gui.isAnyModeActive() || self.gui.statusManager.showStatus()
self.c.Modes().Filtering.Active()
showInfoSection := self.c.UserConfig.Gui.ShowBottomLine ||
self.c.State().GetRepoState().IsSearching() ||
self.modeHelper.IsAnyModeActive() ||
self.appStatusHelper.HasStatus()
infoSectionSize := 0
if showInfoSection {
infoSectionSize = 1
@ -96,11 +119,11 @@ func MergeMaps[K comparable, V any](maps ...map[K]V) map[K]V {
}
func (self *WindowArranger) mainSectionChildren() []*boxlayout.Box {
currentWindow := self.gui.helpers.Window.CurrentWindow()
currentWindow := self.windowHelper.CurrentWindow()
// if we're not in split mode we can just show the one main panel. Likewise if
// the main panel is focused and we're in full-screen mode
if !self.gui.isMainPanelSplit() || (self.gui.State.ScreenMode == types.SCREEN_FULL && currentWindow == "main") {
if !self.c.State().GetRepoState().GetSplitMainPanel() || (self.c.State().GetRepoState().GetScreenMode() == types.SCREEN_FULL && currentWindow == "main") {
return []*boxlayout.Box{
{
Window: "main",
@ -122,10 +145,10 @@ func (self *WindowArranger) mainSectionChildren() []*boxlayout.Box {
}
func (self *WindowArranger) getMidSectionWeights() (int, int) {
currentWindow := self.gui.helpers.Window.CurrentWindow()
currentWindow := self.windowHelper.CurrentWindow()
// we originally specified this as a ratio i.e. .20 would correspond to a weight of 1 against 4
sidePanelWidthRatio := self.gui.c.UserConfig.Gui.SidePanelWidth
sidePanelWidthRatio := self.c.UserConfig.Gui.SidePanelWidth
// we could make this better by creating ratios like 2:3 rather than always 1:something
mainSectionWeight := int(1/sidePanelWidthRatio) - 1
sideSectionWeight := 1
@ -134,14 +157,16 @@ func (self *WindowArranger) getMidSectionWeights() (int, int) {
mainSectionWeight = 5 // need to shrink side panel to make way for main panels if side-by-side
}
screenMode := self.c.State().GetRepoState().GetScreenMode()
if currentWindow == "main" {
if self.gui.State.ScreenMode == types.SCREEN_HALF || self.gui.State.ScreenMode == types.SCREEN_FULL {
if screenMode == types.SCREEN_HALF || screenMode == types.SCREEN_FULL {
sideSectionWeight = 0
}
} else {
if self.gui.State.ScreenMode == types.SCREEN_HALF {
if screenMode == types.SCREEN_HALF {
mainSectionWeight = 1
} else if self.gui.State.ScreenMode == types.SCREEN_FULL {
} else if screenMode == types.SCREEN_FULL {
mainSectionWeight = 0
}
}
@ -150,7 +175,7 @@ func (self *WindowArranger) getMidSectionWeights() (int, int) {
}
func (self *WindowArranger) infoSectionChildren(informationStr string, appStatus string) []*boxlayout.Box {
if self.gui.State.Searching.isSearching {
if self.c.State().GetRepoState().IsSearching() {
return []*boxlayout.Box{
{
Window: "searchPrefix",
@ -166,7 +191,7 @@ func (self *WindowArranger) infoSectionChildren(informationStr string, appStatus
appStatusBox := &boxlayout.Box{Window: "appStatus"}
optionsBox := &boxlayout.Box{Window: "options"}
if !self.gui.c.UserConfig.Gui.ShowBottomLine {
if !self.c.UserConfig.Gui.ShowBottomLine {
optionsBox.Weight = 0
appStatusBox.Weight = 1
} else {
@ -176,7 +201,7 @@ func (self *WindowArranger) infoSectionChildren(informationStr string, appStatus
result := []*boxlayout.Box{appStatusBox, optionsBox}
if self.gui.c.UserConfig.Gui.ShowBottomLine || self.gui.isAnyModeActive() {
if self.c.UserConfig.Gui.ShowBottomLine || self.modeHelper.IsAnyModeActive() {
result = append(result, &boxlayout.Box{
Window: "information",
// unlike appStatus, informationStr has various colors so we need to decolorise before taking the length
@ -188,12 +213,12 @@ func (self *WindowArranger) infoSectionChildren(informationStr string, appStatus
}
func (self *WindowArranger) splitMainPanelSideBySide() bool {
if !self.gui.isMainPanelSplit() {
if !self.c.State().GetRepoState().GetSplitMainPanel() {
return false
}
mainPanelSplitMode := self.gui.c.UserConfig.Gui.MainPanelSplitMode
width, height := self.gui.g.Size()
mainPanelSplitMode := self.c.UserConfig.Gui.MainPanelSplitMode
width, height := self.c.GocuiGui().Size()
switch mainPanelSplitMode {
case "vertical":
@ -210,17 +235,17 @@ func (self *WindowArranger) splitMainPanelSideBySide() bool {
}
func (self *WindowArranger) getExtrasWindowSize(screenHeight int) int {
if !self.gui.ShowExtrasWindow {
if !self.c.State().GetShowExtrasWindow() {
return 0
}
var baseSize int
if self.gui.c.CurrentStaticContext().GetKey() == context.COMMAND_LOG_CONTEXT_KEY {
if self.c.CurrentStaticContext().GetKey() == context.COMMAND_LOG_CONTEXT_KEY {
baseSize = 1000 // my way of saying 'fill the available space'
} else if screenHeight < 40 {
baseSize = 1
} else {
baseSize = self.gui.c.UserConfig.Gui.CommandLogSize
baseSize = self.c.UserConfig.Gui.CommandLogSize
}
frameSize := 2
@ -232,16 +257,14 @@ func (self *WindowArranger) getExtrasWindowSize(screenHeight int) int {
// the default behaviour when accordion mode is NOT in effect. If it is in effect
// then when it's accessed it will have weight 2, not 1.
func (self *WindowArranger) getDefaultStashWindowBox() *boxlayout.Box {
self.gui.State.ContextMgr.RLock()
defer self.gui.State.ContextMgr.RUnlock()
box := &boxlayout.Box{Window: "stash"}
stashWindowAccessed := false
for _, context := range self.gui.State.ContextMgr.ContextStack {
self.c.Context().ForEach(func(context types.Context) {
if context.GetWindowName() == "stash" {
stashWindowAccessed = true
}
}
})
box := &boxlayout.Box{Window: "stash"}
// if the stash window is anywhere in our stack we should enlargen it
if stashWindowAccessed {
box.Weight = 1
@ -253,9 +276,10 @@ func (self *WindowArranger) getDefaultStashWindowBox() *boxlayout.Box {
}
func (self *WindowArranger) sidePanelChildren(width int, height int) []*boxlayout.Box {
currentWindow := self.currentSideWindowName()
currentWindow := self.c.CurrentSideContext().GetWindowName()
if self.gui.State.ScreenMode == types.SCREEN_FULL || self.gui.State.ScreenMode == types.SCREEN_HALF {
screenMode := self.c.State().GetRepoState().GetScreenMode()
if screenMode == types.SCREEN_FULL || screenMode == types.SCREEN_HALF {
fullHeightBox := func(window string) *boxlayout.Box {
if window == currentWindow {
return &boxlayout.Box{
@ -278,7 +302,7 @@ func (self *WindowArranger) sidePanelChildren(width int, height int) []*boxlayou
fullHeightBox("stash"),
}
} else if height >= 28 {
accordionMode := self.gui.c.UserConfig.Gui.ExpandFocusedSidePanel
accordionMode := self.c.UserConfig.Gui.ExpandFocusedSidePanel
accordionBox := func(defaultBox *boxlayout.Box) *boxlayout.Box {
if accordionMode && defaultBox.Window == currentWindow {
return &boxlayout.Box{
@ -329,20 +353,3 @@ func (self *WindowArranger) sidePanelChildren(width int, height int) []*boxlayou
}
}
}
func (self *WindowArranger) currentSideWindowName() string {
// there is always one and only one cyclable context in the context stack. We'll look from top to bottom
self.gui.State.ContextMgr.RLock()
defer self.gui.State.ContextMgr.RUnlock()
for idx := range self.gui.State.ContextMgr.ContextStack {
reversedIdx := len(self.gui.State.ContextMgr.ContextStack) - 1 - idx
context := self.gui.State.ContextMgr.ContextStack[reversedIdx]
if context.GetKind() == types.SIDE_CONTEXT {
return context.GetWindowName()
}
}
return "files" // default
}

View File

@ -20,17 +20,17 @@ type ContextMgr struct {
gui *Gui
}
func NewContextMgr(initialContext types.Context, gui *Gui) ContextMgr {
return ContextMgr{
ContextStack: []types.Context{},
func NewContextMgr(initialContext types.Context, gui *Gui) *ContextMgr {
return &ContextMgr{
ContextStack: []types.Context{initialContext},
RWMutex: sync.RWMutex{},
gui: gui,
}
}
// use replaceContext when you don't want to return to the original context upon
// use when you don't want to return to the original context upon
// hitting escape: you want to go that context's parent instead.
func (self *ContextMgr) replaceContext(c types.Context) error {
func (self *ContextMgr) Replace(c types.Context) error {
if !c.IsFocusable() {
return nil
}
@ -49,9 +49,9 @@ func (self *ContextMgr) replaceContext(c types.Context) error {
return self.activateContext(c, types.OnFocusOpts{})
}
func (self *ContextMgr) pushContext(c types.Context, opts ...types.OnFocusOpts) error {
func (self *ContextMgr) Push(c types.Context, opts ...types.OnFocusOpts) error {
if len(opts) > 1 {
return errors.New("cannot pass multiple opts to pushContext")
return errors.New("cannot pass multiple opts to Push")
}
singleOpts := types.OnFocusOpts{}
@ -135,7 +135,7 @@ func (self *ContextMgr) pushToContextStack(c types.Context) ([]types.Context, ty
return contextsToDeactivate, c
}
func (self *ContextMgr) popContext() error {
func (self *ContextMgr) Pop() error {
self.Lock()
if len(self.ContextStack) == 1 {
@ -213,7 +213,7 @@ func (self *ContextMgr) activateContext(c types.Context, opts types.OnFocusOpts)
return nil
}
func (self *ContextMgr) currentContext() types.Context {
func (self *ContextMgr) Current() types.Context {
self.RLock()
defer self.RUnlock()
@ -229,17 +229,12 @@ func (self *ContextMgr) currentContextWithoutLock() types.Context {
}
// Note that this could return the 'status' context which is not itself a list context.
func (self *ContextMgr) currentSideContext() types.Context {
func (self *ContextMgr) CurrentSide() types.Context {
self.RLock()
defer self.RUnlock()
stack := self.ContextStack
// on startup the stack can be empty so we'll return an empty string in that case
if len(stack) == 0 {
return self.gui.defaultSideContext()
}
// find the first context in the stack with the type of types.SIDE_CONTEXT
for i := range stack {
context := stack[len(stack)-1-i]
@ -253,7 +248,7 @@ func (self *ContextMgr) currentSideContext() types.Context {
}
// static as opposed to popup
func (self *ContextMgr) currentStaticContext() types.Context {
func (self *ContextMgr) CurrentStatic() types.Context {
self.RLock()
defer self.RUnlock()
@ -278,3 +273,16 @@ func (self *ContextMgr) currentStaticContextWithoutLock() types.Context {
return self.gui.defaultSideContext()
}
func (self *ContextMgr) ForEach(f func(types.Context)) {
self.RLock()
defer self.RUnlock()
for _, context := range self.gui.State.ContextMgr.ContextStack {
f(context)
}
}
func (self *ContextMgr) IsCurrent(c types.Context) bool {
return self.Current().GetKey() == c.GetKey()
}

136
pkg/gui/context/setup.go Normal file
View File

@ -0,0 +1,136 @@
package context
import "github.com/jesseduffield/lazygit/pkg/gui/types"
func NewContextTree(c *ContextCommon) *ContextTree {
commitFilesContext := NewCommitFilesContext(c)
return &ContextTree{
Global: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
Kind: types.GLOBAL_CONTEXT,
View: nil, // TODO: see if this breaks anything
WindowName: "",
Key: GLOBAL_CONTEXT_KEY,
Focusable: false,
HasUncontrolledBounds: true, // setting to true because the global context doesn't even have a view
}),
),
Status: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
Kind: types.SIDE_CONTEXT,
View: c.Views().Status,
WindowName: "status",
Key: STATUS_CONTEXT_KEY,
Focusable: true,
}),
),
Files: NewWorkingTreeContext(c),
Submodules: NewSubmodulesContext(c),
Menu: NewMenuContext(c),
Remotes: NewRemotesContext(c),
RemoteBranches: NewRemoteBranchesContext(c),
LocalCommits: NewLocalCommitsContext(c),
CommitFiles: commitFilesContext,
ReflogCommits: NewReflogCommitsContext(c),
SubCommits: NewSubCommitsContext(c),
Branches: NewBranchesContext(c),
Tags: NewTagsContext(c),
Stash: NewStashContext(c),
Suggestions: NewSuggestionsContext(c),
Normal: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
Kind: types.MAIN_CONTEXT,
View: c.Views().Main,
WindowName: "main",
Key: NORMAL_MAIN_CONTEXT_KEY,
Focusable: false,
}),
),
NormalSecondary: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
Kind: types.MAIN_CONTEXT,
View: c.Views().Secondary,
WindowName: "secondary",
Key: NORMAL_SECONDARY_CONTEXT_KEY,
Focusable: false,
}),
),
Staging: NewPatchExplorerContext(
c.Views().Staging,
"main",
STAGING_MAIN_CONTEXT_KEY,
func() []int { return nil },
c,
),
StagingSecondary: NewPatchExplorerContext(
c.Views().StagingSecondary,
"secondary",
STAGING_SECONDARY_CONTEXT_KEY,
func() []int { return nil },
c,
),
CustomPatchBuilder: NewPatchExplorerContext(
c.Views().PatchBuilding,
"main",
PATCH_BUILDING_MAIN_CONTEXT_KEY,
func() []int {
filename := commitFilesContext.GetSelectedPath()
includedLineIndices, err := c.Git().Patch.PatchBuilder.GetFileIncLineIndices(filename)
if err != nil {
c.Log.Error(err)
return nil
}
return includedLineIndices
},
c,
),
CustomPatchBuilderSecondary: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
Kind: types.MAIN_CONTEXT,
View: c.Views().PatchBuildingSecondary,
WindowName: "secondary",
Key: PATCH_BUILDING_SECONDARY_CONTEXT_KEY,
Focusable: false,
}),
),
MergeConflicts: NewMergeConflictsContext(
c,
),
Confirmation: NewConfirmationContext(c),
CommitMessage: NewCommitMessageContext(c),
Search: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
Kind: types.PERSISTENT_POPUP,
View: c.Views().Search,
WindowName: "search",
Key: SEARCH_CONTEXT_KEY,
Focusable: true,
}),
),
CommandLog: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
Kind: types.EXTRAS_CONTEXT,
View: c.Views().Extras,
WindowName: "extras",
Key: COMMAND_LOG_CONTEXT_KEY,
Focusable: true,
}),
),
Snake: NewSimpleContext(
NewBaseContext(NewBaseContextOpts{
Kind: types.SIDE_CONTEXT,
View: c.Views().Snake,
WindowName: "files",
Key: SNAKE_CONTEXT_KEY,
Focusable: true,
}),
),
Options: NewDisplayContext(OPTIONS_CONTEXT_KEY, c.Views().Options, "options"),
AppStatus: NewDisplayContext(APP_STATUS_CONTEXT_KEY, c.Views().AppStatus, "appStatus"),
SearchPrefix: NewDisplayContext(SEARCH_PREFIX_CONTEXT_KEY, c.Views().SearchPrefix, "searchPrefix"),
Information: NewDisplayContext(INFORMATION_CONTEXT_KEY, c.Views().Information, "information"),
Limit: NewDisplayContext(LIMIT_CONTEXT_KEY, c.Views().Limit, "limit"),
}
}

View File

@ -7,134 +7,11 @@ import (
)
func (gui *Gui) contextTree() *context.ContextTree {
return &context.ContextTree{
Global: context.NewSimpleContext(
context.NewBaseContext(context.NewBaseContextOpts{
Kind: types.GLOBAL_CONTEXT,
View: nil, // TODO: see if this breaks anything
WindowName: "",
Key: context.GLOBAL_CONTEXT_KEY,
Focusable: false,
HasUncontrolledBounds: true, // setting to true because the global context doesn't even have a view
}),
),
Status: context.NewSimpleContext(
context.NewBaseContext(context.NewBaseContextOpts{
Kind: types.SIDE_CONTEXT,
View: gui.Views.Status,
WindowName: "status",
Key: context.STATUS_CONTEXT_KEY,
Focusable: true,
}),
),
Snake: context.NewSimpleContext(
context.NewBaseContext(context.NewBaseContextOpts{
Kind: types.SIDE_CONTEXT,
View: gui.Views.Snake,
WindowName: "files",
Key: context.SNAKE_CONTEXT_KEY,
Focusable: true,
}),
),
Files: gui.filesListContext(),
Submodules: gui.submodulesListContext(),
Menu: gui.menuListContext(),
Remotes: gui.remotesListContext(),
RemoteBranches: gui.remoteBranchesListContext(),
LocalCommits: gui.branchCommitsListContext(),
CommitFiles: gui.commitFilesListContext(),
ReflogCommits: gui.reflogCommitsListContext(),
SubCommits: gui.subCommitsListContext(),
Branches: gui.branchesListContext(),
Tags: gui.tagsListContext(),
Stash: gui.stashListContext(),
Suggestions: gui.suggestionsListContext(),
Normal: context.NewSimpleContext(
context.NewBaseContext(context.NewBaseContextOpts{
Kind: types.MAIN_CONTEXT,
View: gui.Views.Main,
WindowName: "main",
Key: context.NORMAL_MAIN_CONTEXT_KEY,
Focusable: false,
}),
),
NormalSecondary: context.NewSimpleContext(
context.NewBaseContext(context.NewBaseContextOpts{
Kind: types.MAIN_CONTEXT,
View: gui.Views.Secondary,
WindowName: "secondary",
Key: context.NORMAL_SECONDARY_CONTEXT_KEY,
Focusable: false,
}),
),
Staging: context.NewPatchExplorerContext(
gui.Views.Staging,
"main",
context.STAGING_MAIN_CONTEXT_KEY,
func() []int { return nil },
gui.contextCommon,
),
StagingSecondary: context.NewPatchExplorerContext(
gui.Views.StagingSecondary,
"secondary",
context.STAGING_SECONDARY_CONTEXT_KEY,
func() []int { return nil },
gui.contextCommon,
),
CustomPatchBuilder: context.NewPatchExplorerContext(
gui.Views.PatchBuilding,
"main",
context.PATCH_BUILDING_MAIN_CONTEXT_KEY,
func() []int {
filename := gui.State.Contexts.CommitFiles.GetSelectedPath()
includedLineIndices, err := gui.git.Patch.PatchBuilder.GetFileIncLineIndices(filename)
if err != nil {
gui.Log.Error(err)
return nil
}
return includedLineIndices
},
gui.contextCommon,
),
CustomPatchBuilderSecondary: context.NewSimpleContext(
context.NewBaseContext(context.NewBaseContextOpts{
Kind: types.MAIN_CONTEXT,
View: gui.Views.PatchBuildingSecondary,
WindowName: "secondary",
Key: context.PATCH_BUILDING_SECONDARY_CONTEXT_KEY,
Focusable: false,
}),
),
MergeConflicts: context.NewMergeConflictsContext(
gui.contextCommon,
),
Confirmation: context.NewConfirmationContext(gui.contextCommon),
CommitMessage: context.NewCommitMessageContext(gui.contextCommon),
Search: context.NewSimpleContext(
context.NewBaseContext(context.NewBaseContextOpts{
Kind: types.PERSISTENT_POPUP,
View: gui.Views.Search,
WindowName: "search",
Key: context.SEARCH_CONTEXT_KEY,
Focusable: true,
}),
),
CommandLog: context.NewSimpleContext(
context.NewBaseContext(context.NewBaseContextOpts{
Kind: types.EXTRAS_CONTEXT,
View: gui.Views.Extras,
WindowName: "extras",
Key: context.COMMAND_LOG_CONTEXT_KEY,
Focusable: true,
}),
),
Options: context.NewDisplayContext(context.OPTIONS_CONTEXT_KEY, gui.Views.Options, "options"),
AppStatus: context.NewDisplayContext(context.APP_STATUS_CONTEXT_KEY, gui.Views.AppStatus, "appStatus"),
SearchPrefix: context.NewDisplayContext(context.SEARCH_PREFIX_CONTEXT_KEY, gui.Views.SearchPrefix, "searchPrefix"),
Information: context.NewDisplayContext(context.INFORMATION_CONTEXT_KEY, gui.Views.Information, "information"),
Limit: context.NewDisplayContext(context.LIMIT_CONTEXT_KEY, gui.Views.Limit, "limit"),
contextCommon := &context.ContextCommon{
IGuiCommon: gui.c.IGuiCommon,
Common: gui.c.Common,
}
return context.NewContextTree(contextCommon)
}
// using this wrapper for when an onFocus function doesn't care about any potential
@ -145,14 +22,6 @@ func OnFocusWrapper(f func() error) func(opts types.OnFocusOpts) error {
}
}
func (gui *Gui) getPatchExplorerContexts() []types.IPatchExplorerContext {
return []types.IPatchExplorerContext{
gui.State.Contexts.Staging,
gui.State.Contexts.StagingSecondary,
gui.State.Contexts.CustomPatchBuilder,
}
}
func (gui *Gui) popupViewNames() []string {
popups := slices.Filter(gui.State.Contexts.Flatten(), func(c types.Context) bool {
return c.GetKind() == types.PERSISTENT_POPUP || c.GetKind() == types.TEMPORARY_POPUP
@ -176,3 +45,29 @@ func (gui *Gui) TransientContexts() []types.Context {
return context.IsTransient()
})
}
func (gui *Gui) getListContexts() []types.IListContext {
return []types.IListContext{
gui.State.Contexts.Menu,
gui.State.Contexts.Files,
gui.State.Contexts.Branches,
gui.State.Contexts.Remotes,
gui.State.Contexts.RemoteBranches,
gui.State.Contexts.Tags,
gui.State.Contexts.LocalCommits,
gui.State.Contexts.ReflogCommits,
gui.State.Contexts.SubCommits,
gui.State.Contexts.Stash,
gui.State.Contexts.CommitFiles,
gui.State.Contexts.Submodules,
gui.State.Contexts.Suggestions,
}
}
func (gui *Gui) getPatchExplorerContexts() []types.IPatchExplorerContext {
return []types.IPatchExplorerContext{
gui.State.Contexts.Staging,
gui.State.Contexts.StagingSecondary,
gui.State.Contexts.CustomPatchBuilder,
}
}

View File

@ -8,9 +8,14 @@ import (
"github.com/jesseduffield/lazygit/pkg/gui/controllers"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/services/custom_commands"
"github.com/jesseduffield/lazygit/pkg/gui/status"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
func (gui *Gui) Helpers() *helpers.Helpers {
return gui.helpers
}
func (gui *Gui) resetControllers() {
helperCommon := gui.c
refsHelper := helpers.NewRefsHelper(helperCommon)
@ -28,27 +33,30 @@ func (gui *Gui) resetControllers() {
stagingHelper := helpers.NewStagingHelper(helperCommon)
mergeConflictsHelper := helpers.NewMergeConflictsHelper(helperCommon)
refreshHelper := helpers.NewRefreshHelper(helperCommon, refsHelper, rebaseHelper, patchBuildingHelper, stagingHelper, mergeConflictsHelper, gui.fileWatcher)
diffHelper := helpers.NewDiffHelper(helperCommon)
cherryPickHelper := helpers.NewCherryPickHelper(
helperCommon,
rebaseHelper,
)
bisectHelper := helpers.NewBisectHelper(helperCommon)
gui.helpers = &helpers.Helpers{
Refs: refsHelper,
Host: helpers.NewHostHelper(helperCommon),
PatchBuilding: patchBuildingHelper,
Staging: stagingHelper,
Bisect: helpers.NewBisectHelper(helperCommon),
Suggestions: suggestionsHelper,
Files: helpers.NewFilesHelper(helperCommon),
WorkingTree: helpers.NewWorkingTreeHelper(helperCommon, refsHelper, setCommitMessage, getSavedCommitMessage),
Tags: helpers.NewTagsHelper(helperCommon),
GPG: gpgHelper,
MergeAndRebase: rebaseHelper,
MergeConflicts: mergeConflictsHelper,
CherryPick: helpers.NewCherryPickHelper(
helperCommon,
rebaseHelper,
),
Refs: refsHelper,
Host: helpers.NewHostHelper(helperCommon),
PatchBuilding: patchBuildingHelper,
Staging: stagingHelper,
Bisect: bisectHelper,
Suggestions: suggestionsHelper,
Files: helpers.NewFilesHelper(helperCommon),
WorkingTree: helpers.NewWorkingTreeHelper(helperCommon, refsHelper, setCommitMessage, getSavedCommitMessage),
Tags: helpers.NewTagsHelper(helperCommon),
GPG: helpers.NewGpgHelper(helperCommon),
MergeAndRebase: rebaseHelper,
MergeConflicts: mergeConflictsHelper,
CherryPick: cherryPickHelper,
Upstream: helpers.NewUpstreamHelper(helperCommon, suggestionsHelper.GetRemoteBranchesSuggestionsFunc),
AmendHelper: helpers.NewAmendHelper(helperCommon, gpgHelper),
Snake: helpers.NewSnakeHelper(helperCommon),
Diff: helpers.NewDiffHelper(helperCommon),
Diff: diffHelper,
Repos: helpers.NewRecentReposHelper(helperCommon, recordDirectoryHelper, gui.onNewRepo),
RecordDirectory: recordDirectoryHelper,
Update: helpers.NewUpdateHelper(helperCommon, gui.Updater),
@ -56,17 +64,26 @@ func (gui *Gui) resetControllers() {
View: viewHelper,
Refresh: refreshHelper,
Confirmation: helpers.NewConfirmationHelper(helperCommon),
Mode: helpers.NewModeHelper(
helperCommon,
diffHelper,
patchBuildingHelper,
cherryPickHelper,
rebaseHelper,
bisectHelper,
),
AppStatus: helpers.NewAppStatusHelper(
helperCommon,
func() *status.StatusManager { return gui.statusManager },
),
}
gui.CustomCommandsClient = custom_commands.NewClient(
helperCommon,
gui.os,
gui.git,
gui.State.Contexts,
gui.helpers,
)
common := controllers.NewControllerCommon(helperCommon, gui.helpers)
common := controllers.NewControllerCommon(helperCommon, gui)
syncController := controllers.NewSyncController(
common,

View File

@ -20,15 +20,15 @@ type ContainsCommits interface {
type BasicCommitsController struct {
baseController
*controllerCommon
c *ControllerCommon
context ContainsCommits
}
func NewBasicCommitsController(controllerCommon *controllerCommon, context ContainsCommits) *BasicCommitsController {
func NewBasicCommitsController(controllerCommon *ControllerCommon, context ContainsCommits) *BasicCommitsController {
return &BasicCommitsController{
baseController: baseController{},
controllerCommon: controllerCommon,
context: context,
baseController: baseController{},
c: controllerCommon,
context: context,
}
}
@ -73,7 +73,7 @@ func (self *BasicCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
},
{
Key: opts.GetKey(opts.Config.Commits.ResetCherryPick),
Handler: self.helpers.CherryPick.Reset,
Handler: self.c.Helpers().CherryPick.Reset,
Description: self.c.Tr.LcResetCherryPick,
},
}
@ -150,7 +150,7 @@ func (self *BasicCommitsController) copyCommitSHAToClipboard(commit *models.Comm
}
func (self *BasicCommitsController) copyCommitURLToClipboard(commit *models.Commit) error {
url, err := self.helpers.Host.GetCommitURL(commit.Sha)
url, err := self.c.Helpers().Host.GetCommitURL(commit.Sha)
if err != nil {
return err
}
@ -212,7 +212,7 @@ func (self *BasicCommitsController) copyCommitMessageToClipboard(commit *models.
}
func (self *BasicCommitsController) openInBrowser(commit *models.Commit) error {
url, err := self.helpers.Host.GetCommitURL(commit.Sha)
url, err := self.c.Helpers().Host.GetCommitURL(commit.Sha)
if err != nil {
return self.c.Error(err)
}
@ -226,11 +226,11 @@ func (self *BasicCommitsController) openInBrowser(commit *models.Commit) error {
}
func (self *BasicCommitsController) newBranch(commit *models.Commit) error {
return self.helpers.Refs.NewBranch(commit.RefName(), commit.Description(), "")
return self.c.Helpers().Refs.NewBranch(commit.RefName(), commit.Description(), "")
}
func (self *BasicCommitsController) createResetMenu(commit *models.Commit) error {
return self.helpers.Refs.CreateGitResetMenu(commit.Sha)
return self.c.Helpers().Refs.CreateGitResetMenu(commit.Sha)
}
func (self *BasicCommitsController) checkout(commit *models.Commit) error {
@ -239,15 +239,15 @@ func (self *BasicCommitsController) checkout(commit *models.Commit) error {
Prompt: self.c.Tr.SureCheckoutThisCommit,
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.CheckoutCommit)
return self.helpers.Refs.CheckoutRef(commit.Sha, types.CheckoutRefOptions{})
return self.c.Helpers().Refs.CheckoutRef(commit.Sha, types.CheckoutRefOptions{})
},
})
}
func (self *BasicCommitsController) copy(commit *models.Commit) error {
return self.helpers.CherryPick.Copy(commit, self.context.GetCommits(), self.context)
return self.c.Helpers().CherryPick.Copy(commit, self.context.GetCommits(), self.context)
}
func (self *BasicCommitsController) copyRange(*models.Commit) error {
return self.helpers.CherryPick.CopyRange(self.context.GetSelectedLineIdx(), self.context.GetCommits(), self.context)
return self.c.Helpers().CherryPick.CopyRange(self.context.GetSelectedLineIdx(), self.context.GetCommits(), self.context)
}

View File

@ -12,17 +12,17 @@ import (
type BisectController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &BisectController{}
func NewBisectController(
common *controllerCommon,
common *ControllerCommon,
) *BisectController {
return &BisectController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -105,7 +105,7 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
{
Label: self.c.Tr.Bisect.ResetOption,
OnPress: func() error {
return self.helpers.Bisect.Reset()
return self.c.Helpers().Bisect.Reset()
},
Key: 'r',
},
@ -133,7 +133,7 @@ func (self *BisectController) openStartBisectMenu(info *git_commands.BisectInfo,
return self.c.Error(err)
}
return self.helpers.Bisect.PostBisectCommandRefresh()
return self.c.Helpers().Bisect.PostBisectCommandRefresh()
},
Key: 'b',
},
@ -149,7 +149,7 @@ func (self *BisectController) openStartBisectMenu(info *git_commands.BisectInfo,
return self.c.Error(err)
}
return self.helpers.Bisect.PostBisectCommandRefresh()
return self.c.Helpers().Bisect.PostBisectCommandRefresh()
},
Key: 'g',
},
@ -177,7 +177,7 @@ func (self *BisectController) showBisectCompleteMessage(candidateShas []string)
return self.c.Error(err)
}
return self.helpers.Bisect.PostBisectCommandRefresh()
return self.c.Helpers().Bisect.PostBisectCommandRefresh()
},
})
}
@ -211,7 +211,7 @@ func (self *BisectController) afterBisectMarkRefresh(selectCurrent bool, waitToR
} else {
selectFn()
return self.helpers.Bisect.PostBisectCommandRefresh()
return self.c.Helpers().Bisect.PostBisectCommandRefresh()
}
}

View File

@ -14,17 +14,17 @@ import (
type BranchesController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &BranchesController{}
func NewBranchesController(
common *controllerCommon,
common *ControllerCommon,
) *BranchesController {
return &BranchesController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -113,7 +113,7 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
func (self *BranchesController) GetOnRenderToMain() func() error {
return func() error {
return self.helpers.Diff.WithDiffModeCheck(func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
var task types.UpdateTask
branch := self.context().GetSelected()
if branch == nil {
@ -161,8 +161,8 @@ func (self *BranchesController) setUpstream(selectedBranch *models.Branch) error
{
LabelColumns: []string{self.c.Tr.LcSetUpstream},
OnPress: func() error {
return self.helpers.Upstream.PromptForUpstreamWithoutInitialContent(selectedBranch, func(upstream string) error {
upstreamRemote, upstreamBranch, err := self.helpers.Upstream.ParseUpstream(upstream)
return self.c.Helpers().Upstream.PromptForUpstreamWithoutInitialContent(selectedBranch, func(upstream string) error {
upstreamRemote, upstreamBranch, err := self.c.Helpers().Upstream.ParseUpstream(upstream)
if err != nil {
return self.c.Error(err)
}
@ -197,12 +197,12 @@ func (self *BranchesController) context() *context.BranchesContext {
}
func (self *BranchesController) press(selectedBranch *models.Branch) error {
if selectedBranch == self.helpers.Refs.GetCheckedOutRef() {
if selectedBranch == self.c.Helpers().Refs.GetCheckedOutRef() {
return self.c.ErrorMsg(self.c.Tr.AlreadyCheckedOutBranch)
}
self.c.LogAction(self.c.Tr.Actions.CheckoutBranch)
return self.helpers.Refs.CheckoutRef(selectedBranch.Name, types.CheckoutRefOptions{})
return self.c.Helpers().Refs.CheckoutRef(selectedBranch.Name, types.CheckoutRefOptions{})
}
func (self *BranchesController) handleCreatePullRequest(selectedBranch *models.Branch) error {
@ -210,7 +210,7 @@ func (self *BranchesController) handleCreatePullRequest(selectedBranch *models.B
}
func (self *BranchesController) handleCreatePullRequestMenu(selectedBranch *models.Branch) error {
checkedOutBranch := self.helpers.Refs.GetCheckedOutRef()
checkedOutBranch := self.c.Helpers().Refs.GetCheckedOutRef()
return self.createPullRequestMenu(selectedBranch, checkedOutBranch)
}
@ -224,7 +224,7 @@ func (self *BranchesController) copyPullRequestURL() error {
return self.c.Error(errors.New(self.c.Tr.NoBranchOnRemote))
}
url, err := self.helpers.Host.GetPullRequestURL(branch.Name, "")
url, err := self.c.Helpers().Host.GetPullRequestURL(branch.Name, "")
if err != nil {
return self.c.Error(err)
}
@ -259,10 +259,10 @@ func (self *BranchesController) forceCheckout() error {
func (self *BranchesController) checkoutByName() error {
return self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.BranchName + ":",
FindSuggestionsFunc: self.helpers.Suggestions.GetRefsSuggestionsFunc(),
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetRefsSuggestionsFunc(),
HandleConfirm: func(response string) error {
self.c.LogAction("Checkout branch")
return self.helpers.Refs.CheckoutRef(response, types.CheckoutRefOptions{
return self.c.Helpers().Refs.CheckoutRef(response, types.CheckoutRefOptions{
OnRefNotFound: func(ref string) error {
return self.c.Confirm(types.ConfirmOpts{
Title: self.c.Tr.BranchNotFoundTitle,
@ -293,7 +293,7 @@ func (self *BranchesController) createNewBranchWithName(newBranchName string) er
}
func (self *BranchesController) delete(branch *models.Branch) error {
checkedOutBranch := self.helpers.Refs.GetCheckedOutRef()
checkedOutBranch := self.c.Helpers().Refs.GetCheckedOutRef()
if checkedOutBranch.Name == branch.Name {
return self.c.ErrorMsg(self.c.Tr.CantDeleteCheckOutBranch)
}
@ -334,12 +334,12 @@ func (self *BranchesController) deleteWithForce(selectedBranch *models.Branch, f
func (self *BranchesController) merge() error {
selectedBranchName := self.context().GetSelected().Name
return self.helpers.MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranchName)
return self.c.Helpers().MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranchName)
}
func (self *BranchesController) rebase() error {
selectedBranchName := self.context().GetSelected().Name
return self.helpers.MergeAndRebase.RebaseOntoRef(selectedBranchName)
return self.c.Helpers().MergeAndRebase.RebaseOntoRef(selectedBranchName)
}
func (self *BranchesController) fastForward(branch *models.Branch) error {
@ -364,7 +364,7 @@ func (self *BranchesController) fastForward(branch *models.Branch) error {
)
return self.c.WithLoaderPanel(message, func() error {
if branch == self.helpers.Refs.GetCheckedOutRef() {
if branch == self.c.Helpers().Refs.GetCheckedOutRef() {
self.c.LogAction(action)
err := self.c.Git().Sync.Pull(
@ -393,11 +393,11 @@ func (self *BranchesController) fastForward(branch *models.Branch) error {
}
func (self *BranchesController) createTag(branch *models.Branch) error {
return self.helpers.Tags.CreateTagMenu(branch.FullRefName(), func() {})
return self.c.Helpers().Tags.CreateTagMenu(branch.FullRefName(), func() {})
}
func (self *BranchesController) createResetMenu(selectedBranch *models.Branch) error {
return self.helpers.Refs.CreateGitResetMenu(selectedBranch.Name)
return self.c.Helpers().Refs.CreateGitResetMenu(selectedBranch.Name)
}
func (self *BranchesController) rename(branch *models.Branch) error {
@ -444,7 +444,7 @@ func (self *BranchesController) rename(branch *models.Branch) error {
}
func (self *BranchesController) newBranch(selectedBranch *models.Branch) error {
return self.helpers.Refs.NewBranch(selectedBranch.FullRefName(), selectedBranch.RefName(), "")
return self.c.Helpers().Refs.NewBranch(selectedBranch.FullRefName(), selectedBranch.RefName(), "")
}
func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Branch, checkedOutBranch *models.Branch) error {
@ -467,7 +467,7 @@ func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Bra
OnPress: func() error {
return self.c.Prompt(types.PromptOpts{
Title: branch.Name + " →",
FindSuggestionsFunc: self.helpers.Suggestions.GetBranchNameSuggestionsFunc(),
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetBranchNameSuggestionsFunc(),
HandleConfirm: func(targetBranchName string) error {
return self.createPullRequest(branch.Name, targetBranchName)
},
@ -495,7 +495,7 @@ func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Bra
}
func (self *BranchesController) createPullRequest(from string, to string) error {
url, err := self.helpers.Host.GetPullRequestURL(from, to)
url, err := self.c.Helpers().Host.GetPullRequestURL(from, to)
if err != nil {
return self.c.Error(err)
}

View File

@ -6,17 +6,17 @@ import (
type CommandLogController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &CommandLogController{}
func NewCommandLogController(
common *controllerCommon,
common *ControllerCommon,
) *CommandLogController {
return &CommandLogController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}

View File

@ -7,7 +7,7 @@ import (
type CommitMessageController struct {
baseController
*controllerCommon
c *ControllerCommon
getCommitMessage func() string
onCommitAttempt func(message string)
@ -17,14 +17,14 @@ type CommitMessageController struct {
var _ types.IController = &CommitMessageController{}
func NewCommitMessageController(
common *controllerCommon,
common *ControllerCommon,
getCommitMessage func() string,
onCommitAttempt func(message string),
onCommitSuccess func(),
) *CommitMessageController {
return &CommitMessageController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
getCommitMessage: getCommitMessage,
onCommitAttempt: onCommitAttempt,
@ -80,7 +80,7 @@ func (self *CommitMessageController) confirm() error {
self.c.LogAction(self.c.Tr.Actions.Commit)
_ = self.c.PopContext()
return self.helpers.GPG.WithGpgHandling(cmdObj, self.c.Tr.CommittingStatus, func() error {
return self.c.Helpers().GPG.WithGpgHandling(cmdObj, self.c.Tr.CommittingStatus, func() error {
self.onCommitSuccess()
return nil
})

View File

@ -11,17 +11,17 @@ import (
type CommitFilesController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &CommitFilesController{}
func NewCommitFilesController(
common *controllerCommon,
common *ControllerCommon,
) *CommitFilesController {
return &CommitFilesController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -120,7 +120,7 @@ func (self *CommitFilesController) checkout(node *filetree.CommitFileNode) error
}
func (self *CommitFilesController) discard(node *filetree.CommitFileNode) error {
if ok, err := self.helpers.PatchBuilding.ValidateNormalWorkingTreeState(); !ok {
if ok, err := self.c.Helpers().PatchBuilding.ValidateNormalWorkingTreeState(); !ok {
return err
}
@ -131,7 +131,7 @@ func (self *CommitFilesController) discard(node *filetree.CommitFileNode) error
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.DiscardOldFileChange)
if err := self.c.Git().Rebase.DiscardOldFileChanges(self.c.Model().Commits, self.c.Contexts().LocalCommits.GetSelectedLineIdx(), node.GetPath()); err != nil {
if err := self.helpers.MergeAndRebase.CheckMergeOrRebase(err); err != nil {
if err := self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err); err != nil {
return err
}
}
@ -143,7 +143,7 @@ func (self *CommitFilesController) discard(node *filetree.CommitFileNode) error
}
func (self *CommitFilesController) open(node *filetree.CommitFileNode) error {
return self.helpers.Files.OpenFile(node.GetPath())
return self.c.Helpers().Files.OpenFile(node.GetPath())
}
func (self *CommitFilesController) edit(node *filetree.CommitFileNode) error {
@ -151,7 +151,7 @@ func (self *CommitFilesController) edit(node *filetree.CommitFileNode) error {
return self.c.ErrorMsg(self.c.Tr.ErrCannotEditDirectory)
}
return self.helpers.Files.EditFile(node.GetPath())
return self.c.Helpers().Files.EditFile(node.GetPath())
}
func (self *CommitFilesController) toggleForPatch(node *filetree.CommitFileNode) error {

View File

@ -4,17 +4,21 @@ import (
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
)
type controllerCommon struct {
c *helpers.HelperCommon
helpers *helpers.Helpers
type ControllerCommon struct {
*helpers.HelperCommon
IGetHelpers
}
type IGetHelpers interface {
Helpers() *helpers.Helpers
}
func NewControllerCommon(
c *helpers.HelperCommon,
helpers *helpers.Helpers,
) *controllerCommon {
return &controllerCommon{
c: c,
helpers: helpers,
IGetHelpers IGetHelpers,
) *ControllerCommon {
return &ControllerCommon{
HelperCommon: c,
IGetHelpers: IGetHelpers,
}
}

View File

@ -7,17 +7,17 @@ import (
type ConfirmationController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &ConfirmationController{}
func NewConfirmationController(
common *controllerCommon,
common *ControllerCommon,
) *ConfirmationController {
return &ConfirmationController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -51,7 +51,7 @@ func (self *ConfirmationController) GetKeybindings(opts types.KeybindingsOpts) [
func (self *ConfirmationController) GetOnFocusLost() func(types.OnFocusLostOpts) error {
return func(types.OnFocusLostOpts) error {
self.helpers.Confirmation.DeactivateConfirmationPrompt()
self.c.Helpers().Confirmation.DeactivateConfirmationPrompt()
return nil
}
}

View File

@ -24,17 +24,17 @@ var CONTEXT_KEYS_SHOWING_DIFFS = []types.ContextKey{
type ContextLinesController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &ContextLinesController{}
func NewContextLinesController(
common *controllerCommon,
common *ControllerCommon,
) *ContextLinesController {
return &ContextLinesController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}

View File

@ -13,7 +13,7 @@ import (
type FilesController struct {
baseController // nolint: unused
*controllerCommon
c *ControllerCommon
setCommitMessage func(message string)
getSavedCommitMessage func() string
@ -22,12 +22,12 @@ type FilesController struct {
var _ types.IController = &FilesController{}
func NewFilesController(
common *controllerCommon,
common *ControllerCommon,
setCommitMessage func(message string),
getSavedCommitMessage func() string,
) *FilesController {
return &FilesController{
controllerCommon: common,
c: common,
setCommitMessage: setCommitMessage,
getSavedCommitMessage: getSavedCommitMessage,
}
@ -47,12 +47,12 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
},
{
Key: opts.GetKey(opts.Config.Files.CommitChanges),
Handler: self.helpers.WorkingTree.HandleCommitPress,
Handler: self.c.Helpers().WorkingTree.HandleCommitPress,
Description: self.c.Tr.CommitChanges,
},
{
Key: opts.GetKey(opts.Config.Files.CommitChangesWithoutHook),
Handler: self.helpers.WorkingTree.HandleWIPCommitPress,
Handler: self.c.Helpers().WorkingTree.HandleWIPCommitPress,
Description: self.c.Tr.LcCommitChangesWithoutHook,
},
{
@ -62,7 +62,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
},
{
Key: opts.GetKey(opts.Config.Files.CommitChangesWithEditor),
Handler: self.helpers.WorkingTree.HandleCommitEditorPress,
Handler: self.c.Helpers().WorkingTree.HandleCommitEditorPress,
Description: self.c.Tr.CommitChangesWithEditor,
},
{
@ -126,7 +126,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
},
{
Key: opts.GetKey(opts.Config.Files.OpenMergeTool),
Handler: self.helpers.WorkingTree.OpenMergeTool,
Handler: self.c.Helpers().WorkingTree.OpenMergeTool,
Description: self.c.Tr.LcOpenMergeTool,
},
{
@ -174,7 +174,7 @@ func (self *FilesController) GetMouseKeybindings(opts types.KeybindingsOpts) []*
func (self *FilesController) GetOnRenderToMain() func() error {
return func() error {
return self.helpers.Diff.WithDiffModeCheck(func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
node := self.context().GetSelected()
if node == nil {
@ -188,17 +188,17 @@ func (self *FilesController) GetOnRenderToMain() func() error {
}
if node.File != nil && node.File.HasInlineMergeConflicts {
hasConflicts, err := self.helpers.MergeConflicts.SetMergeState(node.GetPath())
hasConflicts, err := self.c.Helpers().MergeConflicts.SetMergeState(node.GetPath())
if err != nil {
return err
}
if hasConflicts {
return self.helpers.MergeConflicts.Render(false)
return self.c.Helpers().MergeConflicts.Render(false)
}
}
self.helpers.MergeConflicts.ResetMergeState()
self.c.Helpers().MergeConflicts.ResetMergeState()
pair := self.c.MainViewPairs().Normal
if node.File != nil {
@ -444,7 +444,7 @@ func (self *FilesController) EnterFile(opts types.OnFocusOpts) error {
submoduleConfigs := self.c.Model().Submodules
if file.IsSubmodule(submoduleConfigs) {
submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
return self.helpers.Repos.EnterSubmodule(submoduleConfig)
return self.c.Helpers().Repos.EnterSubmodule(submoduleConfig)
}
if file.HasInlineMergeConflicts {
@ -624,15 +624,15 @@ func (self *FilesController) handleAmendCommitPress() error {
return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle)
}
if !self.helpers.WorkingTree.AnyStagedFiles() {
return self.helpers.WorkingTree.PromptToStageAllAndRetry(self.handleAmendCommitPress)
if !self.c.Helpers().WorkingTree.AnyStagedFiles() {
return self.c.Helpers().WorkingTree.PromptToStageAllAndRetry(self.handleAmendCommitPress)
}
if len(self.c.Model().Commits) == 0 {
return self.c.ErrorMsg(self.c.Tr.NoCommitToAmend)
}
return self.helpers.AmendHelper.AmendHead()
return self.c.Helpers().AmendHelper.AmendHead()
}
func (self *FilesController) handleStatusFilterPressed() error {
@ -671,7 +671,7 @@ func (self *FilesController) edit(node *filetree.FileNode) error {
return self.c.ErrorMsg(self.c.Tr.ErrCannotEditDirectory)
}
return self.helpers.Files.EditFile(node.GetPath())
return self.c.Helpers().Files.EditFile(node.GetPath())
}
func (self *FilesController) Open() error {
@ -680,7 +680,7 @@ func (self *FilesController) Open() error {
return nil
}
return self.helpers.Files.OpenFile(node.GetPath())
return self.c.Helpers().Files.OpenFile(node.GetPath())
}
func (self *FilesController) switchToMerge() error {
@ -689,7 +689,7 @@ func (self *FilesController) switchToMerge() error {
return nil
}
return self.helpers.MergeConflicts.SwitchToMerge(file.Name)
return self.c.Helpers().MergeConflicts.SwitchToMerge(file.Name)
}
func (self *FilesController) createStashMenu() error {
@ -699,7 +699,7 @@ func (self *FilesController) createStashMenu() error {
{
Label: self.c.Tr.LcStashAllChanges,
OnPress: func() error {
if !self.helpers.WorkingTree.IsWorkingTreeDirty() {
if !self.c.Helpers().WorkingTree.IsWorkingTreeDirty() {
return self.c.ErrorMsg(self.c.Tr.NoFilesToStash)
}
return self.handleStashSave(self.c.Git().Stash.Save, self.c.Tr.Actions.StashAllChanges)
@ -709,7 +709,7 @@ func (self *FilesController) createStashMenu() error {
{
Label: self.c.Tr.LcStashAllChangesKeepIndex,
OnPress: func() error {
if !self.helpers.WorkingTree.IsWorkingTreeDirty() {
if !self.c.Helpers().WorkingTree.IsWorkingTreeDirty() {
return self.c.ErrorMsg(self.c.Tr.NoFilesToStash)
}
// if there are no staged files it behaves the same as Stash.Save
@ -728,7 +728,7 @@ func (self *FilesController) createStashMenu() error {
Label: self.c.Tr.LcStashStagedChanges,
OnPress: func() error {
// there must be something in staging otherwise the current implementation mucks the stash up
if !self.helpers.WorkingTree.AnyStagedFiles() {
if !self.c.Helpers().WorkingTree.AnyStagedFiles() {
return self.c.ErrorMsg(self.c.Tr.NoTrackedStagedFilesStash)
}
return self.handleStashSave(self.c.Git().Stash.SaveStagedChanges, self.c.Tr.Actions.StashStagedChanges)
@ -738,10 +738,10 @@ func (self *FilesController) createStashMenu() error {
{
Label: self.c.Tr.LcStashUnstagedChanges,
OnPress: func() error {
if !self.helpers.WorkingTree.IsWorkingTreeDirty() {
if !self.c.Helpers().WorkingTree.IsWorkingTreeDirty() {
return self.c.ErrorMsg(self.c.Tr.NoFilesToStash)
}
if self.helpers.WorkingTree.AnyStagedFiles() {
if self.c.Helpers().WorkingTree.AnyStagedFiles() {
return self.handleStashSave(self.c.Git().Stash.StashUnstagedChanges, self.c.Tr.Actions.StashUnstagedChanges)
}
// ordinary stash
@ -758,7 +758,7 @@ func (self *FilesController) stash() error {
}
func (self *FilesController) createResetToUpstreamMenu() error {
return self.helpers.Refs.CreateGitResetMenu("@{upstream}")
return self.c.Helpers().Refs.CreateGitResetMenu("@{upstream}")
}
func (self *FilesController) handleToggleDirCollapsed() error {

View File

@ -12,17 +12,17 @@ import (
type FilesRemoveController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &FilesRemoveController{}
func NewFilesRemoveController(
common *controllerCommon,
common *ControllerCommon,
) *FilesRemoveController {
return &FilesRemoveController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -148,7 +148,7 @@ func (self *FilesRemoveController) ResetSubmodule(submodule *models.SubmoduleCon
return self.c.WithWaitingStatus(self.c.Tr.LcResettingSubmoduleStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.ResetSubmodule)
file := self.helpers.WorkingTree.FileForSubmodule(submodule)
file := self.c.Helpers().WorkingTree.FileForSubmodule(submodule)
if file != nil {
if err := self.c.Git().WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil {
return self.c.Error(err)

View File

@ -11,17 +11,17 @@ import (
type GitFlowController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &GitFlowController{}
func NewGitFlowController(
common *controllerCommon,
common *ControllerCommon,
) *GitFlowController {
return &GitFlowController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}

View File

@ -12,15 +12,15 @@ import (
type GlobalController struct {
baseController
*controllerCommon
c *ControllerCommon
}
func NewGlobalController(
common *controllerCommon,
common *ControllerCommon,
) *GlobalController {
return &GlobalController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}

View File

@ -0,0 +1,68 @@
package helpers
import (
"time"
"github.com/jesseduffield/lazygit/pkg/gui/status"
"github.com/jesseduffield/lazygit/pkg/utils"
)
type AppStatusHelper struct {
c *HelperCommon
statusMgr func() *status.StatusManager
}
func NewAppStatusHelper(c *HelperCommon, statusMgr func() *status.StatusManager) *AppStatusHelper {
return &AppStatusHelper{
c: c,
statusMgr: statusMgr,
}
}
func (self *AppStatusHelper) Toast(message string) {
self.statusMgr().AddToastStatus(message)
self.renderAppStatus()
}
// withWaitingStatus wraps a function and shows a waiting status while the function is still executing
func (self *AppStatusHelper) WithWaitingStatus(message string, f func() error) {
go utils.Safe(func() {
self.statusMgr().WithWaitingStatus(message, func() {
self.renderAppStatus()
if err := f(); err != nil {
self.c.OnUIThread(func() error {
return self.c.Error(err)
})
}
})
})
}
func (self *AppStatusHelper) HasStatus() bool {
return self.statusMgr().HasStatus()
}
func (self *AppStatusHelper) GetStatusString() string {
return self.statusMgr().GetStatusString()
}
func (self *AppStatusHelper) renderAppStatus() {
go utils.Safe(func() {
ticker := time.NewTicker(time.Millisecond * 50)
defer ticker.Stop()
for range ticker.C {
appStatus := self.statusMgr().GetStatusString()
self.c.OnUIThread(func() error {
self.c.SetViewContent(self.c.Views().AppStatus, appStatus)
return nil
})
if appStatus == "" {
return
}
}
})
}

View File

@ -42,6 +42,8 @@ type Helpers struct {
View *ViewHelper
Refresh *RefreshHelper
Confirmation *ConfirmationHelper
Mode *ModeHelper
AppStatus *AppStatusHelper
}
func NewStubHelpers() *Helpers {
@ -70,5 +72,7 @@ func NewStubHelpers() *Helpers {
View: &ViewHelper{},
Refresh: &RefreshHelper{},
Confirmation: &ConfirmationHelper{},
Mode: &ModeHelper{},
AppStatus: &AppStatusHelper{},
}
}

View File

@ -0,0 +1,159 @@
package helpers
import (
"fmt"
"github.com/jesseduffield/generics/slices"
"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"
)
type ModeHelper struct {
c *HelperCommon
diffHelper *DiffHelper
patchBuildingHelper *PatchBuildingHelper
cherryPickHelper *CherryPickHelper
mergeAndRebaseHelper *MergeAndRebaseHelper
bisectHelper *BisectHelper
}
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.LcShowingGitDiff,
"git diff "+self.diffHelper.DiffStr(),
),
style.FgMagenta,
)
},
Reset: self.diffHelper.ExitDiffMode,
},
{
IsActive: self.c.Git().Patch.PatchBuilder.Active,
Description: func() string {
return self.withResetButton(self.c.Tr.LcBuildingPatch, style.FgYellow.SetBold())
},
Reset: self.patchBuildingHelper.Reset,
},
{
IsActive: self.c.Modes().Filtering.Active,
Description: func() string {
return self.withResetButton(
fmt.Sprintf(
"%s '%s'",
self.c.Tr.LcFilteringBy,
self.c.Modes().Filtering.GetPath(),
),
style.FgRed,
)
},
Reset: self.ExitFilterMode,
},
{
IsActive: self.c.Modes().CherryPicking.Active,
Description: func() string {
copiedCount := len(self.c.Modes().CherryPicking.CherryPickedCommits)
text := self.c.Tr.LcCommitsCopied
if copiedCount == 1 {
text = self.c.Tr.LcCommitCopied
}
return self.withResetButton(
fmt.Sprintf(
"%d %s",
copiedCount,
text,
),
style.FgCyan,
)
},
Reset: self.cherryPickHelper.Reset,
},
{
IsActive: func() bool {
return self.c.Git().Status.WorkingTreeState() != enums.REBASE_MODE_NONE
},
Description: func() string {
workingTreeState := self.c.Git().Status.WorkingTreeState()
return self.withResetButton(
presentation.FormatWorkingTreeState(workingTreeState), style.FgYellow,
)
},
Reset: self.mergeAndRebaseHelper.AbortMergeOrRebaseWithConfirm,
},
{
IsActive: func() bool {
return self.c.Model().BisectInfo.Started()
},
Description: func() string {
return self.withResetButton("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 slices.Find(self.Statuses(), func(mode ModeStatus) bool {
return mode.IsActive()
})
}
func (self *ModeHelper) IsAnyModeActive() bool {
return slices.Some(self.Statuses(), func(mode ModeStatus) bool {
return mode.IsActive()
})
}
func (self *ModeHelper) ExitFilterMode() error {
return self.ClearFiltering()
}
func (self *ModeHelper) ClearFiltering() error {
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}})
}

View File

@ -6,26 +6,26 @@ import (
)
type ListControllerFactory struct {
*controllerCommon
c *ControllerCommon
}
func NewListControllerFactory(c *controllerCommon) *ListControllerFactory {
func NewListControllerFactory(c *ControllerCommon) *ListControllerFactory {
return &ListControllerFactory{
controllerCommon: c,
c: c,
}
}
func (self *ListControllerFactory) Create(context types.IListContext) *ListController {
return &ListController{
baseController: baseController{},
controllerCommon: self.controllerCommon,
context: context,
baseController: baseController{},
c: self.c,
context: context,
}
}
type ListController struct {
baseController
*controllerCommon
c *ControllerCommon
context types.IListContext
}

View File

@ -7,7 +7,6 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
@ -22,7 +21,7 @@ type (
type LocalCommitsController struct {
baseController
*controllerCommon
c *ControllerCommon
pullFiles PullFilesFn
}
@ -30,13 +29,13 @@ type LocalCommitsController struct {
var _ types.IController = &LocalCommitsController{}
func NewLocalCommitsController(
common *controllerCommon,
common *ControllerCommon,
pullFiles PullFilesFn,
) *LocalCommitsController {
return &LocalCommitsController{
baseController: baseController{},
controllerCommon: common,
pullFiles: pullFiles,
baseController: baseController{},
c: common,
pullFiles: pullFiles,
}
}
@ -156,7 +155,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
func (self *LocalCommitsController) GetOnRenderToMain() func() error {
return func() error {
return self.helpers.Diff.WithDiffModeCheck(func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
var task types.UpdateTask
commit := self.context().GetSelected()
if commit == nil {
@ -185,7 +184,7 @@ func (self *LocalCommitsController) GetOnRenderToMain() func() error {
}
}
func secondaryPatchPanelUpdateOpts(c *helpers.HelperCommon) *types.ViewUpdateOpts {
func secondaryPatchPanelUpdateOpts(c *ControllerCommon) *types.ViewUpdateOpts {
if c.Git().Patch.PatchBuilder.Active() {
patch := c.Git().Patch.PatchBuilder.RenderAggregatedPatch(false)
@ -350,7 +349,7 @@ func (self *LocalCommitsController) edit(commit *models.Commit) error {
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.EditCommit)
err := self.c.Git().Rebase.InteractiveRebaseBreakAfter(self.c.Model().Commits, self.context().GetSelectedLineIdx())
return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
})
}
@ -370,7 +369,7 @@ func (self *LocalCommitsController) pick(commit *models.Commit) error {
func (self *LocalCommitsController) interactiveRebase(action string) error {
err := self.c.Git().Rebase.InteractiveRebase(self.c.Model().Commits, self.context().GetSelectedLineIdx(), action)
return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
}
// handleMidRebaseCommand sees if the selected commit is in fact a rebasing
@ -454,7 +453,7 @@ func (self *LocalCommitsController) moveDown(commit *models.Commit) error {
if err == nil {
self.context().MoveSelectedLine(1)
}
return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
})
}
@ -492,13 +491,13 @@ func (self *LocalCommitsController) moveUp(commit *models.Commit) error {
if err == nil {
self.context().MoveSelectedLine(-1)
}
return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
})
}
func (self *LocalCommitsController) amendTo(commit *models.Commit) error {
if self.isHeadCommit() {
if err := self.helpers.AmendHelper.AmendHead(); err != nil {
if err := self.c.Helpers().AmendHelper.AmendHead(); err != nil {
return err
}
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
@ -515,14 +514,14 @@ func (self *LocalCommitsController) amendTo(commit *models.Commit) error {
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.AmendCommit)
err := self.c.Git().Rebase.AmendTo(commit)
return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
})
},
})
}
func (self *LocalCommitsController) amendAttribute(commit *models.Commit) error {
if self.git.Status.WorkingTreeState() != enums.REBASE_MODE_NONE && !self.isHeadCommit() {
if self.c.Git().Status.WorkingTreeState() != enums.REBASE_MODE_NONE && !self.isHeadCommit() {
return self.c.ErrorMsg(self.c.Tr.AlreadyRebasing)
}
@ -559,7 +558,7 @@ func (self *LocalCommitsController) resetAuthor() error {
func (self *LocalCommitsController) setAuthor() error {
return self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.SetAuthorPromptTitle,
FindSuggestionsFunc: self.helpers.Suggestions.GetAuthorsSuggestionsFunc(),
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc(),
HandleConfirm: func(value string) error {
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.SetCommitAuthor)
@ -662,14 +661,14 @@ func (self *LocalCommitsController) squashAllAboveFixupCommits(commit *models.Co
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.SquashAllAboveFixupCommits)
err := self.c.Git().Rebase.SquashAllAboveFixupCommits(commit)
return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
})
},
})
}
func (self *LocalCommitsController) createTag(commit *models.Commit) error {
return self.helpers.Tags.CreateTagMenu(commit.Sha, func() {})
return self.c.Helpers().Tags.CreateTagMenu(commit.Sha, func() {})
}
func (self *LocalCommitsController) openSearch() error {
@ -826,7 +825,7 @@ func (self *LocalCommitsController) context() *context.LocalCommitsContext {
}
func (self *LocalCommitsController) paste() error {
return self.helpers.CherryPick.Paste()
return self.c.Helpers().CherryPick.Paste()
}
func (self *LocalCommitsController) isHeadCommit() bool {

View File

@ -7,17 +7,17 @@ import (
type MenuController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &MenuController{}
func NewMenuController(
common *controllerCommon,
common *ControllerCommon,
) *MenuController {
return &MenuController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}

View File

@ -11,17 +11,17 @@ import (
type MergeConflictsController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &MergeConflictsController{}
func NewMergeConflictsController(
common *controllerCommon,
common *ControllerCommon,
) *MergeConflictsController {
return &MergeConflictsController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -97,7 +97,7 @@ func (self *MergeConflictsController) GetKeybindings(opts types.KeybindingsOpts)
},
{
Key: opts.GetKey(opts.Config.Files.OpenMergeTool),
Handler: self.helpers.WorkingTree.OpenMergeTool,
Handler: self.c.Helpers().WorkingTree.OpenMergeTool,
Description: self.c.Tr.LcOpenMergeTool,
},
{
@ -145,7 +145,7 @@ func (self *MergeConflictsController) GetOnFocus() func(types.OnFocusOpts) error
return func(types.OnFocusOpts) error {
self.c.Views().MergeConflicts.Wrap = false
return self.helpers.MergeConflicts.Render(true)
return self.c.Helpers().MergeConflicts.Render(true)
}
}
@ -187,11 +187,11 @@ func (self *MergeConflictsController) Escape() error {
func (self *MergeConflictsController) HandleEditFile() error {
lineNumber := self.context().GetState().GetSelectedLine()
return self.helpers.Files.EditFileAtLine(self.context().GetState().GetPath(), lineNumber)
return self.c.Helpers().Files.EditFileAtLine(self.context().GetState().GetPath(), lineNumber)
}
func (self *MergeConflictsController) HandleOpenFile() error {
return self.helpers.Files.OpenFile(self.context().GetState().GetPath())
return self.c.Helpers().Files.OpenFile(self.context().GetState().GetPath())
}
func (self *MergeConflictsController) HandleScrollLeft() error {

View File

@ -8,17 +8,17 @@ import (
type PatchBuildingController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &PatchBuildingController{}
func NewPatchBuildingController(
common *controllerCommon,
common *ControllerCommon,
) *PatchBuildingController {
return &PatchBuildingController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -64,7 +64,7 @@ func (self *PatchBuildingController) GetOnFocus() func(types.OnFocusOpts) error
// no need to change wrap on the secondary view because it can't be interacted with
self.c.Views().PatchBuilding.Wrap = false
return self.helpers.PatchBuilding.RefreshPatchBuildingPanel(opts)
return self.c.Helpers().PatchBuilding.RefreshPatchBuildingPanel(opts)
}
}
@ -90,7 +90,7 @@ func (self *PatchBuildingController) OpenFile() error {
return nil
}
return self.helpers.Files.OpenFile(path)
return self.c.Helpers().Files.OpenFile(path)
}
func (self *PatchBuildingController) EditFile() error {
@ -104,7 +104,7 @@ func (self *PatchBuildingController) EditFile() error {
}
lineNumber := self.context().GetState().CurrentLineNumber()
return self.helpers.Files.EditFileAtLine(path, lineNumber)
return self.c.Helpers().Files.EditFileAtLine(path, lineNumber)
}
func (self *PatchBuildingController) ToggleSelectionAndRefresh() error {
@ -154,5 +154,5 @@ func (self *PatchBuildingController) toggleSelection() error {
}
func (self *PatchBuildingController) Escape() error {
return self.helpers.PatchBuilding.Escape()
return self.c.Helpers().PatchBuilding.Escape()
}

View File

@ -6,26 +6,26 @@ import (
)
type PatchExplorerControllerFactory struct {
*controllerCommon
c *ControllerCommon
}
func NewPatchExplorerControllerFactory(c *controllerCommon) *PatchExplorerControllerFactory {
func NewPatchExplorerControllerFactory(c *ControllerCommon) *PatchExplorerControllerFactory {
return &PatchExplorerControllerFactory{
controllerCommon: c,
c: c,
}
}
func (self *PatchExplorerControllerFactory) Create(context types.IPatchExplorerContext) *PatchExplorerController {
return &PatchExplorerController{
baseController: baseController{},
controllerCommon: self.controllerCommon,
context: context,
baseController: baseController{},
c: self.c,
context: context,
}
}
type PatchExplorerController struct {
baseController
*controllerCommon
c *ControllerCommon
context types.IPatchExplorerContext
}

View File

@ -7,17 +7,17 @@ import (
type ReflogCommitsController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &ReflogCommitsController{}
func NewReflogCommitsController(
common *controllerCommon,
common *ControllerCommon,
) *ReflogCommitsController {
return &ReflogCommitsController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -31,7 +31,7 @@ func (self *ReflogCommitsController) context() *context.ReflogCommitsContext {
func (self *ReflogCommitsController) GetOnRenderToMain() func() error {
return func() error {
return self.helpers.Diff.WithDiffModeCheck(func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
commit := self.context().GetSelected()
var task types.UpdateTask
if commit == nil {

View File

@ -12,17 +12,17 @@ import (
type RemoteBranchesController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &RemoteBranchesController{}
func NewRemoteBranchesController(
common *controllerCommon,
common *ControllerCommon,
) *RemoteBranchesController {
return &RemoteBranchesController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -75,7 +75,7 @@ func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts)
func (self *RemoteBranchesController) GetOnRenderToMain() func() error {
return func() error {
return self.helpers.Diff.WithDiffModeCheck(func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
var task types.UpdateTask
remoteBranch := self.context().GetSelected()
if remoteBranch == nil {
@ -140,19 +140,19 @@ func (self *RemoteBranchesController) delete(selectedBranch *models.RemoteBranch
}
func (self *RemoteBranchesController) merge(selectedBranch *models.RemoteBranch) error {
return self.helpers.MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranch.FullName())
return self.c.Helpers().MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranch.FullName())
}
func (self *RemoteBranchesController) rebase(selectedBranch *models.RemoteBranch) error {
return self.helpers.MergeAndRebase.RebaseOntoRef(selectedBranch.FullName())
return self.c.Helpers().MergeAndRebase.RebaseOntoRef(selectedBranch.FullName())
}
func (self *RemoteBranchesController) createResetMenu(selectedBranch *models.RemoteBranch) error {
return self.helpers.Refs.CreateGitResetMenu(selectedBranch.FullName())
return self.c.Helpers().Refs.CreateGitResetMenu(selectedBranch.FullName())
}
func (self *RemoteBranchesController) setAsUpstream(selectedBranch *models.RemoteBranch) error {
checkedOutBranch := self.helpers.Refs.GetCheckedOutRef()
checkedOutBranch := self.c.Helpers().Refs.GetCheckedOutRef()
message := utils.ResolvePlaceholderString(
self.c.Tr.SetUpstreamMessage,
@ -180,5 +180,5 @@ func (self *RemoteBranchesController) newLocalBranch(selectedBranch *models.Remo
// will set to the remote's branch name without the remote name
nameSuggestion := strings.SplitAfterN(selectedBranch.RefName(), "/", 2)[1]
return self.helpers.Refs.NewBranch(selectedBranch.RefName(), selectedBranch.RefName(), nameSuggestion)
return self.c.Helpers().Refs.NewBranch(selectedBranch.RefName(), selectedBranch.RefName(), nameSuggestion)
}

View File

@ -13,7 +13,7 @@ import (
type RemotesController struct {
baseController
*controllerCommon
c *ControllerCommon
setRemoteBranches func([]*models.RemoteBranch)
}
@ -21,12 +21,12 @@ type RemotesController struct {
var _ types.IController = &RemotesController{}
func NewRemotesController(
common *controllerCommon,
common *ControllerCommon,
setRemoteBranches func([]*models.RemoteBranch),
) *RemotesController {
return &RemotesController{
baseController: baseController{},
controllerCommon: common,
c: common,
setRemoteBranches: setRemoteBranches,
}
}
@ -72,7 +72,7 @@ func (self *RemotesController) context() *context.RemotesContext {
func (self *RemotesController) GetOnRenderToMain() func() error {
return func() error {
return self.helpers.Diff.WithDiffModeCheck(func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
var task types.UpdateTask
remote := self.context().GetSelected()
if remote == nil {

View File

@ -7,17 +7,17 @@ import (
type SnakeController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &SnakeController{}
func NewSnakeController(
common *controllerCommon,
common *ControllerCommon,
) *SnakeController {
return &SnakeController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -54,22 +54,22 @@ func (self *SnakeController) Context() types.Context {
func (self *SnakeController) GetOnFocus() func(types.OnFocusOpts) error {
return func(types.OnFocusOpts) error {
self.helpers.Snake.StartGame()
self.c.Helpers().Snake.StartGame()
return nil
}
}
func (self *SnakeController) GetOnFocusLost() func(types.OnFocusLostOpts) error {
return func(types.OnFocusLostOpts) error {
self.helpers.Snake.ExitGame()
self.helpers.Window.MoveToTopOfWindow(self.c.Contexts().Submodules)
self.c.Helpers().Snake.ExitGame()
self.c.Helpers().Window.MoveToTopOfWindow(self.c.Contexts().Submodules)
return nil
}
}
func (self *SnakeController) SetDirection(direction snake.Direction) func() error {
return func() error {
self.helpers.Snake.SetDirection(direction)
self.c.Helpers().Snake.SetDirection(direction)
return nil
}
}

View File

@ -10,7 +10,7 @@ import (
type StagingController struct {
baseController
*controllerCommon
c *ControllerCommon
context types.IPatchExplorerContext
otherContext types.IPatchExplorerContext
@ -22,17 +22,17 @@ type StagingController struct {
var _ types.IController = &StagingController{}
func NewStagingController(
common *controllerCommon,
common *ControllerCommon,
context types.IPatchExplorerContext,
otherContext types.IPatchExplorerContext,
staged bool,
) *StagingController {
return &StagingController{
baseController: baseController{},
controllerCommon: common,
context: context,
otherContext: otherContext,
staged: staged,
baseController: baseController{},
c: common,
context: context,
otherContext: otherContext,
staged: staged,
}
}
@ -75,17 +75,17 @@ func (self *StagingController) GetKeybindings(opts types.KeybindingsOpts) []*typ
},
{
Key: opts.GetKey(opts.Config.Files.CommitChanges),
Handler: self.helpers.WorkingTree.HandleCommitPress,
Handler: self.c.Helpers().WorkingTree.HandleCommitPress,
Description: self.c.Tr.CommitChanges,
},
{
Key: opts.GetKey(opts.Config.Files.CommitChangesWithoutHook),
Handler: self.helpers.WorkingTree.HandleWIPCommitPress,
Handler: self.c.Helpers().WorkingTree.HandleWIPCommitPress,
Description: self.c.Tr.LcCommitChangesWithoutHook,
},
{
Key: opts.GetKey(opts.Config.Files.CommitChangesWithEditor),
Handler: self.helpers.WorkingTree.HandleCommitEditorPress,
Handler: self.c.Helpers().WorkingTree.HandleCommitEditorPress,
Description: self.c.Tr.CommitChangesWithEditor,
},
}
@ -104,7 +104,7 @@ func (self *StagingController) GetOnFocus() func(types.OnFocusOpts) error {
self.c.Views().Staging.Wrap = false
self.c.Views().StagingSecondary.Wrap = false
return self.helpers.Staging.RefreshStagingPanel(opts)
return self.c.Helpers().Staging.RefreshStagingPanel(opts)
}
}
@ -132,7 +132,7 @@ func (self *StagingController) OpenFile() error {
return nil
}
return self.helpers.Files.OpenFile(path)
return self.c.Helpers().Files.OpenFile(path)
}
func (self *StagingController) EditFile() error {
@ -146,7 +146,7 @@ func (self *StagingController) EditFile() error {
}
lineNumber := self.context.GetState().CurrentLineNumber()
return self.helpers.Files.EditFileAtLine(path, lineNumber)
return self.c.Helpers().Files.EditFileAtLine(path, lineNumber)
}
func (self *StagingController) Escape() error {
@ -269,7 +269,7 @@ func (self *StagingController) editHunk() error {
lineOffset := 3
lineIdxInHunk := state.GetSelectedLineIdx() - hunkStartIdx
if err := self.helpers.Files.EditFileAtLineAndWait(patchFilepath, lineIdxInHunk+lineOffset); err != nil {
if err := self.c.Helpers().Files.EditFileAtLineAndWait(patchFilepath, lineIdxInHunk+lineOffset); err != nil {
return err
}

View File

@ -9,17 +9,17 @@ import (
type StashController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &StashController{}
func NewStashController(
common *controllerCommon,
common *ControllerCommon,
) *StashController {
return &StashController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -57,7 +57,7 @@ func (self *StashController) GetKeybindings(opts types.KeybindingsOpts) []*types
func (self *StashController) GetOnRenderToMain() func() error {
return func() error {
return self.helpers.Diff.WithDiffModeCheck(func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
var task types.UpdateTask
stashEntry := self.context().GetSelected()
if stashEntry == nil {
@ -165,7 +165,7 @@ func (self *StashController) postStashRefresh() error {
}
func (self *StashController) handleNewBranchOffStashEntry(stashEntry *models.StashEntry) error {
return self.helpers.Refs.NewBranch(stashEntry.RefName(), stashEntry.Description(), "")
return self.c.Helpers().Refs.NewBranch(stashEntry.RefName(), stashEntry.Description(), "")
}
func (self *StashController) handleRenameStashEntry(stashEntry *models.StashEntry) error {

View File

@ -16,17 +16,17 @@ import (
type StatusController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &StatusController{}
func NewStatusController(
common *controllerCommon,
common *ControllerCommon,
) *StatusController {
return &StatusController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -49,7 +49,7 @@ func (self *StatusController) GetKeybindings(opts types.KeybindingsOpts) []*type
},
{
Key: opts.GetKey(opts.Config.Status.RecentRepos),
Handler: self.helpers.Repos.CreateRecentReposMenu,
Handler: self.c.Helpers().Repos.CreateRecentReposMenu,
Description: self.c.Tr.SwitchRepo,
},
{
@ -96,7 +96,7 @@ func (self *StatusController) Context() types.Context {
func (self *StatusController) onClick() error {
// TODO: move into some abstraction (status is currently not a listViewContext where a lot of this code lives)
currentBranch := self.helpers.Refs.GetCheckedOutRef()
currentBranch := self.c.Helpers().Refs.GetCheckedOutRef()
if currentBranch == nil {
// need to wait for branches to refresh
return nil
@ -114,14 +114,14 @@ func (self *StatusController) onClick() error {
case enums.REBASE_MODE_REBASING, enums.REBASE_MODE_MERGING:
workingTreeStatus := fmt.Sprintf("(%s)", presentation.FormatWorkingTreeState(workingTreeState))
if cursorInSubstring(cx, upstreamStatus+" ", workingTreeStatus) {
return self.helpers.MergeAndRebase.CreateRebaseOptionsMenu()
return self.c.Helpers().MergeAndRebase.CreateRebaseOptionsMenu()
}
if cursorInSubstring(cx, upstreamStatus+" "+workingTreeStatus+" ", repoName) {
return self.helpers.Repos.CreateRecentReposMenu()
return self.c.Helpers().Repos.CreateRecentReposMenu()
}
default:
if cursorInSubstring(cx, upstreamStatus+" ", repoName) {
return self.helpers.Repos.CreateRecentReposMenu()
return self.c.Helpers().Repos.CreateRecentReposMenu()
}
}
@ -173,11 +173,11 @@ func (self *StatusController) askForConfigFile(action func(file string) error) e
}
func (self *StatusController) openConfig() error {
return self.askForConfigFile(self.helpers.Files.OpenFile)
return self.askForConfigFile(self.c.Helpers().Files.OpenFile)
}
func (self *StatusController) editConfig() error {
return self.askForConfigFile(self.helpers.Files.EditFile)
return self.askForConfigFile(self.c.Helpers().Files.EditFile)
}
func (self *StatusController) showAllBranchLogs() error {
@ -194,5 +194,5 @@ func (self *StatusController) showAllBranchLogs() error {
}
func (self *StatusController) handleCheckForUpdate() error {
return self.helpers.Update.CheckForUpdateInForeground()
return self.c.Helpers().Update.CheckForUpdateInForeground()
}

View File

@ -8,17 +8,17 @@ import (
type SubCommitsController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &SubCommitsController{}
func NewSubCommitsController(
common *controllerCommon,
common *ControllerCommon,
) *SubCommitsController {
return &SubCommitsController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -32,7 +32,7 @@ func (self *SubCommitsController) context() *context.SubCommitsContext {
func (self *SubCommitsController) GetOnRenderToMain() func() error {
return func() error {
return self.helpers.Diff.WithDiffModeCheck(func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
commit := self.context().GetSelected()
var task types.UpdateTask
if commit == nil {

View File

@ -13,17 +13,17 @@ import (
type SubmodulesController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &SubmodulesController{}
func NewSubmodulesController(
controllerCommon *controllerCommon,
controllerCommon *ControllerCommon,
) *SubmodulesController {
return &SubmodulesController{
baseController: baseController{},
controllerCommon: controllerCommon,
baseController: baseController{},
c: controllerCommon,
}
}
@ -79,7 +79,7 @@ func (self *SubmodulesController) GetOnClick() func() error {
func (self *SubmodulesController) GetOnRenderToMain() func() error {
return func() error {
return self.helpers.Diff.WithDiffModeCheck(func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
var task types.UpdateTask
submodule := self.context().GetSelected()
if submodule == nil {
@ -92,7 +92,7 @@ func (self *SubmodulesController) GetOnRenderToMain() func() error {
style.FgCyan.Sprint(submodule.Url),
)
file := self.helpers.WorkingTree.FileForSubmodule(submodule)
file := self.c.Helpers().WorkingTree.FileForSubmodule(submodule)
if file == nil {
task = types.NewRenderStringTask(prefix)
} else {
@ -113,7 +113,7 @@ func (self *SubmodulesController) GetOnRenderToMain() func() error {
}
func (self *SubmodulesController) enter(submodule *models.SubmoduleConfig) error {
return self.helpers.Repos.EnterSubmodule(submodule)
return self.c.Helpers().Repos.EnterSubmodule(submodule)
}
func (self *SubmodulesController) add() error {

View File

@ -7,17 +7,17 @@ import (
type SuggestionsController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &SuggestionsController{}
func NewSuggestionsController(
common *controllerCommon,
common *ControllerCommon,
) *SuggestionsController {
return &SuggestionsController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -42,7 +42,7 @@ func (self *SuggestionsController) GetKeybindings(opts types.KeybindingsOpts) []
func (self *SuggestionsController) GetOnFocusLost() func(types.OnFocusLostOpts) error {
return func(types.OnFocusLostOpts) error {
self.helpers.Confirmation.DeactivateConfirmationPrompt()
self.c.Helpers().Confirmation.DeactivateConfirmationPrompt()
return nil
}
}

View File

@ -17,19 +17,19 @@ type CanSwitchToDiffFiles interface {
type SwitchToDiffFilesController struct {
baseController
*controllerCommon
c *ControllerCommon
context CanSwitchToDiffFiles
diffFilesContext *context.CommitFilesContext
}
func NewSwitchToDiffFilesController(
controllerCommon *controllerCommon,
c *ControllerCommon,
context CanSwitchToDiffFiles,
diffFilesContext *context.CommitFilesContext,
) *SwitchToDiffFilesController {
return &SwitchToDiffFilesController{
baseController: baseController{},
controllerCommon: controllerCommon,
c: c,
context: context,
diffFilesContext: diffFilesContext,
}

View File

@ -15,22 +15,22 @@ type CanSwitchToSubCommits interface {
type SwitchToSubCommitsController struct {
baseController
*controllerCommon
c *ControllerCommon
context CanSwitchToSubCommits
setSubCommits func([]*models.Commit)
}
func NewSwitchToSubCommitsController(
controllerCommon *controllerCommon,
controllerCommon *ControllerCommon,
setSubCommits func([]*models.Commit),
context CanSwitchToSubCommits,
) *SwitchToSubCommitsController {
return &SwitchToSubCommitsController{
baseController: baseController{},
controllerCommon: controllerCommon,
context: context,
setSubCommits: setSubCommits,
baseController: baseController{},
c: controllerCommon,
context: context,
setSubCommits: setSubCommits,
}
}

View File

@ -11,17 +11,17 @@ import (
type SyncController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &SyncController{}
func NewSyncController(
common *controllerCommon,
common *ControllerCommon,
) *SyncController {
return &SyncController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -56,7 +56,7 @@ func (self *SyncController) HandlePull() error {
func (self *SyncController) branchCheckedOut(f func(*models.Branch) error) func() error {
return func() error {
currentBranch := self.helpers.Refs.GetCheckedOutRef()
currentBranch := self.c.Helpers().Refs.GetCheckedOutRef()
if currentBranch == nil {
// need to wait for branches to refresh
return nil
@ -79,8 +79,8 @@ func (self *SyncController) push(currentBranch *models.Branch) error {
if self.c.Git().Config.GetPushToCurrent() {
return self.pushAux(pushOpts{setUpstream: true})
} else {
return self.helpers.Upstream.PromptForUpstreamWithInitialContent(currentBranch, func(upstream string) error {
upstreamRemote, upstreamBranch, err := self.helpers.Upstream.ParseUpstream(upstream)
return self.c.Helpers().Upstream.PromptForUpstreamWithInitialContent(currentBranch, func(upstream string) error {
upstreamRemote, upstreamBranch, err := self.c.Helpers().Upstream.ParseUpstream(upstream)
if err != nil {
return self.c.Error(err)
}
@ -100,7 +100,7 @@ func (self *SyncController) pull(currentBranch *models.Branch) error {
// if we have no upstream branch we need to set that first
if !currentBranch.IsTrackingRemote() {
return self.helpers.Upstream.PromptForUpstreamWithInitialContent(currentBranch, func(upstream string) error {
return self.c.Helpers().Upstream.PromptForUpstreamWithInitialContent(currentBranch, func(upstream string) error {
if err := self.setCurrentBranchUpstream(upstream); err != nil {
return self.c.Error(err)
}
@ -113,7 +113,7 @@ func (self *SyncController) pull(currentBranch *models.Branch) error {
}
func (self *SyncController) setCurrentBranchUpstream(upstream string) error {
upstreamRemote, upstreamBranch, err := self.helpers.Upstream.ParseUpstream(upstream)
upstreamRemote, upstreamBranch, err := self.c.Helpers().Upstream.ParseUpstream(upstream)
if err != nil {
return err
}
@ -154,7 +154,7 @@ func (self *SyncController) pullWithLock(opts PullFilesOptions) error {
},
)
return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
}
type pushOpts struct {

View File

@ -9,17 +9,17 @@ import (
type TagsController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &TagsController{}
func NewTagsController(
common *controllerCommon,
common *ControllerCommon,
) *TagsController {
return &TagsController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -58,7 +58,7 @@ func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types.
func (self *TagsController) GetOnRenderToMain() func() error {
return func() error {
return self.helpers.Diff.WithDiffModeCheck(func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
var task types.UpdateTask
tag := self.context().GetSelected()
if tag == nil {
@ -81,7 +81,7 @@ func (self *TagsController) GetOnRenderToMain() func() error {
func (self *TagsController) checkout(tag *models.Tag) error {
self.c.LogAction(self.c.Tr.Actions.CheckoutTag)
if err := self.helpers.Refs.CheckoutRef(tag.Name, types.CheckoutRefOptions{}); err != nil {
if err := self.c.Helpers().Refs.CheckoutRef(tag.Name, types.CheckoutRefOptions{}); err != nil {
return err
}
return self.c.PushContext(self.c.Contexts().Branches)
@ -119,7 +119,7 @@ func (self *TagsController) push(tag *models.Tag) error {
return self.c.Prompt(types.PromptOpts{
Title: title,
InitialContent: "origin",
FindSuggestionsFunc: self.helpers.Suggestions.GetRemoteSuggestionsFunc(),
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetRemoteSuggestionsFunc(),
HandleConfirm: func(response string) error {
return self.c.WithWaitingStatus(self.c.Tr.PushingTagStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.PushTag)
@ -135,12 +135,12 @@ func (self *TagsController) push(tag *models.Tag) error {
}
func (self *TagsController) createResetMenu(tag *models.Tag) error {
return self.helpers.Refs.CreateGitResetMenu(tag.Name)
return self.c.Helpers().Refs.CreateGitResetMenu(tag.Name)
}
func (self *TagsController) create() error {
// leaving commit SHA blank so that we're just creating the tag for the current commit
return self.helpers.Tags.CreateTagMenu("", func() { self.context().SetSelectedLineIdx(0) })
return self.c.Helpers().Tags.CreateTagMenu("", func() { self.context().SetSelectedLineIdx(0) })
}
func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func() error {

View File

@ -20,17 +20,17 @@ import (
type UndoController struct {
baseController
*controllerCommon
c *ControllerCommon
}
var _ types.IController = &UndoController{}
func NewUndoController(
common *controllerCommon,
common *ControllerCommon,
) *UndoController {
return &UndoController{
baseController: baseController{},
controllerCommon: common,
baseController: baseController{},
c: common,
}
}
@ -104,7 +104,7 @@ func (self *UndoController) reflogUndo() error {
Prompt: fmt.Sprintf(self.c.Tr.CheckoutPrompt, action.from),
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.Undo)
return self.helpers.Refs.CheckoutRef(action.from, types.CheckoutRefOptions{
return self.c.Helpers().Refs.CheckoutRef(action.from, types.CheckoutRefOptions{
EnvVars: undoEnvVars,
WaitingStatus: undoingStatus,
})
@ -156,7 +156,7 @@ func (self *UndoController) reflogRedo() error {
Prompt: fmt.Sprintf(self.c.Tr.CheckoutPrompt, action.to),
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.Redo)
return self.helpers.Refs.CheckoutRef(action.to, types.CheckoutRefOptions{
return self.c.Helpers().Refs.CheckoutRef(action.to, types.CheckoutRefOptions{
EnvVars: redoEnvVars,
WaitingStatus: redoingStatus,
})
@ -233,14 +233,14 @@ type hardResetOptions struct {
// only to be used in the undo flow for now (does an autostash)
func (self *UndoController) hardResetWithAutoStash(commitSha string, options hardResetOptions) error {
reset := func() error {
if err := self.helpers.Refs.ResetToRef(commitSha, "hard", options.EnvVars); err != nil {
if err := self.c.Helpers().Refs.ResetToRef(commitSha, "hard", options.EnvVars); err != nil {
return self.c.Error(err)
}
return nil
}
// if we have any modified tracked files we need to ask the user if they want us to stash for them
dirtyWorkingTree := self.helpers.WorkingTree.IsWorkingTreeDirty()
dirtyWorkingTree := self.c.Helpers().WorkingTree.IsWorkingTreeDirty()
if dirtyWorkingTree {
// offer to autostash changes
return self.c.Confirm(types.ConfirmOpts{

View File

@ -9,13 +9,13 @@ import (
// given we have no fields here, arguably we shouldn't even need this factory
// struct, but we're maintaining consistency with the other files.
type VerticalScrollControllerFactory struct {
controllerCommon *controllerCommon
c *ControllerCommon
viewBufferManagerMap *map[string]*tasks.ViewBufferManager
}
func NewVerticalScrollControllerFactory(c *controllerCommon, viewBufferManagerMap *map[string]*tasks.ViewBufferManager) *VerticalScrollControllerFactory {
func NewVerticalScrollControllerFactory(c *ControllerCommon, viewBufferManagerMap *map[string]*tasks.ViewBufferManager) *VerticalScrollControllerFactory {
return &VerticalScrollControllerFactory{
controllerCommon: c,
c: c,
viewBufferManagerMap: viewBufferManagerMap,
}
}
@ -23,7 +23,7 @@ func NewVerticalScrollControllerFactory(c *controllerCommon, viewBufferManagerMa
func (self *VerticalScrollControllerFactory) Create(context types.Context) types.IController {
return &VerticalScrollController{
baseController: baseController{},
controllerCommon: self.controllerCommon,
c: self.c,
context: context,
viewBufferManagerMap: self.viewBufferManagerMap,
}
@ -31,7 +31,7 @@ func (self *VerticalScrollControllerFactory) Create(context types.Context) types
type VerticalScrollController struct {
baseController
*controllerCommon
c *ControllerCommon
context types.Context
viewBufferManagerMap *map[string]*tasks.ViewBufferManager

View File

@ -72,7 +72,7 @@ func (self *FilesController) createResetMenu() error {
Tooltip: self.c.Tr.DiscardStagedChangesDescription,
OnPress: func() error {
self.c.LogAction(self.c.Tr.Actions.RemoveStagedFiles)
if !self.helpers.WorkingTree.IsWorkingTreeDirty() {
if !self.c.Helpers().WorkingTree.IsWorkingTreeDirty() {
return self.c.ErrorMsg(self.c.Tr.NoTrackedStagedFilesStash)
}
if err := self.c.Git().Stash.SaveStagedChanges("[lazygit] tmp stash"); err != nil {

View File

@ -16,13 +16,13 @@ func (gui *Gui) handleCreateExtrasMenuPanel() error {
Label: gui.c.Tr.ToggleShowCommandLog,
OnPress: func() error {
currentContext := gui.c.CurrentStaticContext()
if gui.ShowExtrasWindow && currentContext.GetKey() == context.COMMAND_LOG_CONTEXT_KEY {
if gui.c.State().GetShowExtrasWindow() && currentContext.GetKey() == context.COMMAND_LOG_CONTEXT_KEY {
if err := gui.c.PopContext(); err != nil {
return err
}
}
show := !gui.ShowExtrasWindow
gui.ShowExtrasWindow = show
show := !gui.c.State().GetShowExtrasWindow()
gui.c.State().SetShowExtrasWindow(show)
gui.c.GetAppState().HideCommandLog = !show
_ = gui.c.SaveAppState()
return nil
@ -37,7 +37,7 @@ func (gui *Gui) handleCreateExtrasMenuPanel() error {
}
func (gui *Gui) handleFocusCommandLog() error {
gui.ShowExtrasWindow = true
gui.c.State().SetShowExtrasWindow(true)
// TODO: is this necessary? Can't I just call 'return from context'?
gui.State.Contexts.CommandLog.SetParentContext(gui.c.CurrentSideContext())
return gui.c.PushContext(gui.State.Contexts.CommandLog)

View File

@ -9,7 +9,7 @@ func (gui *Gui) validateNotInFilterMode() bool {
_ = gui.c.Confirm(types.ConfirmOpts{
Title: gui.c.Tr.MustExitFilterModeTitle,
Prompt: gui.c.Tr.MustExitFilterModePrompt,
HandleConfirm: gui.exitFilterMode,
HandleConfirm: gui.helpers.Mode.ExitFilterMode,
})
return false
@ -17,19 +17,6 @@ func (gui *Gui) validateNotInFilterMode() bool {
return true
}
func (gui *Gui) exitFilterMode() error {
return gui.clearFiltering()
}
func (gui *Gui) clearFiltering() error {
gui.State.Modes.Filtering.Reset()
if gui.State.ScreenMode == types.SCREEN_HALF {
gui.State.ScreenMode = types.SCREEN_NORMAL
}
return gui.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.COMMITS}})
}
func (gui *Gui) setFiltering(path string) error {
gui.State.Modes.Filtering.SetPath(path)
if gui.State.ScreenMode == types.SCREEN_NORMAL {

View File

@ -49,7 +49,7 @@ func (gui *Gui) handleCreateFilteringMenuPanel() error {
if gui.State.Modes.Filtering.Active() {
menuItems = append(menuItems, &types.MenuItem{
Label: gui.c.Tr.LcExitFilterMode,
OnPress: gui.clearFiltering,
OnPress: gui.helpers.Mode.ClearFiltering,
})
}

View File

@ -30,6 +30,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/gui/presentation/graph"
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
"github.com/jesseduffield/lazygit/pkg/gui/services/custom_commands"
"github.com/jesseduffield/lazygit/pkg/gui/status"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/integration/components"
@ -67,7 +68,7 @@ type Gui struct {
RepoStateMap map[Repo]*GuiRepoState
Config config.AppConfigurer
Updater *updates.Updater
statusManager *statusManager
statusManager *status.StatusManager
waitForIntro sync.WaitGroup
fileWatcher *fileWatcher
viewBufferManagerMap map[string]*tasks.ViewBufferManager
@ -127,9 +128,8 @@ type Gui struct {
Updating bool
c *helpers.HelperCommon
contextCommon *context.ContextCommon
helpers *helpers.Helpers
c *helpers.HelperCommon
helpers *helpers.Helpers
}
type StateAccessor struct {
@ -170,6 +170,14 @@ func (self *StateAccessor) SetIsRefreshingFiles(value bool) {
self.gui.IsRefreshingFiles = value
}
func (self *StateAccessor) GetShowExtrasWindow() bool {
return self.gui.ShowExtrasWindow
}
func (self *StateAccessor) SetShowExtrasWindow(value bool) {
self.gui.ShowExtrasWindow = value
}
// we keep track of some stuff from one render to the next to see if certain
// things have changed
type PrevLayout struct {
@ -188,7 +196,7 @@ type GuiRepoState struct {
Searching searchingState
StartupStage types.StartupStage // Allows us to not load everything at once
ContextMgr ContextMgr
ContextMgr *ContextMgr
Contexts *context.ContextTree
// WindowViewNameMap is a mapping of windows to the current view of that window.
@ -240,6 +248,22 @@ func (self *GuiRepoState) GetScreenMode() types.WindowMaximisation {
return self.ScreenMode
}
func (self *GuiRepoState) SetScreenMode(value types.WindowMaximisation) {
self.ScreenMode = value
}
func (self *GuiRepoState) IsSearching() bool {
return self.Searching.isSearching
}
func (self *GuiRepoState) SetSplitMainPanel(value bool) {
self.SplitMainPanel = value
}
func (self *GuiRepoState) GetSplitMainPanel() bool {
return self.SplitMainPanel
}
type searchingState struct {
view *gocui.View
isSearching bool
@ -405,7 +429,7 @@ func NewGui(
gitVersion: gitVersion,
Config: config,
Updater: updater,
statusManager: &statusManager{},
statusManager: status.NewStatusManager(),
viewBufferManagerMap: map[string]*tasks.ViewBufferManager{},
viewPtmxMap: map[string]*os.File{},
showRecentRepos: showRecentRepos,
@ -438,17 +462,16 @@ func NewGui(
return gui.helpers.Confirmation.CreatePopupPanel(ctx, opts)
},
func() error { return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) },
gui.popContext,
gui.currentContext,
func() error { return gui.State.ContextMgr.Pop() },
func() types.Context { return gui.State.ContextMgr.Current() },
gui.createMenu,
gui.withWaitingStatus,
gui.toast,
func(message string, f func() error) { gui.helpers.AppStatus.WithWaitingStatus(message, f) },
func(message string) { gui.helpers.AppStatus.Toast(message) },
func() string { return gui.Views.Confirmation.TextArea.GetContent() },
)
guiCommon := &guiCommon{gui: gui, IPopupHandler: gui.PopupHandler}
helperCommon := &helpers.HelperCommon{IGuiCommon: guiCommon, Common: cmn, IGetContexts: gui}
contextCommon := &context.ContextCommon{IGuiCommon: guiCommon, Common: cmn}
credentialsHelper := helpers.NewCredentialsHelper(helperCommon)
@ -467,8 +490,6 @@ func NewGui(
// TODO: reset these controllers upon changing repos due to state changing
gui.c = helperCommon
gui.contextCommon = contextCommon
authors.SetCustomAuthors(gui.UserConfig.Gui.AuthorColors)
icons.SetIconEnabled(gui.UserConfig.Gui.ShowIcons)
presentation.SetCustomBranches(gui.UserConfig.Gui.BranchColors)
@ -804,30 +825,15 @@ func (gui *Gui) startBackgroundRoutines() {
}
func (gui *Gui) getWindowDimensions(informationStr string, appStatus string) map[string]boxlayout.Dimensions {
windowArranger := &WindowArranger{gui: gui}
windowArranger := NewWindowArranger(
gui.c,
gui.helpers.Window,
gui.helpers.Mode,
gui.helpers.AppStatus,
)
return windowArranger.getWindowDimensions(informationStr, appStatus)
}
func (gui *Gui) replaceContext(c types.Context) error {
return gui.State.ContextMgr.replaceContext(c)
}
func (gui *Gui) pushContext(c types.Context, opts ...types.OnFocusOpts) error {
return gui.State.ContextMgr.pushContext(c, opts...)
}
func (gui *Gui) popContext() error {
return gui.State.ContextMgr.popContext()
}
func (gui *Gui) currentContext() types.Context {
return gui.State.ContextMgr.currentContext()
}
func (gui *Gui) currentSideContext() types.Context {
return gui.State.ContextMgr.currentSideContext()
}
func (gui *Gui) currentStaticContext() types.Context {
return gui.State.ContextMgr.currentStaticContext()
return gui.State.ContextMgr.Pop()
}

View File

@ -41,31 +41,35 @@ func (self *guiCommon) RunSubprocess(cmdObj oscommands.ICmdObj) (bool, error) {
}
func (self *guiCommon) PushContext(context types.Context, opts ...types.OnFocusOpts) error {
return self.gui.pushContext(context, opts...)
return self.gui.State.ContextMgr.Push(context, opts...)
}
func (self *guiCommon) PopContext() error {
return self.gui.popContext()
return self.gui.State.ContextMgr.Pop()
}
func (self *guiCommon) ReplaceContext(context types.Context) error {
return self.gui.replaceContext(context)
return self.gui.State.ContextMgr.Replace(context)
}
func (self *guiCommon) CurrentContext() types.Context {
return self.gui.currentContext()
return self.gui.State.ContextMgr.Current()
}
func (self *guiCommon) CurrentStaticContext() types.Context {
return self.gui.currentStaticContext()
return self.gui.State.ContextMgr.CurrentStatic()
}
func (self *guiCommon) CurrentSideContext() types.Context {
return self.gui.currentSideContext()
return self.gui.State.ContextMgr.CurrentSide()
}
func (self *guiCommon) IsCurrentContext(c types.Context) bool {
return self.CurrentContext().GetKey() == c.GetKey()
return self.gui.State.ContextMgr.IsCurrent(c)
}
func (self *guiCommon) Context() types.IContextMgr {
return self.gui.State.ContextMgr
}
func (self *guiCommon) GetAppState() *config.AppState {
@ -148,3 +152,7 @@ func (self *guiCommon) State() types.IStateAccessor {
func (self *guiCommon) KeybindingsOpts() types.KeybindingsOpts {
return self.gui.keybindingOpts()
}
func (self *guiCommon) IsAnyModeActive() bool {
return self.IsAnyModeActive()
}

View File

@ -3,15 +3,14 @@ package gui
import (
"fmt"
"github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/constants"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/mattn/go-runewidth"
)
func (gui *Gui) informationStr() string {
if activeMode, ok := gui.getActiveMode(); ok {
return activeMode.description()
if activeMode, ok := gui.helpers.Mode.GetActiveMode(); ok {
return activeMode.Description()
}
if gui.g.Mouse {
@ -23,18 +22,6 @@ func (gui *Gui) informationStr() string {
}
}
func (gui *Gui) getActiveMode() (modeStatus, bool) {
return slices.Find(gui.modeStatuses(), func(mode modeStatus) bool {
return mode.isActive()
})
}
func (gui *Gui) isAnyModeActive() bool {
return slices.Some(gui.modeStatuses(), func(mode modeStatus) bool {
return mode.isActive()
})
}
func (gui *Gui) handleInfoClick() error {
if !gui.g.Mouse {
return nil
@ -45,11 +32,11 @@ func (gui *Gui) handleInfoClick() error {
cx, _ := view.Cursor()
width, _ := view.Size()
if activeMode, ok := gui.getActiveMode(); ok {
if activeMode, ok := gui.helpers.Mode.GetActiveMode(); ok {
if width-cx > runewidth.StringWidth(gui.c.Tr.ResetInParentheses) {
return nil
}
return activeMode.reset()
return activeMode.Reset()
}
// if we're not in an active mode we show the donate button

View File

@ -23,7 +23,8 @@ func (gui *Gui) layout(g *gocui.Gui) error {
width, height := g.Size()
informationStr := gui.informationStr()
appStatus := gui.statusManager.getStatusString()
appStatus := gui.helpers.AppStatus.GetStatusString()
viewDimensions := gui.getWindowDimensions(informationStr, appStatus)

View File

@ -1,76 +0,0 @@
package gui
import (
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
func (gui *Gui) menuListContext() *context.MenuContext {
return context.NewMenuContext(gui.contextCommon)
}
func (gui *Gui) filesListContext() *context.WorkingTreeContext {
return context.NewWorkingTreeContext(gui.contextCommon)
}
func (gui *Gui) branchesListContext() *context.BranchesContext {
return context.NewBranchesContext(gui.contextCommon)
}
func (gui *Gui) remotesListContext() *context.RemotesContext {
return context.NewRemotesContext(gui.contextCommon)
}
func (gui *Gui) remoteBranchesListContext() *context.RemoteBranchesContext {
return context.NewRemoteBranchesContext(gui.contextCommon)
}
func (gui *Gui) tagsListContext() *context.TagsContext {
return context.NewTagsContext(gui.contextCommon)
}
func (gui *Gui) branchCommitsListContext() *context.LocalCommitsContext {
return context.NewLocalCommitsContext(gui.contextCommon)
}
func (gui *Gui) subCommitsListContext() *context.SubCommitsContext {
return context.NewSubCommitsContext(gui.contextCommon)
}
func (gui *Gui) reflogCommitsListContext() *context.ReflogCommitsContext {
return context.NewReflogCommitsContext(gui.contextCommon)
}
func (gui *Gui) stashListContext() *context.StashContext {
return context.NewStashContext(gui.contextCommon)
}
func (gui *Gui) commitFilesListContext() *context.CommitFilesContext {
return context.NewCommitFilesContext(gui.contextCommon)
}
func (gui *Gui) submodulesListContext() *context.SubmodulesContext {
return context.NewSubmodulesContext(gui.contextCommon)
}
func (gui *Gui) suggestionsListContext() *context.SuggestionsContext {
return context.NewSuggestionsContext(gui.contextCommon)
}
func (gui *Gui) getListContexts() []types.IListContext {
return []types.IListContext{
gui.State.Contexts.Menu,
gui.State.Contexts.Files,
gui.State.Contexts.Branches,
gui.State.Contexts.Remotes,
gui.State.Contexts.RemoteBranches,
gui.State.Contexts.Tags,
gui.State.Contexts.LocalCommits,
gui.State.Contexts.ReflogCommits,
gui.State.Contexts.SubCommits,
gui.State.Contexts.Stash,
gui.State.Contexts.CommitFiles,
gui.State.Contexts.Submodules,
gui.State.Contexts.Suggestions,
}
}

View File

@ -1,104 +0,0 @@
package gui
import (
"fmt"
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/style"
)
type modeStatus struct {
isActive func() bool
description func() string
reset func() error
}
func (gui *Gui) modeStatuses() []modeStatus {
return []modeStatus{
{
isActive: gui.State.Modes.Diffing.Active,
description: func() string {
return gui.withResetButton(
fmt.Sprintf(
"%s %s",
gui.c.Tr.LcShowingGitDiff,
"git diff "+gui.helpers.Diff.DiffStr(),
),
style.FgMagenta,
)
},
reset: gui.helpers.Diff.ExitDiffMode,
},
{
isActive: gui.git.Patch.PatchBuilder.Active,
description: func() string {
return gui.withResetButton(gui.c.Tr.LcBuildingPatch, style.FgYellow.SetBold())
},
reset: gui.helpers.PatchBuilding.Reset,
},
{
isActive: gui.State.Modes.Filtering.Active,
description: func() string {
return gui.withResetButton(
fmt.Sprintf(
"%s '%s'",
gui.c.Tr.LcFilteringBy,
gui.State.Modes.Filtering.GetPath(),
),
style.FgRed,
)
},
reset: gui.exitFilterMode,
},
{
isActive: gui.State.Modes.CherryPicking.Active,
description: func() string {
copiedCount := len(gui.State.Modes.CherryPicking.CherryPickedCommits)
text := gui.c.Tr.LcCommitsCopied
if copiedCount == 1 {
text = gui.c.Tr.LcCommitCopied
}
return gui.withResetButton(
fmt.Sprintf(
"%d %s",
copiedCount,
text,
),
style.FgCyan,
)
},
reset: gui.helpers.CherryPick.Reset,
},
{
isActive: func() bool {
return gui.git.Status.WorkingTreeState() != enums.REBASE_MODE_NONE
},
description: func() string {
workingTreeState := gui.git.Status.WorkingTreeState()
return gui.withResetButton(
presentation.FormatWorkingTreeState(workingTreeState), style.FgYellow,
)
},
reset: gui.helpers.MergeAndRebase.AbortMergeOrRebaseWithConfirm,
},
{
isActive: func() bool {
return gui.State.Model.BisectInfo.Started()
},
description: func() string {
return gui.withResetButton("bisecting", style.FgGreen)
},
reset: gui.helpers.Bisect.Reset,
},
}
}
func (gui *Gui) withResetButton(content string, textStyle style.TextStyle) string {
return textStyle.Sprintf(
"%s %s",
content,
style.AttrUnderline.Sprint(gui.c.Tr.ResetInParentheses),
)
}

View File

@ -22,7 +22,7 @@ type PopupHandler struct {
popContextFn func() error
currentContextFn func() types.Context
createMenuFn func(types.CreateMenuOptions) error
withWaitingStatusFn func(message string, f func() error) error
withWaitingStatusFn func(message string, f func() error)
toastFn func(message string)
getPromptInputFn func() string
}
@ -36,7 +36,7 @@ func NewPopupHandler(
popContextFn func() error,
currentContextFn func() types.Context,
createMenuFn func(types.CreateMenuOptions) error,
withWaitingStatusFn func(message string, f func() error) error,
withWaitingStatusFn func(message string, f func() error),
toastFn func(message string),
getPromptInputFn func() string,
) *PopupHandler {
@ -63,7 +63,8 @@ func (self *PopupHandler) Toast(message string) {
}
func (self *PopupHandler) WithWaitingStatus(message string, f func() error) error {
return self.withWaitingStatusFn(message, f)
self.withWaitingStatusFn(message, f)
return nil
}
func (self *PopupHandler) Error(err error) error {

View File

@ -24,9 +24,9 @@ func (gui *Gui) handleTopLevelReturn() error {
return gui.c.PushContext(parentContext)
}
for _, mode := range gui.modeStatuses() {
if mode.isActive() {
return mode.reset()
for _, mode := range gui.helpers.Mode.Statuses() {
if mode.IsActive() {
return mode.Reset()
}
}

View File

@ -1,10 +1,7 @@
package custom_commands
import (
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
@ -19,14 +16,11 @@ type Client struct {
func NewClient(
c *helpers.HelperCommon,
os *oscommands.OSCommand,
git *commands.GitCommand,
contexts *context.ContextTree,
helpers *helpers.Helpers,
) *Client {
sessionStateLoader := NewSessionStateLoader(contexts, helpers)
handlerCreator := NewHandlerCreator(c, os, git, sessionStateLoader)
keybindingCreator := NewKeybindingCreator(contexts)
sessionStateLoader := NewSessionStateLoader(c, helpers.Refs)
handlerCreator := NewHandlerCreator(c, sessionStateLoader)
keybindingCreator := NewKeybindingCreator(c)
customCommands := c.UserConfig.CustomCommands
return &Client{

View File

@ -5,8 +5,6 @@ import (
"text/template"
"github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/style"
@ -17,8 +15,6 @@ import (
// takes a custom command and returns a function that will be called when the corresponding user-defined keybinding is pressed
type HandlerCreator struct {
c *helpers.HelperCommon
os *oscommands.OSCommand
git *commands.GitCommand
sessionStateLoader *SessionStateLoader
resolver *Resolver
menuGenerator *MenuGenerator
@ -26,8 +22,6 @@ type HandlerCreator struct {
func NewHandlerCreator(
c *helpers.HelperCommon,
os *oscommands.OSCommand,
git *commands.GitCommand,
sessionStateLoader *SessionStateLoader,
) *HandlerCreator {
resolver := NewResolver(c.Common)
@ -35,8 +29,6 @@ func NewHandlerCreator(
return &HandlerCreator{
c: c,
os: os,
git: git,
sessionStateLoader: sessionStateLoader,
resolver: resolver,
menuGenerator: menuGenerator,
@ -144,7 +136,7 @@ func (self *HandlerCreator) confirmPrompt(prompt *config.CustomCommandPrompt, ha
func (self *HandlerCreator) menuPromptFromCommand(prompt *config.CustomCommandPrompt, wrappedF func(string) error) error {
// Run and save output
message, err := self.git.Custom.RunWithOutput(prompt.Command)
message, err := self.c.Git().Custom.RunWithOutput(prompt.Command)
if err != nil {
return self.c.Error(err)
}
@ -181,7 +173,7 @@ func (self *HandlerCreator) getResolveTemplateFn(form map[string]string, promptR
}
funcs := template.FuncMap{
"quote": self.os.Quote,
"quote": self.c.OS().Quote,
}
return func(templateStr string) (string, error) { return utils.ResolveTemplate(templateStr, objects, funcs) }
@ -194,7 +186,7 @@ func (self *HandlerCreator) finalHandler(customCommand config.CustomCommand, ses
return self.c.Error(err)
}
cmdObj := self.os.Cmd.NewShell(cmdStr)
cmdObj := self.c.OS().Cmd.NewShell(cmdStr)
if customCommand.Subprocess {
return self.c.RunSubprocessAndRefresh(cmdObj)

View File

@ -8,18 +8,19 @@ import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
// KeybindingCreator takes a custom command along with its handler and returns a corresponding keybinding
type KeybindingCreator struct {
contexts *context.ContextTree
c *helpers.HelperCommon
}
func NewKeybindingCreator(contexts *context.ContextTree) *KeybindingCreator {
func NewKeybindingCreator(c *helpers.HelperCommon) *KeybindingCreator {
return &KeybindingCreator{
contexts: contexts,
c: c,
}
}
@ -62,7 +63,7 @@ func (self *KeybindingCreator) getViewNameAndContexts(customCommand config.Custo
}
func (self *KeybindingCreator) contextForContextKey(contextKey types.ContextKey) (types.Context, bool) {
for _, context := range self.contexts.Flatten() {
for _, context := range self.c.Contexts().Flatten() {
if context.GetKey() == contextKey {
return context, true
}

View File

@ -2,21 +2,21 @@ package custom_commands
import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
)
// loads the session state at the time that a custom command is invoked, for use
// in the custom command's template strings
type SessionStateLoader struct {
contexts *context.ContextTree
helpers *helpers.Helpers
c *helpers.HelperCommon
helpers *helpers.Helpers
refsHelper *helpers.RefsHelper
}
func NewSessionStateLoader(contexts *context.ContextTree, helpers *helpers.Helpers) *SessionStateLoader {
func NewSessionStateLoader(c *helpers.HelperCommon, refsHelper *helpers.RefsHelper) *SessionStateLoader {
return &SessionStateLoader{
contexts: contexts,
helpers: helpers,
c: c,
refsHelper: refsHelper,
}
}
@ -39,18 +39,18 @@ type SessionState struct {
func (self *SessionStateLoader) call() *SessionState {
return &SessionState{
SelectedFile: self.contexts.Files.GetSelectedFile(),
SelectedPath: self.contexts.Files.GetSelectedPath(),
SelectedLocalCommit: self.contexts.LocalCommits.GetSelected(),
SelectedReflogCommit: self.contexts.ReflogCommits.GetSelected(),
SelectedLocalBranch: self.contexts.Branches.GetSelected(),
SelectedRemoteBranch: self.contexts.RemoteBranches.GetSelected(),
SelectedRemote: self.contexts.Remotes.GetSelected(),
SelectedTag: self.contexts.Tags.GetSelected(),
SelectedStashEntry: self.contexts.Stash.GetSelected(),
SelectedCommitFile: self.contexts.CommitFiles.GetSelectedFile(),
SelectedCommitFilePath: self.contexts.CommitFiles.GetSelectedPath(),
SelectedSubCommit: self.contexts.SubCommits.GetSelected(),
CheckedOutBranch: self.helpers.Refs.GetCheckedOutRef(),
SelectedFile: self.c.Contexts().Files.GetSelectedFile(),
SelectedPath: self.c.Contexts().Files.GetSelectedPath(),
SelectedLocalCommit: self.c.Contexts().LocalCommits.GetSelected(),
SelectedReflogCommit: self.c.Contexts().ReflogCommits.GetSelected(),
SelectedLocalBranch: self.c.Contexts().Branches.GetSelected(),
SelectedRemoteBranch: self.c.Contexts().RemoteBranches.GetSelected(),
SelectedRemote: self.c.Contexts().Remotes.GetSelected(),
SelectedTag: self.c.Contexts().Tags.GetSelected(),
SelectedStashEntry: self.c.Contexts().Stash.GetSelected(),
SelectedCommitFile: self.c.Contexts().CommitFiles.GetSelectedFile(),
SelectedCommitFilePath: self.c.Contexts().CommitFiles.GetSelectedPath(),
SelectedSubCommit: self.c.Contexts().SubCommits.GetSelected(),
CheckedOutBranch: self.refsHelper.GetCheckedOutRef(),
}
}

View File

@ -0,0 +1,94 @@
package status
import (
"time"
"github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/sasha-s/go-deadlock"
)
// StatusManager's job is to handle queuing of loading states and toast notifications
// that you see at the bottom left of the screen.
type StatusManager struct {
statuses []appStatus
nextId int
mutex deadlock.Mutex
}
type appStatus struct {
message string
statusType string
id int
}
func NewStatusManager() *StatusManager {
return &StatusManager{}
}
func (self *StatusManager) WithWaitingStatus(message string, f func()) {
self.mutex.Lock()
self.nextId += 1
id := self.nextId
newStatus := appStatus{
message: message,
statusType: "waiting",
id: id,
}
self.statuses = append([]appStatus{newStatus}, self.statuses...)
self.mutex.Unlock()
f()
self.removeStatus(id)
}
func (self *StatusManager) AddToastStatus(message string) int {
self.mutex.Lock()
defer self.mutex.Unlock()
self.nextId++
id := self.nextId
newStatus := appStatus{
message: message,
statusType: "toast",
id: id,
}
self.statuses = append([]appStatus{newStatus}, self.statuses...)
go func() {
time.Sleep(time.Second * 2)
self.removeStatus(id)
}()
return id
}
func (self *StatusManager) GetStatusString() string {
if len(self.statuses) == 0 {
return ""
}
topStatus := self.statuses[0]
if topStatus.statusType == "waiting" {
return topStatus.message + " " + utils.Loader()
}
return topStatus.message
}
func (self *StatusManager) HasStatus() bool {
return len(self.statuses) > 0
}
func (self *StatusManager) removeStatus(id int) {
self.mutex.Lock()
defer self.mutex.Unlock()
self.statuses = slices.Filter(self.statuses, func(status appStatus) bool {
return status.id != id
})
}

View File

@ -60,6 +60,9 @@ type IGuiCommon interface {
CurrentStaticContext() Context
CurrentSideContext() Context
IsCurrentContext(Context) bool
// TODO: replace the above context-based methods with just using Context() e.g. replace PushContext() with Context().Push()
Context() IContextMgr
// enters search mode for the current view
OpenSearch()
@ -81,6 +84,7 @@ type IGuiCommon interface {
Git() *commands.GitCommand
OS() *oscommands.OSCommand
Model() *Model
Modes() *Modes
Mutexes() Mutexes
@ -90,6 +94,10 @@ type IGuiCommon interface {
KeybindingsOpts() KeybindingsOpts
}
type IModeMgr interface {
IsAnyModeActive() bool
}
type IPopupHandler interface {
// Shows a popup with a (localized) "Error" caption and the given error message (in red).
//
@ -220,6 +228,8 @@ type IStateAccessor interface {
SetUpdating(bool)
SetIsRefreshingFiles(bool)
GetIsRefreshingFiles() bool
GetShowExtrasWindow() bool
SetShowExtrasWindow(bool)
}
type IRepoStateAccessor interface {
@ -230,6 +240,10 @@ type IRepoStateAccessor interface {
GetCurrentPopupOpts() *CreatePopupPanelOpts
SetCurrentPopupOpts(*CreatePopupPanelOpts)
GetScreenMode() WindowMaximisation
SetScreenMode(WindowMaximisation)
IsSearching() bool
SetSplitMainPanel(bool)
GetSplitMainPanel() bool
}
// startup stages so we don't need to load everything at once

View File

@ -198,3 +198,14 @@ type ListItem interface {
// Description is something we would show in a message e.g. '123as14: push blah' for a commit
Description() string
}
type IContextMgr interface {
Push(context Context, opts ...OnFocusOpts) error
Pop() error
Replace(context Context) error
Current() Context
CurrentStatic() Context
CurrentSide() Context
IsCurrent(c Context) bool
ForEach(func(Context))
}