mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(api): Use local LastSet structure in nvim_get_option_info (#22741)
fix(api): use local LastSet structure in nvim_get_option_info * nvim_get_option_info is deprecated. It is always using the global LastSet information as reported in #15232. * nvim_get_option_info2 is added. The new function additionally accepts an 'opts' table {scope, buf, win} allowing to specify the option scope and query local options from another buffer or window.
This commit is contained in:
parent
eac75a971d
commit
b7748662ed
@ -1912,7 +1912,7 @@ nvim_get_all_options_info() *nvim_get_all_options_info()*
|
||||
Gets the option information for all options.
|
||||
|
||||
The dictionary has the full option names as keys and option metadata
|
||||
dictionaries as detailed at |nvim_get_option_info()|.
|
||||
dictionaries as detailed at |nvim_get_option_info2()|.
|
||||
|
||||
Return: ~
|
||||
dictionary of all options
|
||||
@ -1926,8 +1926,8 @@ nvim_get_option({name}) *nvim_get_option()*
|
||||
Return: ~
|
||||
Option value (global)
|
||||
|
||||
nvim_get_option_info({name}) *nvim_get_option_info()*
|
||||
Gets the option information for one option
|
||||
nvim_get_option_info2({name}, {*opts}) *nvim_get_option_info2()*
|
||||
Gets the option information for one option from arbitrary buffer or window
|
||||
|
||||
Resulting dictionary has keys:
|
||||
• name: Name of the option (like 'filetype')
|
||||
@ -1943,8 +1943,19 @@ nvim_get_option_info({name}) *nvim_get_option_info()*
|
||||
• commalist: List of comma separated values
|
||||
• flaglist: List of single char flags
|
||||
|
||||
When {scope} is not provided, the last set information applies to the
|
||||
local value in the current buffer or window if it is available, otherwise
|
||||
the global value information is returned. This behavior can be disabled by
|
||||
explicitly specifying {scope} in the {opts} table.
|
||||
|
||||
Parameters: ~
|
||||
• {name} Option name
|
||||
• {opts} Optional parameters
|
||||
• scope: One of "global" or "local". Analogous to |:setglobal|
|
||||
and |:setlocal|, respectively.
|
||||
• win: |window-ID|. Used for getting window local options.
|
||||
• buf: Buffer number. Used for getting buffer local options.
|
||||
Implies {scope} is "local".
|
||||
|
||||
Return: ~
|
||||
Option Information
|
||||
|
@ -20,6 +20,7 @@ API
|
||||
- *nvim_get_hl_by_name()* Use |nvim_get_hl()| instead.
|
||||
- *nvim_get_hl_by_id()* Use |nvim_get_hl()| instead.
|
||||
- *nvim_exec()* Use |nvim_exec2()| instead.
|
||||
- *nvim_get_option_info()* Use |nvim_get_option_info2()| instead.
|
||||
|
||||
COMMANDS
|
||||
- *:rv* *:rviminfo* Deprecated alias to |:rshada| command.
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "nvim/highlight_group.h"
|
||||
#include "nvim/lua/executor.h"
|
||||
#include "nvim/memory.h"
|
||||
#include "nvim/option.h"
|
||||
#include "nvim/pos.h"
|
||||
#include "nvim/types.h"
|
||||
|
||||
@ -508,3 +509,16 @@ static int64_t convert_index(int64_t index)
|
||||
{
|
||||
return index < 0 ? index - 1 : index;
|
||||
}
|
||||
|
||||
/// Gets the option information for one option
|
||||
///
|
||||
/// @deprecated Use @ref nvim_get_option_info2 instead.
|
||||
///
|
||||
/// @param name Option name
|
||||
/// @param[out] err Error details, if any
|
||||
/// @return Option Information
|
||||
Dictionary nvim_get_option_info(String name, Error *err)
|
||||
FUNC_API_SINCE(7)
|
||||
{
|
||||
return get_vimoption(name, OPT_GLOBAL, curbuf, curwin, err);
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict(
|
||||
/// Gets the option information for all options.
|
||||
///
|
||||
/// The dictionary has the full option names as keys and option metadata
|
||||
/// dictionaries as detailed at |nvim_get_option_info()|.
|
||||
/// dictionaries as detailed at |nvim_get_option_info2()|.
|
||||
///
|
||||
/// @return dictionary of all options
|
||||
Dictionary nvim_get_all_options_info(Error *err)
|
||||
@ -292,7 +292,7 @@ Dictionary nvim_get_all_options_info(Error *err)
|
||||
return get_all_vimoptions();
|
||||
}
|
||||
|
||||
/// Gets the option information for one option
|
||||
/// Gets the option information for one option from arbitrary buffer or window
|
||||
///
|
||||
/// Resulting dictionary has keys:
|
||||
/// - name: Name of the option (like 'filetype')
|
||||
@ -311,15 +311,36 @@ Dictionary nvim_get_all_options_info(Error *err)
|
||||
/// - commalist: List of comma separated values
|
||||
/// - flaglist: List of single char flags
|
||||
///
|
||||
/// When {scope} is not provided, the last set information applies to the local
|
||||
/// value in the current buffer or window if it is available, otherwise the
|
||||
/// global value information is returned. This behavior can be disabled by
|
||||
/// explicitly specifying {scope} in the {opts} table.
|
||||
///
|
||||
/// @param name Option name
|
||||
/// @param name Option name
|
||||
/// @param opts Optional parameters
|
||||
/// - scope: One of "global" or "local". Analogous to
|
||||
/// |:setglobal| and |:setlocal|, respectively.
|
||||
/// - win: |window-ID|. Used for getting window local options.
|
||||
/// - buf: Buffer number. Used for getting buffer local options.
|
||||
/// Implies {scope} is "local".
|
||||
/// @param[out] err Error details, if any
|
||||
/// @return Option Information
|
||||
Dictionary nvim_get_option_info(String name, Error *err)
|
||||
FUNC_API_SINCE(7)
|
||||
Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err)
|
||||
FUNC_API_SINCE(11)
|
||||
{
|
||||
return get_vimoption(name, err);
|
||||
int scope = 0;
|
||||
int opt_type = SREQ_GLOBAL;
|
||||
void *from = NULL;
|
||||
if (!validate_option_value_args(opts, &scope, &opt_type, &from, NULL, err)) {
|
||||
return (Dictionary)ARRAY_DICT_INIT;
|
||||
}
|
||||
|
||||
buf_T *buf = (opt_type == SREQ_BUF) ? (buf_T *)from : curbuf;
|
||||
win_T *win = (opt_type == SREQ_WIN) ? (win_T *)from : curwin;
|
||||
|
||||
return get_vimoption(name, scope, buf, win, err);
|
||||
}
|
||||
|
||||
/// Sets the global value of an option.
|
||||
///
|
||||
/// @param channel_id
|
||||
|
@ -5605,26 +5605,27 @@ long get_sidescrolloff_value(win_T *wp)
|
||||
return wp->w_p_siso < 0 ? p_siso : wp->w_p_siso;
|
||||
}
|
||||
|
||||
Dictionary get_vimoption(String name, Error *err)
|
||||
Dictionary get_vimoption(String name, int scope, buf_T *buf, win_T *win, Error *err)
|
||||
{
|
||||
int opt_idx = findoption_len((const char *)name.data, name.size);
|
||||
VALIDATE_S(opt_idx >= 0, "option (not found)", name.data, {
|
||||
return (Dictionary)ARRAY_DICT_INIT;
|
||||
});
|
||||
return vimoption2dict(&options[opt_idx]);
|
||||
|
||||
return vimoption2dict(&options[opt_idx], scope, buf, win);
|
||||
}
|
||||
|
||||
Dictionary get_all_vimoptions(void)
|
||||
{
|
||||
Dictionary retval = ARRAY_DICT_INIT;
|
||||
for (size_t i = 0; options[i].fullname != NULL; i++) {
|
||||
Dictionary opt_dict = vimoption2dict(&options[i]);
|
||||
Dictionary opt_dict = vimoption2dict(&options[i], OPT_GLOBAL, curbuf, curwin);
|
||||
PUT(retval, options[i].fullname, DICTIONARY_OBJ(opt_dict));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static Dictionary vimoption2dict(vimoption_T *opt)
|
||||
static Dictionary vimoption2dict(vimoption_T *opt, int req_scope, buf_T *buf, win_T *win)
|
||||
{
|
||||
Dictionary dict = ARRAY_DICT_INIT;
|
||||
|
||||
@ -5649,9 +5650,25 @@ static Dictionary vimoption2dict(vimoption_T *opt)
|
||||
|
||||
PUT(dict, "was_set", BOOL(opt->flags & P_WAS_SET));
|
||||
|
||||
PUT(dict, "last_set_sid", INTEGER_OBJ(opt->last_set.script_ctx.sc_sid));
|
||||
PUT(dict, "last_set_linenr", INTEGER_OBJ(opt->last_set.script_ctx.sc_lnum));
|
||||
PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)opt->last_set.channel_id));
|
||||
LastSet last_set = { .channel_id = 0 };
|
||||
if (req_scope == OPT_GLOBAL) {
|
||||
last_set = opt->last_set;
|
||||
} else {
|
||||
// Scope is either OPT_LOCAL or a fallback mode was requested.
|
||||
if (opt->indir & PV_BUF) {
|
||||
last_set = buf->b_p_script_ctx[opt->indir & PV_MASK];
|
||||
}
|
||||
if (opt->indir & PV_WIN) {
|
||||
last_set = win->w_p_script_ctx[opt->indir & PV_MASK];
|
||||
}
|
||||
if (req_scope != OPT_LOCAL && last_set.script_ctx.sc_sid == 0) {
|
||||
last_set = opt->last_set;
|
||||
}
|
||||
}
|
||||
|
||||
PUT(dict, "last_set_sid", INTEGER_OBJ(last_set.script_ctx.sc_sid));
|
||||
PUT(dict, "last_set_linenr", INTEGER_OBJ(last_set.script_ctx.sc_lnum));
|
||||
PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)last_set.channel_id));
|
||||
|
||||
const char *type;
|
||||
Object def;
|
||||
|
@ -2892,6 +2892,99 @@ describe('API', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_get_option_info2', function()
|
||||
local fname
|
||||
local bufs
|
||||
local wins
|
||||
|
||||
before_each(function()
|
||||
fname = tmpname()
|
||||
write_file(fname, [[
|
||||
setglobal dictionary=mydict " 1, global-local (buffer)
|
||||
setlocal formatprg=myprg " 2, global-local (buffer)
|
||||
setglobal equalprg=prg1 " 3, global-local (buffer)
|
||||
setlocal equalprg=prg2 " 4, global-local (buffer)
|
||||
setglobal fillchars=stl:x " 5, global-local (window)
|
||||
setlocal listchars=eol:c " 6, global-local (window)
|
||||
setglobal showbreak=aaa " 7, global-local (window)
|
||||
setlocal showbreak=bbb " 8, global-local (window)
|
||||
setglobal completeopt=menu " 9, global
|
||||
]])
|
||||
|
||||
exec_lua 'vim.cmd.vsplit()'
|
||||
meths.create_buf(false, false)
|
||||
|
||||
bufs = meths.list_bufs()
|
||||
wins = meths.list_wins()
|
||||
|
||||
meths.win_set_buf(wins[1].id, bufs[1].id)
|
||||
meths.win_set_buf(wins[2].id, bufs[2].id)
|
||||
|
||||
meths.set_current_win(wins[2].id)
|
||||
meths.exec('source ' .. fname, false)
|
||||
|
||||
meths.set_current_win(wins[1].id)
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
os.remove(fname)
|
||||
end)
|
||||
|
||||
it('should return option information', function()
|
||||
eq(meths.get_option_info('dictionary'), meths.get_option_info2('dictionary', {})) -- buffer
|
||||
eq(meths.get_option_info('fillchars'), meths.get_option_info2('fillchars', {})) -- window
|
||||
eq(meths.get_option_info('completeopt'), meths.get_option_info2('completeopt', {})) -- global
|
||||
end)
|
||||
|
||||
describe('last set', function()
|
||||
local tests = {
|
||||
{desc="(buf option, global requested, global set) points to global", linenr=1, sid=1, args={'dictionary', {scope='global'}}},
|
||||
{desc="(buf option, global requested, local set) is not set", linenr=0, sid=0, args={'formatprg', {scope='global'}}},
|
||||
{desc="(buf option, global requested, both set) points to global", linenr=3, sid=1, args={'equalprg', {scope='global'}}},
|
||||
{desc="(buf option, local requested, global set) is not set", linenr=0, sid=0, args={'dictionary', {scope='local'}}},
|
||||
{desc="(buf option, local requested, local set) points to local", linenr=2, sid=1, args={'formatprg', {scope='local'}}},
|
||||
{desc="(buf option, local requested, both set) points to local", linenr=4, sid=1, args={'equalprg', {scope='local'}}},
|
||||
{desc="(buf option, fallback requested, global set) points to global", linenr=1, sid=1, args={'dictionary', {}}},
|
||||
{desc="(buf option, fallback requested, local set) points to local", linenr=2, sid=1, args={'formatprg', {}}},
|
||||
{desc="(buf option, fallback requested, both set) points to local", linenr=4, sid=1, args={'equalprg', {}}},
|
||||
{desc="(win option, global requested, global set) points to global", linenr=5, sid=1, args={'fillchars', {scope='global'}}},
|
||||
{desc="(win option, global requested, local set) is not set", linenr=0, sid=0, args={'listchars', {scope='global'}}},
|
||||
{desc="(win option, global requested, both set) points to global", linenr=7, sid=1, args={'showbreak', {scope='global'}}},
|
||||
{desc="(win option, local requested, global set) is not set", linenr=0, sid=0, args={'fillchars', {scope='local'}}},
|
||||
{desc="(win option, local requested, local set) points to local", linenr=6, sid=1, args={'listchars', {scope='local'}}},
|
||||
{desc="(win option, local requested, both set) points to local", linenr=8, sid=1, args={'showbreak', {scope='local'}}},
|
||||
{desc="(win option, fallback requested, global set) points to global", linenr=5, sid=1, args={'fillchars', {}}},
|
||||
{desc="(win option, fallback requested, local set) points to local", linenr=6, sid=1, args={'listchars', {}}},
|
||||
{desc="(win option, fallback requested, both set) points to local", linenr=8, sid=1, args={'showbreak', {}}},
|
||||
{desc="(global option, global requested) points to global", linenr=9, sid=1, args={'completeopt', {scope='global'}}},
|
||||
{desc="(global option, local requested) is not set", linenr=0, sid=0, args={'completeopt', {scope='local'}}},
|
||||
{desc="(global option, fallback requested) points to global", linenr=9, sid=1, args={'completeopt', {}}},
|
||||
}
|
||||
|
||||
for _, t in pairs(tests) do
|
||||
it(t.desc, function()
|
||||
-- Switch to the target buffer/window so that curbuf/curwin are used.
|
||||
meths.set_current_win(wins[2].id)
|
||||
local info = meths.get_option_info2(unpack(t.args))
|
||||
eq(t.linenr, info.last_set_linenr)
|
||||
eq(t.sid, info.last_set_sid)
|
||||
end)
|
||||
end
|
||||
|
||||
it('is provided for cross-buffer requests', function()
|
||||
local info = meths.get_option_info2('formatprg', {buf=bufs[2].id})
|
||||
eq(2, info.last_set_linenr)
|
||||
eq(1, info.last_set_sid)
|
||||
end)
|
||||
|
||||
it('is provided for cross-window requests', function()
|
||||
local info = meths.get_option_info2('listchars', {win=wins[2].id})
|
||||
eq(6, info.last_set_linenr)
|
||||
eq(1, info.last_set_sid)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_echo', function()
|
||||
local screen
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user