summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorStefan Haller <stefan@haller-berlin.de>2023-12-20 19:17:42 +0100
committerStefan Haller <stefan@haller-berlin.de>2024-03-09 10:00:44 +0100
commit41a68f7c4afcda3479b13bf8bd3e63b4906054b8 (patch)
treea036bdfbfeddc44fc55912377709d0ce1ec1307e /pkg
parent944d82028faed05b3b53e630c9fcf0c4747891e0 (diff)
Remove hard line breaks when rewording commits
... and when recalling a commit message from an old commit by pressing up-arrow. This is necessary because committing turns our soft line breaks into real ones, but when rewording we want to turn them back into soft ones again, so that it's possible to insert words at the beginning of a paragraph and have everything rewrap nicely. This is only a best effort; the algorithm only removes those hard line breaks that can be removed without changing the way the message looks. This works well when the previous commit message was wrapped at the same width, which for most users should be the most common case; but if it wasn't, the result is not great. Specifically, if the old wrap width was smaller, some hard line breaks just won't be removed; if it was wider though, you'll get an unpleasant comb effect with alternating long and short lines. In such a case it's best to switch to the editor and use whatever wrapping features you have there (e.g. alt-Q).
Diffstat (limited to 'pkg')
-rw-r--r--pkg/gui/controllers/commit_message_controller.go4
-rw-r--r--pkg/gui/controllers/helpers/commits_helper.go26
-rw-r--r--pkg/gui/controllers/helpers/commits_helper_test.go41
-rw-r--r--pkg/gui/controllers/local_commits_controller.go4
4 files changed, 74 insertions, 1 deletions
diff --git a/pkg/gui/controllers/commit_message_controller.go b/pkg/gui/controllers/commit_message_controller.go
index ef95dffe0..756b240e6 100644
--- a/pkg/gui/controllers/commit_message_controller.go
+++ b/pkg/gui/controllers/commit_message_controller.go
@@ -3,6 +3,7 @@ package controllers
import (
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/gui/context"
+ "github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
@@ -119,6 +120,9 @@ func (self *CommitMessageController) setCommitMessageAtIndex(index int) (bool, e
}
return false, self.c.ErrorMsg(self.c.Tr.CommitWithoutMessageErr)
}
+ if self.c.UserConfig.Git.Commit.AutoWrapCommitMessage {
+ commitMessage = helpers.TryRemoveHardLineBreaks(commitMessage, self.c.UserConfig.Git.Commit.AutoWrapWidth)
+ }
self.c.Helpers().Commits.UpdateCommitPanelView(commitMessage)
return true, nil
}
diff --git a/pkg/gui/controllers/helpers/commits_helper.go b/pkg/gui/controllers/helpers/commits_helper.go
index cd90790a3..0801d5742 100644
--- a/pkg/gui/controllers/helpers/commits_helper.go
+++ b/pkg/gui/controllers/helpers/commits_helper.go
@@ -5,6 +5,7 @@ import (
"strings"
"time"
+ "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/samber/lo"
)
@@ -63,6 +64,31 @@ func (self *CommitsHelper) JoinCommitMessageAndUnwrappedDescription() string {
return self.getCommitSummary() + "\n" + self.getUnwrappedCommitDescription()
}
+func TryRemoveHardLineBreaks(message string, autoWrapWidth int) string {
+ messageRunes := []rune(message)
+ lastHardLineStart := 0
+ for i, r := range messageRunes {
+ if r == '\n' {
+ // Try to make this a soft linebreak by turning it into a space, and
+ // checking whether it still wraps to the same result then.
+ messageRunes[i] = ' '
+
+ _, cursorMapping := gocui.AutoWrapContent(messageRunes[lastHardLineStart:], autoWrapWidth)
+
+ // Look at the cursorMapping to check whether auto-wrapping inserted
+ // a line break. If it did, there will be a cursorMapping entry with
+ // Orig pointing to the position after the inserted line break.
+ if len(cursorMapping) == 0 || cursorMapping[0].Orig != i-lastHardLineStart+1 {
+ // It didn't, so change it back to a newline
+ messageRunes[i] = '\n'
+ }
+ lastHardLineStart = i + 1
+ }
+ }
+
+ return string(messageRunes)
+}
+
func (self *CommitsHelper) SwitchToEditor() error {
if !self.c.Contexts().CommitMessage.CanSwitchToEditor() {
return nil
diff --git a/pkg/gui/controllers/helpers/commits_helper_test.go b/pkg/gui/controllers/helpers/commits_helper_test.go
new file mode 100644
index 000000000..6197c3916
--- /dev/null
+++ b/pkg/gui/controllers/helpers/commits_helper_test.go
@@ -0,0 +1,41 @@
+package helpers
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestTryRemoveHardLineBreaks(t *testing.T) {
+ scenarios := []struct {
+ name string
+ message string
+ autoWrapWidth int
+ expectedResult string
+ }{
+ {
+ name: "empty",
+ message: "",
+ autoWrapWidth: 7,
+ expectedResult: "",
+ },
+ {
+ name: "all line breaks are needed",
+ message: "abc\ndef\n\nxyz",
+ autoWrapWidth: 7,
+ expectedResult: "abc\ndef\n\nxyz",
+ },
+ {
+ name: "some can be unwrapped",
+ message: "123\nabc def\nghi jkl\nmno\n456\n",
+ autoWrapWidth: 7,
+ expectedResult: "123\nabc def ghi jkl mno\n456\n",
+ },
+ }
+ for _, s := range scenarios {
+ t.Run(s.name, func(t *testing.T) {
+ actualResult := TryRemoveHardLineBreaks(s.message, s.autoWrapWidth)
+ assert.Equal(t, s.expectedResult, actualResult)
+ })
+ }
+}
diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go
index ef6b5be80..8c99d7586 100644
--- a/pkg/gui/controllers/local_commits_controller.go
+++ b/pkg/gui/controllers/local_commits_controller.go
@@ -354,7 +354,9 @@ func (self *LocalCommitsController) reword(commit *models.Commit) error {
if err != nil {
return self.c.Error(err)
}
-
+ if self.c.UserConfig.Git.Commit.AutoWrapCommitMessage {
+ commitMessage = helpers.TryRemoveHardLineBreaks(commitMessage, self.c.UserConfig.Git.Commit.AutoWrapWidth)
+ }
return self.c.Helpers().Commits.OpenCommitMessagePanel(
&helpers.OpenCommitMessagePanelOpts{
CommitIndex: self.context().GetSelectedLineIdx(),