mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-25 12:24:47 +02:00
189 lines
5.8 KiB
Go
189 lines
5.8 KiB
Go
package context
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/jesseduffield/gocui"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
"github.com/spf13/afero"
|
|
)
|
|
|
|
const PreservedCommitMessageFileName = "LAZYGIT_PENDING_COMMIT"
|
|
|
|
type CommitMessageContext struct {
|
|
c *ContextCommon
|
|
types.Context
|
|
viewModel *CommitMessageViewModel
|
|
}
|
|
|
|
var _ types.Context = (*CommitMessageContext)(nil)
|
|
|
|
// when selectedIndex (see below) is set to this value, it means that we're not
|
|
// currently viewing a commit message of an existing commit: instead we're making our own
|
|
// new commit message
|
|
const NoCommitIndex = -1
|
|
|
|
type CommitMessageViewModel struct {
|
|
// index of the commit message, where -1 is 'no commit', 0 is the HEAD commit, 1
|
|
// is the prior commit, and so on
|
|
selectedindex int
|
|
// if true, then upon escaping from the commit message panel, we will preserve
|
|
// the message so that it's still shown next time we open the panel
|
|
preserveMessage bool
|
|
// we remember the initial message so that we can tell whether we should preserve
|
|
// the message; if it's still identical to the initial message, we don't
|
|
initialMessage string
|
|
// invoked when pressing enter in the commit message panel
|
|
onConfirm func(string, string) error
|
|
// invoked when pressing the switch-to-editor key binding
|
|
onSwitchToEditor func(string) error
|
|
|
|
// The message typed in before cycling through history
|
|
// We store this separately to 'preservedMessage' because 'preservedMessage'
|
|
// is specifically for committing staged files and we don't want this affected
|
|
// by cycling through history in the context of rewording an old commit.
|
|
historyMessage string
|
|
}
|
|
|
|
func NewCommitMessageContext(
|
|
c *ContextCommon,
|
|
) *CommitMessageContext {
|
|
viewModel := &CommitMessageViewModel{}
|
|
return &CommitMessageContext{
|
|
c: c,
|
|
viewModel: viewModel,
|
|
Context: NewSimpleContext(
|
|
NewBaseContext(NewBaseContextOpts{
|
|
Kind: types.PERSISTENT_POPUP,
|
|
View: c.Views().CommitMessage,
|
|
WindowName: "commitMessage",
|
|
Key: COMMIT_MESSAGE_CONTEXT_KEY,
|
|
Focusable: true,
|
|
HasUncontrolledBounds: true,
|
|
}),
|
|
),
|
|
}
|
|
}
|
|
|
|
func (self *CommitMessageContext) SetSelectedIndex(value int) {
|
|
self.viewModel.selectedindex = value
|
|
}
|
|
|
|
func (self *CommitMessageContext) GetSelectedIndex() int {
|
|
return self.viewModel.selectedindex
|
|
}
|
|
|
|
func (self *CommitMessageContext) GetPreservedMessagePath() string {
|
|
return filepath.Join(self.c.Git().RepoPaths.WorktreeGitDirPath(), PreservedCommitMessageFileName)
|
|
}
|
|
|
|
func (self *CommitMessageContext) GetPreserveMessage() bool {
|
|
return self.viewModel.preserveMessage
|
|
}
|
|
|
|
func (self *CommitMessageContext) getPreservedMessage() (string, error) {
|
|
buf, err := afero.ReadFile(self.c.Fs, self.GetPreservedMessagePath())
|
|
if os.IsNotExist(err) {
|
|
return "", nil
|
|
}
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(buf), nil
|
|
}
|
|
|
|
func (self *CommitMessageContext) GetPreservedMessageAndLogError() string {
|
|
msg, err := self.getPreservedMessage()
|
|
if err != nil {
|
|
self.c.Log.Errorf("error when retrieving persisted commit message: %v", err)
|
|
}
|
|
return msg
|
|
}
|
|
|
|
func (self *CommitMessageContext) setPreservedMessage(message string) error {
|
|
preservedFilePath := self.GetPreservedMessagePath()
|
|
|
|
if len(message) == 0 {
|
|
err := self.c.Fs.Remove(preservedFilePath)
|
|
if os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
return afero.WriteFile(self.c.Fs, preservedFilePath, []byte(message), 0o644)
|
|
}
|
|
|
|
func (self *CommitMessageContext) SetPreservedMessageAndLogError(message string) {
|
|
if err := self.setPreservedMessage(message); err != nil {
|
|
self.c.Log.Errorf("error when persisting commit message: %v", err)
|
|
}
|
|
}
|
|
|
|
func (self *CommitMessageContext) GetInitialMessage() string {
|
|
return strings.TrimSpace(self.viewModel.initialMessage)
|
|
}
|
|
|
|
func (self *CommitMessageContext) GetHistoryMessage() string {
|
|
return self.viewModel.historyMessage
|
|
}
|
|
|
|
func (self *CommitMessageContext) SetHistoryMessage(message string) {
|
|
self.viewModel.historyMessage = message
|
|
}
|
|
|
|
func (self *CommitMessageContext) OnConfirm(summary string, description string) error {
|
|
return self.viewModel.onConfirm(summary, description)
|
|
}
|
|
|
|
func (self *CommitMessageContext) SetPanelState(
|
|
index int,
|
|
summaryTitle string,
|
|
descriptionTitle string,
|
|
preserveMessage bool,
|
|
initialMessage string,
|
|
onConfirm func(string, string) error,
|
|
onSwitchToEditor func(string) error,
|
|
) {
|
|
self.viewModel.selectedindex = index
|
|
self.viewModel.preserveMessage = preserveMessage
|
|
self.viewModel.initialMessage = initialMessage
|
|
self.viewModel.onConfirm = onConfirm
|
|
self.viewModel.onSwitchToEditor = onSwitchToEditor
|
|
self.GetView().Title = summaryTitle
|
|
self.c.Views().CommitDescription.Title = descriptionTitle
|
|
|
|
self.c.Views().CommitDescription.Subtitle = utils.ResolvePlaceholderString(self.c.Tr.CommitDescriptionSubTitle,
|
|
map[string]string{
|
|
"togglePanelKeyBinding": keybindings.Label(self.c.UserConfig().Keybinding.Universal.TogglePanel),
|
|
"commitMenuKeybinding": keybindings.Label(self.c.UserConfig().Keybinding.CommitMessage.CommitMenu),
|
|
})
|
|
|
|
self.c.Views().CommitDescription.Visible = true
|
|
}
|
|
|
|
func (self *CommitMessageContext) RenderCommitLength() {
|
|
if self.c.UserConfig().Gui.CommitLength.Show {
|
|
self.c.Views().CommitMessage.Subtitle = getBufferLength(self.c.Views().CommitMessage)
|
|
} else {
|
|
self.c.Views().CommitMessage.Subtitle = ""
|
|
}
|
|
}
|
|
|
|
func getBufferLength(view *gocui.View) string {
|
|
return " " + strconv.Itoa(strings.Count(view.TextArea.GetContent(), "")-1) + " "
|
|
}
|
|
|
|
func (self *CommitMessageContext) SwitchToEditor(message string) error {
|
|
return self.viewModel.onSwitchToEditor(message)
|
|
}
|
|
|
|
func (self *CommitMessageContext) CanSwitchToEditor() bool {
|
|
return self.viewModel.onSwitchToEditor != nil
|
|
}
|