Support multiple contexts within one command, add tests, update doc

This commit is contained in:
Yam Liu 2024-07-27 16:40:41 +00:00 committed by Stefan Haller
parent 206b2c6f0b
commit 542030f190
5 changed files with 93 additions and 18 deletions

View file

@ -87,6 +87,11 @@ The permitted contexts are:
| stash | The 'Stash' tab | | stash | The 'Stash' tab |
| global | This keybinding will take affect everywhere | | global | This keybinding will take affect everywhere |
> **Bonus**
>
> You can use a comma-separated string, such as `context: 'commits, subCommits'`, to make it effective in multiple contexts.
## Prompts ## Prompts
### Common fields ### Common fields

View file

@ -39,11 +39,11 @@ func (self *Client) GetCustomCommandKeybindings() ([]*types.Binding, error) {
bindings := []*types.Binding{} bindings := []*types.Binding{}
for _, customCommand := range self.customCommands { for _, customCommand := range self.customCommands {
handler := self.handlerCreator.call(customCommand) handler := self.handlerCreator.call(customCommand)
binding, err := self.keybindingCreator.call(customCommand, handler) compoundBindings, err := self.keybindingCreator.call(customCommand, handler)
if err != nil { if err != nil {
return nil, err return nil, err
} }
bindings = append(bindings, binding) bindings = append(bindings, compoundBindings...)
} }
return bindings, nil return bindings, nil

View file

@ -24,12 +24,12 @@ func NewKeybindingCreator(c *helpers.HelperCommon) *KeybindingCreator {
} }
} }
func (self *KeybindingCreator) call(customCommand config.CustomCommand, handler func() error) (*types.Binding, error) { func (self *KeybindingCreator) call(customCommand config.CustomCommand, handler func() error) ([]*types.Binding, error) {
if customCommand.Context == "" { if customCommand.Context == "" {
return nil, formatContextNotProvidedError(customCommand) return nil, formatContextNotProvidedError(customCommand)
} }
viewName, err := self.getViewNameAndContexts(customCommand) viewNames, err := self.getViewNamesAndContexts(customCommand)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -39,27 +39,38 @@ func (self *KeybindingCreator) call(customCommand config.CustomCommand, handler
description = customCommand.Command description = customCommand.Command
} }
return &types.Binding{ return lo.Map(viewNames, func(viewName string, _ int) *types.Binding {
ViewName: viewName, return &types.Binding{
Key: keybindings.GetKey(customCommand.Key), ViewName: viewName,
Modifier: gocui.ModNone, Key: keybindings.GetKey(customCommand.Key),
Handler: handler, Modifier: gocui.ModNone,
Description: description, Handler: handler,
}, nil Description: description,
}
}), nil
} }
func (self *KeybindingCreator) getViewNameAndContexts(customCommand config.CustomCommand) (string, error) { func (self *KeybindingCreator) getViewNamesAndContexts(customCommand config.CustomCommand) ([]string, error) {
if customCommand.Context == "global" { if customCommand.Context == "global" {
return "", nil return []string{""}, nil
} }
ctx, ok := self.contextForContextKey(types.ContextKey(customCommand.Context)) contexts := strings.Split(customCommand.Context, ",")
if !ok { contexts = lo.Map(contexts, func(context string, _ int) string {
return "", formatUnknownContextError(customCommand) return strings.TrimSpace(context)
})
viewNames := []string{}
for _, context := range contexts {
ctx, ok := self.contextForContextKey(types.ContextKey(context))
if !ok {
return []string{}, formatUnknownContextError(customCommand)
}
viewNames = append(viewNames, ctx.GetViewName())
} }
viewName := ctx.GetViewName() return viewNames, nil
return viewName, nil
} }
func (self *KeybindingCreator) contextForContextKey(contextKey types.ContextKey) (types.Context, bool) { func (self *KeybindingCreator) contextForContextKey(contextKey types.ContextKey) (types.Context, bool) {

View file

@ -0,0 +1,58 @@
package custom_commands
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MultipleContexts = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Test that multiple contexts works",
ExtraCmdArgs: []string{},
Skip: false,
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("my change")
},
SetupConfig: func(cfg *config.AppConfig) {
cfg.UserConfig.CustomCommands = []config.CustomCommand{
{
Key: "X",
Context: "commits, reflogCommits",
Command: "touch myfile",
ShowOutput: false,
},
}
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
// commits
t.Views().Commits().
Focus().
Press("X")
t.Views().Files().
Focus().
Lines(Contains("myfile"))
t.Shell().DeleteFile("myfile")
t.GlobalPress(keys.Files.RefreshFiles)
// branches
t.Views().Branches().
Focus().
Press("X")
t.Views().Files().
Focus().
IsEmpty()
// files
t.Views().ReflogCommits().
Focus().
Press("X")
t.Views().Files().
Focus().
Lines(Contains("myfile"))
t.Shell().DeleteFile("myfile")
},
})

View file

@ -126,6 +126,7 @@ var tests = []*components.IntegrationTest{
custom_commands.History, custom_commands.History,
custom_commands.MenuFromCommand, custom_commands.MenuFromCommand,
custom_commands.MenuFromCommandsOutput, custom_commands.MenuFromCommandsOutput,
custom_commands.MultipleContexts,
custom_commands.MultiplePrompts, custom_commands.MultiplePrompts,
custom_commands.OmitFromHistory, custom_commands.OmitFromHistory,
custom_commands.ShowOutputInPanel, custom_commands.ShowOutputInPanel,