diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 18129e8c39..98dd330b48 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -1027,13 +1027,14 @@ nvim_get_color_map() *nvim_get_color_map()* Return: ~ Map of color names and RGB values. -nvim_get_context({types}) *nvim_get_context()* +nvim_get_context({opts}) *nvim_get_context()* Gets a map of the current editor state. Parameters: ~ - {types} Context types ("regs", "jumps", "buflist", - "gvars", ...) to gather, or NIL for all (see - |context-types|). + {opts} Optional parameters. + • types: List of |context-types| ("regs", "jumps", + "bufs", "gvars", …) to gather, or empty for + "all". Return: ~ map of global |context|. diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 5480bb5173..ab67bc2a3e 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -1418,32 +1418,52 @@ Dictionary nvim_get_color_map(void) /// Gets a map of the current editor state. /// -/// @param types Context types ("regs", "jumps", "buflist", "gvars", ...) -/// to gather, or NIL for all (see |context-types|). +/// @param opts Optional parameters. +/// - types: List of |context-types| ("regs", "jumps", "buflist", +/// "gvars", …) to gather, or empty for "all". +/// @param[out] err Error details, if any /// /// @return map of global |context|. -Dictionary nvim_get_context(Array types) +Dictionary nvim_get_context(Dictionary opts, Error *err) FUNC_API_SINCE(6) { - int int_types = 0; - if (types.size == 1 && types.items[0].type == kObjectTypeNil) { - int_types = kCtxAll; - } else { + Array types = ARRAY_DICT_INIT; + for (size_t i = 0; i < opts.size; i++) { + String k = opts.items[i].key; + Object v = opts.items[i].value; + if (strequal("types", k.data)) { + if (v.type != kObjectTypeArray) { + api_set_error(err, kErrorTypeValidation, "invalid value for key: %s", + k.data); + return (Dictionary)ARRAY_DICT_INIT; + } + types = v.data.array; + } else { + api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); + return (Dictionary)ARRAY_DICT_INIT; + } + } + + int int_types = types.size > 0 ? 0 : kCtxAll; + if (types.size > 0) { for (size_t i = 0; i < types.size; i++) { if (types.items[i].type == kObjectTypeString) { - const char *const current = types.items[i].data.string.data; - if (strequal(current, "regs")) { + const char *const s = types.items[i].data.string.data; + if (strequal(s, "regs")) { int_types |= kCtxRegs; - } else if (strequal(current, "jumps")) { + } else if (strequal(s, "jumps")) { int_types |= kCtxJumps; - } else if (strequal(current, "buflist")) { + } else if (strequal(s, "buflist")) { int_types |= kCtxBuflist; - } else if (strequal(current, "gvars")) { + } else if (strequal(s, "gvars")) { int_types |= kCtxGVars; - } else if (strequal(current, "sfuncs")) { + } else if (strequal(s, "sfuncs")) { int_types |= kCtxSFuncs; - } else if (strequal(current, "funcs")) { + } else if (strequal(s, "funcs")) { int_types |= kCtxFuncs; + } else { + api_set_error(err, kErrorTypeValidation, "unexpected type: %s", s); + return (Dictionary)ARRAY_DICT_INIT; } } } diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index c34e7a0945..77296e27f6 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -894,9 +894,17 @@ describe('API', function() end) describe('nvim_get_context', function() - it('returns context dictionary of current editor state', function() - local ctx_items = {'regs', 'jumps', 'buflist', 'gvars'} - eq({}, parse_context(nvim('get_context', ctx_items))) + it('validates args', function() + eq('unexpected key: blah', + pcall_err(nvim, 'get_context', {blah={}})) + eq('invalid value for key: types', + pcall_err(nvim, 'get_context', {types=42})) + eq('unexpected type: zub', + pcall_err(nvim, 'get_context', {types={'jumps', 'zub', 'zam',}})) + end) + it('returns map of current editor state', function() + local opts = {types={'regs', 'jumps', 'buflist', 'gvars'}} + eq({}, parse_context(nvim('get_context', {}))) feed('i123ddddddqahjklquuu') feed('gg') @@ -928,19 +936,21 @@ describe('API', function() ['gvars'] = {{'one', 1}, {'Two', 2}, {'THREE', 3}}, } - eq(expected_ctx, parse_context(nvim('get_context', ctx_items))) + eq(expected_ctx, parse_context(nvim('get_context', opts))) + eq(expected_ctx, parse_context(nvim('get_context', {}))) + eq(expected_ctx, parse_context(nvim('get_context', {types={}}))) end) end) describe('nvim_load_context', function() it('sets current editor state to given context dictionary', function() - local ctx_items = {'regs', 'jumps', 'buflist', 'gvars'} - eq({}, parse_context(nvim('get_context', ctx_items))) + local opts = {types={'regs', 'jumps', 'buflist', 'gvars'}} + eq({}, parse_context(nvim('get_context', opts))) nvim('set_var', 'one', 1) nvim('set_var', 'Two', 2) nvim('set_var', 'THREE', 3) - local ctx = nvim('get_context', ctx_items) + local ctx = nvim('get_context', opts) nvim('set_var', 'one', 'a') nvim('set_var', 'Two', 'b') nvim('set_var', 'THREE', 'c')