feat: add new input processors (readline), add new figlet font
This commit is contained in:
125
InputProcessor.cs
Normal file
125
InputProcessor.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using Spectre.Console;
|
||||
|
||||
namespace AnchorCli
|
||||
{
|
||||
internal class InputProcessor
|
||||
{
|
||||
private static void DisplayText(int left, string buffer, int index = -1, string placeholder = "", int viewportOffset = 0)
|
||||
{
|
||||
Console.CursorLeft = left;
|
||||
|
||||
if (buffer.Length == 0 && index == 0)
|
||||
{
|
||||
AnsiConsole.Markup($"[grey dim]{placeholder}{new string(' ', Console.WindowWidth - 1 - left - placeholder.Length)}[/]");
|
||||
return;
|
||||
}
|
||||
|
||||
var visibleWidth = Console.WindowWidth - left - 1;
|
||||
var displayStart = Math.Min(viewportOffset, Math.Max(0, buffer.Length - 1));
|
||||
var displayEnd = Math.Min(displayStart + visibleWidth, buffer.Length);
|
||||
var displayBuffer = string.Concat(buffer.AsSpan(displayStart, displayEnd - displayStart), " ");
|
||||
|
||||
for (var i = 0; i < displayBuffer.Length; i++)
|
||||
{
|
||||
var actualIndex = displayStart + i;
|
||||
if (index != -1 && actualIndex == index)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Black;
|
||||
Console.BackgroundColor = ConsoleColor.White;
|
||||
}
|
||||
|
||||
Console.Write(displayBuffer[i]);
|
||||
|
||||
if (index != -1 && actualIndex == index)
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
// Fill remaining space with spaces
|
||||
var remainingSpaces = visibleWidth - displayBuffer.Length;
|
||||
if (remainingSpaces > 0)
|
||||
Console.Write(new string(' ', remainingSpaces));
|
||||
}
|
||||
|
||||
public static string ReadLine(string placeholder = "")
|
||||
{
|
||||
Console.CursorVisible = false;
|
||||
var buffer = string.Empty;
|
||||
var index = 0;
|
||||
var viewportOffset = 0;
|
||||
var left = Console.CursorLeft;
|
||||
|
||||
DisplayText(left, buffer, index, placeholder, viewportOffset);
|
||||
|
||||
while (true)
|
||||
{
|
||||
var inputKey = Console.ReadKey(intercept: true);
|
||||
switch (inputKey)
|
||||
{
|
||||
case { Key: ConsoleKey.Enter } when buffer.Length > 0:
|
||||
DisplayText(left, buffer);
|
||||
Console.WriteLine();
|
||||
return buffer;
|
||||
|
||||
case { Key: ConsoleKey.Backspace } when index > 0:
|
||||
index--;
|
||||
buffer = buffer.Remove(index, 1);
|
||||
break;
|
||||
|
||||
case { Key: ConsoleKey.Delete } when index < buffer.Length:
|
||||
buffer = buffer.Remove(index, 1);
|
||||
break;
|
||||
|
||||
case { Key: ConsoleKey.LeftArrow, Modifiers: ConsoleModifiers.Control }:
|
||||
while (index > 0 && buffer[index - 1] == ' ')
|
||||
index--;
|
||||
while (index > 0 && buffer[index - 1] != ' ')
|
||||
index--;
|
||||
break;
|
||||
|
||||
case { Key: ConsoleKey.RightArrow, Modifiers: ConsoleModifiers.Control }:
|
||||
while (index < buffer.Length && buffer[index] == ' ')
|
||||
index++;
|
||||
while (index < buffer.Length && buffer[index] != ' ')
|
||||
index++;
|
||||
break;
|
||||
|
||||
case { Key: ConsoleKey.LeftArrow } when index > 0:
|
||||
index--;
|
||||
break;
|
||||
|
||||
case { Key: ConsoleKey.RightArrow } when index < buffer.Length:
|
||||
index++;
|
||||
break;
|
||||
|
||||
case { Key: ConsoleKey.W, Modifiers: ConsoleModifiers.Control } when index > 0:
|
||||
var deleteStart = index;
|
||||
while (deleteStart > 0 && buffer[deleteStart - 1] == ' ')
|
||||
deleteStart--;
|
||||
while (deleteStart > 0 && buffer[deleteStart - 1] != ' ')
|
||||
deleteStart--;
|
||||
var charsToDelete = index - deleteStart;
|
||||
buffer = buffer.Remove(deleteStart, charsToDelete);
|
||||
index = deleteStart;
|
||||
break;
|
||||
|
||||
default:
|
||||
var keyChar = inputKey.KeyChar;
|
||||
if (!(char.IsLetterOrDigit(keyChar) || char.IsWhiteSpace(keyChar) || char.IsPunctuation(keyChar) || char.IsSymbol(keyChar)))
|
||||
break;
|
||||
|
||||
buffer = buffer.Insert(index, inputKey.KeyChar.ToString());
|
||||
index++;
|
||||
break;
|
||||
}
|
||||
// Adjust viewport for scrolling
|
||||
var visibleWidth = Console.WindowWidth - left - 1;
|
||||
if (index < viewportOffset)
|
||||
viewportOffset = index;
|
||||
else if (index >= viewportOffset + visibleWidth)
|
||||
viewportOffset = index - visibleWidth + 1;
|
||||
|
||||
DisplayText(left, buffer, index, placeholder, viewportOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user