From 635acc7dc848853fe4a5db2f0c85dc52e8eabed0 Mon Sep 17 00:00:00 2001 From: Barrett Ruth <62671086+barrettruth@users.noreply.github.com> Date: Tue, 28 Jul 2026 13:59:18 -0500 Subject: [PATCH] fix(terminal): cursor moves on resize when line above is full width #40996 --- src/nvim/vterm/screen.c | 2 +- test/functional/terminal/window_spec.lua | 28 ++++++++++++++++++++++++ test/unit/vterm_spec.lua | 22 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/nvim/vterm/screen.c b/src/nvim/vterm/screen.c index 99c8e61748..4e8de11428 100644 --- a/src/nvim/vterm/screen.c +++ b/src/nvim/vterm/screen.c @@ -608,7 +608,7 @@ static void resize_buffer(VTermScreen *screen, int bufidx, int new_rows, int new count--; } - if (old_cursor.row == old_row && old_cursor.col >= old_col) { + if (old_row <= old_row_end && old_cursor.row == old_row && old_cursor.col >= old_col) { new_cursor.row = new_row, new_cursor.col = (old_cursor.col - old_col + new_col); if (new_cursor.col >= new_cols) { new_cursor.col = new_cols - 1; diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua index 978fd921ce..752def3c57 100644 --- a/test/functional/terminal/window_spec.lua +++ b/test/functional/terminal/window_spec.lua @@ -16,6 +16,7 @@ local eval = n.eval local skip = t.skip local is_os = t.is_os local testprg = n.testprg +local api = n.api describe(':terminal window', function() before_each(clear) @@ -36,6 +37,33 @@ describe(':terminal window', function() eq({ 1, 1, 1 }, eval('[&l:list, &list, &g:list]')) end) + it('keeps the cursor put on resize when the line above it is full width', function() + local screen = Screen.new(50, 7) + local buf = api.nvim_create_buf(true, true) + local chan = api.nvim_open_term(buf, {}) + api.nvim_win_set_buf(0, buf) + feed('i') + api.nvim_chan_send(chan, 'l1\r\nl2\r\nl3\r\nl4\r\n' .. ('A'):rep(50) .. '\r\nX') + screen:expect([[ + l1 | + l2 | + l3 | + l4 | + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| + X^ | + {5:-- TERMINAL --} | + ]]) + screen:try_resize(50, 6) + screen:expect([[ + l2 | + l3 | + l4 | + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| + X^ | + {5:-- TERMINAL --} | + ]]) + end) + it('resets horizontal scroll on resize #35331', function() skip(is_os('win'), 'Too flaky on Windows') local screen = tt.setup_screen(0, { testprg('shell-test'), 'INTERACT' }) diff --git a/test/unit/vterm_spec.lua b/test/unit/vterm_spec.lua index 27cf65c34c..da118d33b4 100644 --- a/test/unit/vterm_spec.lua +++ b/test/unit/vterm_spec.lua @@ -3800,6 +3800,28 @@ putglyph 1f3f4,200d,2620,fe0f 2 0,4]]) push('\x1b[2;1Habc\r\n\x1b[H', vt) resize(1, 1, vt) cursor(0, 0, state) + + reset(state, screen) + resize(4, 4, vt) + push('ABCD\r\nX', vt) + screen_row(0, 'ABCD', screen, vt.cols) + screen_row(1, 'X', screen, vt.cols) + cursor(1, 1, state) + resize(4, 5, vt) + screen_row(0, 'ABCD', screen, vt.cols) + screen_row(1, 'X', screen, vt.cols) + cursor(1, 1, state) + + reset(state, screen) + resize(4, 4, vt) + push('ABCD\r\nX', vt) + cursor(1, 1, state) + resize(3, 4, vt) + screen_row(0, 'ABCD', screen, vt.cols) + screen_row(1, 'X', screen, vt.cols) + cursor(1, 1, state) + + resize(5, 10, vt) end) pending('90vttest_01-movement-1', function() end)