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:
commit
61ae5e16ae
2
go.mod
2
go.mod
@ -16,7 +16,7 @@ require (
|
|||||||
github.com/integrii/flaggy v1.4.0
|
github.com/integrii/flaggy v1.4.0
|
||||||
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68
|
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68
|
||||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d
|
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/kill v0.0.0-20220618033138-bfbe04675d10
|
||||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
|
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
|
||||||
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e
|
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e
|
||||||
|
4
go.sum
4
go.sum
@ -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/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 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/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.20240824081936-a3adeb73f602 h1:nzGt/sRT0WCancALG5Q9e4DlQWGo7QUMc35rApdt+aM=
|
||||||
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/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 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0=
|
||||||
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo=
|
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=
|
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY=
|
||||||
|
@ -354,6 +354,7 @@ func (gui *Gui) resetHelpersAndControllers() {
|
|||||||
|
|
||||||
controllers.AttachControllers(gui.State.Contexts.CommitDescription,
|
controllers.AttachControllers(gui.State.Contexts.CommitDescription,
|
||||||
commitDescriptionController,
|
commitDescriptionController,
|
||||||
|
verticalScrollControllerFactory.Create(gui.State.Contexts.CommitDescription),
|
||||||
)
|
)
|
||||||
|
|
||||||
controllers.AttachControllers(gui.State.Contexts.RemoteBranches,
|
controllers.AttachControllers(gui.State.Contexts.RemoteBranches,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/jesseduffield/gocui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
)
|
)
|
||||||
@ -45,11 +46,17 @@ func (self *CommitDescriptionController) GetKeybindings(opts types.KeybindingsOp
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitDescriptionController) Context() types.Context {
|
func (self *CommitDescriptionController) Context() types.Context {
|
||||||
return self.context()
|
return self.c.Contexts().CommitDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitDescriptionController) context() *context.CommitMessageContext {
|
func (self *CommitDescriptionController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
|
||||||
return self.c.Contexts().CommitMessage
|
return []*gocui.ViewMouseBinding{
|
||||||
|
{
|
||||||
|
ViewName: self.Context().GetViewName(),
|
||||||
|
Key: gocui.MouseLeft,
|
||||||
|
Handler: self.onClick,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitDescriptionController) switchToCommitMessage() error {
|
func (self *CommitDescriptionController) switchToCommitMessage() error {
|
||||||
@ -68,3 +75,12 @@ func (self *CommitDescriptionController) openCommitMenu() error {
|
|||||||
authorSuggestion := self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc()
|
authorSuggestion := self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc()
|
||||||
return self.c.Helpers().Commits.OpenCommitMenu(authorSuggestion)
|
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
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/gocui"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
|
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
|
||||||
@ -58,6 +59,16 @@ func (self *CommitMessageController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
return bindings
|
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 {
|
func (self *CommitMessageController) GetOnFocusLost() func(types.OnFocusLostOpts) error {
|
||||||
return func(types.OnFocusLostOpts) error {
|
return func(types.OnFocusLostOpts) error {
|
||||||
self.context().RenderCommitLength()
|
self.context().RenderCommitLength()
|
||||||
@ -137,3 +148,12 @@ func (self *CommitMessageController) openCommitMenu() error {
|
|||||||
authorSuggestion := self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc()
|
authorSuggestion := self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc()
|
||||||
return self.c.Helpers().Commits.OpenCommitMenu(authorSuggestion)
|
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
|
||||||
|
}
|
||||||
|
@ -424,8 +424,14 @@ func (gui *Gui) SetKeybinding(binding *types.Binding) error {
|
|||||||
func (gui *Gui) SetMouseKeybinding(binding *gocui.ViewMouseBinding) error {
|
func (gui *Gui) SetMouseKeybinding(binding *gocui.ViewMouseBinding) error {
|
||||||
baseHandler := binding.Handler
|
baseHandler := binding.Handler
|
||||||
newHandler := func(opts gocui.ViewMouseBindingOpts) error {
|
newHandler := func(opts gocui.ViewMouseBindingOpts) error {
|
||||||
// we ignore click events on views that aren't popup panels, when a popup panel is focused
|
// 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 {
|
// 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
37
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
@ -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
|
newCx := mx - v.x0 - 1
|
||||||
newCy := my - v.y0 - 1
|
newCy := my - v.y0 - 1
|
||||||
// if view is editable don't go further than the furthest character for that line
|
// newX and newY are relative to the view's content, independent of its scroll position
|
||||||
if v.Editable && newCy >= 0 && newCy <= len(v.lines)-1 {
|
newX := newCx + v.ox
|
||||||
lastCharForLine := len(v.lines[newCy])
|
newY := newCy + v.oy
|
||||||
if lastCharForLine < newCx {
|
// if view is editable don't go further than the furthest character for that line
|
||||||
newCx = lastCharForLine
|
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 !IsMouseScrollKey(ev.Key) {
|
||||||
if err := v.SetCursor(newCx, newCy); err != nil {
|
if err := v.SetCursor(newCx, newCy); err != nil {
|
||||||
return err
|
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) {
|
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)
|
matched, err := g.execMouseKeybindings(v, ev, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
22
vendor/github.com/jesseduffield/gocui/text_area.go
generated
vendored
22
vendor/github.com/jesseduffield/gocui/text_area.go
generated
vendored
@ -282,13 +282,7 @@ func (self *TextArea) GoToEndOfLine() {
|
|||||||
|
|
||||||
self.cursor = self.closestNewlineOnRight()
|
self.cursor = self.closestNewlineOnRight()
|
||||||
|
|
||||||
// If the end of line is a soft line break, we need to move left by one so
|
self.moveLeftFromSoftLineBreak()
|
||||||
// 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) closestNewlineOnRight() int {
|
func (self *TextArea) closestNewlineOnRight() int {
|
||||||
@ -303,6 +297,16 @@ func (self *TextArea) closestNewlineOnRight() int {
|
|||||||
return len(self.content)
|
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 {
|
func (self *TextArea) atLineStart() bool {
|
||||||
return self.cursor == 0 ||
|
return self.cursor == 0 ||
|
||||||
(len(self.content) > self.cursor-1 && self.content[self.cursor-1] == '\n')
|
(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 {
|
for _, r := range self.wrappedContent {
|
||||||
if x <= 0 && y == 0 {
|
if x <= 0 && y == 0 {
|
||||||
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
|
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
|
||||||
|
if self.wrappedContent[newCursor] == '\n' {
|
||||||
|
self.moveLeftFromSoftLineBreak()
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if r == '\n' {
|
if r == '\n' {
|
||||||
if y == 0 {
|
if y == 0 {
|
||||||
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
|
self.cursor = self.wrappedCursorToOrigCursor(newCursor)
|
||||||
|
self.moveLeftFromSoftLineBreak()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
y--
|
y--
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -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/index
|
||||||
github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
|
github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
|
||||||
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
|
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
|
## explicit; go 1.12
|
||||||
github.com/jesseduffield/gocui
|
github.com/jesseduffield/gocui
|
||||||
# github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10
|
# github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10
|
||||||
|
Loading…
x
Reference in New Issue
Block a user