Pass a table from nvim_create_user_command to a lua function

I currently have a lua function that has several parameters and runs different workflows depending on those parameters. For demonstration purposes, something like this:

function Do_this_thing(param1, param2, param3, param4)
  if param1 == "this" then
    // do something
  else 
    // do something else
  end

  if param2 == "that" then
    // do something
  else 
    // do something else
  end

  // etc etc
end

I have then set-up a command with nvim_create_user_command so I can use it when I’m writing code:

vim.api.nvim_create_user_command('RunTheThing, function(opts) Do_this_thing(opts.fargs[1], opts.fargs[2], opts.fargs[3], opts.fargs[4]) end, {nargs = "+"})

The issue is, I would like for some of the parameters to be optional/have defaults, but if I want to set param4 all the others have to be passed through (obviously) otherwise it would get confusing.

Ideally, I’d like to just call it with a table so I only need one or two parameters. Something like :RunTheThing thisParam {param2 = "this", param3 = "that"}, but the table gets interpreted as a string so it then can’t be indexed/accessed.

Is there a way to do it like that?

Try using the Lua function load to parse the string into a table:

local tbl = "{hello = 'world'}"
local parsed = load("return " .. tbl)()
vim.print(parsed)

Note that you have to first concatenate it with return because load returns a function. Then just add the calling () and you have the parsed table to index it!

Ohhh that’s sweet, thank you!

function UseATable(tbl)
  local parsed = load("return " .. tbl.args)()

  vim.print(parsed.hello, parsed.foo, parsed.bar)
end

vim.api.nvim_create_user_command('UseATable', UseATable, { nargs = "+" })

outputs:

world
bar
baz
1 Like