From 4c6af62424b059df749e8babd67545a01a05d173 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 16 Jun 2026 16:53:54 +0200 Subject: [PATCH] Select the line in the middle of the content, not the viewport Pressing space in the focused main view starts the selection at the middle row of the viewport. When the diff is shorter than the viewport that row is empty space below the content, so the selection clamps onto the last line instead of landing somewhere useful. Anchor on the middle of the visible content instead; once the content fills the view this is the same row as before. Co-Authored-By: Claude Opus 4.8 (1M context) --- pkg/gocui/view.go | 10 ++++++++++ pkg/gui/controllers/main_view_controller.go | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) 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 }