public static void Help() { CLI.Line("HELP: cmd -arg [value] {-optionalArg [optional value]} {-optionalBool}"); Break(); foreach (var cmd in Commands) { Help(cmd); CLI.Line(); } Break(); }
public static void Start(Commands commands) { Initialize(commands); Console.OutputEncoding = System.Text.Encoding.Unicode; CLI.Out(InputPrefix); var input = Console.ReadLine(); while (!Stopped) { if (input.Length != 0) { Run(input); CLI.Line(); } Console.Write(InputPrefix); input = Console.ReadLine(); } }
private static void Initialize(Commands commands) { Stopped = false; //core logic requires "help" command always existing, need to make this not true in order to provide an option to remove the help command //all DefaultCommands are overrideable by regular Commands still, though. DefaultCommands.Add(new Command { Name = "help", Description = "Shows this list of commands", Function = args => { if (args.Count > 0) { var input = args.Keys.First(); var cmd = Commands[input]; if (cmd == null) { var top3 = FuzzyCommandSearch(input).Take(3); foreach (var c in top3) { Help(c); } return; } else { CLI.Help(cmd); return; } } CLI.Help(); } }); if (Options.EnableColorsCommand) { DefaultCommands.Add(new Command { Name = "colors", Description = "Displays examples for all available console colors", Function = args => { var colors = System.Enum.GetValues(typeof(ConsoleColor)).Cast <ConsoleColor>(); foreach (var c in colors) { CLI.Line(c.ToString(), c); } foreach (var c in colors) { CLI.Line(c.ToString(), ConsoleColor.Gray, c); } } }); } if (Options.EnableExitCommand) { DefaultCommands.Add(new Command { Name = "exit", Function = args => { CLI.Stop(); } }); } Commands = commands; foreach (var cmd in DefaultCommands) { if (!Commands.Any(x => x.Name == cmd.Name)) { Commands.Insert(0, cmd); } } }
/// <summary> /// Parse raw input and execute it /// </summary> /// <param name="input"></param> public static void Run(string input) => CLI.Run(ParseInput(input));
private static void Run(InputCommand cmd) { Command exec = Commands[cmd.Name.ToLower()]; if (exec == null) { //fuzzy command suggestions var suggestedCommand = FuzzyCommandSearch(cmd.Name).FirstOrDefault(); if (suggestedCommand != null) { CLI.Out("Did you mean "); CLI.Out(suggestedCommand.Name, ConsoleColor.Cyan); if (cmd.Arguments.Count > 0) { CLI.Out(" "); } foreach (var a in cmd.Arguments) { CLI.Out($"-{a.Key} {a.Value} ", ConsoleColor.DarkCyan); } CLI.Out("? "); CLI.Line("[Y/n]", ConsoleColor.Green); Console.ForegroundColor = ConsoleColor.Green; //not using CLI.Out(ConsoleColor) because I want the user input to also be Cyan CLI.Out(InputPrefix); if (Console.ReadLine() == "Y") { exec = suggestedCommand; } else { exec = Commands["help"]; } Console.ResetColor(); } else { exec = Commands["help"]; } } var missingRequiredArgs = exec.RequiredArgs.Select(x => x.Tag.ToLower()).Where(x => !cmd.Arguments.ContainsKey(x.ToLower())).ToList(); if (missingRequiredArgs.Count > 0) { //fuzzy argument suggestions if (cmd.Arguments.Count > 0) { CLI.Out("Did you mean "); CLI.Out(exec.Name + " ", ConsoleColor.DarkCyan); //input arguments that don't exist in the Command definition, mapped to include suggested alternatives var nonexistentArgs = cmd.Arguments .Where(x => !exec.RequiredArgs .Select(y => y.Tag.ToLower()) .Contains(x.Key.ToLower()) ) .Select(x => new { Original = x, Suggestion = exec.RequiredArgs.OrderBy(y => y.Tag.ToLower().DistanceFrom(x.Key.ToLower())).First() }) .ToList(); //input arguments that do exist in the Command definition var existentArgs = cmd.Arguments .Where(x => exec.RequiredArgs .Select(y => y.Tag.ToLower()) .Contains(x.Key.ToLower()) ); foreach (var n in nonexistentArgs) { CLI.Out($"-{n.Suggestion.Tag} {n.Original.Value} ", ConsoleColor.Cyan); } foreach (var e in existentArgs) { CLI.Out($"-{e.Key} {e.Value} ", ConsoleColor.DarkCyan); } CLI.Out("? "); CLI.Line("[Y/n]", ConsoleColor.Green); Console.ForegroundColor = ConsoleColor.Green; //not using CLI.Out(ConsoleColor) because I want the user input to also be Cyan CLI.Out(InputPrefix); if (Console.ReadLine() == "Y") { foreach (var arg in nonexistentArgs) { var inArg = cmd.Arguments.First(x => x.Key == arg.Original.Key); cmd.Arguments.Remove(inArg.Key); cmd.Arguments.Add(arg.Suggestion.Tag, inArg.Value); } } else { exec = Commands["help"]; } Console.ResetColor(); } else { exec = Commands["help"]; } } Stopwatch sw = new Stopwatch(); sw.Start(); try { exec.Function.Invoke(cmd.Arguments); sw.Stop(); CLI.Line(sw.ElapsedMilliseconds + "ms"); } catch (Exception e) { sw.Stop(); CLI.Line(e.Message, ConsoleColor.Red); } }