diff --git a/pkg/gocui/view.go b/pkg/gocui/view.go index d2dd9384c..d8223e5c1 100644 --- a/pkg/gocui/view.go +++ b/pkg/gocui/view.go @@ -2095,6 +2095,16 @@ func (v *View) SelectedLineIdx() int { return seletedLineIdx } +// MiddleVisibleLineIdx returns the index of the view line at the middle of the +// content currently on screen. When the content is taller than the viewport this is +// the middle row of the viewport; when it's shorter, it's the middle of the content, +// so the result lands within the content rather than in the empty space below it. +func (v *View) MiddleVisibleLineIdx() int { + top := v.OriginY() + bottom := min(top+v.InnerHeight(), v.ViewLinesHeight()) + return (top + bottom) / 2 +} + // expected to only be used in tests func (v *View) SelectedLine() string { v.writeMutex.Lock() diff --git a/pkg/gui/controllers/main_view_controller.go b/pkg/gui/controllers/main_view_controller.go index 35de0db52..8b1205749 100644 --- a/pkg/gui/controllers/main_view_controller.go +++ b/pkg/gui/controllers/main_view_controller.go @@ -203,8 +203,8 @@ func (self *MainViewController) toggleSelection() error { v.Highlight = false return nil } - // Start the selection in the middle of the visible area. - showSelectionAtLine(v, v.OriginY()+v.InnerHeight()/2, false) + // Start the selection in the middle of the visible content. + showSelectionAtLine(v, v.MiddleVisibleLineIdx(), false) return nil }