diff options
-rw-r--r-- | pkg/gui/controllers/files_controller.go | 124 | ||||
-rw-r--r-- | pkg/gui/controllers/helpers/working_tree_helper.go | 137 | ||||
-rw-r--r-- | pkg/gui/controllers/staging_controller.go | 15 |
3 files changed, 154 insertions, 122 deletions
diff --git a/pkg/gui/controllers/files_controller.go b/pkg/gui/controllers/files_controller.go index 22da8332b..27ae9b3fd 100644 --- a/pkg/gui/controllers/files_controller.go +++ b/pkg/gui/controllers/files_controller.go @@ -1,18 +1,14 @@ package controllers import ( - "fmt" - "regexp" "strings" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/types" - "github.com/jesseduffield/lazygit/pkg/utils" ) type FilesController struct { @@ -54,12 +50,12 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types }, { Key: opts.GetKey(opts.Config.Files.CommitChanges), - Handler: self.HandleCommitPress, + Handler: self.helpers.WorkingTree.HandleCommitPress, Description: self.c.Tr.CommitChanges, }, { Key: opts.GetKey(opts.Config.Files.CommitChangesWithoutHook), - Handler: self.HandleWIPCommitPress, + Handler: self.helpers.WorkingTree.HandleWIPCommitPress, Description: self.c.Tr.LcCommitChangesWithoutHook, }, { @@ -69,7 +65,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types }, { Key: opts.GetKey(opts.Config.Files.CommitChangesWithEditor), - Handler: self.HandleCommitEditorPress, + Handler: self.helpers.WorkingTree.HandleCommitEditorPress, Description: self.c.Tr.CommitChangesWithEditor, }, { @@ -554,112 +550,17 @@ func (self *FilesController) ignoreOrExcludeMenu(node *filetree.FileNode) error }) } -func (self *FilesController) HandleWIPCommitPress() error { - skipHookPrefix := self.c.UserConfig.Git.SkipHookPrefix - if skipHookPrefix == "" { - return self.c.ErrorMsg(self.c.Tr.SkipHookPrefixNotConfigured) - } - - self.setCommitMessage(skipHookPrefix) - - return self.HandleCommitPress() -} - -func (self *FilesController) commitPrefixConfigForRepo() *config.CommitPrefixConfig { - cfg, ok := self.c.UserConfig.Git.CommitPrefixes[utils.GetCurrentRepoName()] - if !ok { - return nil - } - - return &cfg -} - -func (self *FilesController) prepareFilesForCommit() error { - noStagedFiles := !self.helpers.WorkingTree.AnyStagedFiles() - if noStagedFiles && self.c.UserConfig.Gui.SkipNoStagedFilesWarning { - self.c.LogAction(self.c.Tr.Actions.StageAllFiles) - err := self.git.WorkingTree.StageAll() - if err != nil { - return err - } - - return self.syncRefresh() - } - - return nil -} - -// for when you need to refetch files before continuing an action. Runs synchronously. -func (self *FilesController) syncRefresh() error { - return self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.FILES}}) -} - func (self *FilesController) refresh() error { return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}}) } -func (self *FilesController) HandleCommitPress() error { - if err := self.prepareFilesForCommit(); err != nil { - return self.c.Error(err) - } - - if len(self.model.Files) == 0 { - return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) - } - - if !self.helpers.WorkingTree.AnyStagedFiles() { - return self.promptToStageAllAndRetry(self.HandleCommitPress) - } - - savedCommitMessage := self.getSavedCommitMessage() - if len(savedCommitMessage) > 0 { - self.setCommitMessage(savedCommitMessage) - } else { - commitPrefixConfig := self.commitPrefixConfigForRepo() - if commitPrefixConfig != nil { - prefixPattern := commitPrefixConfig.Pattern - prefixReplace := commitPrefixConfig.Replace - rgx, err := regexp.Compile(prefixPattern) - if err != nil { - return self.c.ErrorMsg(fmt.Sprintf("%s: %s", self.c.Tr.LcCommitPrefixPatternError, err.Error())) - } - prefix := rgx.ReplaceAllString(self.helpers.Refs.GetCheckedOutRef().Name, prefixReplace) - self.setCommitMessage(prefix) - } - } - - if err := self.c.PushContext(self.contexts.CommitMessage); err != nil { - return err - } - - return nil -} - -func (self *FilesController) promptToStageAllAndRetry(retry func() error) error { - return self.c.Confirm(types.ConfirmOpts{ - Title: self.c.Tr.NoFilesStagedTitle, - Prompt: self.c.Tr.NoFilesStagedPrompt, - HandleConfirm: func() error { - self.c.LogAction(self.c.Tr.Actions.StageAllFiles) - if err := self.git.WorkingTree.StageAll(); err != nil { - return self.c.Error(err) - } - if err := self.syncRefresh(); err != nil { - return self.c.Error(err) - } - - return retry() - }, - }) -} - func (self *FilesController) handleAmendCommitPress() error { if len(self.model.Files) == 0 { return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) } if !self.helpers.WorkingTree.AnyStagedFiles() { - return self.promptToStageAllAndRetry(self.handleAmendCommitPress) + return self.helpers.WorkingTree.PromptToStageAllAndRetry(self.handleAmendCommitPress) } if len(self.model.Commits) == 0 { @@ -677,23 +578,6 @@ func (self *FilesController) handleAmendCommitPress() error { }) } -// HandleCommitEditorPress - handle when the user wants to commit changes via -// their editor rather than via the popup panel -func (self *FilesController) HandleCommitEditorPress() error { - if len(self.model.Files) == 0 { - return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) - } - - if !self.helpers.WorkingTree.AnyStagedFiles() { - return self.promptToStageAllAndRetry(self.HandleCommitEditorPress) - } - - self.c.LogAction(self.c.Tr.Actions.Commit) - return self.c.RunSubprocessAndRefresh( - self.git.Commit.CommitEditorCmdObj(), - ) -} - func (self *FilesController) handleStatusFilterPressed() error { return self.c.Menu(types.CreateMenuOptions{ Title: self.c.Tr.FilteringMenuTitle, diff --git a/pkg/gui/controllers/helpers/working_tree_helper.go b/pkg/gui/controllers/helpers/working_tree_helper.go index ab52a37c7..a40bcbc6e 100644 --- a/pkg/gui/controllers/helpers/working_tree_helper.go +++ b/pkg/gui/controllers/helpers/working_tree_helper.go @@ -1,9 +1,14 @@ package helpers import ( + "fmt" + "regexp" "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/config" + "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/jesseduffield/lazygit/pkg/gui/context" ) type IWorkingTreeHelper interface { @@ -16,15 +21,30 @@ type IWorkingTreeHelper interface { type WorkingTreeHelper struct { c *types.HelperCommon git *commands.GitCommand - + contexts *context.ContextTree + refHelper *RefsHelper model *types.Model + setCommitMessage func(message string) + getSavedCommitMessage func() string } -func NewWorkingTreeHelper(c *types.HelperCommon, git *commands.GitCommand, model *types.Model) *WorkingTreeHelper { +func NewWorkingTreeHelper( + c *types.HelperCommon, + git *commands.GitCommand, + contexts *context.ContextTree, + refHelper *RefsHelper, + model *types.Model, + setCommitMessage func(message string), + getSavedCommitMessage func() string, +) *WorkingTreeHelper { return &WorkingTreeHelper{ c: c, git: git, + contexts: contexts, + refHelper: refHelper, model: model, + setCommitMessage: setCommitMessage, + getSavedCommitMessage: getSavedCommitMessage, } } @@ -72,3 +92,116 @@ func (self *WorkingTreeHelper) OpenMergeTool() error { }, }) } + +func (self *WorkingTreeHelper) HandleCommitPress() error { + if err := self.prepareFilesForCommit(); err != nil { + return self.c.Error(err) + } + + if len(self.model.Files) == 0 { + return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) + } + + if !self.AnyStagedFiles() { + return self.PromptToStageAllAndRetry(self.HandleCommitPress) + } + + savedCommitMessage := self.getSavedCommitMessage() + if len(savedCommitMessage) > 0 { + self.setCommitMessage(savedCommitMessage) + } else { + commitPrefixConfig := self.commitPrefixConfigForRepo() + if commitPrefixConfig != nil { + prefixPattern := commitPrefixConfig.Pattern + prefixReplace := commitPrefixConfig.Replace + rgx, err := regexp.Compile(prefixPattern) + if err != nil { + return self.c.ErrorMsg(fmt.Sprintf("%s: %s", self.c.Tr.LcCommitPrefixPatternError, err.Error())) + } + prefix := rgx.ReplaceAllString(self.refHelper.GetCheckedOutRef().Name, prefixReplace) + self.setCommitMessage(prefix) + } + } + + if err := self.c.PushContext(self.contexts.CommitMessage); err != nil { + return err + } + + return nil +} + +// HandleCommitEditorPress - handle when the user wants to commit changes via +// their editor rather than via the popup panel +func (self *WorkingTreeHelper) HandleCommitEditorPress() error { + if len(self.model.Files) == 0 { + return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) + } + + if !self.AnyStagedFiles() { + return self.PromptToStageAllAndRetry(self.HandleCommitEditorPress) + } + + self.c.LogAction(self.c.Tr.Actions.Commit) + return self.c.RunSubprocessAndRefresh( + self.git.Commit.CommitEditorCmdObj(), + ) +} + +func (self *WorkingTreeHelper) HandleWIPCommitPress() error { + skipHookPrefix := self.c.UserConfig.Git.SkipHookPrefix + if skipHookPrefix == "" { + return self.c.ErrorMsg(self.c.Tr.SkipHookPrefixNotConfigured) + } + + self.setCommitMessage(skipHookPrefix) + + return self.HandleCommitPress() +} + +func (self *WorkingTreeHelper) PromptToStageAllAndRetry(retry func() error) error { + return self.c.Confirm(types.ConfirmOpts{ + Title: self.c.Tr.NoFilesStagedTitle, + Prompt: self.c.Tr.NoFilesStagedPrompt, + HandleConfirm: func() error { + self.c.LogAction(self.c.Tr.Actions.StageAllFiles) + if err := self.git.WorkingTree.StageAll(); err != nil { + return self.c.Error(err) + } + if err := self.syncRefresh(); err != nil { + return self.c.Error(err) + } + + return retry() + }, + }) +} + +// for when you need to refetch files before continuing an action. Runs synchronously. +func (self *WorkingTreeHelper) syncRefresh() error { + return self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.FILES}}) +} + +func (self *WorkingTreeHelper) prepareFilesForCommit() error { + noStagedFiles := !self.AnyStagedFiles() + if noStagedFiles && self.c.UserConfig.Gui.SkipNoStagedFilesWarning { + self.c.LogAction(self.c.Tr.Actions.StageAllFiles) + err := self.git.WorkingTree.StageAll() + if err != nil { + return err + } + + return self.syncRefresh(); + } + + return nil +} + +func (self *WorkingTreeHelper) commitPrefixConfigForRepo() *config.CommitPrefixConfig { + cfg, ok := self.c.UserConfig.Git.CommitPrefixes[utils.GetCurrentRepoName()] + if !ok { + return nil + } + + return &cfg +} + diff --git a/pkg/gui/controllers/staging_controller.go b/pkg/gui/controllers/staging_controller.go index d41bb1ff5..a141c4740 100644 --- a/pkg/gui/controllers/staging_controller.go +++ b/pkg/gui/controllers/staging_controller.go @@ -73,6 +73,21 @@ func (self *StagingController) GetKeybindings(opts types.KeybindingsOpts) []*typ Handler: self.EditHunkAndRefresh, Description: self.c.Tr.EditHunk, }, + { + Key: opts.GetKey(opts.Config.Files.CommitChanges), + Handler: self.helpers.WorkingTree.HandleCommitPress, + Description: self.c.Tr.CommitChanges, + }, + { + Key: opts.GetKey(opts.Config.Files.CommitChangesWithoutHook), + Handler: self.helpers.WorkingTree.HandleWIPCommitPress, + Description: self.c.Tr.LcCommitChangesWithoutHook, + }, + { + Key: opts.GetKey(opts.Config.Files.CommitChangesWithEditor), + Handler: self.helpers.WorkingTree.HandleCommitEditorPress, + Description: self.c.Tr.CommitChangesWithEditor, + }, } } |