1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-06-23 00:39:13 +02:00

Better tag creation UX

Previously we used a single-line prompt for a tag annotation. Now we're using the commit message
prompt.

I've had to update other uses of that prompt to allow the summary and description labels to
be passed in
This commit is contained in:
Jesse Duffield
2023-07-22 14:05:42 +10:00
parent b284970bac
commit 7807b40322
27 changed files with 212 additions and 190 deletions

View File

@ -395,7 +395,7 @@ func (self *BranchesController) fastForward(branch *models.Branch) error {
}
func (self *BranchesController) createTag(branch *models.Branch) error {
return self.c.Helpers().Tags.CreateTagMenu(branch.FullRefName(), func() {})
return self.c.Helpers().Tags.OpenCreateTagPrompt(branch.FullRefName(), func() {})
}
func (self *BranchesController) createResetMenu(selectedBranch *models.Branch) error {

View File

@ -63,33 +63,44 @@ func (self *CommitsHelper) JoinCommitMessageAndDescription() string {
}
func (self *CommitsHelper) UpdateCommitPanelView(message string) {
// first try the passed in message, if not fallback to context -> view in that order
if message != "" {
self.SetMessageAndDescriptionInView(message)
return
}
message = self.c.Contexts().CommitMessage.GetPreservedMessage()
if message != "" {
self.SetMessageAndDescriptionInView(message)
} else {
self.SetMessageAndDescriptionInView(self.getCommitSummary())
if self.c.Contexts().CommitMessage.GetPreserveMessage() {
preservedMessage := self.c.Contexts().CommitMessage.GetPreservedMessage()
self.SetMessageAndDescriptionInView(preservedMessage)
return
}
self.SetMessageAndDescriptionInView("")
}
type OpenCommitMessagePanelOpts struct {
CommitIndex int
Title string
PreserveMessage bool
OnConfirm func(string) error
InitialMessage string
CommitIndex int
SummaryTitle string
DescriptionTitle string
PreserveMessage bool
OnConfirm func(summary string, description string) error
InitialMessage string
}
func (self *CommitsHelper) OpenCommitMessagePanel(opts *OpenCommitMessagePanelOpts) error {
onConfirm := func(summary string, description string) error {
if err := self.CloseCommitMessagePanel(); err != nil {
return err
}
return opts.OnConfirm(summary, description)
}
self.c.Contexts().CommitMessage.SetPanelState(
opts.CommitIndex,
opts.Title,
opts.SummaryTitle,
opts.DescriptionTitle,
opts.PreserveMessage,
opts.OnConfirm,
onConfirm,
)
self.UpdateCommitPanelView(opts.InitialMessage)
@ -102,17 +113,16 @@ func (self *CommitsHelper) OnCommitSuccess() {
if self.c.Contexts().CommitMessage.GetPreserveMessage() {
self.c.Contexts().CommitMessage.SetPreservedMessage("")
}
self.SetMessageAndDescriptionInView("")
}
func (self *CommitsHelper) HandleCommitConfirm() error {
fullMessage := self.JoinCommitMessageAndDescription()
summary, description := self.getCommitSummary(), self.getCommitDescription()
if fullMessage == "" {
if summary == "" {
return self.c.ErrorMsg(self.c.Tr.CommitWithoutMessageErr)
}
err := self.c.Contexts().CommitMessage.OnConfirm(fullMessage)
err := self.c.Contexts().CommitMessage.OnConfirm(summary, description)
if err != nil {
return err
}

View File

@ -1,77 +1,54 @@
package helpers
import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
// Helper structs are for defining functionality that could be used by multiple contexts.
// For example, here we have a CreateTagMenu which is applicable to both the tags context
// and the commits context.
type TagsHelper struct {
c *HelperCommon
c *HelperCommon
commitsHelper *CommitsHelper
}
func NewTagsHelper(c *HelperCommon) *TagsHelper {
func NewTagsHelper(c *HelperCommon, commitsHelper *CommitsHelper) *TagsHelper {
return &TagsHelper{
c: c,
c: c,
commitsHelper: commitsHelper,
}
}
func (self *TagsHelper) CreateTagMenu(ref string, onCreate func()) error {
return self.c.Menu(types.CreateMenuOptions{
Title: self.c.Tr.TagMenuTitle,
Items: []*types.MenuItem{
{
Label: self.c.Tr.LightweightTag,
OnPress: func() error {
return self.handleCreateLightweightTag(ref, onCreate)
},
},
{
Label: self.c.Tr.AnnotatedTag,
OnPress: func() error {
return self.handleCreateAnnotatedTag(ref, onCreate)
},
},
},
})
}
func (self *TagsHelper) afterTagCreate(onCreate func()) error {
onCreate()
return self.c.Refresh(types.RefreshOptions{
Mode: types.ASYNC, Scope: []types.RefreshableView{types.COMMITS, types.TAGS},
})
}
func (self *TagsHelper) handleCreateAnnotatedTag(ref string, onCreate func()) error {
return self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.TagNameTitle,
HandleConfirm: func(tagName string) error {
return self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.TagMessageTitle,
HandleConfirm: func(msg string) error {
self.c.LogAction(self.c.Tr.Actions.CreateAnnotatedTag)
if err := self.c.Git().Tag.CreateAnnotated(tagName, ref, msg); err != nil {
return self.c.Error(err)
}
return self.afterTagCreate(onCreate)
},
})
},
})
}
func (self *TagsHelper) handleCreateLightweightTag(ref string, onCreate func()) error {
return self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.TagNameTitle,
HandleConfirm: func(tagName string) error {
self.c.LogAction(self.c.Tr.Actions.CreateLightweightTag)
if err := self.c.Git().Tag.CreateLightweight(tagName, ref); err != nil {
return self.c.Error(err)
func (self *TagsHelper) OpenCreateTagPrompt(ref string, onCreate func()) error {
onConfirm := func(tagName string, description string) error {
return self.c.WithWaitingStatus(self.c.Tr.CreatingTag, func(gocui.Task) error {
if description != "" {
self.c.LogAction(self.c.Tr.Actions.CreateAnnotatedTag)
if err := self.c.Git().Tag.CreateAnnotated(tagName, ref, description); err != nil {
return self.c.Error(err)
}
} else {
self.c.LogAction(self.c.Tr.Actions.CreateLightweightTag)
if err := self.c.Git().Tag.CreateLightweight(tagName, ref); err != nil {
return self.c.Error(err)
}
}
return self.afterTagCreate(onCreate)
self.commitsHelper.OnCommitSuccess()
return self.c.Refresh(types.RefreshOptions{
Mode: types.ASYNC, Scope: []types.RefreshableView{types.COMMITS, types.TAGS},
})
})
}
return self.commitsHelper.OpenCommitMessagePanel(
&OpenCommitMessagePanelOpts{
CommitIndex: context.NoCommitIndex,
InitialMessage: "",
SummaryTitle: self.c.Tr.TagNameTitle,
DescriptionTitle: self.c.Tr.TagMessageTitle,
PreserveMessage: false,
OnConfirm: onConfirm,
},
})
)
}

View File

@ -99,19 +99,19 @@ func (self *WorkingTreeHelper) HandleCommitPressWithMessage(initialMessage strin
return self.commitsHelper.OpenCommitMessagePanel(
&OpenCommitMessagePanelOpts{
CommitIndex: context.NoCommitIndex,
InitialMessage: initialMessage,
Title: self.c.Tr.CommitSummary,
PreserveMessage: true,
OnConfirm: self.handleCommit,
CommitIndex: context.NoCommitIndex,
InitialMessage: initialMessage,
SummaryTitle: self.c.Tr.CommitSummaryTitle,
DescriptionTitle: self.c.Tr.CommitDescriptionTitle,
PreserveMessage: true,
OnConfirm: self.handleCommit,
},
)
}
func (self *WorkingTreeHelper) handleCommit(message string) error {
cmdObj := self.c.Git().Commit.CommitCmdObj(message)
func (self *WorkingTreeHelper) handleCommit(summary string, description string) error {
cmdObj := self.c.Git().Commit.CommitCmdObj(summary, description)
self.c.LogAction(self.c.Tr.Actions.Commit)
_ = self.commitsHelper.PopCommitMessageContexts()
return self.gpgHelper.WithGpgHandling(cmdObj, self.c.Tr.CommittingStatus, func() error {
self.commitsHelper.OnCommitSuccess()
return nil

View File

@ -267,22 +267,22 @@ func (self *LocalCommitsController) reword(commit *models.Commit) error {
return self.c.Helpers().Commits.OpenCommitMessagePanel(
&helpers.OpenCommitMessagePanelOpts{
CommitIndex: self.context().GetSelectedLineIdx(),
InitialMessage: commitMessage,
Title: self.c.Tr.Actions.RewordCommit,
PreserveMessage: false,
OnConfirm: self.handleReword,
CommitIndex: self.context().GetSelectedLineIdx(),
InitialMessage: commitMessage,
SummaryTitle: self.c.Tr.Actions.RewordCommit,
DescriptionTitle: self.c.Tr.CommitDescriptionTitle,
PreserveMessage: false,
OnConfirm: self.handleReword,
},
)
}
func (self *LocalCommitsController) handleReword(message string) error {
err := self.c.Git().Rebase.RewordCommit(self.c.Model().Commits, self.c.Contexts().LocalCommits.GetSelectedLineIdx(), message)
func (self *LocalCommitsController) handleReword(summary string, description string) error {
err := self.c.Git().Rebase.RewordCommit(self.c.Model().Commits, self.c.Contexts().LocalCommits.GetSelectedLineIdx(), summary, description)
if err != nil {
return self.c.Error(err)
}
self.c.Helpers().Commits.OnCommitSuccess()
_ = self.c.Helpers().Commits.PopCommitMessageContexts()
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
}
@ -682,7 +682,7 @@ func (self *LocalCommitsController) squashAllAboveFixupCommits(commit *models.Co
}
func (self *LocalCommitsController) createTag(commit *models.Commit) error {
return self.c.Helpers().Tags.CreateTagMenu(commit.Sha, func() {})
return self.c.Helpers().Tags.OpenCreateTagPrompt(commit.Sha, func() {})
}
func (self *LocalCommitsController) openSearch() error {

View File

@ -141,7 +141,7 @@ func (self *TagsController) createResetMenu(tag *models.Tag) error {
func (self *TagsController) create() error {
// leaving commit SHA blank so that we're just creating the tag for the current commit
return self.c.Helpers().Tags.CreateTagMenu("", func() { self.context().SetSelectedLineIdx(0) })
return self.c.Helpers().Tags.OpenCreateTagPrompt("", func() { self.context().SetSelectedLineIdx(0) })
}
func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func() error {