1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-06-25 00:46:54 +02:00

Bump gocui

This commit is contained in:
Stefan Haller
2024-08-24 17:45:51 +02:00
parent 37f32755b5
commit 8d37f48744
6 changed files with 119 additions and 10 deletions

2
go.mod
View File

@ -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.20240824094505-8cce5f5d2511 github.com/jesseduffield/gocui v0.3.1-0.20240824154427-0fc91d5098e4
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
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/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.20240824094505-8cce5f5d2511 h1:FN3QrzVxV3lM/SdvBCz2lUtfW0VOKLUMHj5xYWdv3Mc= github.com/jesseduffield/gocui v0.3.1-0.20240824154427-0fc91d5098e4 h1:2su9wjacqT/WxvNrzzdvA6rBJa6n/yZ/jvaS1r60HfM=
github.com/jesseduffield/gocui v0.3.1-0.20240824094505-8cce5f5d2511/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8= github.com/jesseduffield/gocui v0.3.1-0.20240824154427-0fc91d5098e4/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=

View File

@ -180,6 +180,8 @@ type Gui struct {
suspended bool suspended bool
taskManager *TaskManager taskManager *TaskManager
lastHoverView *View
} }
type NewGuiOpts struct { type NewGuiOpts struct {
@ -836,7 +838,7 @@ func (g *Gui) processRemainingEvents() error {
// etc.) // etc.)
func (g *Gui) handleEvent(ev *GocuiEvent) error { func (g *Gui) handleEvent(ev *GocuiEvent) error {
switch ev.Type { switch ev.Type {
case eventKey, eventMouse: case eventKey, eventMouse, eventMouseMove:
return g.onKey(ev) return g.onKey(ev)
case eventError: case eventError:
return ev.Err return ev.Err
@ -1395,6 +1397,19 @@ func (g *Gui) onKey(ev *GocuiEvent) error {
return err return err
} }
case eventMouseMove:
mx, my := ev.MouseX, ev.MouseY
v, err := g.VisibleViewByPosition(mx, my)
if err != nil {
break
}
if g.lastHoverView != nil && g.lastHoverView != v {
g.lastHoverView.lastHoverPosition = nil
g.lastHoverView.hoveredHyperlink = nil
}
g.lastHoverView = v
v.onMouseMove(mx, my)
default: default:
} }

View File

@ -176,6 +176,7 @@ const (
eventKey eventKey
eventResize eventResize
eventMouse eventMouse
eventMouseMove // only used when no button is down, otherwise it's eventMouse
eventFocus eventFocus
eventInterrupt eventInterrupt
eventError eventError
@ -387,7 +388,11 @@ func (g *Gui) pollEvent() GocuiEvent {
if !wheeling { if !wheeling {
switch dragState { switch dragState {
case NOT_DRAGGING: case NOT_DRAGGING:
return GocuiEvent{Type: eventNone} return GocuiEvent{
Type: eventMouseMove,
MouseX: x,
MouseY: y,
}
// if we haven't released the left mouse button and we've moved the cursor then we're dragging // if we haven't released the left mouse button and we've moved the cursor then we're dragging
case MAYBE_DRAGGING: case MAYBE_DRAGGING:
if x != lastX || y != lastY { if x != lastX || y != lastY {

View File

@ -56,6 +56,13 @@ type View struct {
// tained is true if the viewLines must be updated // tained is true if the viewLines must be updated
tainted bool tainted bool
// the last position that the mouse was hovering over; nil if the mouse is outside of
// this view, or not hovering over a cell
lastHoverPosition *pos
// the location of the hyperlink that the mouse is currently hovering over; nil if none
hoveredHyperlink *SearchPosition
// internal representation of the view's buffer. We will keep viewLines around // internal representation of the view's buffer. We will keep viewLines around
// from a previous render until we explicitly set them to nil, allowing us to // from a previous render until we explicitly set them to nil, allowing us to
// render the same content twice without flicker. Wherever we want to render // render the same content twice without flicker. Wherever we want to render
@ -180,6 +187,14 @@ type View struct {
// if true, the user can scroll all the way past the last item until it appears at the top of the view // if true, the user can scroll all the way past the last item until it appears at the top of the view
CanScrollPastBottom bool CanScrollPastBottom bool
// if true, the view will underline hyperlinks only when the cursor is on
// them; otherwise, they will always be underlined
UnderlineHyperLinksOnlyOnHover bool
}
type pos struct {
x, y int
} }
// call this in the event of a view resize, or if you want to render new content // call this in the event of a view resize, or if you want to render new content
@ -188,6 +203,7 @@ type View struct {
func (v *View) clearViewLines() { func (v *View) clearViewLines() {
v.tainted = true v.tainted = true
v.viewLines = nil v.viewLines = nil
v.clearHover()
} }
type searcher struct { type searcher struct {
@ -532,6 +548,10 @@ func (v *View) setRune(x, y int, ch rune, fgColor, bgColor Attribute) error {
} }
} }
if v.isHoveredHyperlink(x, y) {
fgColor |= AttrUnderline
}
// Don't display NUL characters // Don't display NUL characters
if ch == 0 { if ch == 0 {
ch = ' ' ch = ' '
@ -756,6 +776,7 @@ func (v *View) WriteRunes(p []rune) {
// writeRunes copies slice of runes into internal lines buffer. // writeRunes copies slice of runes into internal lines buffer.
func (v *View) writeRunes(p []rune) { func (v *View) writeRunes(p []rune) {
v.tainted = true v.tainted = true
v.clearHover()
// Fill with empty cells, if writing outside current view buffer // Fill with empty cells, if writing outside current view buffer
v.makeWriteable(v.wx, v.wy) v.makeWriteable(v.wx, v.wy)
@ -1164,7 +1185,7 @@ func (v *View) draw() error {
if bgColor == ColorDefault { if bgColor == ColorDefault {
bgColor = v.BgColor bgColor = v.BgColor
} }
if c.hyperlink != "" { if c.hyperlink != "" && !v.UnderlineHyperLinksOnlyOnHover {
fgColor |= AttrUnderline fgColor |= AttrUnderline
} }
@ -1236,6 +1257,15 @@ func (v *View) isPatternMatchedRune(x, y int) (bool, bool) {
return false, false return false, false
} }
func (v *View) isHoveredHyperlink(x, y int) bool {
if v.UnderlineHyperLinksOnlyOnHover && v.hoveredHyperlink != nil {
adjustedY := y + v.oy
adjustedX := x + v.ox
return adjustedY == v.hoveredHyperlink.Y && adjustedX >= v.hoveredHyperlink.XStart && adjustedX < v.hoveredHyperlink.XEnd
}
return false
}
// realPosition returns the position in the internal buffer corresponding to the // realPosition returns the position in the internal buffer corresponding to the
// point (x, y) of the view. // point (x, y) of the view.
func (v *View) realPosition(vx, vy int) (x, y int, err error) { func (v *View) realPosition(vx, vy int) (x, y int, err error) {
@ -1406,6 +1436,7 @@ func (v *View) SetHighlight(y int, on bool) error {
} }
v.tainted = true v.tainted = true
v.lines[y] = cells v.lines[y] = cells
v.clearHover()
return nil return nil
} }
@ -1672,8 +1703,12 @@ func (v *View) ScrollUp(amount int) {
amount = v.oy amount = v.oy
} }
if amount != 0 {
v.oy -= amount v.oy -= amount
v.cy += amount v.cy += amount
v.clearHover()
}
} }
// ensures we don't scroll past the end of the view's content // ensures we don't scroll past the end of the view's content
@ -1682,6 +1717,8 @@ func (v *View) ScrollDown(amount int) {
if adjustedAmount > 0 { if adjustedAmount > 0 {
v.oy += adjustedAmount v.oy += adjustedAmount
v.cy -= adjustedAmount v.cy -= adjustedAmount
v.clearHover()
} }
} }
@ -1690,12 +1727,18 @@ func (v *View) ScrollLeft(amount int) {
if newOx < 0 { if newOx < 0 {
newOx = 0 newOx = 0
} }
if newOx != v.ox {
v.ox = newOx v.ox = newOx
v.clearHover()
}
} }
// not applying any limits to this // not applying any limits to this
func (v *View) ScrollRight(amount int) { func (v *View) ScrollRight(amount int) {
v.ox += amount v.ox += amount
v.clearHover()
} }
func (v *View) adjustDownwardScrollAmount(scrollHeight int) int { func (v *View) adjustDownwardScrollAmount(scrollHeight int) int {
@ -1769,3 +1812,49 @@ func containsColoredTextInLine(fgColorStr string, text string, line []cell) bool
return strings.Contains(currentMatch, text) return strings.Contains(currentMatch, text)
} }
func (v *View) onMouseMove(x int, y int) {
if v.Editable || !v.UnderlineHyperLinksOnlyOnHover {
return
}
// newCx and newCy are relative to the view port, i.e. to the visible area of the view
newCx := x - v.x0 - 1
newCy := y - v.y0 - 1
// newX and newY are relative to the view's content, independent of its scroll position
newX := newCx + v.ox
newY := newCy + v.oy
if newY >= 0 && newY <= len(v.viewLines)-1 && newX >= 0 && newX <= len(v.viewLines[newY].line)-1 {
if v.lastHoverPosition == nil || v.lastHoverPosition.x != newX || v.lastHoverPosition.y != newY {
v.hoveredHyperlink = v.findHyperlinkAt(newX, newY)
}
v.lastHoverPosition = &pos{x: newX, y: newY}
} else {
v.lastHoverPosition = nil
v.hoveredHyperlink = nil
}
}
func (v *View) findHyperlinkAt(x, y int) *SearchPosition {
linkStr := v.viewLines[y].line[x].hyperlink
if linkStr == "" {
return nil
}
xStart := x
for xStart > 0 && v.viewLines[y].line[xStart-1].hyperlink == linkStr {
xStart--
}
xEnd := x + 1
for xEnd < len(v.viewLines[y].line) && v.viewLines[y].line[xEnd].hyperlink == linkStr {
xEnd++
}
return &SearchPosition{XStart: xStart, XEnd: xEnd, Y: y}
}
func (v *View) clearHover() {
v.hoveredHyperlink = nil
v.lastHoverPosition = nil
}

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/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.20240824094505-8cce5f5d2511 # github.com/jesseduffield/gocui v0.3.1-0.20240824154427-0fc91d5098e4
## 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