Skip to content

Commit

Permalink
fix(api): nvim_set_option_value for global-local options
Browse files Browse the repository at this point in the history
global-local window options need to be handled specially. When `win` is
given but `scope` is not, then we want to set the local version of the
option but not the global one, therefore we need to force
`scope='local'`.

Note this does not apply to window-local only options (e.g. 'number')

Example:

   nvim_set_option_value('scrolloff', 10, {})       -- global-local window option; set global value
   nvim_set_option_value('scrolloff', 20, {win=0})  -- global-local window option; set local value
   nvim_set_option_value('number', true, {})        -- local window option

is now equivalent to:

   nvim_set_option_value('scrolloff', 10, {})
   nvim_set_option_value('scrolloff', 20, {win=0, scope='local'})  -- changed from before
   nvim_set_option_value('number', true, {win=0})                  -- unchanged from before

Only the global-local option with a `win` provided gets forced to local
scope.
  • Loading branch information
lewis6991 committed Jun 22, 2022
1 parent dd591ad commit d234655
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
22 changes: 18 additions & 4 deletions src/nvim/api/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,19 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error
return;
}

// If:
// - window id is provided
// - scope is not provided
// - option is global or local to window (global-local)
//
// Then force scope to local since we don't want to change the global option
if (opt_type == SREQ_WIN && scope == 0) {
int flags = get_option_value_strict(name.data, NULL, NULL, opt_type, to);
if (flags & SOPT_GLOBAL) {
scope = OPT_LOCAL;
}
}

long numval = 0;
char *stringval = NULL;

Expand Down Expand Up @@ -454,11 +467,12 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object
stringval = value.data.string.data;
}

WITH_SCRIPT_CONTEXT(channel_id, {
const int opt_flags = (type == SREQ_WIN && !(flags & SOPT_GLOBAL))
? 0 : (type == SREQ_GLOBAL)
? OPT_GLOBAL : OPT_LOCAL;
// For global-win-local options -> setlocal
// For win-local options -> setglobal and setlocal (opt_flags == 0)
const int opt_flags = (type == SREQ_WIN && !(flags & SOPT_GLOBAL)) ? 0 :
(type == SREQ_GLOBAL) ? OPT_GLOBAL : OPT_LOCAL;

WITH_SCRIPT_CONTEXT(channel_id, {
access_option_value_for(name.data, &numval, &stringval, opt_flags, type, to, false, err);
});
}
Expand Down
7 changes: 7 additions & 0 deletions test/functional/lua/vim_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,13 @@ describe('lua stdlib', function()
vim.wo[1000].cole = 0
]]
eq(0, funcs.luaeval "vim.wo[1000].cole")

-- Can handle global-local values
exec_lua [[vim.o.scrolloff = 100]]
exec_lua [[vim.wo.scrolloff = 200]]
eq(200, funcs.luaeval "vim.wo.scrolloff")
exec_lua [[vim.wo.scrolloff = -1]]
eq(100, funcs.luaeval "vim.wo.scrolloff")
end)

describe('vim.opt', function()
Expand Down

0 comments on commit d234655

Please sign in to comment.