1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-27 12:32:37 +02:00

Improve mouse support for commit message panel (#3836)

#### PR Description

* Fix some minor problems related to cursor movement in an auto-wrapped
  commit message
* Allow clicking in an editable view to set the cursor (most useful in
  longer commit descriptions)
* Allow switching between commit message and description by clicking
This commit is contained in:
Stefan Haller 2024-08-24 10:29:44 +02:00 committed by GitHub
commit 61ae5e16ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 98 additions and 22 deletions

2
go.mod
View File

@ -16,7 +16,7 @@ require (
github.com/integrii/flaggy v1.4.0
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d
github.com/jesseduffield/gocui v0.3.1-0.20240818082312-49cc572a9ffa
github.com/jesseduffield/gocui v0.3.1-0.20240824081936-a3adeb73f602
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e

4
go.sum
View File

@ -188,8 +188,8 @@ github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8T
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk=
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d h1:bO+OmbreIv91rCe8NmscRwhFSqkDJtzWCPV4Y+SQuXE=
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o=
github.com/jesseduffield/gocui v0.3.1-0.20240818082312-49cc572a9ffa h1:XZX6Rf60E3IuF1K+fvxjIr29f4p9kNY83mveGoJ5Uuo=
github.com/jesseduffield/gocui v0.3.1-0.20240818082312-49cc572a9ffa/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8=
github.com/jesseduffield/gocui v0.3.1-0.20240824081936-a3adeb73f602 h1:nzGt/sRT0WCancALG5Q9e4DlQWGo7QUMc35rApdt+aM=
github.com/jesseduffield/gocui v0.3.1-0.20240824081936-a3adeb73f602/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8=
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0=
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo=
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY=

View File

@ -354,6 +354,7 @@ func (gui *Gui) resetHelpersAndControllers() {
controllers.AttachControllers(gui.State.Contexts.CommitDescription,
commitDescriptionController,
verticalScrollControllerFactory.Create(gui.State.Contexts.CommitDescription),
)
controllers.AttachControllers(gui.State.Contexts.RemoteBranches,

View File

@ -1,6 +1,7 @@
package controllers
import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
@ -45,11 +46,17 @@ func (self *CommitDescriptionController) GetKeybindings(opts types.KeybindingsOp
}
func (self *CommitDescriptionController) Context() types.Context {
return self.context()
return self.c.Contexts().CommitDescription
}
func (self *CommitDescriptionController) context() *context.CommitMessageContext {
return self.c.Contexts().CommitMessage
func (self *CommitDescriptionController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
return []*gocui.ViewMouseBinding{
{
ViewName: self.Context().GetViewName(),
Key: gocui.MouseLeft,
Handler: self.onClick,
},
}
}
func (self *CommitDescriptionController) switchToCommitMessage() error {
@ -68,3 +75,12 @@ func (self *CommitDescriptionController) openCommitMenu() error {
authorSuggestion := self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc()
return self.c.Helpers().Commits.OpenCommitMenu(authorSuggestion)
}
func (self *CommitDescriptionController) onClick(opts gocui.ViewMouseBindingOpts) error {
// Activate the description panel when the commit message panel is currently active
if self.c.Context().Current().GetKey() == context.COMMIT_MESSAGE_CONTEXT_KEY {
return self.c.Context().Replace(self.c.Contexts().CommitDescription)
}
return nil
}

View File

@ -3,6 +3,7 @@ package controllers
import (
"errors"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
@ -58,6 +59,16 @@ func (self *CommitMessageController) GetKeybindings(opts types.KeybindingsOpts)
return bindings
}
func (self *CommitMessageController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
return []*gocui.ViewMouseBinding{
{
ViewName: self.Context().GetViewName(),
Key: gocui.MouseLeft,
Handler: self.onClick,
},
}
}
func (self *CommitMessageController) GetOnFocusLost() func(types.OnFocusLostOpts) error {
return func(types.OnFocusLostOpts) error {
self.context().RenderCommitLength()
@ -137,3 +148,12 @@ func (self *CommitMessageController) openCommitMenu() error {
authorSuggestion := self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc()
return self.c.Helpers().Commits.OpenCommitMenu(authorSuggestion)
}
func (self *CommitMessageController) onClick(opts gocui.ViewMouseBindingOpts) error {
// Activate the commit message panel when the commit description panel is currently active
if self.c.Context().Current().GetKey() == context.COMMIT_DESCRIPTION_CONTEXT_KEY {
return self.c.Context().Replace(self.c.Contexts().CommitMessage)
}
return nil
}

View File

@ -424,8 +424,14 @@ func (gui *Gui) SetKeybinding(binding *types.Binding) error {
func (gui *Gui) SetMouseKeybinding(binding *gocui.ViewMouseBinding) error {
baseHandler := binding.Handler
newHandler := func(opts gocui.ViewMouseBindingOpts) error {
// we ignore click events on views that aren't popup panels, when a popup panel is focused
if gui.helpers.Confirmation.IsPopupPanelFocused() && gui.currentViewName() != binding.ViewName {
// we ignore click events on views that aren't popup panels, when a popup panel is focused.
// Unless both the current view and the clicked-on view are either commit message or commit
// description, because we want to allow switching between those two views by clicking.
isCommitMessageView := func(viewName string) bool {
return viewName == "commitMessage" || viewName == "commitDescription"
}
if gui.helpers.Confirmation.IsPopupPanelFocused() && gui.currentViewName() != binding.ViewName &&
(!isCommitMessageView(gui.currentViewName()) || !isCommitMessageView(binding.ViewName)) {
return nil
}

View File

@ -1327,23 +1327,48 @@ func (g *Gui) onKey(ev *GocuiEvent) error {
}
}
// newCx and newCy are relative to the view port, i.e. to the visible area of the view
newCx := mx - v.x0 - 1
newCy := my - v.y0 - 1
// if view is editable don't go further than the furthest character for that line
if v.Editable && newCy >= 0 && newCy <= len(v.lines)-1 {
lastCharForLine := len(v.lines[newCy])
if lastCharForLine < newCx {
newCx = lastCharForLine
// newX and newY are relative to the view's content, independent of its scroll position
newX := newCx + v.ox
newY := newCy + v.oy
// if view is editable don't go further than the furthest character for that line
if v.Editable {
if newY < 0 {
newY = 0
newCy = -v.oy
} else if newY >= len(v.lines) {
newY = len(v.lines) - 1
newCy = newY - v.oy
}
lastCharForLine := len(v.lines[newY])
for lastCharForLine > 0 && v.lines[newY][lastCharForLine-1].chr == 0 {
lastCharForLine--
}
if lastCharForLine < newX {
newX = lastCharForLine
newCx = lastCharForLine - v.ox
}
}
if !IsMouseScrollKey(ev.Key) {
if err := v.SetCursor(newCx, newCy); err != nil {
return err
}
if v.Editable {
v.TextArea.SetCursor2D(newX, newY)
// SetCursor2D might have adjusted the text area's cursor to the
// left to move left from a soft line break, so we need to
// update the view's cursor to match the text area's cursor.
cX, _ := v.TextArea.GetCursorXY()
v.SetCursorX(cX)
}
}
if IsMouseKey(ev.Key) {
opts := ViewMouseBindingOpts{X: newCx + v.ox, Y: newCy + v.oy}
opts := ViewMouseBindingOpts{X: newX, Y: newY}
matched, err := g.execMouseKeybindings(v, ev, opts)
if err != nil {
return err

View File

@ -282,13 +282,7 @@ func (self *TextArea) GoToEndOfLine() {
self.cursor = self.closestNewlineOnRight()
// If the end of line is a soft line break, we need to move left by one so
// that we end up at the last whitespace before the line break. Otherwise
// we'd be at the start of the next line, since the newline character
// doesn't really exist in the real content.
if self.cursor < len(self.content) && self.content[self.cursor] != '\n' {
self.cursor--
}
self.moveLeftFromSoftLineBreak()
}
func (self *TextArea) closestNewlineOnRight() int {
@ -303,6 +297,16 @@ func (self *TextArea) closestNewlineOnRight() int {
return len(self.content)
}
func (self *TextArea) moveLeftFromSoftLineBreak() {
// If the end of line is a soft line break, we need to move left by one so
// that we end up at the last whitespace before the line break. Otherwise
// we'd be at the start of the next line, since the newline character
// doesn't really exist in the real content.
if self.cursor < len(self.content) && self.content[self.cursor] != '\n' {
self.cursor--
}
}
func (self *TextArea) atLineStart() bool {
return self.cursor == 0 ||
(len(self.content) > self.cursor-1 && self.content[self.cursor-1] == '\n')
@ -420,12 +424,16 @@ func (self *TextArea) SetCursor2D(x int, y int) {
for _, r := range self.wrappedContent {
if x <= 0 && y == 0 {
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
if self.wrappedContent[newCursor] == '\n' {
self.moveLeftFromSoftLineBreak()
}
return
}
if r == '\n' {
if y == 0 {
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
self.moveLeftFromSoftLineBreak()
return
}
y--

2
vendor/modules.txt vendored
View File

@ -172,7 +172,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem
github.com/jesseduffield/go-git/v5/utils/merkletrie/index
github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
# github.com/jesseduffield/gocui v0.3.1-0.20240818082312-49cc572a9ffa
# github.com/jesseduffield/gocui v0.3.1-0.20240824081936-a3adeb73f602
## explicit; go 1.12
github.com/jesseduffield/gocui
# github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10