diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 3771ec003..8a7abb55b 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -705,11 +705,6 @@ func (c *GitCommand) Checkout(branch string, options CheckoutOptions) error { return c.OSCommand.RunCommandWithOptions(fmt.Sprintf("git checkout %s %s", forceArg, branch), RunCommandOptions{EnvVars: options.EnvVars}) } -// PrepareCommitSubProcess prepares a subprocess for `git commit` -func (c *GitCommand) PrepareCommitSubProcess() *exec.Cmd { - return c.OSCommand.PrepareSubProcess("git", "commit") -} - // PrepareCommitAmendSubProcess prepares a subprocess for `git commit --amend --allow-empty` func (c *GitCommand) PrepareCommitAmendSubProcess() *exec.Cmd { return c.OSCommand.PrepareSubProcess("git", "commit", "--amend", "--allow-empty") diff --git a/pkg/gui/custom_commands.go b/pkg/gui/custom_commands.go index 8dcff163d..190fc5586 100644 --- a/pkg/gui/custom_commands.go +++ b/pkg/gui/custom_commands.go @@ -2,8 +2,10 @@ package gui import ( "bytes" + "log" "text/template" + "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" ) @@ -21,7 +23,7 @@ type CustomCommandObjects struct { CurrentBranch *commands.Branch } -func (gui *Gui) handleCustomCommandKeybinding(templateStr string) func() error { +func (gui *Gui) handleCustomCommandKeybinding(customCommand CustomCommand) func() error { return func() error { objects := CustomCommandObjects{ SelectedFile: gui.getSelectedFile(), @@ -37,7 +39,7 @@ func (gui *Gui) handleCustomCommandKeybinding(templateStr string) func() error { CurrentBranch: gui.currentBranch(), } - tmpl, err := template.New("custom command template").Parse(templateStr) + tmpl, err := template.New("custom command template").Parse(customCommand.Command) if err != nil { return gui.surfaceError(err) } @@ -49,7 +51,14 @@ func (gui *Gui) handleCustomCommandKeybinding(templateStr string) func() error { cmdStr := buf.String() + if customCommand.Subprocess { + gui.PrepareSubProcess(cmdStr) + return nil + } + return gui.WithWaitingStatus(gui.Tr.SLocalize("runningCustomCommandStatus"), func() error { + gui.OSCommand.PrepareSubProcess(cmdStr) + if err := gui.OSCommand.RunCommand(cmdStr); err != nil { return gui.surfaceError(err) } @@ -57,3 +66,47 @@ func (gui *Gui) handleCustomCommandKeybinding(templateStr string) func() error { }) } } + +type CustomCommand struct { + Key string `yaml:"key"` + Context string `yaml:"context"` + Command string `yaml:"command"` + Subprocess bool `yaml:"subprocess"` +} + +func (gui *Gui) GetCustomCommandKeybindings() []*Binding { + bindings := []*Binding{} + + var customCommands []CustomCommand + + if err := gui.Config.GetUserConfig().UnmarshalKey("customCommands", &customCommands); err != nil { + log.Fatalf("Error parsing custom command keybindings: %v", err) + } + + for _, customCommand := range customCommands { + var viewName string + if customCommand.Context == "global" || customCommand.Context == "" { + viewName = "" + } else { + context := gui.contextForContextKey(customCommand.Context) + if context == nil { + log.Fatalf("Error when setting custom command keybindings: unknown context: %s", customCommand.Context) + } + // 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 = context.GetViewName() + } + + bindings = append(bindings, &Binding{ + ViewName: viewName, + Contexts: []string{customCommand.Context}, + Key: gui.getKey(customCommand.Key), + Modifier: gocui.ModNone, + Handler: gui.wrappedHandler(gui.handleCustomCommandKeybinding(customCommand)), + Description: customCommand.Command, + }) + } + + return bindings +} diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index c2ec97e3b..aa01b4b36 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -14,6 +14,7 @@ import ( "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/mgutz/str" ) // list panel functions @@ -356,13 +357,14 @@ func (gui *Gui) handleCommitEditorPress() error { }) } - gui.PrepareSubProcess("git", "commit") + gui.PrepareSubProcess("git commit") return nil } // PrepareSubProcess - prepare a subprocess for execution and tell the gui to switch to it -func (gui *Gui) PrepareSubProcess(commands ...string) { - gui.SubProcess = gui.GitCommand.PrepareCommitSubProcess() +func (gui *Gui) PrepareSubProcess(command string) { + splitCmd := str.ToArgv(command) + gui.SubProcess = gui.OSCommand.PrepareSubProcess(splitCmd[0], splitCmd[1:]...) gui.g.Update(func(g *gocui.Gui) error { return gui.Errors.ErrSubProcess }) diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 8b6e80d20..d7b62051d 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -1563,41 +1563,6 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { return bindings } -func (gui *Gui) GetCustomCommandKeybindings() []*Binding { - bindings := []*Binding{} - - ms := gui.Config.GetUserConfig().GetStringMap("customCommands") - for contextKey := range ms { - var viewName string - if contextKey == "global" { - viewName = "" - } else { - context := gui.contextForContextKey(contextKey) - if context == nil { - log.Fatalf("Error when setting custom command keybindings: unknown context: %s", contextKey) - } - // 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 = context.GetViewName() - } - - keyMap := gui.Config.GetUserConfig().GetStringMapString(fmt.Sprintf("customCommands.%s", contextKey)) - for key, command := range keyMap { - bindings = append(bindings, &Binding{ - ViewName: viewName, - Contexts: []string{contextKey}, - Key: gui.getKey(key), - Modifier: gocui.ModNone, - Handler: gui.wrappedHandler(gui.handleCustomCommandKeybinding(command)), - Description: command, - }) - } - } - - return bindings -} - func (gui *Gui) keybindings() error { bindings := gui.GetCustomCommandKeybindings()