mirror of
				https://github.com/jesseduffield/lazygit.git
				synced 2025-10-30 23:57:43 +02:00 
			
		
		
		
	Scroll views up if needed to show all their content (#3839)
- **PR Description** There are many situations where this can arise. Some examples are: - the terminal window is small, and you are showing a view that shows more content than fits into the view port, and the view is scrolled all the way down; now you resize the terminal window to a taller size. Previously, the scroll position of the view would stay the same, so it would add blank space at the bottom; now it will scroll to fill that blank space with content - expandFocusedSidePanel is on, you go to the bottom of a list view, now switch to a different panel, then scroll that (now unfocused) panel all the way down with the scroll wheel; now you focus that panel again. It becomes larger because of the accordion behavior, but would show blank space at the bottom. And probably others that I can't remember right now. I only remember that I always found it confusing to look at a view that had blank space at the bottom even though it had more content to scroll into view.
This commit is contained in:
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @@ -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.20240824083442-15b7fbca7ae9 | ||||
| 	github.com/jesseduffield/gocui v0.3.1-0.20240824084618-5083ac1413f5 | ||||
| 	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
									
									
									
									
									
								
							
							
						
						
									
										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/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.20240824083442-15b7fbca7ae9 h1:1muwCO0cmCGHpOvNz1qTOrCFPECnBAV87yDE9Fgwy6U= | ||||
| github.com/jesseduffield/gocui v0.3.1-0.20240824083442-15b7fbca7ae9/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8= | ||||
| github.com/jesseduffield/gocui v0.3.1-0.20240824084618-5083ac1413f5 h1:o1UykbP+XdUYrYooTWx2K4emyE1ke6spIfU7aVd5CAc= | ||||
| github.com/jesseduffield/gocui v0.3.1-0.20240824084618-5083ac1413f5/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= | ||||
|   | ||||
| @@ -212,3 +212,7 @@ func (self *BaseContext) NeedsRerenderOnHeightChange() bool { | ||||
| func (self *BaseContext) Title() string { | ||||
| 	return "" | ||||
| } | ||||
|  | ||||
| func (self *BaseContext) TotalContentHeight() int { | ||||
| 	return self.view.ViewLinesHeight() | ||||
| } | ||||
|   | ||||
| @@ -140,3 +140,11 @@ func (self *ListContextTrait) RangeSelectEnabled() bool { | ||||
| func (self *ListContextTrait) RenderOnlyVisibleLines() bool { | ||||
| 	return self.renderOnlyVisibleLines | ||||
| } | ||||
|  | ||||
| func (self *ListContextTrait) TotalContentHeight() int { | ||||
| 	result := self.list.Len() | ||||
| 	if self.getNonModelItems != nil { | ||||
| 		result += len(self.getNonModelItems()) | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|   | ||||
| @@ -73,6 +73,19 @@ func (gui *Gui) layout(g *gocui.Gui) error { | ||||
| 		} | ||||
|  | ||||
| 		mustRerender := false | ||||
| 		newHeight := dimensionsObj.Y1 - dimensionsObj.Y0 + 2*frameOffset | ||||
| 		maxOriginY := context.TotalContentHeight() | ||||
| 		if !view.CanScrollPastBottom { | ||||
| 			maxOriginY -= newHeight - 1 | ||||
| 		} | ||||
| 		if oldOriginY := view.OriginY(); oldOriginY > maxOriginY { | ||||
| 			view.ScrollUp(oldOriginY - maxOriginY) | ||||
| 			// the view might not have scrolled actually (if it was at the limit | ||||
| 			// already), so we need to check if it did | ||||
| 			if oldOriginY != view.OriginY() && context.NeedsRerenderOnHeightChange() { | ||||
| 				mustRerender = true | ||||
| 			} | ||||
| 		} | ||||
| 		if context.NeedsRerenderOnWidthChange() == types.NEEDS_RERENDER_ON_WIDTH_CHANGE_WHEN_WIDTH_CHANGES { | ||||
| 			// view.Width() returns the width -1 for some reason | ||||
| 			oldWidth := view.Width() + 1 | ||||
|   | ||||
| @@ -71,6 +71,9 @@ type IBaseContext interface { | ||||
| 	// determined independently. | ||||
| 	HasControlledBounds() bool | ||||
|  | ||||
| 	// the total height of the content that the view is currently showing | ||||
| 	TotalContentHeight() int | ||||
|  | ||||
| 	// to what extent the view needs to be rerendered when its width changes | ||||
| 	NeedsRerenderOnWidthChange() NeedsRerenderOnWidthChangeLevel | ||||
|  | ||||
|   | ||||
							
								
								
									
										61
									
								
								vendor/github.com/jesseduffield/gocui/view.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/jesseduffield/gocui/view.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1095,34 +1095,8 @@ func (v *View) draw() error { | ||||
| 		} | ||||
| 		v.ox = 0 | ||||
| 	} | ||||
| 	if v.tainted { | ||||
| 		lineIdx := 0 | ||||
| 		lines := v.lines | ||||
| 		if v.HasLoader { | ||||
| 			lines = v.loaderLines() | ||||
| 		} | ||||
| 		for i, line := range lines { | ||||
| 			wrap := 0 | ||||
| 			if v.Wrap { | ||||
| 				wrap = maxX | ||||
| 			} | ||||
|  | ||||
| 			ls := lineWrap(line, wrap) | ||||
| 			for j := range ls { | ||||
| 				vline := viewLine{linesX: j, linesY: i, line: ls[j]} | ||||
|  | ||||
| 				if lineIdx > len(v.viewLines)-1 { | ||||
| 					v.viewLines = append(v.viewLines, vline) | ||||
| 				} else { | ||||
| 					v.viewLines[lineIdx] = vline | ||||
| 				} | ||||
| 				lineIdx++ | ||||
| 			} | ||||
| 		} | ||||
| 		if !v.HasLoader { | ||||
| 			v.tainted = false | ||||
| 		} | ||||
| 	} | ||||
| 	v.refreshViewLinesIfNeeded() | ||||
|  | ||||
| 	visibleViewLinesHeight := v.viewLineLengthIgnoringTrailingBlankLines() | ||||
| 	if v.Autoscroll && visibleViewLinesHeight > maxY { | ||||
| @@ -1207,6 +1181,38 @@ func (v *View) draw() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (v *View) refreshViewLinesIfNeeded() { | ||||
| 	if v.tainted { | ||||
| 		maxX := v.Width() | ||||
| 		lineIdx := 0 | ||||
| 		lines := v.lines | ||||
| 		if v.HasLoader { | ||||
| 			lines = v.loaderLines() | ||||
| 		} | ||||
| 		for i, line := range lines { | ||||
| 			wrap := 0 | ||||
| 			if v.Wrap { | ||||
| 				wrap = maxX | ||||
| 			} | ||||
|  | ||||
| 			ls := lineWrap(line, wrap) | ||||
| 			for j := range ls { | ||||
| 				vline := viewLine{linesX: j, linesY: i, line: ls[j]} | ||||
|  | ||||
| 				if lineIdx > len(v.viewLines)-1 { | ||||
| 					v.viewLines = append(v.viewLines, vline) | ||||
| 				} else { | ||||
| 					v.viewLines[lineIdx] = vline | ||||
| 				} | ||||
| 				lineIdx++ | ||||
| 			} | ||||
| 		} | ||||
| 		if !v.HasLoader { | ||||
| 			v.tainted = false | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // if autoscroll is enabled but we only have a single row of cells shown to the | ||||
| // user, we don't want to scroll to the final line if it contains no text. So | ||||
| // this tells us the view lines height when we ignore any trailing blank lines | ||||
| @@ -1310,6 +1316,7 @@ func (v *View) LinesHeight() int { | ||||
|  | ||||
| // ViewLinesHeight is the count of view lines (i.e. lines including wrapping) | ||||
| func (v *View) ViewLinesHeight() int { | ||||
| 	v.refreshViewLinesIfNeeded() | ||||
| 	return len(v.viewLines) | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										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/internal/frame | ||||
| github.com/jesseduffield/go-git/v5/utils/merkletrie/noder | ||||
| # github.com/jesseduffield/gocui v0.3.1-0.20240824083442-15b7fbca7ae9 | ||||
| # github.com/jesseduffield/gocui v0.3.1-0.20240824084618-5083ac1413f5 | ||||
| ## explicit; go 1.12 | ||||
| github.com/jesseduffield/gocui | ||||
| # github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user