### Running PrettyPrompt Examples Source: https://github.com/waf/prettyprompt/blob/main/README.md If you have the 'dotnet example' global tool installed, you can run the project's examples by executing this command in the repository root. ```bash dotnet example FruitPrompt ``` -------------------------------- ### Install PrettyPrompt via NuGet Source: https://github.com/waf/prettyprompt/blob/main/README.md Install the PrettyPrompt package using the .NET CLI. This command adds the necessary dependency to your project. ```bash dotnet add package PrettyPrompt ``` -------------------------------- ### Basic PrettyPrompt Usage Example Source: https://github.com/waf/prettyprompt/blob/main/README.md A simple read-eval-print-loop (REPL) demonstrating the basic usage of PrettyPrompt. It continuously prompts the user for input until 'exit' is entered or the input is cancelled. ```csharp var prompt = new Prompt(); while (true) { var response = await prompt.ReadLineAsync("> "); if (response.IsSuccess) // false if user cancels, i.e. ctrl-c { if (response.Text == "exit") break; Console.WriteLine("You wrote " + response.Text); } } ``` -------------------------------- ### Write Text to Console with ANSI Escape Codes Source: https://github.com/waf/prettyprompt/blob/main/tests/PrettyPrompt.IntegrationTests/Data/record Utilize Write commands with ANSI escape codes to control text formatting, cursor movement, and screen clearing. This example demonstrates setting text color and position. ```plaintext Write("\n\n\n\n\n\n\n\n\n\n\n#[11A#[1G#[0m") Write("#[0m") Write("#[0m") Write("#[0;31m") Write(">") After Write: CursorLeft: 0 -> 1 Write("#[0m") Write("#[0;33m") Write(">") After Write: CursorLeft: 1 -> 2 Write("#[0m") Write("#[0;32m") Write(">") After Write: CursorLeft: 2 -> 3 Write("#[0m") Write("#[0m") Write(" ") After Write: CursorLeft: 3 -> 4 Write("#[0m") ``` -------------------------------- ### FormatSpan Struct Source: https://context7.com/waf/prettyprompt/llms.txt The FormatSpan struct defines formatting for a specific range of text, including start position, length, and console formatting properties like colors, bold, and underline. ```APIDOC ## FormatSpan Struct ### Description Defines formatting for a specific range of text. Used to apply colors and styles to text segments. ### Properties - **start** (int) - The starting index of the span. - **length** (int) - The length of the span. - **formatting** (ConsoleFormat) - The console formatting properties (Foreground, Background, Bold, Underline, Inverted). ### Usage Example ```csharp // Simple color span var redSpan = new FormatSpan(0, 5, AnsiColor.Red); // Span with full console format var fancySpan = new FormatSpan( start: 10, length: 8, formatting: new ConsoleFormat( Foreground: AnsiColor.BrightWhite, Background: AnsiColor.Blue, Bold: true ) ); ``` ``` -------------------------------- ### TextSpan Struct Source: https://context7.com/waf/prettyprompt/llms.txt The TextSpan struct represents a range of text with a start position and length, commonly used for completion replacement ranges and highlighting spans. ```APIDOC ## TextSpan Struct ### Description Represents a range of text with a start position and length. Provides utility methods for bounds checking, overlap detection, and intersection calculations. ### Properties - **Start** (int) - The starting index of the span. - **Length** (int) - The length of the span. - **End** (int) - The exclusive end index of the span. - **IsEmpty** (bool) - Indicates if the span has zero length. ### Methods - **FromBounds(int start, int end)** - Creates a span from inclusive start and exclusive end indices. - **Contains(int position)** - Checks if a position is within the span. - **OverlapsWith(TextSpan other)** - Determines if this span overlaps with another. - **Intersection(TextSpan other)** - Returns the intersection of two spans. ``` -------------------------------- ### TextSpan Struct for Text Ranges Source: https://context7.com/waf/prettyprompt/llms.txt The `TextSpan` struct defines a range of text using start position and length. Used for specifying completion replacement ranges and highlighting spans. Supports creation from bounds and various overlap/intersection checks. ```csharp using PrettyPrompt.Documents; // Create span from start and length var span1 = new TextSpan(start: 5, length: 10); // Characters 5-14 // Create span from bounds (start inclusive, end exclusive) var span2 = TextSpan.FromBounds(start: 5, end: 15); // Also characters 5-14 // Span properties int start = span1.Start; // 5 int length = span1.Length; // 10 int end = span1.End; // 15 bool empty = span1.IsEmpty; // false // Position checks bool contains5 = span1.Contains(5); // true (start is inclusive) bool contains14 = span1.Contains(14); // true bool contains15 = span1.Contains(15); // false (end is exclusive) // Span containment var innerSpan = new TextSpan(7, 3); bool containsInner = span1.Contains(innerSpan); // true // Overlap detection var overlapping = new TextSpan(10, 10); // Characters 10-19 bool overlaps = span1.OverlapsWith(overlapping); // true // Get the overlap TextSpan? overlap = span1.Overlap(10, 10); // TextSpan(10, 5) = characters 10-14 // Intersection (includes adjacent spans) bool intersects = span1.IntersectsWith(new TextSpan(15, 5)); // true (shares boundary) TextSpan? intersection = span1.Intersection(new TextSpan(10, 10)); // TextSpan(10, 5) // Use in completion callback to determine replacement range protected override Task GetSpanToReplaceByCompletionAsync( string text, int caret, CancellationToken cancellationToken) { // Find word boundaries around caret int wordStart = caret; while (wordStart > 0 && char.IsLetterOrDigit(text[wordStart - 1])) wordStart--; int wordEnd = caret; while (wordEnd < text.Length && char.IsLetterOrDigit(text[wordEnd])) wordEnd++; return Task.FromResult(TextSpan.FromBounds(wordStart, wordEnd)); } ``` -------------------------------- ### Initialize and Use Prompt Class Source: https://context7.com/waf/prettyprompt/llms.txt Demonstrates basic REPL loop implementation and advanced configuration including custom formatting, history persistence, and completion styling. ```csharp using PrettyPrompt; using PrettyPrompt.Highlighting; // Basic usage - simple REPL loop var prompt = new Prompt(); while (true) { var response = await prompt.ReadLineAsync(); if (response.IsSuccess) { if (response.Text == "exit") break; Console.WriteLine("You wrote: " + response.Text); } } // Advanced usage with all configuration options await using var advancedPrompt = new Prompt( persistentHistoryFilepath: "./history-file", callbacks: new MyCustomCallbacks(), configuration: new PromptConfiguration( prompt: new FormattedString(">>> ", new FormatSpan(0, 1, AnsiColor.Red), new FormatSpan(1, 1, AnsiColor.Yellow), new FormatSpan(2, 1, AnsiColor.Green)), completionItemDescriptionPaneBackground: AnsiColor.Rgb(30, 30, 30), selectedCompletionItemBackground: AnsiColor.Rgb(30, 30, 30), selectedTextBackground: AnsiColor.Rgb(20, 61, 102), maxCompletionItemsCount: 12, tabSize: 4 ) ); while (true) { var response = await advancedPrompt.ReadLineAsync(); if (response.IsSuccess) { if (response.Text == "exit") break; // Use CancellationToken to allow user to cancel long operations with Ctrl+C await ProcessInput(response.Text, response.CancellationToken); } } ``` -------------------------------- ### Configure Prompt Appearance and Behavior Source: https://context7.com/waf/prettyprompt/llms.txt Illustrates creating a fully customized PromptConfiguration, including custom prompt strings with formatting, completion menu styling, text selection colors, list sizing, custom key bindings, and tab size. Use this to tailor the prompt experience. ```csharp // Default configuration var defaultConfig = new PromptConfiguration(); // Fully customized configuration var customConfig = new PromptConfiguration( // Custom prompt string with colors prompt: new FormattedString("myapp> ", new FormatSpan(0, 5, new ConsoleFormat( Foreground: AnsiColor.Cyan, Bold: true))), // Completion menu styling completionBoxBorderFormat: new ConsoleFormat(Foreground: AnsiColor.Blue), completionItemDescriptionPaneBackground: AnsiColor.Rgb(40, 40, 40), selectedCompletionItemBackground: AnsiColor.Rgb(60, 60, 100), selectedCompletionItemMarkSymbol: new FormattedString(">", new FormatSpan(0, 1, AnsiColor.BrightGreen)), // Text selection highlighting selectedTextBackground: AnsiColor.Rgb(20, 61, 102), // Completion list sizing minCompletionItemsCount: 1, maxCompletionItemsCount: 12, proportionOfWindowHeightForCompletionPane: 0.5, // Use half of window height max // Custom key bindings keyBindings: new KeyBindings( commitCompletion: new KeyPressPatterns( new KeyPressPattern(ConsoleKey.Enter), new KeyPressPattern(ConsoleKey.Tab)), triggerCompletionList: new KeyPressPatterns( new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.Spacebar)), newLine: new KeyPressPatterns( new KeyPressPattern(ConsoleModifiers.Shift, ConsoleKey.Enter)), submitPrompt: new KeyPressPatterns( new KeyPressPattern(ConsoleKey.Enter), new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.Enter)) ), // Tab character width tabSize: 4 ); var prompt = new Prompt(configuration: customConfig); ``` -------------------------------- ### Configure Custom Key Bindings for PrettyPrompt Source: https://context7.com/waf/prettyprompt/llms.txt Demonstrates creating custom key bindings for prompt actions like completion, newline, and submission. Use this to override default behaviors or define new shortcuts. ```csharp using PrettyPrompt; using PrettyPrompt.Consoles; // Default key bindings var defaults = new KeyBindings(); // CommitCompletion: Enter, Tab // TriggerCompletionList: Ctrl+Space // NewLine: Shift+Enter // SubmitPrompt: Enter, Ctrl+Enter, Ctrl+Alt+Enter // HistoryPrevious: UpArrow // HistoryNext: DownArrow // Custom key bindings var customBindings = new KeyBindings( // Accept completion with Tab only commitCompletion: new KeyPressPatterns( new KeyPressPattern(ConsoleKey.Tab)), // Open completion with Ctrl+Space or Ctrl+J triggerCompletionList: new KeyPressPatterns( new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.Spacebar), new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.J)), // Insert newline with Shift+Enter or Ctrl+Enter newLine: new KeyPressPatterns( new KeyPressPattern(ConsoleModifiers.Shift, ConsoleKey.Enter), new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.Enter)), // Submit with Enter only submitPrompt: new KeyPressPatterns( new KeyPressPattern(ConsoleKey.Enter)), // Navigate history with Ctrl+Up/Down historyPrevious: new KeyPressPatterns( new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.UpArrow)), historyNext: new KeyPressPatterns( new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.DownArrow)), // Manual overload trigger with Ctrl+Shift+Space triggerOverloadList: new KeyPressPatterns( new KeyPressPattern(ConsoleModifiers.Control | ConsoleModifiers.Shift, ConsoleKey.Spacebar)) ); var config = new PromptConfiguration(keyBindings: customBindings); var prompt = new Prompt(configuration: config); ``` -------------------------------- ### Prompt Class - Main Entry Point Source: https://context7.com/waf/prettyprompt/llms.txt The Prompt class is the primary interface for reading user input. It supports configuration for history, syntax highlighting, and autocompletion. ```APIDOC ## Prompt.ReadLineAsync() ### Description Reads a line of input from the user with support for syntax highlighting, autocompletion, and history. ### Method Async Method ### Response - **PromptResult** (object) - Returns a PromptResult object containing the user input, success status, and cancellation token. ``` -------------------------------- ### KeyBindings Configuration Source: https://context7.com/waf/prettyprompt/llms.txt Configures keyboard shortcuts for various prompt actions. Supports multiple key patterns per action. ```APIDOC ## KeyBindings Class ### Description The KeyBindings class allows customization of keyboard shortcuts for prompt actions. It accepts KeyPressPatterns for actions like completion, history navigation, and submission. ### Parameters #### Request Body - **commitCompletion** (KeyPressPatterns) - Optional - Keys to accept a completion. - **triggerCompletionList** (KeyPressPatterns) - Optional - Keys to open the completion list. - **newLine** (KeyPressPatterns) - Optional - Keys to insert a new line. - **submitPrompt** (KeyPressPatterns) - Optional - Keys to submit the prompt. - **historyPrevious** (KeyPressPatterns) - Optional - Keys to navigate to the previous history item. - **historyNext** (KeyPressPatterns) - Optional - Keys to navigate to the next history item. - **triggerOverloadList** (KeyPressPatterns) - Optional - Keys to trigger the overload list. ``` -------------------------------- ### Create Basic CompletionItem Source: https://context7.com/waf/prettyprompt/llms.txt Instantiate a basic CompletionItem with just the replacement text. Useful for simple autocompletion suggestions. ```csharp var simpleItem = new CompletionItem( replacementText: "Console.WriteLine" ); ``` -------------------------------- ### Create and Manipulate FormatSpan Objects Source: https://context7.com/waf/prettyprompt/llms.txt Demonstrates creating FormatSpan instances with simple colors or full console formats, and performing operations like checking containment, overlap, translation, and resizing. Useful for defining text styles in console applications. ```csharp using PrettyPrompt.Highlighting; using PrettyPrompt.Documents; // Simple color span var redSpan = new FormatSpan(0, 5, AnsiColor.Red); // Span with full console format var fancySpan = new FormatSpan( start: 10, length: 8, formatting: new ConsoleFormat( Foreground: AnsiColor.BrightWhite, Background: AnsiColor.Blue, Bold: true, Underline: false, Inverted: false )); // Create span from bounds (start inclusive, end exclusive) var boundsSpan = FormatSpan.FromBounds(5, 12, new ConsoleFormat(Foreground: AnsiColor.Green)); // Span operations bool containsIndex = redSpan.Contains(3); // true bool containsTextSpan = redSpan.Contains(new TextSpan(1, 2)); // true bool overlaps = redSpan.OverlapsWith(new TextSpan(3, 5)); // true // Get overlap between spans FormatSpan? overlap = fancySpan.Overlap(8, 6); // Returns span [10..14) // Translate span position FormatSpan offset = redSpan.Offset(10); // Now starts at 10 instead of 0 // Change span length FormatSpan resized = redSpan.WithLength(10); // Same start, length = 10 ``` -------------------------------- ### Use FormatSpan in Syntax Highlighting Source: https://context7.com/waf/prettyprompt/llms.txt Shows how to implement a syntax highlighting callback by generating a collection of FormatSpan objects based on text content. This is typically used within a prompt or editor to colorize specific parts of the input, like keywords. ```csharp // Use in syntax highlighting callback protected override Task> HighlightCallbackAsync( string text, CancellationToken cancellationToken) { var spans = new List(); // Highlight keywords string[] keywords = { "if", "else", "for", "while", "return" }; foreach (var keyword in keywords) { int index = 0; while ((index = text.IndexOf(keyword, index)) != -1) { spans.Add(new FormatSpan(index, keyword.Length, AnsiColor.Blue)); index += keyword.Length; } } return Task.FromResult>(spans); } ``` -------------------------------- ### Create Formatted CompletionItem with Lazy Description Source: https://context7.com/waf/prettyprompt/llms.txt Create a CompletionItem with formatted display text, custom filter text, a lazy-loaded extended description, and configurable commit character rules. The extended description is loaded only when the item is selected, improving performance. ```csharp var formattedItem = new CompletionItem( replacementText: "Console.WriteLine", displayText: new FormattedString("Console.WriteLine", new FormatSpan(0, 7, AnsiColor.Cyan), // "Console" in cyan new FormatSpan(8, 9, AnsiColor.Yellow)), // "WriteLine" in yellow filterText: "writeline", // Custom filter text for matching getExtendedDescription: async ct => { // Lazy-load documentation (only called when item is selected) await Task.Delay(10, ct); // Simulate async lookup return new FormattedString( "Writes the specified string value to the standard output stream.", new FormatSpan(0, 6, new ConsoleFormat(Bold: true)) // "Writes" in bold ); }, commitCharacterRules: ImmutableArray.Create( new CharacterSetModificationRule(CharacterSetModificationKind.Add, ImmutableArray.Create('(', '.', ' ')), new CharacterSetModificationRule(CharacterSetModificationKind.Remove, ImmutableArray.Create('\t')) ) ); ``` -------------------------------- ### PromptConfiguration Class Source: https://context7.com/waf/prettyprompt/llms.txt The PromptConfiguration class configures the visual appearance and behavior of the prompt, including the prompt string, completion menu styling, keyboard bindings, and tab size. ```APIDOC ## PromptConfiguration Class ### Description Configures the visual appearance and behavior of the prompt. Allows customization of colors, completion menus, and key bindings. ### Key Configuration Options - **prompt** (FormattedString) - The custom prompt string. - **completionBoxBorderFormat** (ConsoleFormat) - Styling for the completion menu border. - **keyBindings** (KeyBindings) - Custom key mappings for actions like committing completion or submitting the prompt. - **tabSize** (int) - The width of a tab character. ### Usage Example ```csharp var customConfig = new PromptConfiguration( prompt: new FormattedString("myapp> ", new FormatSpan(0, 5, new ConsoleFormat(Foreground: AnsiColor.Cyan))), tabSize: 4, keyBindings: new KeyBindings( commitCompletion: new KeyPressPatterns(new KeyPressPattern(ConsoleKey.Enter)) ) ); ``` ``` -------------------------------- ### Generate OverloadItem for Method Signature Help Source: https://context7.com/waf/prettyprompt/llms.txt Create OverloadItem instances to display method signature, summary, return type description, and parameter documentation. This is typically used in tooltips for method calls. ```csharp protected override Task<(IReadOnlyList, int ArgumentIndex)> GetOverloadsAsync( string text, int caret, CancellationToken cancellationToken) { // Check if we're inside a method call if (!text.Contains("Print(")) return Task.FromResult<(IReadOnlyList, int)>((Array.Empty(), 0)); var overloads = new List { new OverloadItem( signature: new FormattedString("void Print(string message)", new FormatSpan(0, 4, AnsiColor.Blue), // "void" keyword new FormatSpan(5, 5, AnsiColor.Yellow)), // "Print" method name summary: "Prints a message to the console.", returnDescription: "This method does not return a value.", parameters: new[] { new OverloadItem.Parameter("message", "The string to write to the console output.") } ), new OverloadItem( signature: new FormattedString("void Print(string format, params object[] args)", new FormatSpan(0, 4, AnsiColor.Blue), new FormatSpan(5, 5, AnsiColor.Yellow)), summary: "Prints a formatted message to the console.", returnDescription: FormattedString.Empty, parameters: new[] { new OverloadItem.Parameter("format", "A composite format string."), new OverloadItem.Parameter("args", "An object array containing values to format.") } ) }; // Determine which parameter the caret is on (0-indexed) int argumentIndex = text.Substring(0, caret).Count(c => c == ','); return Task.FromResult<(IReadOnlyList, int)>((overloads, argumentIndex)); } ``` -------------------------------- ### Implement Custom Prompt Behavior Source: https://context7.com/waf/prettyprompt/llms.txt Inherit from PromptCallbacks to define custom syntax highlighting, completion items, and keyboard shortcuts. Pass the implementation to the Prompt constructor to activate. ```csharp using PrettyPrompt; using PrettyPrompt.Completion; using PrettyPrompt.Consoles; using PrettyPrompt.Documents; using PrettyPrompt.Highlighting; using System.Collections.Immutable; public class MyPromptCallbacks : PromptCallbacks { private readonly (string Name, string Description, AnsiColor Color)[] completionItems = new[] { ("apple", "A round fruit with red or green skin", AnsiColor.BrightRed), ("banana", "A long curved yellow fruit", AnsiColor.BrightYellow), ("cherry", "A small round red fruit", AnsiColor.Red), }; // Provide syntax highlighting for input text protected override Task> HighlightCallbackAsync( string text, CancellationToken cancellationToken) { var highlights = new List(); foreach (var item in completionItems) { int index = 0; while ((index = text.IndexOf(item.Name, index, StringComparison.OrdinalIgnoreCase)) != -1) { highlights.Add(new FormatSpan(index, item.Name.Length, item.Color)); index += item.Name.Length; } } return Task.FromResult>(highlights); } // Provide autocompletion items protected override Task> GetCompletionItemsAsync( string text, int caret, TextSpan spanToBeReplaced, CancellationToken cancellationToken) { var typedWord = text.Substring(spanToBeReplaced.Start, spanToBeReplaced.Length); var items = completionItems .Where(item => item.Name.StartsWith(typedWord, StringComparison.OrdinalIgnoreCase)) .Select(item => new CompletionItem( replacementText: item.Name, displayText: new FormattedString(item.Name, new FormatSpan(0, item.Name.Length, item.Color)), getExtendedDescription: _ => Task.FromResult(item.Description), commitCharacterRules: ImmutableArray.Create( new CharacterSetModificationRule( CharacterSetModificationKind.Add, ImmutableArray.Create(' ', '.'))) )) .ToList(); return Task.FromResult>(items); } // Register custom keyboard shortcuts protected override IEnumerable<(KeyPressPattern Pattern, KeyPressCallbackAsync Callback)> GetKeyPressCallbacks() { yield return (new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.F1), ShowHelp); yield return (new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.D), ClearAndSubmit); } private Task ShowHelp(string text, int caret, CancellationToken ct) { Console.WriteLine("\nAvailable commands: apple, banana, cherry"); return Task.FromResult(null); // null = stay on prompt } private Task ClearAndSubmit(string text, int caret, CancellationToken ct) { // Return non-null to submit the prompt with custom output return Task.FromResult( new KeyPressCallbackResult(input: "", output: "Cleared!")); } } // Usage var prompt = new Prompt(callbacks: new MyPromptCallbacks()); ``` -------------------------------- ### Define KeyPressPattern for Key Combinations Source: https://context7.com/waf/prettyprompt/llms.txt Illustrates creating KeyPressPattern instances to represent simple keys, keys with single or multiple modifiers, and direct character matches. These are used to define specific input triggers. ```csharp using PrettyPrompt.Consoles; using System; // Simple key without modifiers var enterKey = new KeyPressPattern(ConsoleKey.Enter); var tabKey = new KeyPressPattern(ConsoleKey.Tab); var escapeKey = new KeyPressPattern(ConsoleKey.Escape); // Key with single modifier var ctrlC = new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.C); var altF4 = new KeyPressPattern(ConsoleModifiers.Alt, ConsoleKey.F4); var shiftTab = new KeyPressPattern(ConsoleModifiers.Shift, ConsoleKey.Tab); // Key with multiple modifiers (combined with |) var ctrlShiftP = new KeyPressPattern( ConsoleModifiers.Control | ConsoleModifiers.Shift, ConsoleKey.P); var ctrlAltDel = new KeyPressPattern( ConsoleModifiers.Control | ConsoleModifiers.Alt, ConsoleKey.Delete); // Match by character (ignores modifiers except Shift for casing) var atSymbol = new KeyPressPattern('@'); var dollarSign = new KeyPressPattern('$'); // Use in custom callbacks protected override IEnumerable<(KeyPressPattern, KeyPressCallbackAsync)> GetKeyPressCallbacks() { // Ctrl+F1 for help yield return (new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.F1), ShowHelp); // Ctrl+Shift+C for copy as code yield return (new KeyPressPattern(ConsoleModifiers.Control | ConsoleModifiers.Shift, ConsoleKey.C), CopyAsCode); // F5 to run yield return (new KeyPressPattern(ConsoleKey.F5), RunCode); } // Check if a pattern matches a key press var pattern = new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.S); var keyInfo = new ConsoleKeyInfo('s', ConsoleKey.S, shift: false, alt: false, control: true); bool matches = pattern.Matches(keyInfo); // true ``` -------------------------------- ### Configure Console Buffer and Window Size Source: https://github.com/waf/prettyprompt/blob/main/tests/PrettyPrompt.IntegrationTests/Data/record Set the dimensions for the console buffer and the visible window. BufferHeight can be set to a large value to allow for scrolling. ```plaintext BufferWidth=120 BufferHeight=3000 CursorLeft=0 CursorTop=1 WindowWidth=120 WindowHeight=30 WindowLeft=0 WindowTop=0 ``` -------------------------------- ### Implement Async Streaming Input with StreamingInputCallbackResult Source: https://context7.com/waf/prettyprompt/llms.txt Inherit from PromptCallbacks to define custom key bindings that trigger asynchronous text streaming. The GenerateTextStream method must return an IAsyncEnumerable to facilitate real-time updates. ```csharp using PrettyPrompt; public class StreamingCallbacks : PromptCallbacks { protected override IEnumerable<(KeyPressPattern, KeyPressCallbackAsync)> GetKeyPressCallbacks() { // Ctrl+G to generate AI response yield return (new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.G), GenerateAIResponse); } private async Task GenerateAIResponse( string text, int caret, CancellationToken cancellationToken) { // Return a streaming result that will insert text as it arrives return new StreamingInputCallbackResult(GenerateTextStream(text, cancellationToken)); } private async IAsyncEnumerable GenerateTextStream( string prompt, [System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken ct) { // Simulate streaming AI response string[] words = { "The ", "answer ", "to ", "your ", "question ", "is: ", "42" }; foreach (var word in words) { if (ct.IsCancellationRequested) yield break; await Task.Delay(100, ct); // Simulate network latency yield return word; } } } // Usage var prompt = new Prompt(callbacks: new StreamingCallbacks()); Console.WriteLine("Press Ctrl+G to generate AI response"); while (true) { var response = await prompt.ReadLineAsync(); if (response.IsSuccess) { Console.WriteLine($"Final text: {response.Text}"); } } ``` -------------------------------- ### Handle PromptResult Input Source: https://context7.com/waf/prettyprompt/llms.txt Shows how to process user input, check submission keys, and utilize the cancellation token for long-running operations. ```csharp using PrettyPrompt; var prompt = new Prompt(); var response = await prompt.ReadLineAsync(); // Check if user submitted successfully (not cancelled with Ctrl+C) if (response.IsSuccess) { string userInput = response.Text; // Check which key was used to submit (Enter, Ctrl+Enter, etc.) if (response.SubmitKeyInfo.Modifiers.HasFlag(ConsoleModifiers.Control)) { Console.WriteLine("Submitted with Ctrl+Enter: " + userInput.ToUpper()); } else { Console.WriteLine("Submitted with Enter: " + userInput); } // Use the cancellation token for long-running operations try { await LongRunningOperation(userInput, response.CancellationToken); } catch (OperationCanceledException) { Console.WriteLine("Operation cancelled by user"); } } else { Console.WriteLine("User cancelled input with Ctrl+C"); } ``` -------------------------------- ### OverloadItem Class Source: https://context7.com/waf/prettyprompt/llms.txt Represents method overload information displayed in a tooltip pane. Shows method signature, summary, return type description, and parameter documentation. ```APIDOC ## OverloadItem Class - Method Signature Display ### Description The `OverloadItem` class represents method overload information displayed in a tooltip pane. Shows method signature, summary, return type description, and parameter documentation. ### Usage Example **Create overload items for method signature help:** ```csharp protected override Task<(IReadOnlyList, int ArgumentIndex)> GetOverloadsAsync( string text, int caret, CancellationToken cancellationToken) { // Check if we're inside a method call if (!text.Contains("Print(")) return Task.FromResult<(IReadOnlyList, int)>((Array.Empty(), 0)); var overloads = new List { new OverloadItem( signature: new FormattedString("void Print(string message)", new FormatSpan(0, 4, AnsiColor.Blue), // "void" keyword new FormatSpan(5, 5, AnsiColor.Yellow)), // "Print" method name summary: "Prints a message to the console.", returnDescription: "This method does not return a value.", parameters: new[] { new OverloadItem.Parameter("message", "The string to write to the console output.") } ), new OverloadItem( signature: new FormattedString("void Print(string format, params object[] args)", new FormatSpan(0, 4, AnsiColor.Blue), new FormatSpan(5, 5, AnsiColor.Yellow)), summary: "Prints a formatted message to the console.", returnDescription: FormattedString.Empty, parameters: new[] { new OverloadItem.Parameter("format", "A composite format string."), new OverloadItem.Parameter("args", "An object array containing values to format.") } ) }; // Determine which parameter the caret is on (0-indexed) int argumentIndex = text.Substring(0, caret).Count(c => c == ','); return Task.FromResult<(IReadOnlyList, int)>((overloads, argumentIndex)); } ``` ``` -------------------------------- ### Render ANSI Output with Syntax Highlighting Source: https://context7.com/waf/prettyprompt/llms.txt Use `RenderAnsiOutput` to generate ANSI escape sequences for syntax-highlighted text. Useful for displaying results with the same highlighting as the prompt input. Supports word wrapping. ```csharp using PrettyPrompt; using PrettyPrompt.Highlighting; // Generate highlighted output for display string code = "var result = Calculate(42);"; var formatting = new List { new FormatSpan(0, 3, AnsiColor.Blue), // "var" keyword new FormatSpan(4, 6, AnsiColor.Cyan), // "result" variable new FormatSpan(13, 9, AnsiColor.Yellow), // "Calculate" method new FormatSpan(23, 2, AnsiColor.Magenta) // "42" number }; // Render with word wrapping at console width string ansiOutput = Prompt.RenderAnsiOutput( text: code, formatting: formatting, textWidth: Console.BufferWidth ); // Write the highlighted output Console.WriteLine(ansiOutput); // Example: Display command results with syntax highlighting async Task DisplayResult(string result, IReadOnlyCollection highlights) { var output = Prompt.RenderAnsiOutput(result, highlights, Console.BufferWidth); Console.WriteLine("Result:"); Console.Write(output); Console.WriteLine(); // Reset formatting } // Complete REPL with highlighted input AND output var prompt = new Prompt(callbacks: new MyHighlightingCallbacks()); while (true) { var response = await prompt.ReadLineAsync(); if (!response.IsSuccess) continue; if (response.Text == "exit") break; // Process and get result var (resultText, resultHighlights) = ProcessAndHighlight(response.Text); // Display highlighted result var output = Prompt.RenderAnsiOutput(resultText, resultHighlights, Console.BufferWidth); Console.WriteLine(output); } ``` -------------------------------- ### Prompt.RenderAnsiOutput Source: https://context7.com/waf/prettyprompt/llms.txt The RenderAnsiOutput method generates ANSI escape sequences for displaying syntax-highlighted text, allowing for consistent formatting in console applications. ```APIDOC ## Prompt.RenderAnsiOutput ### Description Generates ANSI escape sequences for displaying syntax-highlighted text output. Useful for rendering results with the same highlighting used in the prompt input. ### Parameters - **text** (string) - The raw text to be rendered. - **formatting** (List) - A collection of formatting spans defining colors and styles. - **textWidth** (int) - The width for word wrapping. ### Request Example ```csharp string ansiOutput = Prompt.RenderAnsiOutput( text: "var result = Calculate(42);", formatting: formattingList, textWidth: Console.BufferWidth ); ``` ``` -------------------------------- ### PromptCallbacks Class - Customization Hooks Source: https://context7.com/waf/prettyprompt/llms.txt The PromptCallbacks class provides virtual methods for customizing prompt behavior including syntax highlighting, autocompletion, key press handling, and input formatting. Inherit from this class to implement custom behavior. ```APIDOC ## PromptCallbacks Class - Customization Hooks ### Description The `PromptCallbacks` class provides virtual methods for customizing prompt behavior including syntax highlighting, autocompletion, key press handling, and input formatting. Inherit from this class to implement custom behavior. ### Methods #### `HighlightCallbackAsync(string text, CancellationToken cancellationToken)` - **Description**: Provides syntax highlighting for input text. - **Returns**: A task that represents the asynchronous operation. The task result contains a read-only collection of `FormatSpan` objects, defining the highlighting. #### `GetCompletionItemsAsync(string text, int caret, TextSpan spanToBeReplaced, CancellationToken cancellationToken)` - **Description**: Provides autocompletion items based on the current input. - **Returns**: A task that represents the asynchronous operation. The task result contains a read-only list of `CompletionItem` objects. #### `GetKeyPressCallbacks()` - **Description**: Registers custom keyboard shortcuts and their associated callbacks. - **Returns**: An enumerable collection of tuples, where each tuple contains a `KeyPressPattern` and a `KeyPressCallbackAsync` delegate. ### Example Usage ```csharp using PrettyPrompt; using PrettyPrompt.Completion; using PrettyPrompt.Consoles; using PrettyPrompt.Documents; using PrettyPrompt.Highlighting; using System.Collections.Immutable; public class MyPromptCallbacks : PromptCallbacks { private readonly (string Name, string Description, AnsiColor Color)[] completionItems = new[] { ("apple", "A round fruit with red or green skin", AnsiColor.BrightRed), ("banana", "A long curved yellow fruit", AnsiColor.BrightYellow), ("cherry", "A small round red fruit", AnsiColor.Red), }; // Provide syntax highlighting for input text protected override Task> HighlightCallbackAsync( string text, CancellationToken cancellationToken) { var highlights = new List(); foreach (var item in completionItems) { int index = 0; while ((index = text.IndexOf(item.Name, index, StringComparison.OrdinalIgnoreCase)) != -1) { highlights.Add(new FormatSpan(index, item.Name.Length, item.Color)); index += item.Name.Length; } } return Task.FromResult>(highlights); } // Provide autocompletion items protected override Task> GetCompletionItemsAsync( string text, int caret, TextSpan spanToBeReplaced, CancellationToken cancellationToken) { var typedWord = text.Substring(spanToBeReplaced.Start, spanToBeReplaced.Length); var items = completionItems .Where(item => item.Name.StartsWith(typedWord, StringComparison.OrdinalIgnoreCase)) .Select(item => new CompletionItem( replacementText: item.Name, displayText: new FormattedString(item.Name, new FormatSpan(0, item.Name.Length, item.Color)), getExtendedDescription: _ => Task.FromResult(item.Description), commitCharacterRules: ImmutableArray.Create( new CharacterSetModificationRule( CharacterSetModificationKind.Add, ImmutableArray.Create(' ', '.'))))) .ToList(); return Task.FromResult>(items); } // Register custom keyboard shortcuts protected override IEnumerable<(KeyPressPattern Pattern, KeyPressCallbackAsync Callback)> GetKeyPressCallbacks() { yield return (new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.F1), ShowHelp); yield return (new KeyPressPattern(ConsoleModifiers.Control, ConsoleKey.D), ClearAndSubmit); } private Task ShowHelp(string text, int caret, CancellationToken ct) { Console.WriteLine("\nAvailable commands: apple, banana, cherry"); return Task.FromResult(null); // null = stay on prompt } private Task ClearAndSubmit(string text, int caret, CancellationToken ct) { // Return non-null to submit the prompt with custom output return Task.FromResult( new KeyPressCallbackResult(input: "", output: "Cleared!")); } } // Usage var prompt = new Prompt(callbacks: new MyPromptCallbacks()); ``` ``` -------------------------------- ### KeyPressPattern Definition Source: https://context7.com/waf/prettyprompt/llms.txt Defines a specific keyboard input pattern, supporting console keys with modifiers or character matching. ```APIDOC ## KeyPressPattern Struct ### Description Defines a keyboard input pattern for matching key presses. Supports ConsoleKey codes with ConsoleModifiers or direct character matching. ### Constructors - **KeyPressPattern(ConsoleKey)** - Matches a key without modifiers. - **KeyPressPattern(ConsoleModifiers, ConsoleKey)** - Matches a key with a specific modifier. - **KeyPressPattern(char)** - Matches a character input. ### Methods - **Matches(ConsoleKeyInfo)** (bool) - Checks if the provided key info matches the defined pattern. ``` -------------------------------- ### Clear Screen and Move Cursor Source: https://github.com/waf/prettyprompt/blob/main/tests/PrettyPrompt.IntegrationTests/Data/record Use ANSI escape codes to clear the screen from the cursor's current position and move the cursor to the beginning of the line. This is often used after reading input to prepare for new output. ```plaintext Write("#[1G\n#[0J") After Write: CursorLeft: 4 -> 0 CursorTop: 1 -> 2 ``` -------------------------------- ### Read User Input Source: https://github.com/waf/prettyprompt/blob/main/tests/PrettyPrompt.IntegrationTests/Data/record Pause execution and wait for user input. The ReadKey(True) function reads a single key press, and True indicates that the key should not be displayed in the console. ```plaintext ReadKey(True): Enter ``` -------------------------------- ### Write Line with Newline Source: https://github.com/waf/prettyprompt/blob/main/tests/PrettyPrompt.IntegrationTests/Data/record Write a string to the console followed by a newline character. This automatically advances the cursor to the next line. ```plaintext WriteLine("You wrote ") After WriteLine: CursorTop: 2 -> 3 ``` -------------------------------- ### CompletionItem Class Source: https://context7.com/waf/prettyprompt/llms.txt Represents a single item in the autocompletion menu. Supports formatted display text, lazy-loaded extended descriptions, custom filter text, and configurable commit character rules. ```APIDOC ## CompletionItem Class - Autocompletion Entry ### Description The `CompletionItem` class represents a single item in the autocompletion menu. Supports formatted display text, lazy-loaded extended descriptions, custom filter text, and configurable commit character rules. ### Usage Examples **Basic completion item:** ```csharp var simpleItem = new CompletionItem( replacementText: "Console.WriteLine" ); ``` **Completion item with formatted display and description:** ```csharp var formattedItem = new CompletionItem( replacementText: "Console.WriteLine", displayText: new FormattedString("Console.WriteLine", new FormatSpan(0, 7, AnsiColor.Cyan), // "Console" in cyan new FormatSpan(8, 9, AnsiColor.Yellow)), // "WriteLine" in yellow filterText: "writeline", // Custom filter text for matching getExtendedDescription: async ct => { // Lazy-load documentation (only called when item is selected) await Task.Delay(10, ct); // Simulate async lookup return new FormattedString( "Writes the specified string value to the standard output stream.", new FormatSpan(0, 6, new ConsoleFormat(Bold: true)) // "Writes" in bold ); }, commitCharacterRules: ImmutableArray.Create( new CharacterSetModificationRule(CharacterSetModificationKind.Add, ImmutableArray.Create('(', '.', ' ')), new CharacterSetModificationRule(CharacterSetModificationKind.Remove, ImmutableArray.Create('\t')) ) ); ``` **Custom completion item with priority override:** ```csharp public class PriorityCompletionItem : CompletionItem { private readonly int basePriority; public PriorityCompletionItem(string replacementText, int priority) : base(replacementText) { basePriority = priority; } public override int GetCompletionItemPriority(string text, int caret, TextSpan spanToBeReplaced) { var defaultPriority = base.GetCompletionItemPriority(text, caret, spanToBeReplaced); return defaultPriority >= 0 ? defaultPriority + basePriority : defaultPriority; } } ``` ``` -------------------------------- ### Check for User Color Preference Source: https://context7.com/waf/prettyprompt/llms.txt Checks if the user has disabled console colors using the NO_COLOR environment variable. This is useful for adapting application output to user preferences. ```csharp using PrettyPrompt; using PrettyPrompt.Highlighting; // Check if user has disabled colors via NO_COLOR environment variable if (PromptConfiguration.HasUserOptedOutFromColor) { Console.WriteLine("Colors are disabled by user preference"); } ``` -------------------------------- ### Custom CompletionItem with Priority Override Source: https://context7.com/waf/prettyprompt/llms.txt Define a custom CompletionItem that overrides the default priority calculation. This allows for custom sorting of completion suggestions based on specific logic. ```csharp public class PriorityCompletionItem : CompletionItem { private readonly int basePriority; public PriorityCompletionItem(string replacementText, int priority) : base(replacementText) { basePriority = priority; } public override int GetCompletionItemPriority(string text, int caret, TextSpan spanToBeReplaced) { var defaultPriority = base.GetCompletionItemPriority(text, caret, spanToBeReplaced); return defaultPriority >= 0 ? defaultPriority + basePriority : defaultPriority; } } ``` -------------------------------- ### AnsiColor Struct - Terminal Colors Source: https://context7.com/waf/prettyprompt/llms.txt Defines standard, bright, and RGB ANSI color codes for terminal output. Use for setting foreground and background colors, and for parsing color strings. ```csharp using PrettyPrompt.Highlighting; // Standard terminal colors (16-color palette) var red = AnsiColor.Red; var green = AnsiColor.Green; var blue = AnsiColor.Blue; var yellow = AnsiColor.Yellow; var cyan = AnsiColor.Cyan; var magenta = AnsiColor.Magenta; var white = AnsiColor.White; var black = AnsiColor.Black; // Bright variants var brightRed = AnsiColor.BrightRed; var brightGreen = AnsiColor.BrightGreen; var brightBlue = AnsiColor.BrightBlue; var brightYellow = AnsiColor.BrightYellow; var brightCyan = AnsiColor.BrightCyan; var brightMagenta = AnsiColor.BrightMagenta; var brightWhite = AnsiColor.BrightWhite; var brightBlack = AnsiColor.BrightBlack; // Gray // Full RGB colors (24-bit true color) var orange = AnsiColor.Rgb(255, 165, 0); var purple = AnsiColor.Rgb(128, 0, 128); var customBlue = AnsiColor.Rgb(30, 144, 255); var darkBackground = AnsiColor.Rgb(30, 30, 30); // Parse colors from strings if (AnsiColor.TryParse("#FF5733", out var parsedHex)) Console.WriteLine($"Parsed hex color: {parsedHex}"); if (AnsiColor.TryParse("BrightCyan", out var parsedName)) Console.WriteLine($"Parsed named color: {parsedName}"); // Get ANSI escape sequences for manual output string fgEscape = orange.GetEscapeSequence(AnsiColor.Type.Foreground); string bgEscape = darkBackground.GetEscapeSequence(AnsiColor.Type.Background); Console.Write($"{fgEscape}{bgEscape}Colored text\x1b[0m"); ``` -------------------------------- ### FormattedString Struct - Text with Formatting Source: https://context7.com/waf/prettyprompt/llms.txt Represents text with non-overlapping formatting spans. Supports string conversion, concatenation, substring, and building formatted strings dynamically. ```csharp using PrettyPrompt.Highlighting; // Implicit conversion from plain string FormattedString plain = "Hello, World!"; // String with multiple format spans var colored = new FormattedString("Hello, World!", new FormatSpan(0, 5, AnsiColor.Green), // "Hello" in green new FormatSpan(7, 5, AnsiColor.Blue)); // "World" in blue // String with full formatting (foreground, background, bold, underline) var fancy = new FormattedString("Important Message", new FormatSpan(0, 9, new ConsoleFormat( Foreground: AnsiColor.BrightYellow, Background: AnsiColor.Red, Bold: true, Underline: true ))) ; // Concatenation preserves formatting FormattedString combined = colored + " - " + fancy; // Substring with preserved formatting FormattedString sub = colored.Substring(0, 5); // "Hello" (still green) // Trim whitespace var padded = new FormattedString(" trimmed ", new FormatSpan(2, 7, AnsiColor.Cyan)); FormattedString trimmed = padded.Trim(); // "trimmed" (still cyan) // Replace text FormattedString replaced = colored.Replace("World", "Universe"); // Build formatted strings dynamically var builder = new FormattedStringBuilder(); builder.Append("Status: ", new ConsoleFormat(Bold: true)); builder.Append("OK", new ConsoleFormat(Foreground: AnsiColor.Green)); FormattedString status = builder.ToFormattedString(); // Using with completion items var completionDisplay = new FormattedString("Console.WriteLine", new FormatSpan(0, 7, new ConsoleFormat(Foreground: AnsiColor.Cyan)), new FormatSpan(8, 9, new ConsoleFormat(Foreground: AnsiColor.Yellow))); ```