feat(api): tab-local option scope #39811

Problem:
2d795face6 added support for tab-local options ('cmdheight')
to `nvim_get_option_value`, but not to:

    nvim_get_option_info2()
    nvim_set_option_value(…, { tab = … })
    gettabwinvar()

Solution:
- Update `options.lua` to model tab-local options. Introduce `kOptScopeTab`.
- Handle tab scope in the options layer so it works for all options APIs.

Note:
- No change to `gettabvar()`. Not sure if needed/wanted.

fix https://github.com/neovim/neovim/issues/31140
This commit is contained in:
Justin M. Keyes
2026-05-17 10:24:46 -04:00
committed by GitHub
parent c55b6128f8
commit e572c9c80a
15 changed files with 297 additions and 173 deletions

View File

@@ -1973,8 +1973,8 @@ describe('API', function()
pcall_err(api.nvim_get_option_value, 'shiftwidth', { tab = tab1 })
)
eq(
"Conflict: 'tab' not allowed with this function",
pcall_err(api.nvim_set_option_value, 'cmdheight', 2, { tab = tab1 })
"Conflict: 'tab' not allowed with 'shiftwidth'",
pcall_err(api.nvim_set_option_value, 'shiftwidth', 2, { tab = tab1 })
)
eq(
"Conflict: 'tab' not allowed with this function",
@@ -1986,7 +1986,7 @@ describe('API', function()
)
end)
it("tabpage-local 'cmdheight' #31140", function()
it("tabpage-local option ('cmdheight') #31140", function()
api.nvim_set_option_value('cmdheight', 1, {})
local tab1 = api.nvim_get_current_tabpage()
eq(1, api.nvim_get_option_value('cmdheight', { tab = 0 }))
@@ -1998,6 +1998,14 @@ describe('API', function()
eq(4, api.nvim_get_option_value('cmdheight', { tab = tab2 }))
eq(1, api.nvim_get_option_value('cmdheight', { tab = tab1 }))
eq(4, api.nvim_get_option_value('cmdheight', {}))
-- Set non-current tab option.
api.nvim_set_option_value('cmdheight', 3, { tab = tab1 })
eq(3, api.nvim_get_option_value('cmdheight', { tab = tab1 }))
eq(4, api.nvim_get_option_value('cmdheight', { tab = tab2 }))
eq(4, api.nvim_get_option_value('cmdheight', {}))
command('tabnext')
eq(3, api.nvim_get_option_value('cmdheight', {}))
end)
it('can get local values when global value is set', function()
@@ -3891,10 +3899,11 @@ describe('API', function()
os.remove(fname)
end)
it('should return option information', function()
it('gets option info', function()
eq(api.nvim_get_option_info('dictionary'), api.nvim_get_option_info2('dictionary', {})) -- buffer
eq(api.nvim_get_option_info('fillchars'), api.nvim_get_option_info2('fillchars', {})) -- window
eq(api.nvim_get_option_info('completeopt'), api.nvim_get_option_info2('completeopt', {})) -- global
eq('tab', api.nvim_get_option_info2('cmdheight', {}).scope) -- tab #31140
end)
describe('last set', function()
@@ -3933,13 +3942,13 @@ describe('API', function()
end)
end
it('is provided for cross-buffer requests', function()
it('cross-buffer', function()
local info = api.nvim_get_option_info2('formatprg', { buf = bufs[2] })
eq(2, info.last_set_linenr)
eq(1, info.last_set_sid)
end)
it('is provided for cross-window requests', function()
it('cross-window', function()
local info = api.nvim_get_option_info2('listchars', { win = wins[2] })
eq(6, info.last_set_linenr)
eq(1, info.last_set_sid)