summaryrefslogtreecommitdiffstats
path: root/pkg/gui/custom_commands.go
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2020-09-26 19:48:13 +1000
committerJesse Duffield <jessedduffield@gmail.com>2020-09-27 09:49:30 +1000
commitb5066f1d8e6b00113b35fb7b0ca43633f4f95921 (patch)
tree24a823b3a99fac1152d624e2558f24c2fce6ba70 /pkg/gui/custom_commands.go
parent266d8bf0d5d3797c8fc97a29ccc0aad9229b6d58 (diff)
support prompts in custom commands
Diffstat (limited to 'pkg/gui/custom_commands.go')
-rw-r--r--pkg/gui/custom_commands.go117
1 files changed, 82 insertions, 35 deletions
diff --git a/pkg/gui/custom_commands.go b/pkg/gui/custom_commands.go
index 7181ec2e2..8af82e123 100644
--- a/pkg/gui/custom_commands.go
+++ b/pkg/gui/custom_commands.go
@@ -21,57 +21,104 @@ type CustomCommandObjects struct {
SelectedStashEntry *commands.StashEntry
SelectedCommitFile *commands.CommitFile
CheckedOutBranch *commands.Branch
+ PromptResponses []string
+}
+
+func (gui *Gui) resolveTemplate(templateStr string, promptResponses []string) (string, error) {
+ objects := CustomCommandObjects{
+ SelectedFile: gui.getSelectedFile(),
+ SelectedLocalCommit: gui.getSelectedLocalCommit(),
+ SelectedReflogCommit: gui.getSelectedReflogCommit(),
+ SelectedLocalBranch: gui.getSelectedBranch(),
+ SelectedRemoteBranch: gui.getSelectedRemoteBranch(),
+ SelectedRemote: gui.getSelectedRemote(),
+ SelectedTag: gui.getSelectedTag(),
+ SelectedStashEntry: gui.getSelectedStashEntry(),
+ SelectedCommitFile: gui.getSelectedCommitFile(),
+ SelectedSubCommit: gui.getSelectedSubCommit(),
+ CheckedOutBranch: gui.currentBranch(),
+ PromptResponses: promptResponses,
+ }
+
+ tmpl, err := template.New("template").Parse(templateStr)
+ if err != nil {
+ return "", err
+ }
+
+ var buf bytes.Buffer
+ if err := tmpl.Execute(&buf, objects); err != nil {
+ return "", err
+ }
+
+ cmdStr := buf.String()
+
+ return cmdStr, nil
}
func (gui *Gui) handleCustomCommandKeybinding(customCommand CustomCommand) func() error {
return func() error {
- objects := CustomCommandObjects{
- SelectedFile: gui.getSelectedFile(),
- SelectedLocalCommit: gui.getSelectedLocalCommit(),
- SelectedReflogCommit: gui.getSelectedReflogCommit(),
- SelectedLocalBranch: gui.getSelectedBranch(),
- SelectedRemoteBranch: gui.getSelectedRemoteBranch(),
- SelectedRemote: gui.getSelectedRemote(),
- SelectedTag: gui.getSelectedTag(),
- SelectedStashEntry: gui.getSelectedStashEntry(),
- SelectedCommitFile: gui.getSelectedCommitFile(),
- SelectedSubCommit: gui.getSelectedSubCommit(),
- CheckedOutBranch: gui.currentBranch(),
- }
+ promptResponses := make([]string, len(customCommand.Prompts))
- tmpl, err := template.New("custom command template").Parse(customCommand.Command)
- if err != nil {
- return gui.surfaceError(err)
- }
+ f := func() error {
+ cmdStr, err := gui.resolveTemplate(customCommand.Command, promptResponses)
+ if err != nil {
+ return gui.surfaceError(err)
+ }
- var buf bytes.Buffer
- if err := tmpl.Execute(&buf, objects); err != nil {
- return gui.surfaceError(err)
- }
+ if customCommand.Subprocess {
+ gui.PrepareSubProcess(cmdStr)
+ return nil
+ }
- cmdStr := buf.String()
+ return gui.WithWaitingStatus(gui.Tr.SLocalize("runningCustomCommandStatus"), func() error {
+ gui.OSCommand.PrepareSubProcess(cmdStr)
- if customCommand.Subprocess {
- gui.PrepareSubProcess(cmdStr)
- return nil
+ if err := gui.OSCommand.RunCommand(cmdStr); err != nil {
+ return gui.surfaceError(err)
+ }
+ return gui.refreshSidePanels(refreshOptions{})
+ })
}
- return gui.WithWaitingStatus(gui.Tr.SLocalize("runningCustomCommandStatus"), func() error {
- gui.OSCommand.PrepareSubProcess(cmdStr)
+ // if we have prompts we'll recursively wrap our confirm handlers with more prompts
+ // until we reach the actual command
+ for reverseIdx := range customCommand.Prompts {
+ idx := len(customCommand.Prompts) - 1 - reverseIdx
- if err := gui.OSCommand.RunCommand(cmdStr); err != nil {
- return gui.surfaceError(err)
+ // going backwards so the outermost prompt is the first one
+ prompt := customCommand.Prompts[idx]
+
+ gui.Log.Warn(prompt.Title)
+
+ wrappedF := f // need to do this because f's value will change with each iteration
+ f = func() error {
+ return gui.prompt(
+ prompt.Title,
+ prompt.InitialValue,
+ func(str string) error {
+ promptResponses[idx] = str
+
+ return wrappedF()
+ },
+ )
}
- return gui.refreshSidePanels(refreshOptions{})
- })
+ }
+
+ return f()
}
}
+type CustomCommandPrompt struct {
+ Title string `yaml:"title"`
+ InitialValue string `yaml:"initialValue"`
+}
+
type CustomCommand struct {
- Key string `yaml:"key"`
- Context string `yaml:"context"`
- Command string `yaml:"command"`
- Subprocess bool `yaml:"subprocess"`
+ Key string `yaml:"key"`
+ Context string `yaml:"context"`
+ Command string `yaml:"command"`
+ Subprocess bool `yaml:"subprocess"`
+ Prompts []CustomCommandPrompt `yaml:"prompts"`
}
func (gui *Gui) GetCustomCommandKeybindings() []*Binding {