This commit is contained in:
Jesse Duffield 2024-11-09 16:38:14 +11:00
parent b62546c391
commit 0a71b5f837
8 changed files with 101 additions and 16 deletions

View file

@ -70,6 +70,8 @@ func (self *ContextMgr) Push(c types.Context, opts ...types.OnFocusOpts) {
return
}
gui.resetHelpersAndControllers()
contextsToDeactivate, contextToActivate := self.pushToContextStack(c)
for _, contextToDeactivate := range contextsToDeactivate {

View file

@ -14,6 +14,7 @@ type ConfirmationContext struct {
type ConfirmationContextState struct {
OnConfirm func() error
OnClose func() error
Multiline bool
}
var _ types.Context = (*ConfirmationContext)(nil)

View file

@ -24,20 +24,54 @@ func NewConfirmationController(
}
func (self *ConfirmationController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
bindings := []*types.Binding{
{
Key: opts.GetKey(opts.Config.Universal.Confirm),
Handler: func() error { return self.context().State.OnConfirm() },
Description: self.c.Tr.Confirm,
DisplayOnScreen: true,
},
{
bindings := []*types.Binding{}
if self.context().State.Multiline {
bindings = append(bindings,
&types.Binding{
// Hard coding because this is always the button that adds a newline.
Key: opts.GetKey("<enter>"),
Handler: func() error {
self.c.Log.Warn("In <enter> handler")
self.c.Views().Confirmation.TextArea.TypeString("\n")
self.c.Views().Confirmation.RenderTextArea()
return nil
},
Description: self.c.Tr.Confirm,
DisplayOnScreen: false,
},
&types.Binding{
Key: opts.GetKey(opts.Config.Universal.ConfirmInEditor),
Handler: func() error {
self.c.Log.Warn("In <alt-enter> handler")
return self.context().State.OnConfirm()
},
Description: self.c.Tr.Confirm,
DisplayOnScreen: true,
},
)
} else {
bindings = append(bindings,
&types.Binding{
Key: opts.GetKey(opts.Config.Universal.Confirm),
Handler: func() error {
self.c.Log.Warn("In single-line confirm handler")
return self.context().State.OnConfirm()
},
Description: self.c.Tr.Confirm,
DisplayOnScreen: true,
},
)
}
bindings = append(bindings,
&types.Binding{
Key: opts.GetKey(opts.Config.Universal.Return),
Handler: func() error { return self.context().State.OnClose() },
Description: self.c.Tr.CloseCancel,
DisplayOnScreen: true,
},
{
&types.Binding{
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
Handler: func() error {
if len(self.c.Contexts().Suggestions.State.Suggestions) > 0 {
@ -54,7 +88,7 @@ func (self *ConfirmationController) GetKeybindings(opts types.KeybindingsOpts) [
return nil
},
},
}
)
return bindings
}

View file

@ -8,6 +8,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/theme"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/mattn/go-runewidth"
)
@ -156,12 +157,14 @@ func (self *ConfirmationHelper) getPopupPanelWidth() int {
func (self *ConfirmationHelper) prepareConfirmationPanel(
opts types.ConfirmOpts,
) {
self.c.Views().Confirmation.Title = opts.Title
self.c.Contexts().Confirmation.State.Multiline = opts.Multiline
confirmationView := self.c.Views().Confirmation
confirmationView.Title = opts.Title
// for now we do not support wrapping in our editor
self.c.Views().Confirmation.Wrap = !opts.Editable
self.c.Views().Confirmation.FgColor = theme.GocuiDefaultTextColor
self.c.Views().Confirmation.Mask = runeForMask(opts.Mask)
self.c.Views().Confirmation.SetOrigin(0, 0)
confirmationView.Wrap = !opts.Editable
confirmationView.FgColor = theme.GocuiDefaultTextColor
confirmationView.Mask = runeForMask(opts.Mask)
confirmationView.SetOrigin(0, 0)
suggestionsContext := self.c.Contexts().Suggestions
suggestionsContext.State.FindSuggestions = opts.FindSuggestionsFunc
@ -206,6 +209,7 @@ func (self *ConfirmationHelper) CreatePopupPanel(ctx goContext.Context, opts typ
self.prepareConfirmationPanel(
types.ConfirmOpts{
Title: opts.Title,
Multiline: opts.Multiline,
Prompt: opts.Prompt,
FindSuggestionsFunc: opts.FindSuggestionsFunc,
Editable: opts.Editable,
@ -213,6 +217,14 @@ func (self *ConfirmationHelper) CreatePopupPanel(ctx goContext.Context, opts typ
})
confirmationView := self.c.Views().Confirmation
confirmationView.Editable = opts.Editable
if opts.Multiline {
confirmationView.Subtitle = utils.ResolvePlaceholderString(
self.c.Tr.PressToSubmit,
map[string]string{"Key": self.c.UserConfig().Keybinding.Universal.ConfirmInEditor},
)
} else {
confirmationView.Subtitle = ""
}
if opts.Editable {
textArea := confirmationView.TextArea
@ -363,7 +375,16 @@ func (self *ConfirmationHelper) resizeConfirmationPanel(parentPopupContext types
prompt = self.c.Views().Confirmation.TextArea.GetContent()
wrap = false
}
panelHeight := getMessageHeight(wrap, prompt, panelWidth) + suggestionsViewHeight
multiline := self.c.Contexts().Confirmation.State.Multiline
inputHeight := getMessageHeight(wrap, prompt, panelWidth)
minMultilineHeight := 5
if multiline && inputHeight < minMultilineHeight {
inputHeight = minMultilineHeight
}
panelHeight := inputHeight + suggestionsViewHeight
x0, y0, x1, y1 := self.getPopupPanelDimensionsAux(panelWidth, panelHeight, parentPopupContext)
confirmationViewBottom := y1 - suggestionsViewHeight
_, _ = self.c.GocuiGui().SetView(self.c.Views().Confirmation.Name(), x0, y0, x1, confirmationViewBottom, 0)

View file

@ -107,6 +107,7 @@ func (self *PopupHandler) Confirm(opts types.ConfirmOpts) {
func (self *PopupHandler) Prompt(opts types.PromptOpts) {
self.createPopupPanelFn(context.Background(), types.CreatePopupPanelOpts{
Title: opts.Title,
Multiline: opts.Multiline,
Prompt: opts.InitialContent,
Editable: true,
HandleConfirmPrompt: opts.HandleConfirm,

View file

@ -79,6 +79,14 @@ func (self *HandlerCreator) call(customCommand config.CustomCommand) func() erro
}
return self.inputPrompt(resolvedPrompt, wrappedF)
}
case "textbox":
f = func() error {
resolvedPrompt, err := self.resolver.resolvePrompt(&prompt, resolveTemplate)
if err != nil {
return err
}
return self.textboxPrompt(resolvedPrompt, wrappedF)
}
case "menu":
f = func() error {
resolvedPrompt, err := self.resolver.resolvePrompt(&prompt, resolveTemplate)
@ -130,6 +138,19 @@ func (self *HandlerCreator) inputPrompt(prompt *config.CustomCommandPrompt, wrap
return nil
}
func (self *HandlerCreator) textboxPrompt(prompt *config.CustomCommandPrompt, wrappedF func(string) error) error {
self.c.Prompt(types.PromptOpts{
Title: prompt.Title,
InitialContent: prompt.InitialValue,
Multiline: true,
HandleConfirm: func(str string) error {
return wrappedF(str)
},
})
return nil
}
func (self *HandlerCreator) generateFindSuggestionsFunc(prompt *config.CustomCommandPrompt) (func(string) []*types.Suggestion, error) {
if prompt.Suggestions.Preset != "" && prompt.Suggestions.Command != "" {
return nil, fmt.Errorf(

View file

@ -153,6 +153,7 @@ type CreatePopupPanelOpts struct {
HasLoader bool
Editable bool
Title string
Multiline bool
Prompt string
HandleConfirm func() error
HandleConfirmPrompt func(string) error
@ -166,6 +167,7 @@ type CreatePopupPanelOpts struct {
type ConfirmOpts struct {
Title string
Multiline bool
Prompt string
HandleConfirm func() error
HandleClose func() error
@ -176,6 +178,7 @@ type ConfirmOpts struct {
type PromptOpts struct {
Title string
Multiline bool
InitialContent string
FindSuggestionsFunc func(string) []*Suggestion
HandleConfirm func(string) error

View file

@ -555,6 +555,7 @@ type TranslationSet struct {
MustStashWarning string
MustStashTitle string
ConfirmationTitle string
PressToSubmit string
PrevPage string
NextPage string
GotoTop string
@ -1545,6 +1546,7 @@ func EnglishTranslationSet() *TranslationSet {
MustStashWarning: "Pulling a patch out into the index requires stashing and unstashing your changes. If something goes wrong, you'll be able to access your files from the stash. Continue?",
MustStashTitle: "Must stash",
ConfirmationTitle: "Confirmation panel",
PressToSubmit: "Press {{.Key}} to submit",
PrevPage: "Previous page",
NextPage: "Next page",
GotoTop: "Scroll to top",