/// <summary> /// Creates a new reader. /// </summary> public RichTextCommandLineReader() { Console = new StdConsoleProvider(); HistoryManager = new ConsoleHistoryManager(); TabHandler = new TabKeyHandler(); KeyHandlers = new Dictionary <ConsoleKey, IKeyHandler>(); RegisterHandler(new EnterKeyHandler()); RegisterHandler(new ArrowKeysHandler()); RegisterHandler(new HomeAndEndKeysHandler()); RegisterHandler(new BackspaceAndDeleteKeysHandler()); RegisterHandler(TabHandler); }
/// <summary> /// Before PowerArgs parses the args, this hook inspects the command line for the indicator and if found /// takes over the command line and provides tab completion. /// </summary> /// <param name="context">The context used to inspect the command line arguments.</param> public override void BeforeParse(ArgHook.HookContext context) { if (CompletionSourceType != null && CompletionSourceType.GetInterfaces().Contains(typeof(ITabCompletionSource)) == false && CompletionSourceType.GetInterfaces().Contains(typeof(ISmartTabCompletionSource)) == false) { throw new InvalidArgDefinitionException("Type does not implement ITabCompletionSource or ISmartTabCompletionSource: " + CompletionSourceType.FullName); } if (context.Definition.IsNonInteractive) { this.REPL = false; return; } if (Indicator == "" && context.CmdLineArgs.Length != 0) { this.REPL = false; return; } if (Indicator != "" && (context.CmdLineArgs.Length != 1 || context.CmdLineArgs[0] != Indicator)) { this.REPL = false; return; } if (REPL && ShowREPLWelcome) { ConsoleString.Empty.WriteLine(); var message = REPLWelcomeMessage.Replace("{{Indicator}}", REPLExitIndicator); ConsoleString.WriteLine(message, ConsoleColor.Cyan); ConsoleString.Empty.WriteLine(); ConsoleString.Write(Indicator + "> ", ConsoleColor.Cyan); ShowREPLWelcome = false; } else if (REPL) { ConsoleString.Write(Indicator + "> ", ConsoleColor.Cyan); } else { // This is a little hacky, but I could not find a better way to make the tab completion start on the same lime // as the command line input try { var lastLine = StdConsoleProvider.ReadALineOfConsoleOutput(Console.CursorTop - 1); Console.CursorTop--; Console.WriteLine(lastLine); Console.CursorTop--; Console.CursorLeft = lastLine.Length + 1; } catch (Exception) { Console.WriteLine(); Console.Write(Indicator + "> "); } } PowerArgsRichCommandLineReader reader = new PowerArgsRichCommandLineReader(context.Definition, LoadHistory()); IHighlighterConfigurator customConfigurator; if (HighlighterConfiguratorType.TryCreate <IHighlighterConfigurator>(out customConfigurator)) { customConfigurator.Configure(reader.Highlighter); } var newCommandLineString = reader.ReadLine().ToString(); var newCommandLineArray = Args.Convert(newCommandLineString); if (REPL && newCommandLineArray.Length == 1 && string.Equals(newCommandLineArray[0], REPLExitIndicator, StringComparison.OrdinalIgnoreCase)) { throw new REPLExitException(); } if (REPL && newCommandLineArray.Length == 1 && newCommandLineArray[0] == "cls") { ConsoleProvider.Current.Clear(); throw new REPLContinueException(); } else if (REPL && newCommandLineArray.Length == 0 && string.IsNullOrWhiteSpace(REPLExitIndicator) == false) { throw new REPLContinueException(); } context.CmdLineArgs = newCommandLineArray; AddToHistory(newCommandLineString); }
/// <summary> /// Before PowerArgs parses the args, this hook inspects the command line for the indicator and if found /// takes over the command line and provides tab completion. /// </summary> /// <param name="context">The context used to inspect the command line arguments.</param> public override void BeforeParse(ArgHook.HookContext context) { if (Indicator == "" && context.CmdLineArgs.Length != 0) { return; } else if (Indicator != "" && (context.CmdLineArgs.Length != 1 || context.CmdLineArgs[0] != Indicator)) { return; } var existingColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Cyan; try { if (REPL && ShowREPLWelcome) { Console.WriteLine(); var message = REPLWelcomeMessage.Replace("{{Indicator}}", REPLExitIndicator); Console.WriteLine(message); Console.WriteLine(); Console.Write(Indicator + "> "); ShowREPLWelcome = false; } else if (REPL) { Console.Write(Indicator + "> "); } else { // This is a little hacky, but I could not find a better way to make the tab completion start on the same lime // as the command line input try { var lastLine = StdConsoleProvider.ReadALineOfConsoleOutput(Console.CursorTop - 1); Console.CursorTop--; Console.WriteLine(lastLine); Console.CursorTop--; Console.CursorLeft = lastLine.Length + 1; } catch (Exception) { Console.WriteLine(); Console.Write(Indicator + "> "); } } } finally { Console.ForegroundColor = existingColor; } List <string> completions = FindTabCompletions(context.Definition.Arguments, context.Definition.Actions); List <ITabCompletionSource> completionSources = new List <ITabCompletionSource>(); if (this.completionSource != null) { completionSources.Add((ITabCompletionSource)Activator.CreateInstance(this.completionSource)); } completionSources.Add(new EnumTabCompletionSource(context.Definition)); completionSources.Add(new SimpleTabCompletionSource(completions) { MinCharsBeforeCyclingBegins = 0 }); completionSources.Add(new FileSystemTabCompletionSource()); string str = null; var newCommandLine = ConsoleHelper.ReadLine(ref str, LoadHistory(), new MultiTabCompletionSource(completionSources)); if (REPL && newCommandLine.Length == 1 && string.Equals(newCommandLine[0], REPLExitIndicator, StringComparison.OrdinalIgnoreCase)) { throw new REPLExitException(); } if (REPL && newCommandLine.Length == 1 && newCommandLine[0] == "cls") { ConsoleHelper.ConsoleImpl.Clear(); throw new REPLContinueException(); } else if (REPL && newCommandLine.Length == 0 && string.IsNullOrWhiteSpace(REPLExitIndicator) == false) { throw new REPLContinueException(); } context.CmdLineArgs = newCommandLine; AddToHistory(str); }