commit b614c1539265887a6c7a059416504e9c6b145935
parent ead2b4f76999234fbe6280cfa92e78507f604e01
Author: zeertzjq <zeertzjq@outlook.com>
Date: Sun, 15 Feb 2026 17:25:22 +0800
refactor(terminal): don't put cursor at bottom-left in Normal mode (#37873)
When the terminal process is suspended, putting cursor at bottom-left
hints that pressing a key will change the suspended state. However, when
returning to Normal mode, the user is more likely to interact with the
actual terminal output (e.g. copying it), so it's better to put cursor
at the old position which should be closer to the output.
Also, using is_focused() to check for mode is confusing. Just check
`State & MODE_TERMINAL` instead.
Diffstat:
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
@@ -978,12 +978,13 @@ static void terminal_check_cursor(void)
if (topline != curwin->w_topline) {
set_topline(curwin, topline);
}
- if (term->suspended) {
- // If the terminal process is suspended, keep cursor at the bottom-left corner.
+ if (term->suspended && (State & MODE_TERMINAL)) {
+ // Put cursor at the "[Process suspended]" text to hint that pressing a key will
+ // change the suspended state.
curwin->w_cursor = (pos_T){ .lnum = curbuf->b_ml.ml_line_count };
} else {
// Nudge cursor when returning to normal-mode.
- int off = is_focused(term) ? 0 : (curwin->w_p_rl ? 1 : -1);
+ int off = (State & MODE_TERMINAL) ? 0 : (curwin->w_p_rl ? 1 : -1);
coladvance(curwin, MAX(0, term->cursor.col + off));
}
}
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
@@ -519,12 +519,27 @@ describe(':terminal buffer', function()
command('set mousemodel=extend')
local pid = eval('jobpid(&channel)')
vim.uv.kill(pid, 'sigstop')
- screen:expect([[
+ -- In Terminal mode the cursor is at the "[Process suspended]" text to hint that
+ -- pressing a key will change the suspended state.
+ local s0 = [[
tty ready |
|*4
^[Process suspended] |
{5:-- TERMINAL --} |
+ ]]
+ screen:expect(s0)
+ feed([[<C-\><C-N>]])
+ -- Returning to Normal mode puts the cursor at its previous position as that's
+ -- closer to the terminal output, making it easier for the user to copy.
+ screen:expect([[
+ tty ready |
+ ^ |
+ |*3
+ [Process suspended] |
+ |
]])
+ feed('i')
+ screen:expect(s0)
command('set laststatus=0 | botright vsplit')
screen:expect([[
tty ready │tty ready |