mirror of
https://github.com/neovim/neovim.git
synced 2025-12-14 18:35:47 +00:00
fix(terminal): wrong row in TermRequest with full scrollback (#36298)
Problem: Wrong row in TermRequest with full scrollback.
Solution: Subtract by the number of lines deleted from scrollback.
(cherry picked from commit 67832710a5)
This commit is contained in:
committed by
github-actions[bot]
parent
e67fec1541
commit
169dc60a44
@@ -1028,7 +1028,8 @@ TermRequest When a |:terminal| child process emits an OSC,
|
|||||||
- sequence: the received sequence
|
- sequence: the received sequence
|
||||||
- cursor: (1,0)-indexed, buffer-relative
|
- cursor: (1,0)-indexed, buffer-relative
|
||||||
position of the cursor when the sequence was
|
position of the cursor when the sequence was
|
||||||
received
|
received (line number may be <= 0 if the
|
||||||
|
position is no longer in the buffer)
|
||||||
|
|
||||||
This is triggered even when inside an
|
This is triggered even when inside an
|
||||||
autocommand defined without |autocmd-nested|.
|
autocommand defined without |autocmd-nested|.
|
||||||
|
|||||||
@@ -566,7 +566,9 @@ do
|
|||||||
callback = function(args)
|
callback = function(args)
|
||||||
if string.match(args.data.sequence, '^\027]133;A') then
|
if string.match(args.data.sequence, '^\027]133;A') then
|
||||||
local lnum = args.data.cursor[1] ---@type integer
|
local lnum = args.data.cursor[1] ---@type integer
|
||||||
vim.api.nvim_buf_set_extmark(args.buf, nvim_terminal_prompt_ns, lnum - 1, 0, {})
|
if lnum >= 1 then
|
||||||
|
vim.api.nvim_buf_set_extmark(args.buf, nvim_terminal_prompt_ns, lnum - 1, 0, {})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ struct terminal {
|
|||||||
// it actually points to entries that are no longer in sb_buffer (because the
|
// it actually points to entries that are no longer in sb_buffer (because the
|
||||||
// window height has increased) and must be deleted from the terminal buffer
|
// window height has increased) and must be deleted from the terminal buffer
|
||||||
int sb_pending;
|
int sb_pending;
|
||||||
|
size_t sb_deleted; // Lines deleted from sb_buffer.
|
||||||
|
|
||||||
char *title; // VTermStringFragment buffer
|
char *title; // VTermStringFragment buffer
|
||||||
size_t title_len; // number of rows pushed to sb_buffer
|
size_t title_len; // number of rows pushed to sb_buffer
|
||||||
@@ -221,6 +222,7 @@ static void emit_termrequest(void **argv)
|
|||||||
StringBuilder *pending_send = argv[3];
|
StringBuilder *pending_send = argv[3];
|
||||||
int row = (int)(intptr_t)argv[4];
|
int row = (int)(intptr_t)argv[4];
|
||||||
int col = (int)(intptr_t)argv[5];
|
int col = (int)(intptr_t)argv[5];
|
||||||
|
size_t sb_deleted = (size_t)(intptr_t)argv[6];
|
||||||
|
|
||||||
if (term->sb_pending > 0) {
|
if (term->sb_pending > 0) {
|
||||||
// Don't emit the event while there is pending scrollback because we need
|
// Don't emit the event while there is pending scrollback because we need
|
||||||
@@ -228,14 +230,15 @@ static void emit_termrequest(void **argv)
|
|||||||
// the event onto the pending queue where it will be executed after the
|
// the event onto the pending queue where it will be executed after the
|
||||||
// terminal is refreshed and the pending scrollback is cleared.
|
// terminal is refreshed and the pending scrollback is cleared.
|
||||||
multiqueue_put(term->pending.events, emit_termrequest, term, sequence, (void *)sequence_length,
|
multiqueue_put(term->pending.events, emit_termrequest, term, sequence, (void *)sequence_length,
|
||||||
pending_send, (void *)(intptr_t)row, (void *)(intptr_t)col);
|
pending_send, (void *)(intptr_t)row, (void *)(intptr_t)col,
|
||||||
|
(void *)(intptr_t)sb_deleted);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_vim_var_string(VV_TERMREQUEST, sequence, (ptrdiff_t)sequence_length);
|
set_vim_var_string(VV_TERMREQUEST, sequence, (ptrdiff_t)sequence_length);
|
||||||
|
|
||||||
MAXSIZE_TEMP_ARRAY(cursor, 2);
|
MAXSIZE_TEMP_ARRAY(cursor, 2);
|
||||||
ADD_C(cursor, INTEGER_OBJ(row));
|
ADD_C(cursor, INTEGER_OBJ(row - (int64_t)(term->sb_deleted - sb_deleted)));
|
||||||
ADD_C(cursor, INTEGER_OBJ(col));
|
ADD_C(cursor, INTEGER_OBJ(col));
|
||||||
|
|
||||||
MAXSIZE_TEMP_DICT(data, 2);
|
MAXSIZE_TEMP_DICT(data, 2);
|
||||||
@@ -269,7 +272,8 @@ static void schedule_termrequest(Terminal *term)
|
|||||||
multiqueue_put(main_loop.events, emit_termrequest, term,
|
multiqueue_put(main_loop.events, emit_termrequest, term,
|
||||||
xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size),
|
xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size),
|
||||||
(void *)(intptr_t)term->termrequest_buffer.size, term->pending.send,
|
(void *)(intptr_t)term->termrequest_buffer.size, term->pending.send,
|
||||||
(void *)(intptr_t)line, (void *)(intptr_t)term->cursor.col);
|
(void *)(intptr_t)line, (void *)(intptr_t)term->cursor.col,
|
||||||
|
(void *)(intptr_t)term->sb_deleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_osc8(const char *str, int *attr)
|
static int parse_osc8(const char *str, int *attr)
|
||||||
@@ -1372,6 +1376,7 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
|
|||||||
} else {
|
} else {
|
||||||
xfree(term->sb_buffer[term->sb_current - 1]);
|
xfree(term->sb_buffer[term->sb_current - 1]);
|
||||||
}
|
}
|
||||||
|
term->sb_deleted++;
|
||||||
|
|
||||||
// Make room at the start by shifting to the right.
|
// Make room at the start by shifting to the right.
|
||||||
memmove(term->sb_buffer + 1, term->sb_buffer,
|
memmove(term->sb_buffer + 1, term->sb_buffer,
|
||||||
|
|||||||
@@ -473,6 +473,83 @@ describe(':terminal buffer', function()
|
|||||||
{5:-- TERMINAL --} |
|
{5:-- TERMINAL --} |
|
||||||
]])
|
]])
|
||||||
eq({ 22, 6 }, exec_lua('return _G.cursor'))
|
eq({ 22, 6 }, exec_lua('return _G.cursor'))
|
||||||
|
|
||||||
|
api.nvim_chan_send(term, '\nHello\027]133;D\027\\\nworld!\n')
|
||||||
|
screen:expect([[
|
||||||
|
> |*4
|
||||||
|
Hello |
|
||||||
|
world! |
|
||||||
|
Hello |
|
||||||
|
world! |
|
||||||
|
^ |
|
||||||
|
{5:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
eq({ 23, 5 }, exec_lua('return _G.cursor'))
|
||||||
|
|
||||||
|
api.nvim_chan_send(term, 'Hello\027]133;D\027\\\nworld!' .. ('\n'):rep(6))
|
||||||
|
screen:expect([[
|
||||||
|
world! |
|
||||||
|
Hello |
|
||||||
|
world! |
|
||||||
|
|*5
|
||||||
|
^ |
|
||||||
|
{5:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
eq({ 25, 5 }, exec_lua('return _G.cursor'))
|
||||||
|
|
||||||
|
api.nvim_set_option_value('scrollback', 10, {})
|
||||||
|
eq(19, api.nvim_buf_line_count(0))
|
||||||
|
|
||||||
|
api.nvim_chan_send(term, 'Hello\nworld!\027]133;D\027\\')
|
||||||
|
screen:expect([[
|
||||||
|
Hello |
|
||||||
|
world! |
|
||||||
|
|*5
|
||||||
|
Hello |
|
||||||
|
world!^ |
|
||||||
|
{5:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
eq({ 19, 6 }, exec_lua('return _G.cursor'))
|
||||||
|
|
||||||
|
api.nvim_chan_send(term, '\nHello\027]133;D\027\\\nworld!\n')
|
||||||
|
screen:expect([[
|
||||||
|
|*4
|
||||||
|
Hello |
|
||||||
|
world! |
|
||||||
|
Hello |
|
||||||
|
world! |
|
||||||
|
^ |
|
||||||
|
{5:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
eq({ 17, 5 }, exec_lua('return _G.cursor'))
|
||||||
|
|
||||||
|
api.nvim_chan_send(term, 'Hello\027]133;D\027\\\nworld!' .. ('\n'):rep(6))
|
||||||
|
screen:expect([[
|
||||||
|
world! |
|
||||||
|
Hello |
|
||||||
|
world! |
|
||||||
|
|*5
|
||||||
|
^ |
|
||||||
|
{5:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
eq({ 12, 5 }, exec_lua('return _G.cursor'))
|
||||||
|
|
||||||
|
api.nvim_chan_send(term, 'Hello\027]133;D\027\\\nworld!' .. ('\n'):rep(8))
|
||||||
|
screen:expect([[
|
||||||
|
world! |
|
||||||
|
|*7
|
||||||
|
^ |
|
||||||
|
{5:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
eq({ 10, 5 }, exec_lua('return _G.cursor'))
|
||||||
|
|
||||||
|
api.nvim_chan_send(term, 'Hello\027]133;D\027\\\nworld!' .. ('\n'):rep(20))
|
||||||
|
screen:expect([[
|
||||||
|
|*8
|
||||||
|
^ |
|
||||||
|
{5:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
eq({ -2, 5 }, exec_lua('return _G.cursor'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('does not cause hang in vim.wait() #32753', function()
|
it('does not cause hang in vim.wait() #32753', function()
|
||||||
|
|||||||
Reference in New Issue
Block a user