mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-11-06 13:00:59 -04:00
Don't leave a re-rendered diff scrolled further right than it reaches
The main view keeps its horizontal scroll position when a diff is rendered again. If the new rendering is narrower, for example because the only long line in it was just staged, the view can end up scrolled past the end of every line and look empty. If one line still reaches into the view, the view shows only a sliver of it, although the whole diff would fit without scrolling. Once a render has been read to the end, scroll the view back as far as it takes to put the end of the widest line at the right edge. A long diff that is read only in part is checked once the rest of it has been read. Nothing scrolls the main view horizontally yet, so this changes nothing on its own. It prepares for scrolling the focused main view sideways with H and L. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
4f678b7d0d
commit
6da4f658d7
@@ -2693,6 +2693,37 @@ func (v *View) ScrollRight(amount int) {
|
||||
v.clearHover()
|
||||
}
|
||||
|
||||
// ClampOriginXToContent scrolls the view back to the left if it is scrolled further
|
||||
// than its content needs, so that the end of the widest line is at the right edge.
|
||||
// A view that doesn't wrap keeps its horizontal scroll position when its content
|
||||
// changes, and the new content may not reach as far.
|
||||
func (v *View) ClampOriginXToContent() {
|
||||
v.writeMutex.Lock()
|
||||
defer v.writeMutex.Unlock()
|
||||
|
||||
if v.ox == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
v.refreshViewLinesIfNeeded()
|
||||
widest := 0
|
||||
for _, vline := range v.viewLines {
|
||||
width := 0
|
||||
for _, c := range vline.line {
|
||||
width += c.width
|
||||
}
|
||||
widest = max(widest, width)
|
||||
}
|
||||
|
||||
contentWidth := v.InnerWidth() - v.inclusionGutterWidth()
|
||||
newOx := min(v.ox, max(0, widest-contentWidth))
|
||||
if newOx != v.ox {
|
||||
v.SetOriginX(newOx)
|
||||
|
||||
v.clearHover()
|
||||
}
|
||||
}
|
||||
|
||||
func (v *View) adjustDownwardScrollAmount(scrollHeight int) int {
|
||||
_, oy := v.Origin()
|
||||
y := oy
|
||||
|
||||
@@ -1351,6 +1351,36 @@ func TestInclusionGutterWithHorizontallyScrolledContent(t *testing.T) {
|
||||
assert.Equal(t, " 3456789a", row(2))
|
||||
}
|
||||
|
||||
// A view scrolled further right than its content needs goes back as far as it takes
|
||||
// to put the end of the widest line at the right edge, and no further.
|
||||
func TestClampOriginXToContent(t *testing.T) {
|
||||
v := NewView("name", 0, 0, 11, 5, OutputNormal) // InnerWidth 10
|
||||
v.InclusionGutterMarker = "✓"
|
||||
|
||||
// The widest line is 16 wide.
|
||||
v.writeString("0123456789abcdef\nshort\n")
|
||||
|
||||
v.SetOriginX(4)
|
||||
v.ClampOriginXToContent()
|
||||
assert.Equal(t, 4, v.OriginX(), "the widest line still reaches the right edge")
|
||||
|
||||
v.SetOriginX(10)
|
||||
v.ClampOriginXToContent()
|
||||
assert.Equal(t, 6, v.OriginX())
|
||||
|
||||
// The gutter leaves the content eight columns.
|
||||
v.SetInclusionGutter(true, []bool{false, false})
|
||||
v.SetOriginX(10)
|
||||
v.ClampOriginXToContent()
|
||||
assert.Equal(t, 8, v.OriginX())
|
||||
|
||||
// Content that fits needs no scrolling at all.
|
||||
v.Clear()
|
||||
v.writeString("short\n")
|
||||
v.ClampOriginXToContent()
|
||||
assert.Equal(t, 0, v.OriginX())
|
||||
}
|
||||
|
||||
// A marked line the view wraps is marked on every segment it is drawn as, so that
|
||||
// the mark doesn't look like it belongs to the first part of the line alone. The
|
||||
// gutter takes its columns out of the width the content wraps in.
|
||||
|
||||
@@ -235,6 +235,7 @@ func (gui *Gui) getManager(view *gocui.View) *tasks.ViewBufferManager {
|
||||
|
||||
view.SetOriginY(newOriginY)
|
||||
}
|
||||
view.ClampOriginXToContent()
|
||||
|
||||
gui.updateDiffPaneDecorations(view, true)
|
||||
gui.clampDiffSelectionToContent(view)
|
||||
|
||||
Reference in New Issue
Block a user