@@ -72,6 +72,7 @@ type selectionState struct {
7272 endLine int
7373 endCol int
7474 mouseButtonDown bool
75+ mouseY int // Screen Y coordinate for autoscroll
7576}
7677
7778// start initializes a new selection at the given position
@@ -156,13 +157,15 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
156157 if msg .Button == tea .MouseLeft {
157158 line , col := m .mouseToLineCol (msg .X , msg .Y )
158159 m .selection .start (line , col )
160+ m .selection .mouseY = msg .Y // Store screen Y for autoscroll
159161 }
160162 return m , nil
161163
162164 case tea.MouseMotionMsg :
163165 if m .selection .mouseButtonDown && m .selection .active {
164166 line , col := m .mouseToLineCol (msg .X , msg .Y )
165167 m .selection .update (line , col )
168+ m .selection .mouseY = msg .Y // Store screen Y for autoscroll
166169
167170 cmd := m .autoScroll ()
168171 return m , cmd
@@ -1009,23 +1012,31 @@ func (m *model) autoScroll() tea.Cmd {
10091012 const scrollThreshold = 2
10101013 direction := 0
10111014
1012- if m .selection .endCol < scrollThreshold && m .scrollOffset > 0 {
1013- // Scroll up
1015+ // Use stored screen Y coordinate to check if mouse is in autoscroll region
1016+ // mouseToLineCol subtracts 2 for header, so viewport-relative Y is mouseY - 2
1017+ viewportY := m .selection .mouseY - 2
1018+
1019+ // Ensure viewportY is valid (can't be negative or beyond viewport)
1020+ if viewportY < 0 {
1021+ viewportY = 0
1022+ }
1023+
1024+ if viewportY < scrollThreshold && m .scrollOffset > 0 {
1025+ // Scroll up - mouse is near top of viewport
10141026 direction = - 1
10151027 m .scrollUp ()
1016- if m . selection . endLine > 0 {
1017- m . selection . endLine --
1018- }
1019- } else if m . selection . endCol >= m .height - scrollThreshold {
1020- // Scroll down
1028+ // Update endLine to reflect new scroll position
1029+ // When scrolling up, content moves up, so mouse points to a line that's 1 less in absolute terms
1030+ m . selection . endLine = max ( 0 , m . selection . endLine - 1 )
1031+ } else if viewportY >= m .height - scrollThreshold && viewportY < m . height {
1032+ // Scroll down - mouse is near bottom of viewport
10211033 maxScrollOffset := max (0 , m .totalHeight - m .height )
10221034 if m .scrollOffset < maxScrollOffset {
10231035 direction = 1
10241036 m .scrollDown ()
1025- lines := strings .Split (m .rendered , "\n " )
1026- if m .selection .endLine < len (lines )- 1 {
1027- m .selection .endLine ++
1028- }
1037+ // Update endLine to reflect new scroll position
1038+ // When scrolling down, content moves down, so mouse points to a line that's 1 more in absolute terms
1039+ m .selection .endLine ++
10291040 }
10301041 }
10311042
0 commit comments