public void DisplayAllCompletions() { const string s = "So"; var console = new SimulatedConsoleOutput(width: 10); const string prompt = "Prompt>"; var completions = new[] { "Some", "somebody", "Something", "soy" }; ConsoleCompletionHandler completionHandler = (tokens, tokenIndex) => completions; var input = CreateInputWithText(console, s, completionHandler); input.Prompt = prompt; input.MoveCursorBackward(1).Should().BeTrue(); input.DisplayAllCompletions(); input.Contents.Should().Be(s); GetContents(console).Replace('\0', ' ').TrimEnd().Should().Be( "So " + "Some " + "somebody " + "Something " + "soy " + prompt + s); console.CursorTop.Should().Be(5); console.CursorLeft.Should().Be(prompt.Length + s.Length - 1); }
/// <summary> /// Basic constructor. /// </summary> /// <param name="consoleOutput">Interface for interacting with the output /// console.</param> /// <param name="buffer">Console input buffer to use.</param> /// <param name="history">Console history object to use.</param> /// <param name="completionHandler">Optionally provides completion /// handler.</param> public ConsoleLineInput(IConsoleOutput consoleOutput, IConsoleInputBuffer buffer, IConsoleHistory history, ConsoleCompletionHandler completionHandler) { ConsoleOutput = consoleOutput; Buffer = buffer; History = history; CompletionHandler = completionHandler; }
public void Completion() { var completions = new[] { "Hello there", "Hello, world!" }; ConsoleCompletionHandler completionHandler = (tokens, index) => completions; Process( completionHandler, "hello".AsKeys(), ConsoleKey.Home.AsInfo(), ConsoleKey.Tab.WithShift()) .Should().Be("\"Hello, world!\""); Process( completionHandler, "hello".AsKeys(), ConsoleKey.Home.AsInfo(), ConsoleKey.Tab.AsInfo()) .Should().Be("\"Hello there\""); Process( completionHandler, "hello".AsKeys(), ConsoleKey.Oem2.WithAlt().WithShift()) .Should().Be("hello"); Process( completionHandler, "hello".AsKeys(), ConsoleKey.D8.WithAlt().WithShift()) .Should().Be("\"Hello there\" \"Hello, world!\" "); }
private void ReplaceWithAllCompletions(string text, int cursorIndex, IEnumerable <string> textAsTokens, int?expectedCompletionTokenIndex) { var calls = new List <Tuple <List <string>, int> >(); var console = new SimulatedConsoleOutput(); ConsoleCompletionHandler completionHandler = (tokens, tokenIndex) => { calls.Add(Tuple.Create(tokens.ToList(), tokenIndex)); return(Enumerable.Empty <string>()); }; var input = CreateInputWithText(console, text, completionHandler); input.MoveCursorToStart(); input.MoveCursorForward(cursorIndex).Should().BeTrue(); input.ReplaceCurrentTokenWithAllCompletions(); calls.Should().HaveCount(expectedCompletionTokenIndex.HasValue ? 1 : 0); if (expectedCompletionTokenIndex.HasValue) { calls[0].Item1.Should().ContainInOrder(textAsTokens.ToArray()); calls[0].Item2.Should().Be(expectedCompletionTokenIndex.Value); } }
/// <summary> /// Basic constructor. /// </summary> /// <param name="consoleOutput">Interface for interacting with the output /// console.</param> /// <param name="buffer">Console input buffer to use.</param> /// <param name="history">Console history object to use.</param> /// <param name="completionHandler">Optionally provides completion /// handler.</param> public ConsoleLineInput(IConsoleOutput consoleOutput, IConsoleInputBuffer buffer, IConsoleHistory history, ConsoleCompletionHandler completionHandler) { ConsoleOutput = consoleOutput; Buffer = buffer; History = history; CompletionHandler = completionHandler; }
/// <summary> /// Generate completions for the "current" token in the specified input /// text. /// </summary> /// <param name="inputText">The input text string.</param> /// <param name="cursorIndex">The current cursor index into the string. /// </param> /// <param name="completionHandler">Completion handler to invoke. /// </param> /// <returns>The generated completion set.</returns> public static TokenCompletionSet Create(string inputText, int cursorIndex, ConsoleCompletionHandler completionHandler) { if (completionHandler == null) { throw new ArgumentNullException(nameof(completionHandler)); } var completions = Create(inputText, cursorIndex, completionHandler, out int tokenStartIndex, out int tokenLength); var originalToken = new Token(new Substring(inputText, tokenStartIndex, tokenLength)); return(new TokenCompletionSet(inputText, originalToken, completions)); }
public void UntokenizableString() { const string text = "\"s\"x\""; ConsoleCompletionHandler completionHandler = (tokens, index) => Enumerable.Empty <string>(); var set = TokenCompletionSet.Create(text, 0, completionHandler); set.InputText.Should().Be(text); set.Completions.Should().HaveCount(0); set.Count.Should().Be(0); set.Empty.Should().BeTrue(); }
public void ReplaceWithAllCompletionsButNoCompletions() { var console = new SimulatedConsoleOutput(); ConsoleCompletionHandler completionHandler = (tokens, tokenIndex) => Enumerable.Empty <string>(); var input = CreateInput(console, completionHandler); input.ReplaceCurrentTokenWithAllCompletions(); input.Contents.Should().BeEmpty(); GetContents(console).Should().BeEmpty(); console.CursorTop.Should().Be(0); console.CursorLeft.Should().Be(0); }
public void ReplaceWithPreviousCompletionEncountersEmptyString() { const string text = "S"; string[] completions = { "S", string.Empty, "szy" }; var console = new SimulatedConsoleOutput(); ConsoleCompletionHandler completionHandler = (tokens, index) => completions; var input = CreateInputWithText(console, text, completionHandler); ValidateCompletion(input, 1, true, false, "szy"); ValidateCompletion(input, null, true, true, StringUtilities.QuoteIfNeeded(string.Empty)); ValidateCompletion(input, null, true, true, "S"); }
public void ReplaceWithNextCompletionWithNoCompletions() { const string s = "Something"; var console = new SimulatedConsoleOutput(); ConsoleCompletionHandler completionHandler = (tokens, index) => Enumerable.Empty <string>(); var input = CreateInputWithText(console, s, completionHandler); input.ReplaceCurrentTokenWithNextCompletion(false); input.Contents.Should().Be(s); GetContents(console).Should().Be(s); console.CursorTop.Should().Be(0); console.CursorLeft.Should().Be(s.Length); }
/// <summary> /// Generate completions for the "current" token in the specified input /// text. /// </summary> /// <param name="inputText">The input text string.</param> /// <param name="cursorIndex">The current cursor index into the string. /// </param> /// <param name="completionHandler">Completion handler to invoke. /// </param> /// <returns>The generated completion set.</returns> public static TokenCompletionSet Create(string inputText, int cursorIndex, ConsoleCompletionHandler completionHandler) { if (completionHandler == null) { throw new ArgumentNullException(nameof(completionHandler)); } int tokenStartIndex; int tokenLength; var completions = Create(inputText, cursorIndex, completionHandler, out tokenStartIndex, out tokenLength); var originalToken = new Token(new Substring(inputText, tokenStartIndex, tokenLength)); return new TokenCompletionSet(inputText, originalToken, completions); }
public void DisplayAllCompletionsWithNoCompletions() { const string s = "Hello world something"; var console = new SimulatedConsoleOutput(width: 10); ConsoleCompletionHandler completionHandler = (tokens, tokenIndex) => Enumerable.Empty <string>(); var input = CreateInputWithText(console, s, completionHandler); var previousConsoleContents = GetContents(console); input.DisplayAllCompletions(); input.Contents.Should().Be(s); GetContents(console).Should().Be(previousConsoleContents); }
private ConsoleLineInput CreateInput(IConsoleOutput consoleOutput = null, ConsoleCompletionHandler completionHandler = null) { consoleOutput = consoleOutput ?? Substitute.For <IConsoleOutput>(); var buffer = new ConsoleInputBuffer(); var history = new ConsoleHistory(); var input = new ConsoleLineInput(consoleOutput, buffer, history, completionHandler); input.ConsoleOutput.Should().BeSameAs(consoleOutput); input.Buffer.Should().BeSameAs(buffer); input.History.Should().BeSameAs(history); input.CompletionHandler.Should().BeSameAs(completionHandler); input.InsertMode.Should().BeTrue(); return(input); }
public void SimpleStringWithCompletions() { const string text = "a b"; var completions = new[] { "abc", "aZx" }; ConsoleCompletionHandler completionHandler = (tokens, index) => completions; var set = TokenCompletionSet.Create(text, 0, completionHandler); set.InputText.Should().Be(text); set.Completions.Should().HaveCount(2); set.Count.Should().Be(2); set.Empty.Should().BeFalse(); set[0].Should().Be("abc"); set[1].Should().Be("aZx"); }
public void ReplaceWithNextCompletion() { const string text = "S"; string[] completions = { "S", "Sa", "sc", "szy" }; var console = new SimulatedConsoleOutput(); ConsoleCompletionHandler completionHandler = (tokens, index) => completions; var input = CreateInputWithText(console, text, completionHandler); ValidateCompletion(input, 1, false, false, "S"); ValidateCompletion(input, null, false, true, "Sa"); ValidateCompletion(input, null, false, false, "S"); ValidateCompletion(input, null, false, true, "Sa"); ValidateCompletion(input, null, false, true, "sc"); ValidateCompletion(input, null, false, true, "szy"); ValidateCompletion(input, null, false, true, "S"); }
public void ReplaceWithAllCompletionsAtEnd() { var console = new SimulatedConsoleOutput(); var completions = new[] { "abcd", "aXYZ", "aw | i" }; ConsoleCompletionHandler completionHandler = (tokens, tokenIndex) => completions; var input = CreateInput(console, completionHandler); input.Insert("a"); input.MoveCursorToEnd(); var completionsAsText = string.Join(" ", completions.Select(StringUtilities.QuoteIfNeeded)) + " "; input.ReplaceCurrentTokenWithAllCompletions(); input.Contents.Should().Be(completionsAsText); GetContents(console).Should().Be(completionsAsText); console.CursorTop.Should().Be(0); console.CursorLeft.Should().Be(completionsAsText.Length); }
private static string Process(ConsoleCompletionHandler completionHandler, params IEnumerable <ConsoleKeyInfo>[] keyInfo) => Process(keyInfo.SelectMany(x => x), completionHandler: completionHandler);
private static string Process(ConsoleCompletionHandler completionHandler, params IEnumerable<ConsoleKeyInfo>[] keyInfo) { return Process(keyInfo.SelectMany(x => x), completionHandler: completionHandler); }
private static string Process(IEnumerable<ConsoleKeyInfo> keyInfo, ConsoleCompletionHandler completionHandler = null) { return CreateReader(keyInfo.Concat(ConsoleKey.Enter), completionHandler).ReadLine(); }
private static ConsoleReader CreateReader(IEnumerable<ConsoleKeyInfo> keyStream, ConsoleCompletionHandler completionHandler = null) { var consoleOutput = new SimulatedConsoleOutput(); var consoleInput = new SimulatedConsoleInput(keyStream); var input = new ConsoleLineInput(consoleOutput, new ConsoleInputBuffer(), new ConsoleHistory(), completionHandler); return new ConsoleReader(input, consoleInput, consoleOutput, null); }
private ConsoleLineInput CreateInputWithText(IConsoleOutput consoleOutput, string text, ConsoleCompletionHandler completionHandler = null) { var input = CreateInput(consoleOutput, completionHandler); input.Insert(text); input.MoveCursorToEnd(); return(input); }
/// <summary> /// Generate completions for the "current" token in the specified input /// text. /// </summary> /// <param name="inputText">The input text string.</param> /// <param name="cursorIndex">The current cursor index into the string. /// </param> /// <param name="completionHandler">Completion handler to invoke. /// </param> /// <param name="existingTokenStartIndex">Receives the start index of /// the current token.</param> /// <param name="existingTokenLength">Receives the length of the current /// token.</param> /// <returns>The generated completions.</returns> private static IReadOnlyList <string> Create(string inputText, int cursorIndex, ConsoleCompletionHandler completionHandler, out int existingTokenStartIndex, out int existingTokenLength) { // // Try to parse the line. If we fail to parse it, then just // return immediately. // var tokens = CommandLineParser.Tokenize( inputText, CommandLineTokenizerOptions.AllowPartialInput).ToList(); // // Figure out which token we're in // int tokenIndex; for (tokenIndex = 0; tokenIndex < tokens.Count; ++tokenIndex) { var token = tokens[tokenIndex]; if (cursorIndex > token.OuterEndingOffset) { continue; } if (cursorIndex >= token.OuterStartingOffset) { break; } // Insert an empty token here. tokens.Insert( tokenIndex, new Token(new Substring(inputText, cursorIndex, 0))); break; } if (tokenIndex < tokens.Count) { var token = tokens[tokenIndex]; existingTokenStartIndex = token.OuterStartingOffset; existingTokenLength = token.OuterLength; } else { existingTokenStartIndex = cursorIndex; existingTokenLength = 0; } // // Ask for completions. // var tokenStrings = tokens.Select(token => RemoveQuotes(token.ToString())).ToArray(); var completions = completionHandler.Invoke(tokenStrings, tokenIndex).ToList(); // If necessary quote! for (var j = 0; j < completions.Count; j++) { var completion = completions[j]; if (!completion.StartsWith("\"", StringComparison.OrdinalIgnoreCase)) { completions[j] = StringUtilities.QuoteIfNeeded(completions[j]); } } return(completions); }
private static ConsoleReader CreateReader(IEnumerable <ConsoleKeyInfo> keyStream = null, ConsoleCompletionHandler completionHandler = null) { var consoleOutput = new SimulatedConsoleOutput(); var consoleInput = new SimulatedConsoleInput(keyStream ?? Enumerable.Empty <ConsoleKeyInfo>()); var input = Substitute.For <IConsoleLineInput>(); return(new ConsoleReader(input, consoleInput, consoleOutput, null)); }
/// <summary> /// Generate completions for the "current" token in the specified input /// text. /// </summary> /// <param name="inputText">The input text string.</param> /// <param name="cursorIndex">The current cursor index into the string. /// </param> /// <param name="completionHandler">Completion handler to invoke. /// </param> /// <param name="existingTokenStartIndex">Receives the start index of /// the current token.</param> /// <param name="existingTokenLength">Receives the length of the current /// token.</param> /// <returns>The generated completions.</returns> private static IReadOnlyList<string> Create(string inputText, int cursorIndex, ConsoleCompletionHandler completionHandler, out int existingTokenStartIndex, out int existingTokenLength) { // // Try to parse the line. If we fail to parse it, then just // return immediately. // var tokens = CommandLineParser.Tokenize( inputText, CommandLineTokenizerOptions.AllowPartialInput).ToList(); // // Figure out which token we're in // int tokenIndex; for (tokenIndex = 0; tokenIndex < tokens.Count; ++tokenIndex) { var token = tokens[tokenIndex]; if (cursorIndex > token.OuterEndingOffset) { continue; } if (cursorIndex >= token.OuterStartingOffset) { break; } // Insert an empty token here. tokens.Insert( tokenIndex, new Token(new Substring(inputText, cursorIndex, 0))); break; } if (tokenIndex < tokens.Count) { var token = tokens[tokenIndex]; existingTokenStartIndex = token.OuterStartingOffset; existingTokenLength = token.OuterLength; } else { existingTokenStartIndex = cursorIndex; existingTokenLength = 0; } // // Ask for completions. // var tokenStrings = tokens.Select(token => RemoveQuotes(token.ToString())).ToArray(); var completions = completionHandler.Invoke(tokenStrings, tokenIndex).ToList(); // If necessary quote! for (var j = 0; j < completions.Count; j++) { var completion = completions[j]; if (!completion.StartsWith("\"", StringComparison.OrdinalIgnoreCase)) { completions[j] = StringUtilities.QuoteIfNeeded(completions[j]); } } return completions; }
private static string Process(IEnumerable <ConsoleKeyInfo> keyInfo, ConsoleCompletionHandler completionHandler = null) => CreateReader(keyInfo.Concat(ConsoleKey.Enter), completionHandler).ReadLine();
private static ConsoleReader CreateReader(IEnumerable <ConsoleKeyInfo> keyStream, ConsoleCompletionHandler completionHandler = null) { var consoleOutput = new SimulatedConsoleOutput(); var consoleInput = new SimulatedConsoleInput(keyStream); var input = new ConsoleLineInput(consoleOutput, new ConsoleInputBuffer(), new ConsoleHistory(), completionHandler); return(new ConsoleReader(input, consoleInput, consoleOutput, null)); }