NConsoleMenu icon indicating copy to clipboard operation
NConsoleMenu copied to clipboard

Allow parsing of multiple args for a command

Open selmaohneh opened this issue 7 years ago • 4 comments

Allow stuff like

menu.Add("greet", (x,y) => Greet(x,y), "Greets a name a number of times.");

Would be great to have multiple parsed arguments instead of a single string.

selmaohneh avatar Sep 25 '18 11:09 selmaohneh

Do I understand this correctly: You want to add a menu entry. When this entry is called like

$ greet Jon 4

It should call the action body with the two parameters Jon and 4, i.e. it should call

`Greet("Jon","4")`

Is that right?

I think the only generic approach to this would be to add something like a regex, that parses the argument and fills in the varargs of the action body. This could probably be done in the library itself. But why not just parse the regex in the action body directly? You have full control then.

That is to say, I would probably do it like this:

menu.Add ("greet", s => {
	var regex = new Regex (@"(?<name>[^ ]*) (?<times>[0-9]*)");
	var match = regex.Match (s);
	var name = match.Groups["name"].Value;
	var times = int.Parse (match.Groups["times"].Value);
	for (int i = 0; i < times; i++) {
		Console.WriteLine ($"Hello {name}!");
	}
}, "Greets a name a number of times.");	

$ greet Jon 3
Hello Jon!
Hello Jon!
Hello Jon!

nerai avatar Sep 25 '18 16:09 nerai

You understand it right. :) In addition I would even like to call Greet("Jon", 4), i.e. with the second value directly parsed to an int. It would be very convinient to have the parsing done in the library instead of writing it everytime on my own. Currently I do that in combintation with PowerArgs. Having both of your libraries work together feels like a custom git bash with my own commands :) . So, in summary:

Yeah, it works your way, but it is not that convinient. Maybe think about adding a argument parsing similar to PowerArgs.

Let me know your decision.

EDIT:

I know this has no high priority. In addition I think it is not that trivial, since it would involve reflection stuff. Maybe using PowerArgs in combination is the right way... I don't want to invent the wheel again, you don't want the dependency to PowerArgs, I guess...

selmaohneh avatar Sep 26 '18 05:09 selmaohneh

I did not know about PowerArgs, it looks like a nice library. Thanks for showing! I see some synergy in adding it here. However, it is also a significant change and dependency that I need to examine in detail. Currently I sadly lack the time, so I want to postpone this for now. Sorry!

For your use case, I'm not sure if it is possible, but what comes to mind is deriving from CMenuItem. This subclass could then implement PowerArgs, and you could create instances from it. Is that possible with PowerArgs? If your menu items are large anyway, this would probably be easier to maintain, too.

What sadly does not work at the moment is using the predefined Add-style methods like menu.Add ("x", ...) in combination with PowerArgs. Deriving from CMenuItem is required.

However, I'll add a factory method in the next patch. Then your own class gets constructed when you call Add. Maybe that helps with this effort.

nerai avatar Sep 26 '18 12:09 nerai

It's in the master branch. I'll push it to Nuget later, too.

nerai avatar Sep 26 '18 12:09 nerai