@@ -60,6 +60,88 @@ describe('swap_buf', function()
6060 ss .swap_buf_right ({ move_cursor = false })
6161 assert .equals (wins [1 ], helpers .curwin ())
6262 end )
63+
64+ it (' preserves scroll position when move_cursor is true' , function ()
65+ ss .setup ({ swap = { move_cursor = true } })
66+ local wins = helpers .create_vsplits (2 )
67+ helpers .unique_buffers (wins )
68+
69+ -- Fill buffers with enough lines to scroll
70+ local lines = {}
71+ for i = 1 , 100 do
72+ table.insert (lines , ' Line ' .. i )
73+ end
74+ vim .api .nvim_buf_set_lines (vim .api .nvim_win_get_buf (wins [1 ]), 0 , - 1 , false , lines )
75+ vim .api .nvim_buf_set_lines (vim .api .nvim_win_get_buf (wins [2 ]), 0 , - 1 , false , lines )
76+
77+ -- Scroll each window to different positions
78+ helpers .focus (wins [1 ])
79+ vim .api .nvim_win_set_cursor (wins [1 ], { 50 , 0 })
80+ vim .cmd (' normal! zz' )
81+ local view_1_before = vim .fn .winsaveview ()
82+
83+ helpers .focus (wins [2 ])
84+ vim .api .nvim_win_set_cursor (wins [2 ], { 75 , 0 })
85+ vim .cmd (' normal! zz' )
86+ local view_2_before = vim .fn .winsaveview ()
87+
88+ -- Swap with move_cursor
89+ helpers .focus (wins [1 ])
90+ ss .swap_buf_right ()
91+
92+ -- Cursor should be in win_2 (following buf_1)
93+ assert .equals (wins [2 ], helpers .curwin ())
94+
95+ -- Scroll position should be preserved
96+ local view_1_after = vim .fn .winsaveview ()
97+ assert .equals (view_1_before .topline , view_1_after .topline )
98+ assert .equals (view_1_before .lnum , view_1_after .lnum )
99+
100+ -- Check win_1 as well
101+ helpers .focus (wins [1 ])
102+ local view_2_after = vim .fn .winsaveview ()
103+ assert .equals (view_2_before .topline , view_2_after .topline )
104+ assert .equals (view_2_before .lnum , view_2_after .lnum )
105+ end )
106+
107+ it (' preserves scroll position when move_cursor is false' , function ()
108+ -- default: move_cursor = false
109+ local wins = helpers .create_vsplits (2 )
110+ helpers .unique_buffers (wins )
111+
112+ local lines = {}
113+ for i = 1 , 100 do
114+ table.insert (lines , ' Line ' .. i )
115+ end
116+ vim .api .nvim_buf_set_lines (vim .api .nvim_win_get_buf (wins [1 ]), 0 , - 1 , false , lines )
117+ vim .api .nvim_buf_set_lines (vim .api .nvim_win_get_buf (wins [2 ]), 0 , - 1 , false , lines )
118+
119+ helpers .focus (wins [1 ])
120+ vim .api .nvim_win_set_cursor (wins [1 ], { 50 , 0 })
121+ vim .cmd (' normal! zz' )
122+ local view_1_before = vim .fn .winsaveview ()
123+
124+ helpers .focus (wins [2 ])
125+ vim .api .nvim_win_set_cursor (wins [2 ], { 75 , 0 })
126+ vim .cmd (' normal! zz' )
127+ local view_2_before = vim .fn .winsaveview ()
128+
129+ -- Swap without move_cursor (default)
130+ helpers .focus (wins [1 ])
131+ ss .swap_buf_right ()
132+
133+ -- Cursor should stay in win_1
134+ assert .equals (wins [1 ], helpers .curwin ())
135+
136+ -- win_1 now has buf_2, so it should have view_2's scroll position
137+ local view_1_after = vim .fn .winsaveview ()
138+ assert .equals (view_2_before .topline , view_1_after .topline )
139+
140+ -- win_2 now has buf_1, so it should have view_1's scroll position
141+ helpers .focus (wins [2 ])
142+ local view_2_after = vim .fn .winsaveview ()
143+ assert .equals (view_1_before .topline , view_2_after .topline )
144+ end )
63145 end )
64146
65147 describe (' vertical swaps' , function ()
0 commit comments