Skip to content

Commit

Permalink
Handle pasting multi-line commit messages
Browse files Browse the repository at this point in the history
When pasting a multi-line commit message into the subject field of the commit
editor, we would interpret the first newline as the confirmation for closing the
editor, and then all remaining characters as whatever command they are bound to,
resulting in executing all sorts of arbitrary commands.

Now we recognize this being a paste, and interpret the first newline as moving
to the description.

Also, prevent tabs in the pasted content from switching to the respective other
panel; simply insert four spaces instead, which should be good enough for the
leading indentation in pasted code snippets, for example.
  • Loading branch information
stefanhaller committed Feb 5, 2025
1 parent 1930fe8 commit 943d78f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
18 changes: 17 additions & 1 deletion pkg/gui/controllers/commit_description_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (self *CommitDescriptionController) GetKeybindings(opts types.KeybindingsOp
bindings := []*types.Binding{
{
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
Handler: self.switchToCommitMessage,
Handler: self.handleTogglePanel,
},
{
Key: opts.GetKey(opts.Config.Universal.Return),
Expand Down Expand Up @@ -75,6 +75,22 @@ func (self *CommitDescriptionController) switchToCommitMessage() error {
return nil
}

func (self *CommitDescriptionController) handleTogglePanel() error {
if self.c.GocuiGui().IsPasting {
// Handling tabs in pasted commit messages is not optimal, but hopefully
// good enough for now. We simply insert 4 spaces without worrying about
// column alignment. This works well enough for leading indentation,
// which is common in pasted code snippets.
view := self.Context().GetView()
for range 4 {
view.Editor.Edit(view, gocui.KeySpace, ' ', 0)
}
return nil
}

return self.switchToCommitMessage()
}

func (self *CommitDescriptionController) close() error {
self.c.Helpers().Commits.CloseCommitMessagePanel()
return nil
Expand Down
22 changes: 21 additions & 1 deletion pkg/gui/controllers/commit_message_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (self *CommitMessageController) GetKeybindings(opts types.KeybindingsOpts)
},
{
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
Handler: self.switchToCommitDescription,
Handler: self.handleTogglePanel,
},
{
Key: opts.GetKey(opts.Config.CommitMessage.CommitMenu),
Expand Down Expand Up @@ -105,6 +105,22 @@ func (self *CommitMessageController) switchToCommitDescription() error {
return nil
}

func (self *CommitMessageController) handleTogglePanel() error {
if self.c.GocuiGui().IsPasting {
// It is unlikely that a pasted commit message contains a tab in the
// subject line, so it shouldn't matter too much how we handle it.
// Simply insert 4 spaces instead; all that matters is that we don't
// switch to the description panel.
view := self.context().GetView()
for range 4 {
view.Editor.Edit(view, gocui.KeySpace, ' ', 0)
}
return nil
}

return self.switchToCommitDescription()
}

func (self *CommitMessageController) handleCommitIndexChange(value int) error {
currentIndex := self.context().GetSelectedIndex()
newIndex := currentIndex + value
Expand Down Expand Up @@ -140,6 +156,10 @@ func (self *CommitMessageController) setCommitMessageAtIndex(index int) (bool, e
}

func (self *CommitMessageController) confirm() error {
if self.c.GocuiGui().IsPasting {
return self.switchToCommitDescription()
}

return self.c.Helpers().Commits.HandleCommitConfirm()
}

Expand Down

0 comments on commit 943d78f

Please sign in to comment.