2022-02-24 04:29:48 +02:00
package custom_commands
import (
"fmt"
"strings"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/context"
2023-03-23 09:47:29 +02:00
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
2022-08-06 10:50:52 +02:00
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
2022-02-24 04:29:48 +02:00
"github.com/jesseduffield/lazygit/pkg/gui/types"
2023-07-24 05:06:42 +02:00
"github.com/samber/lo"
2022-02-24 04:29:48 +02:00
)
// KeybindingCreator takes a custom command along with its handler and returns a corresponding keybinding
type KeybindingCreator struct {
2023-03-23 09:47:29 +02:00
c * helpers . HelperCommon
2022-02-24 04:29:48 +02:00
}
2023-03-23 09:47:29 +02:00
func NewKeybindingCreator ( c * helpers . HelperCommon ) * KeybindingCreator {
2022-02-24 04:29:48 +02:00
return & KeybindingCreator {
2023-03-23 09:47:29 +02:00
c : c ,
2022-02-24 04:29:48 +02:00
}
}
func ( self * KeybindingCreator ) call ( customCommand config . CustomCommand , handler func ( ) error ) ( * types . Binding , error ) {
if customCommand . Context == "" {
return nil , formatContextNotProvidedError ( customCommand )
}
2022-06-13 03:01:26 +02:00
viewName , err := self . getViewNameAndContexts ( customCommand )
2022-02-24 04:29:48 +02:00
if err != nil {
return nil , err
}
description := customCommand . Description
if description == "" {
description = customCommand . Command
}
return & types . Binding {
ViewName : viewName ,
2022-08-06 10:50:52 +02:00
Key : keybindings . GetKey ( customCommand . Key ) ,
2022-02-24 04:29:48 +02:00
Modifier : gocui . ModNone ,
Handler : handler ,
Description : description ,
} , nil
}
2022-06-13 03:01:26 +02:00
func ( self * KeybindingCreator ) getViewNameAndContexts ( customCommand config . CustomCommand ) ( string , error ) {
2022-02-24 04:29:48 +02:00
if customCommand . Context == "global" {
2022-06-13 03:01:26 +02:00
return "" , nil
2022-02-24 04:29:48 +02:00
}
ctx , ok := self . contextForContextKey ( types . ContextKey ( customCommand . Context ) )
if ! ok {
2022-06-13 03:01:26 +02:00
return "" , formatUnknownContextError ( customCommand )
2022-02-24 04:29:48 +02:00
}
viewName := ctx . GetViewName ( )
2022-06-13 03:01:26 +02:00
return viewName , nil
2022-02-24 04:29:48 +02:00
}
func ( self * KeybindingCreator ) contextForContextKey ( contextKey types . ContextKey ) ( types . Context , bool ) {
2023-03-23 09:47:29 +02:00
for _ , context := range self . c . Contexts ( ) . Flatten ( ) {
2022-02-24 04:29:48 +02:00
if context . GetKey ( ) == contextKey {
return context , true
}
}
return nil , false
}
func formatUnknownContextError ( customCommand config . CustomCommand ) error {
2023-07-24 05:06:42 +02:00
allContextKeyStrings := lo . Map ( context . AllContextKeys , func ( key types . ContextKey , _ int ) string {
2022-03-19 10:12:58 +02:00
return string ( key )
} )
2022-02-24 04:29:48 +02:00
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 )
}