@@ -239,3 +239,103 @@ describe('renderer.scroll_to_bottom', function()
239239 config .values .ui .output .always_scroll_to_bottom = false
240240 end )
241241end )
242+
243+ describe (' renderer._add_message_to_buffer scrolling' , function ()
244+ local renderer = require (' opencode.ui.renderer' )
245+ local formatter = require (' opencode.ui.formatter' )
246+ local stub = require (' luassert.stub' )
247+ local buf , win
248+
249+ before_each (function ()
250+ config .setup ({})
251+ buf = vim .api .nvim_create_buf (false , true )
252+ vim .api .nvim_buf_set_lines (buf , 0 , - 1 , false , { ' existing line' })
253+
254+ win = vim .api .nvim_open_win (buf , true , {
255+ relative = ' editor' , width = 80 , height = 10 , row = 0 , col = 0 ,
256+ })
257+
258+ state .windows = { output_win = win , output_buf = buf }
259+ state .active_session = { id = ' test-session' }
260+ state .messages = {}
261+ renderer ._prev_line_count = 1
262+ renderer ._render_state :reset ()
263+ end )
264+
265+ after_each (function ()
266+ pcall (vim .api .nvim_win_close , win , true )
267+ pcall (vim .api .nvim_buf_delete , buf , { force = true })
268+ state .windows = nil
269+ state .active_session = nil
270+ state .messages = nil
271+ renderer ._prev_line_count = 0
272+ renderer ._render_state :reset ()
273+ end )
274+
275+ it (' scrolls to bottom when user message is added' , function ()
276+ vim .api .nvim_win_set_cursor (win , { 1 , 0 })
277+
278+ local user_message = {
279+ info = {
280+ id = ' msg-1' ,
281+ sessionID = ' test-session' ,
282+ role = ' user' ,
283+ },
284+ parts = {},
285+ }
286+
287+ local scroll_called_with_force = false
288+ stub (renderer , ' scroll_to_bottom' ).invokes (function (force )
289+ scroll_called_with_force = force == true
290+ end )
291+
292+ renderer ._add_message_to_buffer (user_message )
293+
294+ assert .is_true (scroll_called_with_force )
295+ assert .stub (renderer .scroll_to_bottom ).was_called_with (true )
296+
297+ renderer .scroll_to_bottom :revert ()
298+ end )
299+
300+ it (' does not scroll when assistant message is added' , function ()
301+ vim .api .nvim_win_set_cursor (win , { 1 , 0 })
302+
303+ local assistant_message = {
304+ info = {
305+ id = ' msg-2' ,
306+ sessionID = ' test-session' ,
307+ role = ' assistant' ,
308+ },
309+ parts = {},
310+ }
311+
312+ stub (renderer , ' scroll_to_bottom' )
313+
314+ renderer ._add_message_to_buffer (assistant_message )
315+
316+ assert .stub (renderer .scroll_to_bottom ).was_not_called ()
317+
318+ renderer .scroll_to_bottom :revert ()
319+ end )
320+
321+ it (' does not scroll when system message is added' , function ()
322+ vim .api .nvim_win_set_cursor (win , { 1 , 0 })
323+
324+ local system_message = {
325+ info = {
326+ id = ' msg-3' ,
327+ sessionID = ' test-session' ,
328+ role = ' system' ,
329+ },
330+ parts = {},
331+ }
332+
333+ stub (renderer , ' scroll_to_bottom' )
334+
335+ renderer ._add_message_to_buffer (system_message )
336+
337+ assert .stub (renderer .scroll_to_bottom ).was_not_called ()
338+
339+ renderer .scroll_to_bottom :revert ()
340+ end )
341+ end )
0 commit comments