diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 4acc4f9fd4..41408ef36a 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -2397,19 +2397,18 @@ static void refresh_scrollback(Terminal *term, buf_T *buf) mark_adjust_buf(buf, 1, deleted, MAXLNUM, -deleted, true, kMarkAdjustTerm, kExtmarkUndo); term->old_sb_deleted = term->sb_deleted; + int old_height = term->old_height; int width, height; vterm_get_size(term->vt, &height, &width); - int max_line_count = (int)term->sb_current - term->sb_pending + height; - // Remove extra lines at the top if scrollback lines have been deleted. - while (deleted > 0 && buf->b_ml.ml_line_count > max_line_count) { + // Remove deleted scrollback lines at the top, but don't unnecessarily remove + // lines that will be overwritten by refresh_screen(). + while (deleted > 0 && buf->b_ml.ml_line_count > old_height) { ml_delete_buf(buf, 1, false); deleted_lines_buf(buf, 1, 1); deleted--; } - max_line_count += term->sb_pending; - int old_height = MIN(term->old_height, buf->b_ml.ml_line_count); while (term->sb_pending > 0) { // This means that either the window height has decreased or the screen // became full and libvterm had to push all rows up. Convert the first @@ -2422,6 +2421,7 @@ static void refresh_scrollback(Terminal *term, buf_T *buf) term->sb_pending--; } + int max_line_count = (int)term->sb_current + height; // Remove extra lines at the bottom. while (buf->b_ml.ml_line_count > max_line_count) { ml_delete_buf(buf, buf->b_ml.ml_line_count, false); diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua index 198e75adf6..31d2a3ee30 100644 --- a/test/functional/terminal/scrollback_spec.lua +++ b/test/functional/terminal/scrollback_spec.lua @@ -1263,6 +1263,25 @@ describe('scrollback is correct', function() check_buffer_lines(0, 99) end) end + + describe('with full scrollback,', function() + before_each(function() + api.nvim_set_option_value('scrollback', 6, { buf = buf }) + check_buffer_lines(82, 94) + end) + + it('output first', function() + command(send_cmd .. ' | resize +2') + screen:expect(screen_final) + check_buffer_lines(87, 99) + end) + + it('resize first', function() + command('resize +2 | ' .. send_cmd) + screen:expect(screen_final) + check_buffer_lines(85, 99) + end) + end) end) describe('decreases in the same refresh cycle as outputting lines', function()