fix(terminal): adjust marks when deleting scrollback lines (#36294)

This also fixes inconsistent scrolling behavior on terminal output when
cursor is in the middle of the buffer and the scrollback is full.
This commit is contained in:
zeertzjq
2025-10-25 06:48:04 +08:00
parent 0e1c83fae2
commit d78d5cf1aa
7 changed files with 260 additions and 34 deletions

View File

@@ -73,6 +73,7 @@
#include "nvim/macros_defs.h"
#include "nvim/main.h"
#include "nvim/map_defs.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
@@ -150,10 +151,11 @@ struct terminal {
// window height has increased) and must be deleted from the terminal buffer
int sb_pending;
size_t sb_deleted; // Lines deleted from sb_buffer.
size_t sb_deleted_last; // Value of sb_deleted on last refresh_scrollback()
char *title; // VTermStringFragment buffer
size_t title_len; // number of rows pushed to sb_buffer
size_t title_size; // sb_buffer size
size_t title_len;
size_t title_size;
// buf_T instance that acts as a "drawing surface" for libvterm
// we can't store a direct reference to the buffer because the
@@ -2141,6 +2143,8 @@ static void adjust_scrollback(Terminal *term, buf_T *buf)
term->sb_current--;
xfree(term->sb_buffer[term->sb_current]);
}
mark_adjust_buf(buf, 1, (linenr_T)diff, MAXLNUM, -(linenr_T)diff, true,
kMarkAdjustTerm, kExtmarkUndo);
deleted_lines_buf(buf, 1, (linenr_T)diff);
}
@@ -2156,6 +2160,11 @@ static void adjust_scrollback(Terminal *term, buf_T *buf)
// Refresh the scrollback of an invalidated terminal.
static void refresh_scrollback(Terminal *term, buf_T *buf)
{
linenr_T deleted = (linenr_T)(term->sb_deleted - term->sb_deleted_last);
deleted = MIN(deleted, buf->b_ml.ml_line_count);
mark_adjust_buf(buf, 1, deleted, MAXLNUM, -deleted, true, kMarkAdjustTerm, kExtmarkUndo);
term->sb_deleted_last = term->sb_deleted;
int width, height;
vterm_get_size(term->vt, &height, &width);