mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
fix(api): fix crash after set_option_value_for() #15390
Problem: This crashes Nvim: tabedit call nvim_win_set_option(1000, 'statusline', 'status') split wincmd J wincmd j Solution: - Change `no_display` parameter value to be the same as in matching `restore_win_noblock` call. In case of different values `topframe` isn't restored to `curtab->tp_topframe`. - Call `restore_win_noblock` if `switch_win_noblock` returns `FAIL` (`switch_win` must always have matching `restore_win`) - Change `switch_win`/`restore_win` to `_noblock` versions to allow autocommands. fixes #14097 fixes #13577
This commit is contained in:
parent
2f9b9e61d7
commit
8b0e6cc05d
@ -1413,8 +1413,10 @@ static void set_option_value_for(char *key, int numval, char *stringval, int opt
|
|||||||
switch (opt_type)
|
switch (opt_type)
|
||||||
{
|
{
|
||||||
case SREQ_WIN:
|
case SREQ_WIN:
|
||||||
if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
|
if (switch_win_noblock(&save_curwin, &save_curtab, (win_T *)from,
|
||||||
win_find_tabpage((win_T *)from), false) == FAIL) {
|
win_find_tabpage((win_T *)from), true)
|
||||||
|
== FAIL) {
|
||||||
|
restore_win_noblock(save_curwin, save_curtab, true);
|
||||||
if (try_end(err)) {
|
if (try_end(err)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1424,7 +1426,7 @@ static void set_option_value_for(char *key, int numval, char *stringval, int opt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
set_option_value_err(key, numval, stringval, opt_flags, err);
|
set_option_value_err(key, numval, stringval, opt_flags, err);
|
||||||
restore_win(save_curwin, save_curtab, true);
|
restore_win_noblock(save_curwin, save_curtab, true);
|
||||||
break;
|
break;
|
||||||
case SREQ_BUF:
|
case SREQ_BUF:
|
||||||
aucmd_prepbuf(&aco, (buf_T *)from);
|
aucmd_prepbuf(&aco, (buf_T *)from);
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
local helpers = require('test.functional.helpers')(after_each)
|
local helpers = require('test.functional.helpers')(after_each)
|
||||||
local clear, nvim, curbuf, curbuf_contents, window, curwin, eq, neq,
|
local clear, nvim, curbuf, curbuf_contents, window, curwin, eq, neq,
|
||||||
ok, feed, insert, eval = helpers.clear, helpers.nvim, helpers.curbuf,
|
ok, feed, insert, eval, tabpage = helpers.clear, helpers.nvim, helpers.curbuf,
|
||||||
helpers.curbuf_contents, helpers.window, helpers.curwin, helpers.eq,
|
helpers.curbuf_contents, helpers.window, helpers.curwin, helpers.eq,
|
||||||
helpers.neq, helpers.ok, helpers.feed, helpers.insert, helpers.eval
|
helpers.neq, helpers.ok, helpers.feed, helpers.insert, helpers.eval,
|
||||||
|
helpers.tabpage
|
||||||
local poke_eventloop = helpers.poke_eventloop
|
local poke_eventloop = helpers.poke_eventloop
|
||||||
local curwinmeths = helpers.curwinmeths
|
local curwinmeths = helpers.curwinmeths
|
||||||
local funcs = helpers.funcs
|
local funcs = helpers.funcs
|
||||||
@ -11,6 +12,7 @@ local NIL = helpers.NIL
|
|||||||
local meths = helpers.meths
|
local meths = helpers.meths
|
||||||
local command = helpers.command
|
local command = helpers.command
|
||||||
local pcall_err = helpers.pcall_err
|
local pcall_err = helpers.pcall_err
|
||||||
|
local assert_alive = helpers.assert_alive
|
||||||
|
|
||||||
-- check if str is visible at the beginning of some line
|
-- check if str is visible at the beginning of some line
|
||||||
local function is_visible(str)
|
local function is_visible(str)
|
||||||
@ -206,7 +208,7 @@ describe('API/win', function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('{get,set}_option', function()
|
describe('nvim_win_get_option, nvim_win_set_option', function()
|
||||||
it('works', function()
|
it('works', function()
|
||||||
curwin('set_option', 'colorcolumn', '4,3')
|
curwin('set_option', 'colorcolumn', '4,3')
|
||||||
eq('4,3', curwin('get_option', 'colorcolumn'))
|
eq('4,3', curwin('get_option', 'colorcolumn'))
|
||||||
@ -224,6 +226,18 @@ describe('API/win', function()
|
|||||||
pcall_err(curwin, 'get_option', 'statusline'))
|
pcall_err(curwin, 'get_option', 'statusline'))
|
||||||
eq('', eval('&l:statusline')) -- confirm local value was not copied
|
eq('', eval('&l:statusline')) -- confirm local value was not copied
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('after switching windows #15390', function()
|
||||||
|
nvim('command', 'tabnew')
|
||||||
|
local tab1 = unpack(nvim('list_tabpages'))
|
||||||
|
local win1 = unpack(tabpage('list_wins', tab1))
|
||||||
|
window('set_option', win1, 'statusline', 'window-status')
|
||||||
|
nvim('command', 'split')
|
||||||
|
nvim('command', 'wincmd J')
|
||||||
|
nvim('command', 'wincmd j')
|
||||||
|
eq('window-status', window('get_option', win1, 'statusline'))
|
||||||
|
assert_alive()
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('get_position', function()
|
describe('get_position', function()
|
||||||
@ -354,13 +368,13 @@ describe('API/win', function()
|
|||||||
local win = meths.open_win(0, true, {
|
local win = meths.open_win(0, true, {
|
||||||
relative='editor', row=10, col=10, width=50, height=10
|
relative='editor', row=10, col=10, width=50, height=10
|
||||||
})
|
})
|
||||||
local tabpage = eval('tabpagenr()')
|
local tab = eval('tabpagenr()')
|
||||||
command('tabprevious')
|
command('tabprevious')
|
||||||
eq(1, eval('tabpagenr()'))
|
eq(1, eval('tabpagenr()'))
|
||||||
meths.win_close(win, false)
|
meths.win_close(win, false)
|
||||||
|
|
||||||
eq(1001, meths.tabpage_get_win(tabpage).id)
|
eq(1001, meths.tabpage_get_win(tab).id)
|
||||||
helpers.assert_alive()
|
assert_alive()
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user