Skip to content

Commit

Permalink
fix lbl scrolling
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseduffield committed Jun 5, 2021
1 parent 6d91661 commit f91adf0
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 12 deletions.
52 changes: 52 additions & 0 deletions pkg/gui/lbl/focus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package lbl

import "github.com/jesseduffield/lazygit/pkg/utils"

func calculateOrigin(currentOrigin int, bufferHeight int, firstLineIdx int, lastLineIdx int, selectedLineIdx int, mode selectMode) int {
needToSeeIdx, wantToSeeIdx := getNeedAndWantLineIdx(firstLineIdx, lastLineIdx, selectedLineIdx, mode)

return calculateNewOriginWithNeededAndWantedIdx(currentOrigin, bufferHeight, needToSeeIdx, wantToSeeIdx)
}

// we want to scroll our origin so that the index we need to see is in view
// and the other index we want to see (e.g. the other side of a line range)
// is in as close to being in view as possible.
func calculateNewOriginWithNeededAndWantedIdx(currentOrigin int, bufferHeight int, needToSeeIdx int, wantToSeeIdx int) int {
origin := currentOrigin
if needToSeeIdx < currentOrigin {
origin = needToSeeIdx
} else if needToSeeIdx > currentOrigin+bufferHeight {
origin = needToSeeIdx - bufferHeight
}

bottom := origin + bufferHeight

if wantToSeeIdx < origin {
requiredChange := origin - wantToSeeIdx
allowedChange := bottom - needToSeeIdx
return origin - utils.Min(requiredChange, allowedChange)
} else if wantToSeeIdx > origin+bufferHeight {
requiredChange := wantToSeeIdx - bottom
allowedChange := needToSeeIdx - origin
return origin + utils.Min(requiredChange, allowedChange)
} else {
return origin
}
}

func getNeedAndWantLineIdx(firstLineIdx int, lastLineIdx int, selectedLineIdx int, mode selectMode) (int, int) {
switch mode {
case LINE:
return selectedLineIdx, selectedLineIdx
case RANGE:
if selectedLineIdx == firstLineIdx {
return firstLineIdx, lastLineIdx
} else {
return lastLineIdx, firstLineIdx
}
case HUNK:
return firstLineIdx, lastLineIdx
default:
panic("unknown mode")
}
}
100 changes: 100 additions & 0 deletions pkg/gui/lbl/focus_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package lbl

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestNewOrigin(t *testing.T) {
type scenario struct {
name string
origin int
bufferHeight int
firstLineIdx int
lastLineIdx int
selectedLineIdx int
selectMode selectMode
expected int
}

scenarios := []scenario{
{
name: "selection above scroll window",
origin: 50,
bufferHeight: 100,
firstLineIdx: 10,
lastLineIdx: 10,
selectedLineIdx: 10,
selectMode: LINE,
expected: 10,
},
{
name: "selection below scroll window",
origin: 0,
bufferHeight: 100,
firstLineIdx: 150,
lastLineIdx: 150,
selectedLineIdx: 150,
selectMode: LINE,
expected: 50,
},
{
name: "selection within scroll window",
origin: 0,
bufferHeight: 100,
firstLineIdx: 50,
lastLineIdx: 50,
selectedLineIdx: 50,
selectMode: LINE,
expected: 0,
},
{
name: "range ending below scroll window with selection at end of range",
origin: 0,
bufferHeight: 100,
firstLineIdx: 40,
lastLineIdx: 150,
selectedLineIdx: 150,
selectMode: RANGE,
expected: 50,
},
{
name: "range ending below scroll window with selection at beginning of range",
origin: 0,
bufferHeight: 100,
firstLineIdx: 40,
lastLineIdx: 150,
selectedLineIdx: 40,
selectMode: RANGE,
expected: 40,
},
{
name: "range starting above scroll window with selection at beginning of range",
origin: 50,
bufferHeight: 100,
firstLineIdx: 40,
lastLineIdx: 150,
selectedLineIdx: 40,
selectMode: RANGE,
expected: 40,
},
{
name: "hunk extending beyond both bounds of scroll window",
origin: 50,
bufferHeight: 100,
firstLineIdx: 40,
lastLineIdx: 200,
selectedLineIdx: 70,
selectMode: HUNK,
expected: 40,
},
}

for _, s := range scenarios {
s := s
t.Run(s.name, func(t *testing.T) {
assert.EqualValues(t, s.expected, calculateOrigin(s.origin, s.bufferHeight, s.firstLineIdx, s.lastLineIdx, s.selectedLineIdx, s.selectMode))
})
}
}
6 changes: 6 additions & 0 deletions pkg/gui/lbl/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,9 @@ func (s *State) SelectTop() {
s.SetLineSelectMode()
s.SelectLine(0)
}

func (s *State) CalculateOrigin(currentOrigin int, bufferHeight int) int {
firstLineIdx, lastLineIdx := s.SelectedRange()

return calculateOrigin(currentOrigin, bufferHeight, firstLineIdx, lastLineIdx, s.GetSelectedLineIdx(), s.selectMode)
}
15 changes: 3 additions & 12 deletions pkg/gui/line_by_line_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,25 +155,16 @@ func (gui *Gui) focusSelection(state *LblPanelState) error {
bufferHeight := viewHeight - 1
_, origin := stagingView.Origin()

firstLineIdx, lastLineIdx := state.SelectedRange()
selectedLineIdx := state.GetSelectedLineIdx()

margin := 0 // we may want to have a margin in place to show context but right now I'm thinking we keep this at zero

var newOrigin int
if firstLineIdx-origin < margin {
newOrigin = firstLineIdx - margin
} else if lastLineIdx-origin > bufferHeight-margin {
newOrigin = lastLineIdx - bufferHeight + margin
} else {
newOrigin = origin
}
newOrigin := state.CalculateOrigin(origin, bufferHeight)

gui.g.Update(func(*gocui.Gui) error {
if err := stagingView.SetOrigin(0, newOrigin); err != nil {
return err
}

return stagingView.SetCursor(0, state.GetSelectedLineIdx()-newOrigin)
return stagingView.SetCursor(0, selectedLineIdx-newOrigin)
})

return nil
Expand Down

0 comments on commit f91adf0

Please sign in to comment.