micro icon indicating copy to clipboard operation
micro copied to clipboard

Is there a possibility of accessing arguments of a plugin command from the lua plugin?

Open Twix53791 opened this issue 2 years ago • 4 comments

I am writing a couple of small plugins for micro and for one of them I would like to get user arguments: in the prompt the user would write . I saw than the function creating the plugin details the action as a function containing bp and args. I know how to use bp from the lua plugin to call micro functions, but how to use args?

// MakeCommand is a function to easily create new commands
// This can be called by plugins in Lua so that plugins can define their own commands
func MakeCommand(name string, action func(bp *BufPane, args []string), completer buffer.Completer) {
	if action != nil {
		commands[name] = Command{action, completer}
	}
}

In lua, when I pass an argument to my plugin function, I saw it if I print args[1], but its type is a userdata, and if I understood well (I don't know a lot of lua...), userdata are pure blocks of raw memory, and we can retrieves data from them, they just point to the C code. So is there a way to retrieve the argument I passed as a string? From micro?

Thanks for any clues!

Twix53791 avatar Sep 06 '23 21:09 Twix53791

The type of args[1] should be a string. The type of args itself may be a userdata, but it has the [] operator overloaded to access the array elements from the underlying Go slice. Are you seeing a userdata type for args[1] even when passing an argument to the command?

For example, I put this in my `init.lua to test:

local config = import("micro/config")
local micro = import("micro")

function init()
    config.MakeCommand("foo", function(bp, args)
        micro.Log("foo", type(args[1]))
    end, config.NoComplete)
end

When I run > foo hello with micro -debug, I see in log.txt that the type of args[1] is string (and the value is hello).

zyedidia avatar Sep 06 '23 21:09 zyedidia

Thanks for the reply @zyedidia ! Actually, it works like a string that's right. But I run into another problem : when I pass no argument to the function, args[1], actually {args[1]} returns an error "index out of range". So I tried to check if args was empty or not before, but I did'nt find a way. "args" is not an empty string, is not nil, if args then is always true...

To give more context, I trying to add a functionality to the excellent plugin fzfinder, the possibility of execute fzf in a custom directory passed as an argument. So the code is the following:

function fzfinder(bp, args)
  -- if args then
  bp:CdCmd({args[1]})
...

PS: by the way, I think fzfinder, the fzf plugin of @MuratovAS should became the default fzf plugin in the micro plugin-channel repo. The actual fzf plugin listed, https://github.com/samdmarshall/micro-fzf-plugin, is archived since 2019, buggy and lacks many functionalities we added with @MuratovAS, like easy config via options, choose to open in new tab/split, or look in the current folder of the file open and not the root directory of the project.

Twix53791 avatar Sep 13 '23 11:09 Twix53791

You can try using the length operator: if #args == 0 then ....

zyedidia avatar Sep 14 '23 22:09 zyedidia

Can we close this?

dmaluka avatar Jul 20 '25 15:07 dmaluka