1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-10-22 06:52:19 +03:00
Files
lazygit/pkg/gui/controllers/quit_actions.go
Stefan Haller a8e44dcea6 Show context-specific labels for the global <esc> binding
WHen several modes are active at the same time, it isn't totally obvious which
one will be cancelled first, so show this in the status bar.
2025-08-14 17:59:38 +02:00

171 lines
3.8 KiB
Go

package controllers
import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
type QuitActions struct {
c *ControllerCommon
}
func (self *QuitActions) Quit() error {
self.c.State().SetRetainOriginalDir(false)
return self.quitAux()
}
func (self *QuitActions) QuitWithoutChangingDirectory() error {
self.c.State().SetRetainOriginalDir(true)
return self.quitAux()
}
func (self *QuitActions) quitAux() error {
if self.c.State().GetUpdating() {
return self.confirmQuitDuringUpdate()
}
return self.c.ConfirmIf(self.c.UserConfig().ConfirmOnQuit,
types.ConfirmOpts{
Title: "",
Prompt: self.c.Tr.ConfirmQuit,
HandleConfirm: func() error {
return gocui.ErrQuit
},
})
}
func (self *QuitActions) confirmQuitDuringUpdate() error {
self.c.Confirm(types.ConfirmOpts{
Title: self.c.Tr.ConfirmQuitDuringUpdateTitle,
Prompt: self.c.Tr.ConfirmQuitDuringUpdate,
HandleConfirm: func() error {
return gocui.ErrQuit
},
})
return nil
}
func (self *QuitActions) Escape() error {
// If you make changes to this function, be sure to update EscapeEnabled and EscapeDescription accordingly.
currentContext := self.c.Context().Current()
if listContext, ok := currentContext.(types.IListContext); ok {
if listContext.GetList().IsSelectingRange() {
listContext.GetList().CancelRangeSelect()
self.c.PostRefreshUpdate(listContext)
return nil
}
}
// Cancelling searching (as opposed to filtering) is handled by gocui
if ctx, ok := currentContext.(types.IFilterableContext); ok {
if ctx.IsFiltering() {
self.c.Helpers().Search.Cancel()
return nil
}
}
parentContext := currentContext.GetParentContext()
if parentContext != nil {
// TODO: think about whether this should be marked as a return rather than adding to the stack
self.c.Context().Push(parentContext, types.OnFocusOpts{})
return nil
}
for _, mode := range self.c.Helpers().Mode.Statuses() {
if mode.IsActive() {
return mode.Reset()
}
}
repoPathStack := self.c.State().GetRepoPathStack()
if !repoPathStack.IsEmpty() {
return self.c.Helpers().Repos.DispatchSwitchToRepo(repoPathStack.Pop(), context.NO_CONTEXT)
}
if self.c.UserConfig().QuitOnTopLevelReturn {
return self.Quit()
}
return nil
}
func (self *QuitActions) EscapeEnabled() bool {
currentContext := self.c.Context().Current()
if listContext, ok := currentContext.(types.IListContext); ok {
if listContext.GetList().IsSelectingRange() {
return true
}
}
if ctx, ok := currentContext.(types.IFilterableContext); ok {
if ctx.IsFiltering() {
return true
}
}
parentContext := currentContext.GetParentContext()
if parentContext != nil {
return true
}
for _, mode := range self.c.Helpers().Mode.Statuses() {
if mode.IsActive() {
return true
}
}
repoPathStack := self.c.State().GetRepoPathStack()
if !repoPathStack.IsEmpty() {
return true
}
if self.c.UserConfig().QuitOnTopLevelReturn {
return true
}
return false
}
func (self *QuitActions) EscapeDescription() string {
currentContext := self.c.Context().Current()
if listContext, ok := currentContext.(types.IListContext); ok {
if listContext.GetList().IsSelectingRange() {
return self.c.Tr.DismissRangeSelect
}
}
if ctx, ok := currentContext.(types.IFilterableContext); ok {
if ctx.IsFiltering() {
return self.c.Tr.ExitFilterMode
}
}
parentContext := currentContext.GetParentContext()
if parentContext != nil {
return self.c.Tr.ExitSubview
}
for _, mode := range self.c.Helpers().Mode.Statuses() {
if mode.IsActive() {
return mode.CancelLabel()
}
}
repoPathStack := self.c.State().GetRepoPathStack()
if !repoPathStack.IsEmpty() {
return self.c.Tr.BackToParentRepo
}
if self.c.UserConfig().QuitOnTopLevelReturn {
return self.c.Tr.Quit
}
return self.c.Tr.Cancel
}