fix(terminal): keep last cursor if it's on the last row

This commit is contained in:
zeertzjq
2025-10-28 08:10:58 +08:00
parent 3fb56ff8af
commit 4ef7aa83c4
3 changed files with 180 additions and 81 deletions

View File

@@ -1246,7 +1246,8 @@ void mark_adjust_buf(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amount
ONE_ADJUST(&(buf->b_last_change.mark.lnum));
// last cursor position, if it was set
if (!equalpos(buf->b_last_cursor.mark, initpos)) {
if (!equalpos(buf->b_last_cursor.mark, initpos)
&& (!by_term || buf->b_last_cursor.mark.lnum < buf->b_ml.ml_line_count)) {
ONE_ADJUST(&(buf->b_last_cursor.mark.lnum));
}
@@ -1364,7 +1365,9 @@ void mark_adjust_buf(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amount
// adjust per-window "last cursor" positions
for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) {
WinInfo *wip = kv_A(buf->b_wininfo, i);
ONE_ADJUST_CURSOR(&(wip->wi_mark.mark));
if (!by_term || wip->wi_mark.mark.lnum < buf->b_ml.ml_line_count) {
ONE_ADJUST_CURSOR(&(wip->wi_mark.mark));
}
}
}

View File

@@ -773,7 +773,7 @@ bool terminal_enter(void)
set_terminal_winopts(s);
s->term->pending.cursor = true; // Update the cursor shape table
adjust_topline(s->term, buf, 0); // scroll to end
adjust_topline_cursor(s->term, buf, 0); // scroll to end
showmode();
ui_cursor_shape();
@@ -2108,7 +2108,7 @@ static void refresh_terminal(Terminal *term)
refresh_screen(term, buf);
int ml_added = buf->b_ml.ml_line_count - ml_before;
adjust_topline(term, buf, ml_added);
adjust_topline_cursor(term, buf, ml_added);
// Copy pending events back to the main event queue
multiqueue_move_events(main_loop.events, term->pending.events);
@@ -2324,8 +2324,10 @@ static void refresh_screen(Terminal *term, buf_T *buf)
term->invalid_end = -1;
}
static void adjust_topline(Terminal *term, buf_T *buf, int added)
static void adjust_topline_cursor(Terminal *term, buf_T *buf, int added)
{
linenr_T ml_end = buf->b_ml.ml_line_count;
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_buffer == buf) {
if (wp == curwin && is_focused(term)) {
@@ -2334,9 +2336,7 @@ static void adjust_topline(Terminal *term, buf_T *buf, int added)
continue;
}
linenr_T ml_end = buf->b_ml.ml_line_count;
bool following = ml_end == wp->w_cursor.lnum + added; // cursor at end?
if (following) {
// "Follow" the terminal output
wp->w_cursor.lnum = ml_end;
@@ -2348,6 +2348,17 @@ static void adjust_topline(Terminal *term, buf_T *buf, int added)
mb_check_adjust_col(wp);
}
}
if (ml_end == buf->b_last_cursor.mark.lnum + added) {
buf->b_last_cursor.mark.lnum = ml_end;
}
for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) {
WinInfo *wip = kv_A(buf->b_wininfo, i);
if (ml_end == wip->wi_mark.mark.lnum + added) {
wip->wi_mark.mark.lnum = ml_end;
}
}
}
static int row_to_linenr(Terminal *term, int row)