mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-31 14:24:25 +03:00
Add Key field to CustomCommandPrompt struct
Add Form field to CustomCommandObjects struct Write user prompts responses to Form field Ensure that map keys exists Add form prompts integration test Remove redundant index
This commit is contained in:
committed by
Jesse Duffield
parent
c81333fefe
commit
7e9dffe1b9
@ -314,6 +314,8 @@ type CustomCommand struct {
|
||||
}
|
||||
|
||||
type CustomCommandPrompt struct {
|
||||
Key string `yaml:"key"`
|
||||
|
||||
// one of 'input', 'menu', 'confirm', or 'menuFromCommand'
|
||||
Type string `yaml:"type"`
|
||||
|
||||
|
@ -45,8 +45,9 @@ func (self *HandlerCreator) call(customCommand config.CustomCommand) func() erro
|
||||
return func() error {
|
||||
sessionState := self.sessionStateLoader.call()
|
||||
promptResponses := make([]string, len(customCommand.Prompts))
|
||||
form := make(map[string]string)
|
||||
|
||||
f := func() error { return self.finalHandler(customCommand, sessionState, promptResponses) }
|
||||
f := func() error { return self.finalHandler(customCommand, sessionState, promptResponses, form) }
|
||||
|
||||
// if we have prompts we'll recursively wrap our confirm handlers with more prompts
|
||||
// until we reach the actual command
|
||||
@ -60,10 +61,11 @@ func (self *HandlerCreator) call(customCommand config.CustomCommand) func() erro
|
||||
|
||||
wrappedF := func(response string) error {
|
||||
promptResponses[idx] = response
|
||||
form[prompt.Key] = response
|
||||
return g()
|
||||
}
|
||||
|
||||
resolveTemplate := self.getResolveTemplateFn(promptResponses, sessionState)
|
||||
resolveTemplate := self.getResolveTemplateFn(form, promptResponses, sessionState)
|
||||
resolvedPrompt, err := self.resolver.resolvePrompt(&prompt, resolveTemplate)
|
||||
if err != nil {
|
||||
return self.c.Error(err)
|
||||
@ -154,19 +156,21 @@ func (self *HandlerCreator) menuPromptFromCommand(prompt *config.CustomCommandPr
|
||||
type CustomCommandObjects struct {
|
||||
*SessionState
|
||||
PromptResponses []string
|
||||
Form map[string]string
|
||||
}
|
||||
|
||||
func (self *HandlerCreator) getResolveTemplateFn(promptResponses []string, sessionState *SessionState) func(string) (string, error) {
|
||||
func (self *HandlerCreator) getResolveTemplateFn(form map[string]string, promptResponses []string, sessionState *SessionState) func(string) (string, error) {
|
||||
objects := CustomCommandObjects{
|
||||
SessionState: sessionState,
|
||||
PromptResponses: promptResponses,
|
||||
Form: form,
|
||||
}
|
||||
|
||||
return func(templateStr string) (string, error) { return utils.ResolveTemplate(templateStr, objects) }
|
||||
}
|
||||
|
||||
func (self *HandlerCreator) finalHandler(customCommand config.CustomCommand, sessionState *SessionState, promptResponses []string) error {
|
||||
resolveTemplate := self.getResolveTemplateFn(promptResponses, sessionState)
|
||||
func (self *HandlerCreator) finalHandler(customCommand config.CustomCommand, sessionState *SessionState, promptResponses []string, form map[string]string) error {
|
||||
resolveTemplate := self.getResolveTemplateFn(form, promptResponses, sessionState)
|
||||
cmdStr, err := resolveTemplate(customCommand.Command)
|
||||
if err != nil {
|
||||
return self.c.Error(err)
|
||||
|
88
pkg/integration/tests/custom_commands/form_prompts.go
Normal file
88
pkg/integration/tests/custom_commands/form_prompts.go
Normal file
@ -0,0 +1,88 @@
|
||||
package custom_commands
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||
)
|
||||
|
||||
var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Description: "Using a custom command reffering prompt responses by name",
|
||||
ExtraCmdArgs: "",
|
||||
Skip: false,
|
||||
SetupRepo: func(shell *Shell) {
|
||||
shell.EmptyCommit("blah")
|
||||
},
|
||||
SetupConfig: func(cfg *config.AppConfig) {
|
||||
cfg.UserConfig.CustomCommands = []config.CustomCommand{
|
||||
{
|
||||
Key: "a",
|
||||
Context: "files",
|
||||
Command: `echo "{{.Form.FileContent}}" > {{.Form.FileName}}`,
|
||||
Prompts: []config.CustomCommandPrompt{
|
||||
{
|
||||
Key: "FileName",
|
||||
Type: "input",
|
||||
Title: "Enter a file name",
|
||||
},
|
||||
{
|
||||
Key: "FileContent",
|
||||
Type: "menu",
|
||||
Title: "Choose file content",
|
||||
Options: []config.CustomCommandMenuOption{
|
||||
{
|
||||
Name: "foo",
|
||||
Description: "Foo",
|
||||
Value: "FOO",
|
||||
},
|
||||
{
|
||||
Name: "bar",
|
||||
Description: "Bar",
|
||||
Value: "BAR",
|
||||
},
|
||||
{
|
||||
Name: "baz",
|
||||
Description: "Baz",
|
||||
Value: "BAZ",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: "confirm",
|
||||
Title: "Are you sure?",
|
||||
Body: "Are you REALLY sure you want to make this file? Up to you buddy.",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
Run: func(
|
||||
shell *Shell,
|
||||
input *Input,
|
||||
assert *Assert,
|
||||
keys config.KeybindingConfig,
|
||||
) {
|
||||
assert.WorkingTreeFileCount(0)
|
||||
|
||||
input.PressKeys("a")
|
||||
|
||||
assert.InPrompt()
|
||||
assert.MatchCurrentViewTitle(Equals("Enter a file name"))
|
||||
input.Type("myfile")
|
||||
input.Confirm()
|
||||
|
||||
assert.InMenu()
|
||||
assert.MatchCurrentViewTitle(Equals("Choose file content"))
|
||||
assert.MatchSelectedLine(Contains("foo"))
|
||||
input.NextItem()
|
||||
assert.MatchSelectedLine(Contains("bar"))
|
||||
input.Confirm()
|
||||
|
||||
assert.InConfirm()
|
||||
assert.MatchCurrentViewTitle(Equals("Are you sure?"))
|
||||
input.Confirm()
|
||||
|
||||
assert.WorkingTreeFileCount(1)
|
||||
assert.MatchSelectedLine(Contains("myfile"))
|
||||
assert.MatchMainViewContent(Contains("BAR"))
|
||||
},
|
||||
})
|
@ -36,6 +36,7 @@ var tests = []*components.IntegrationTest{
|
||||
bisect.FromOtherBranch,
|
||||
cherry_pick.CherryPick,
|
||||
cherry_pick.CherryPickConflicts,
|
||||
custom_commands.FormPrompts,
|
||||
}
|
||||
|
||||
func GetTests() []*components.IntegrationTest {
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func ResolveTemplate(templateStr string, object interface{}) (string, error) {
|
||||
tmpl, err := template.New("template").Parse(templateStr)
|
||||
tmpl, err := template.New("template").Option("missingkey=error").Parse(templateStr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
blah
|
@ -0,0 +1 @@
|
||||
ref: refs/heads/master
|
@ -0,0 +1,8 @@
|
||||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
[user]
|
||||
email = CI@example.com
|
||||
name = CI
|
@ -0,0 +1 @@
|
||||
Unnamed repository; edit this file 'description' to name the repository.
|
Binary file not shown.
@ -0,0 +1,6 @@
|
||||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
@ -0,0 +1 @@
|
||||
0000000000000000000000000000000000000000 6cd61dc75eb17cf3e01d4d5f8f2b38a73ed9be90 CI <CI@example.com> 1660591942 +0000 commit (initial): blah
|
@ -0,0 +1 @@
|
||||
0000000000000000000000000000000000000000 6cd61dc75eb17cf3e01d4d5f8f2b38a73ed9be90 CI <CI@example.com> 1660591942 +0000 commit (initial): blah
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
||||
6cd61dc75eb17cf3e01d4d5f8f2b38a73ed9be90
|
@ -0,0 +1 @@
|
||||
BAR
|
Reference in New Issue
Block a user