mirror of
https://github.com/neovim/neovim.git
synced 2026-02-10 13:58:48 +00:00
fix(terminal): wrong scrollback with nvim_open_term() on buffer (#37791)
Problem: Wrong scrollback when passing a buffer with many lines to
nvim_open_term().
Solution: Delete all buffer lines before opening the terminal.
I tried to use buf_clear(), but it crashes inside deleted_lines_mark(),
so I'll just use deleted_lines_buf() for now. The behavior of marks can
be decided later.
This commit is contained in:
@@ -544,8 +544,8 @@ Terminal *terminal_alloc(buf_T *buf, TerminalOptions opts)
|
||||
}
|
||||
vterm_state_set_termprop(state, VTERM_PROP_CURSORBLINK, &cursor_blink);
|
||||
|
||||
// force a initial refresh of the screen to ensure the buffer will always
|
||||
// have as many lines as screen rows when refresh_scrollback is called
|
||||
// Force a initial refresh of the screen to ensure the buffer will always
|
||||
// have as many lines as screen rows when refresh_scrollback() is called.
|
||||
term->invalid_start = 0;
|
||||
term->invalid_end = opts.height;
|
||||
|
||||
@@ -556,6 +556,12 @@ Terminal *terminal_alloc(buf_T *buf, TerminalOptions opts)
|
||||
// events from this queue are copied back onto the main event queue.
|
||||
term->pending.events = multiqueue_new(NULL, NULL);
|
||||
|
||||
linenr_T line_count = buf->b_ml.ml_line_count;
|
||||
while (!(buf->b_ml.ml_flags & ML_EMPTY)) {
|
||||
ml_delete_buf(buf, 1, false);
|
||||
}
|
||||
deleted_lines_buf(buf, 1, line_count);
|
||||
|
||||
return term;
|
||||
}
|
||||
|
||||
|
||||
@@ -1102,3 +1102,96 @@ describe('pending scrollback line handling', function()
|
||||
assert_alive()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_open_term()', function()
|
||||
local screen --- @type test.functional.ui.screen
|
||||
local buf --- @type integer
|
||||
local win --- @type integer
|
||||
|
||||
before_each(function()
|
||||
clear()
|
||||
screen = Screen.new(30, 7)
|
||||
screen:add_extra_attr_ids({
|
||||
[100] = { foreground = tonumber('0xe00000'), fg_indexed = true },
|
||||
[101] = { foreground = Screen.colors.White, background = Screen.colors.DarkGreen },
|
||||
[102] = {
|
||||
bold = true,
|
||||
foreground = Screen.colors.White,
|
||||
background = Screen.colors.DarkGreen,
|
||||
},
|
||||
})
|
||||
api.nvim_buf_set_lines(0, 0, -1, true, { '\027[31mTEST\027[0m 0' })
|
||||
feed('yy99pG$<C-V>98kg<C-A>')
|
||||
screen:expect([[
|
||||
{18:^[}[31mTEST{18:^[}[0m 0 |
|
||||
{18:^[}[31mTEST{18:^[}[0m ^1 |
|
||||
{18:^[}[31mTEST{18:^[}[0m 2 |
|
||||
{18:^[}[31mTEST{18:^[}[0m 3 |
|
||||
{18:^[}[31mTEST{18:^[}[0m 4 |
|
||||
{18:^[}[31mTEST{18:^[}[0m 5 |
|
||||
99 lines changed |
|
||||
]])
|
||||
buf = api.nvim_get_current_buf()
|
||||
win = api.nvim_get_current_win()
|
||||
command('set winwidth=10 | 10vnew')
|
||||
end)
|
||||
|
||||
local function check_buffer_lines(start, stop)
|
||||
local lines = api.nvim_buf_get_lines(buf, 0, -1, true)
|
||||
for i = start, stop do
|
||||
eq(('TEST %d'):format(i), lines[i - start + 1])
|
||||
end
|
||||
end
|
||||
|
||||
local function check_common()
|
||||
feed('<C-W>lG')
|
||||
screen:expect([[
|
||||
│{100:TEST} 96 |
|
||||
{1:~ }│{100:TEST} 97 |
|
||||
{1:~ }│{100:TEST} 98 |
|
||||
{1:~ }│{100:TEST} 99 |
|
||||
{1:~ }│^ |
|
||||
{2:[No Name] }{102:[Scratch] [-] }|
|
||||
99 lines changed |
|
||||
]])
|
||||
end
|
||||
|
||||
it('on buffer with fewer lines than scrollback', function()
|
||||
exec_lua(function()
|
||||
vim.api.nvim_open_term(buf, {})
|
||||
vim.api.nvim_win_set_cursor(win, { 3, 0 })
|
||||
end)
|
||||
screen:expect([[
|
||||
^ │{100:TEST} 0 |
|
||||
{1:~ }│{100:TEST} 1 |
|
||||
{1:~ }│{100:TEST} 2 |
|
||||
{1:~ }│{100:TEST} 3 |
|
||||
{1:~ }│{100:TEST} 4 |
|
||||
{3:[No Name] }{101:[Scratch] [-] }|
|
||||
99 lines changed |
|
||||
]])
|
||||
eq({ 3, 0 }, api.nvim_win_get_cursor(win))
|
||||
check_buffer_lines(0, 99)
|
||||
check_common()
|
||||
end)
|
||||
|
||||
it('on buffer with more lines than scrollback', function()
|
||||
api.nvim_set_option_value('scrollback', 10, { buf = buf })
|
||||
exec_lua(function()
|
||||
vim.api.nvim_open_term(buf, {})
|
||||
vim.api.nvim_win_set_cursor(win, { 3, 3 })
|
||||
end)
|
||||
screen:expect([[
|
||||
^ │{100:TEST} 86 |
|
||||
{1:~ }│{100:TEST} 87 |
|
||||
{1:~ }│{100:TEST} 88 |
|
||||
{1:~ }│{100:TEST} 89 |
|
||||
{1:~ }│{100:TEST} 90 |
|
||||
{3:[No Name] }{101:[Scratch] [-] }|
|
||||
99 lines changed |
|
||||
]])
|
||||
eq({ 1, 0 }, api.nvim_win_get_cursor(win))
|
||||
check_buffer_lines(86, 99)
|
||||
check_common()
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user