mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-30 03:23:08 +03:00
refactor custom commands
more custom command refactoring
This commit is contained in:
91
pkg/gui/services/custom_commands/keybinding_creator.go
Normal file
91
pkg/gui/services/custom_commands/keybinding_creator.go
Normal file
@ -0,0 +1,91 @@
|
||||
package custom_commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
// KeybindingCreator takes a custom command along with its handler and returns a corresponding keybinding
|
||||
type KeybindingCreator struct {
|
||||
contexts *context.ContextTree
|
||||
getKey func(string) interface{}
|
||||
}
|
||||
|
||||
func NewKeybindingCreator(contexts *context.ContextTree, getKey func(string) interface{}) *KeybindingCreator {
|
||||
return &KeybindingCreator{
|
||||
contexts: contexts,
|
||||
getKey: getKey,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *KeybindingCreator) call(customCommand config.CustomCommand, handler func() error) (*types.Binding, error) {
|
||||
if customCommand.Context == "" {
|
||||
return nil, formatContextNotProvidedError(customCommand)
|
||||
}
|
||||
|
||||
viewName, contexts, err := self.getViewNameAndContexts(customCommand)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
description := customCommand.Description
|
||||
if description == "" {
|
||||
description = customCommand.Command
|
||||
}
|
||||
|
||||
return &types.Binding{
|
||||
ViewName: viewName,
|
||||
Contexts: contexts,
|
||||
Key: self.getKey(customCommand.Key),
|
||||
Modifier: gocui.ModNone,
|
||||
Handler: handler,
|
||||
Description: description,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (self *KeybindingCreator) getViewNameAndContexts(customCommand config.CustomCommand) (string, []string, error) {
|
||||
if customCommand.Context == "global" {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
ctx, ok := self.contextForContextKey(types.ContextKey(customCommand.Context))
|
||||
if !ok {
|
||||
return "", nil, formatUnknownContextError(customCommand)
|
||||
}
|
||||
|
||||
// here we assume that a given context will always belong to the same view.
|
||||
// Currently this is a safe bet but it's by no means guaranteed in the long term
|
||||
// and we might need to make some changes in the future to support it.
|
||||
viewName := ctx.GetViewName()
|
||||
contexts := []string{customCommand.Context}
|
||||
return viewName, contexts, nil
|
||||
}
|
||||
|
||||
func (self *KeybindingCreator) contextForContextKey(contextKey types.ContextKey) (types.Context, bool) {
|
||||
for _, context := range self.contexts.Flatten() {
|
||||
if context.GetKey() == contextKey {
|
||||
return context, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func formatUnknownContextError(customCommand config.CustomCommand) error {
|
||||
// stupid golang making me build an array of strings for this.
|
||||
allContextKeyStrings := make([]string, len(context.AllContextKeys))
|
||||
for i := range context.AllContextKeys {
|
||||
allContextKeyStrings[i] = string(context.AllContextKeys[i])
|
||||
}
|
||||
|
||||
return fmt.Errorf("Error when setting custom command keybindings: unknown context: %s. Key: %s, Command: %s.\nPermitted contexts: %s", customCommand.Context, customCommand.Key, customCommand.Command, strings.Join(allContextKeyStrings, ", "))
|
||||
}
|
||||
|
||||
func formatContextNotProvidedError(customCommand config.CustomCommand) error {
|
||||
return fmt.Errorf("Error parsing custom command keybindings: context not provided (use context: 'global' for the global context). Key: %s, Command: %s", customCommand.Key, customCommand.Command)
|
||||
}
|
Reference in New Issue
Block a user