mirror of
https://github.com/neovim/neovim.git
synced 2026-04-21 06:45:37 +00:00
fix(terminal): restore options properly when switching buffer (#37485)
This commit is contained in:
@@ -737,29 +737,50 @@ static void unset_terminal_winopts(TerminalState *const s)
|
|||||||
|
|
||||||
win_T *const wp = handle_get_window(s->save_curwin_handle);
|
win_T *const wp = handle_get_window(s->save_curwin_handle);
|
||||||
if (!wp) {
|
if (!wp) {
|
||||||
free_string_option(s->save_w_p_culopt);
|
goto end;
|
||||||
s->save_curwin_handle = 0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (win_valid(wp)) { // No need to redraw if window not in curtab.
|
winopt_T *winopts = NULL;
|
||||||
if (s->save_w_p_cuc != wp->w_p_cuc) {
|
if (wp->w_buffer->handle != s->term->buf_handle) { // Buffer no longer in "wp".
|
||||||
redraw_later(wp, UPD_SOME_VALID);
|
buf_T *buf = handle_get_buffer(s->term->buf_handle);
|
||||||
} else if (s->save_w_p_cul != wp->w_p_cul
|
if (buf == NULL) {
|
||||||
|| (s->save_w_p_cul && s->save_w_p_culopt_flags != wp->w_p_culopt_flags)) {
|
goto end; // Nothing to restore as the buffer was deleted.
|
||||||
redraw_later(wp, UPD_VALID);
|
|
||||||
}
|
}
|
||||||
|
for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) {
|
||||||
|
WinInfo *wip = kv_A(buf->b_wininfo, i);
|
||||||
|
if (wip->wi_win == wp && wip->wi_optset) {
|
||||||
|
winopts = &wip->wi_opt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (winopts == NULL) {
|
||||||
|
goto end; // Nothing to restore as there is no matching WinInfo.
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
winopts = &wp->w_onebuf_opt;
|
||||||
|
if (win_valid(wp)) { // No need to redraw if window not in curtab.
|
||||||
|
if (s->save_w_p_cuc != wp->w_p_cuc) {
|
||||||
|
redraw_later(wp, UPD_SOME_VALID);
|
||||||
|
} else if (s->save_w_p_cul != wp->w_p_cul
|
||||||
|
|| (s->save_w_p_cul && s->save_w_p_culopt_flags != wp->w_p_culopt_flags)) {
|
||||||
|
redraw_later(wp, UPD_VALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wp->w_p_culopt_flags = s->save_w_p_culopt_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
wp->w_p_cul = s->save_w_p_cul;
|
|
||||||
if (s->save_w_p_culopt) {
|
if (s->save_w_p_culopt) {
|
||||||
free_string_option(wp->w_p_culopt);
|
free_string_option(winopts->wo_culopt);
|
||||||
wp->w_p_culopt = s->save_w_p_culopt;
|
winopts->wo_culopt = s->save_w_p_culopt;
|
||||||
|
s->save_w_p_culopt = NULL;
|
||||||
}
|
}
|
||||||
wp->w_p_culopt_flags = s->save_w_p_culopt_flags;
|
winopts->wo_cul = s->save_w_p_cul;
|
||||||
wp->w_p_cuc = s->save_w_p_cuc;
|
winopts->wo_cuc = s->save_w_p_cuc;
|
||||||
wp->w_p_so = s->save_w_p_so;
|
winopts->wo_so = s->save_w_p_so;
|
||||||
wp->w_p_siso = s->save_w_p_siso;
|
winopts->wo_siso = s->save_w_p_siso;
|
||||||
|
|
||||||
|
end:
|
||||||
|
free_string_option(s->save_w_p_culopt);
|
||||||
s->save_curwin_handle = 0;
|
s->save_curwin_handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,21 +33,35 @@ describe(':terminal buffer', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it('terminal-mode forces various options', function()
|
it('terminal-mode forces various options', function()
|
||||||
|
local expr =
|
||||||
|
'[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]'
|
||||||
|
|
||||||
feed([[<C-\><C-N>]])
|
feed([[<C-\><C-N>]])
|
||||||
command('setlocal cursorline cursorlineopt=both cursorcolumn scrolloff=4 sidescrolloff=7')
|
command('setlocal cursorline cursorlineopt=both cursorcolumn scrolloff=4 sidescrolloff=7')
|
||||||
eq(
|
eq({ 'both', 1, 1, 4, 7 }, eval(expr))
|
||||||
{ 'both', 1, 1, 4, 7 },
|
|
||||||
eval('[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]')
|
|
||||||
)
|
|
||||||
eq('nt', eval('mode(1)'))
|
eq('nt', eval('mode(1)'))
|
||||||
|
|
||||||
-- Enter terminal-mode ("insert" mode in :terminal).
|
-- Enter Terminal mode ("insert" mode in :terminal).
|
||||||
feed('i')
|
feed('i')
|
||||||
eq('t', eval('mode(1)'))
|
eq('t', eval('mode(1)'))
|
||||||
eq(
|
eq({ 'number', 1, 0, 0, 0 }, eval(expr))
|
||||||
{ 'number', 1, 0, 0, 0 },
|
|
||||||
eval('[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]')
|
-- Return to Normal mode.
|
||||||
)
|
feed([[<C-\><C-N>]])
|
||||||
|
eq('nt', eval('mode(1)'))
|
||||||
|
eq({ 'both', 1, 1, 4, 7 }, eval(expr))
|
||||||
|
|
||||||
|
-- Enter Terminal mode again.
|
||||||
|
feed('i')
|
||||||
|
eq('t', eval('mode(1)'))
|
||||||
|
eq({ 'number', 1, 0, 0, 0 }, eval(expr))
|
||||||
|
|
||||||
|
-- Delete the terminal buffer and return to the previous buffer.
|
||||||
|
command('bwipe!')
|
||||||
|
feed('<Ignore>') -- Add input to separate two RPC requests
|
||||||
|
eq('n', eval('mode(1)'))
|
||||||
|
-- Window options in the old buffer should be unchanged. #37484
|
||||||
|
eq({ 'both', 0, 0, -1, -1 }, eval(expr))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('terminal-mode does not change cursorlineopt if cursorline is disabled', function()
|
it('terminal-mode does not change cursorlineopt if cursorline is disabled', function()
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ describe(':terminal window', function()
|
|||||||
file foo
|
file foo
|
||||||
setlocal cursorline
|
setlocal cursorline
|
||||||
vsplit
|
vsplit
|
||||||
setlocal nocursorline cursorcolumn
|
setlocal nocursorline cursorcolumn cursorlineopt=number
|
||||||
]])
|
]])
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{19:t}ty ready │tty ready |
|
{19:t}ty ready │tty ready |
|
||||||
@@ -580,6 +580,49 @@ describe(':terminal window', function()
|
|||||||
{7:[No Name] }{18:foo [-] }|
|
{7:[No Name] }{18:foo [-] }|
|
||||||
|
|
|
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
command('wincmd l | enew | setlocal cursorline nocursorcolumn')
|
||||||
|
screen:expect([[
|
||||||
|
{1: }{5:2}{1: [No Name] }{2: foo }{4: }{2:X}|
|
||||||
|
│{12:^ }|
|
||||||
|
{6:~ }│{6:~ }|*3
|
||||||
|
{4:[No Name] }{7:[No Name] }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
command('buffer # | startinsert')
|
||||||
|
screen:expect([[
|
||||||
|
{1: }{5:2}{1: foo }{2: foo }{4: }{2:X}|
|
||||||
|
│rows: 5, cols: 25 |
|
||||||
|
{6:~ }│rows: 5, cols: 50 |
|
||||||
|
{6:~ }│^ |
|
||||||
|
{6:~ }│ |
|
||||||
|
{4:[No Name] }{17:foo [-] }|
|
||||||
|
{1:-- TERMINAL --} |
|
||||||
|
]])
|
||||||
|
-- Switching to another buffer shouldn't change window options there. #37484
|
||||||
|
command('buffer # | call setline(1, ["aaa", "bbb", "ccc"]) | normal! jl')
|
||||||
|
screen:expect([[
|
||||||
|
{1: }{5:2}{1:+ [No Name] }{2: foo }{4: }{2:X}|
|
||||||
|
│aaa |
|
||||||
|
{6:~ }│{12:b^bb }|
|
||||||
|
{6:~ }│ccc |
|
||||||
|
{6:~ }│{6:~ }|
|
||||||
|
{4:[No Name] }{7:[No Name] [+] }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
-- Window options are restored when switching back to the terminal buffer.
|
||||||
|
command('buffer #')
|
||||||
|
screen:expect([[
|
||||||
|
{1: }{5:2}{1: foo }{2: foo }{4: }{2:X}|
|
||||||
|
│{19:r}ows: 5, cols: 25 |
|
||||||
|
{6:~ }│{19:r}ows: 5, cols: 50 |
|
||||||
|
{6:~ }│^ |
|
||||||
|
{6:~ }│{19: } |
|
||||||
|
{4:[No Name] }{17:foo [-] }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
-- 'cursorlineopt' should still be "number".
|
||||||
|
eq('number', eval('&l:cursorlineopt'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('not unnecessarily redrawn by events', function()
|
it('not unnecessarily redrawn by events', function()
|
||||||
|
|||||||
Reference in New Issue
Block a user