From 9d304098bb91336f621fefdef53a645b22dbb9d5 Mon Sep 17 00:00:00 2001 From: Michael Mead Date: Fri, 24 Jun 2022 22:37:10 -0700 Subject: [PATCH] feat: add confirm prompt for custom keybindings - Supports configuring a custom confirmation prompt via `config.yml` for custom keybindings. A new `CustomCommandPrompt.Body` field is used to store the immutable body text of the confirmation popup. - Adds a sample 'confirm' prompt to the example `config.yml`. - Updates the `Prompts` section of the documentation to include 'confirm' prompt type and also describe which fields pertain to it (i.e. `initialValue`). Closes: https://github.com/jesseduffield/lazygit/issues/1858 Signed-off-by: Michael Mead --- docs/Custom_Command_Keybindings.md | 24 ++++++++++++------- pkg/config/user_config.go | 5 +++- .../custom_commands/handler_creator.go | 14 ++++++++++- pkg/gui/services/custom_commands/resolver.go | 5 ++++ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/docs/Custom_Command_Keybindings.md b/docs/Custom_Command_Keybindings.md index 0b677fa48..47b9d8f97 100644 --- a/docs/Custom_Command_Keybindings.md +++ b/docs/Custom_Command_Keybindings.md @@ -49,6 +49,13 @@ customCommands: filter: '.*{{index .PromptResponses 0}}/(?P.*)' valueFormat: '{{ .branch }}' labelFormat: '{{ .branch | green }}' + - key: '' + command: 'git reset --soft {{.CheckedOutBranch.UpstreamRemote}}' + context: 'files' + prompts: + - type: 'confirm' + title: "Confirm:" + body: "Are you sure you want to reset HEAD to {{.CheckedOutBranch.UpstreamRemote}}?" ``` Looking at the command assigned to the 'n' key, here's what the result looks like: @@ -94,14 +101,15 @@ The permitted contexts are: The permitted prompt fields are: -| _field_ | _description_ | _required_ | -| ------------ | -------------------------------------------------------------------------------- | ---------- | -| type | one of 'input' or 'menu' | yes | -| title | the title to display in the popup panel | no | -| initialValue | (only applicable to 'input' prompts) the initial value to appear in the text box | no | -| options | (only applicable to 'menu' prompts) the options to display in the menu | no | -| command | (only applicable to 'menuFromCommand' prompts) the command to run to generate | yes | -| | menu options | | +| _field_ | _description_ | _required_ | +| ------------ | -----------------------------------------------------------------------------------------------| ---------- | +| type | one of 'input', 'menu', or 'confirm' | yes | +| title | the title to display in the popup panel | no | +| initialValue | (only applicable to 'input' prompts) the initial value to appear in the text box | no | +| body | (only applicable to 'confirm' prompts) the immutable body text to appear in the text box | no | +| options | (only applicable to 'menu' prompts) the options to display in the menu | no | +| command | (only applicable to 'menuFromCommand' prompts) the command to run to generate | yes | +| | menu options | | | filter | (only applicable to 'menuFromCommand' prompts) the regexp to run specifying groups which are going to be kept from the command's output | yes | | valueFormat | (only applicable to 'menuFromCommand' prompts) how to format matched groups from the filter to construct a menu item's value (What gets appended to prompt responses when the item is selected). You can use named groups, or `{{ .group_GROUPID }}`. PS: named groups keep first match only | yes | | labelFormat | (only applicable to 'menuFromCommand' prompts) how to format matched groups from the filter to construct the item's label (What's shown on screen). You can use named groups, or `{{ .group_GROUPID }}`. You can also color each match with `{{ .group_GROUPID \| colorname }}` (Color names from [here](https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md)). If `labelFormat` is not specified, `valueFormat` is shown instead. PS: named groups keep first match only | no | diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 0b3a91bf6..650594a50 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -313,12 +313,15 @@ type CustomCommand struct { } type CustomCommandPrompt struct { - Type string `yaml:"type"` // one of 'input' and 'menu' + Type string `yaml:"type"` // one of 'input', 'menu', or 'confirm' Title string `yaml:"title"` // this only apply to prompts InitialValue string `yaml:"initialValue"` + // this only applies to confirm prompts + Body string `yaml:"body"` + // this only applies to menus Options []CustomCommandMenuOption diff --git a/pkg/gui/services/custom_commands/handler_creator.go b/pkg/gui/services/custom_commands/handler_creator.go index 446ac95f4..3dd9a0517 100644 --- a/pkg/gui/services/custom_commands/handler_creator.go +++ b/pkg/gui/services/custom_commands/handler_creator.go @@ -80,8 +80,12 @@ func (self *HandlerCreator) call(customCommand config.CustomCommand) func() erro f = func() error { return self.menuPromptFromCommand(resolvedPrompt, wrappedF) } + case "confirm": + f = func() error { + return self.confirmPrompt(resolvedPrompt, g) + } default: - return self.c.ErrorMsg("custom command prompt must have a type of 'input', 'menu' or 'menuFromCommand'") + return self.c.ErrorMsg("custom command prompt must have a type of 'input', 'menu', 'menuFromCommand', or 'confirm'") } } @@ -112,6 +116,14 @@ func (self *HandlerCreator) menuPrompt(prompt *config.CustomCommandPrompt, wrapp return self.c.Menu(types.CreateMenuOptions{Title: prompt.Title, Items: menuItems}) } +func (self *HandlerCreator) confirmPrompt(prompt *config.CustomCommandPrompt, handleConfirm func() error) error { + return self.c.Confirm(types.ConfirmOpts{ + Title: prompt.Title, + Prompt: prompt.Body, + HandleConfirm: handleConfirm, + }) +} + func (self *HandlerCreator) menuPromptFromCommand(prompt *config.CustomCommandPrompt, wrappedF func(string) error) error { // Run and save output message, err := self.git.Custom.RunWithOutput(prompt.Command) diff --git a/pkg/gui/services/custom_commands/resolver.go b/pkg/gui/services/custom_commands/resolver.go index ee965e5cd..35ebbd9d1 100644 --- a/pkg/gui/services/custom_commands/resolver.go +++ b/pkg/gui/services/custom_commands/resolver.go @@ -34,6 +34,11 @@ func (self *Resolver) resolvePrompt( return nil, err } + result.Body, err = resolveTemplate(prompt.Body) + if err != nil { + return nil, err + } + result.Command, err = resolveTemplate(prompt.Command) if err != nil { return nil, err