mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-04 10:35:27 +08:00 
			
		
		
		
	Add support for fake input in asciicast recordings
* Fixes a bug with `SelectionPrompt` and page size. * Allow `IAnsiConsoleInput` to return `null`.
This commit is contained in:
		
				
					committed by
					
						
						Phil Scott
					
				
			
			
				
	
			
			
			
						parent
						
							46abadaccb
						
					
				
				
					commit
					450d87f5d3
				
			@@ -0,0 +1,81 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
namespace Generator.Commands
 | 
			
		||||
{
 | 
			
		||||
    public sealed class AsciiCastInput : IAnsiConsoleInput
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Queue<(ConsoleKeyInfo?, int)> _input;
 | 
			
		||||
        private readonly Random _random = new Random();
 | 
			
		||||
 | 
			
		||||
        public AsciiCastInput()
 | 
			
		||||
        {
 | 
			
		||||
            _input = new Queue<(ConsoleKeyInfo?, int)>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void PushText(string input, int keypressDelayMs)
 | 
			
		||||
        {
 | 
			
		||||
            if (input is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(input));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (var character in input)
 | 
			
		||||
            {
 | 
			
		||||
                PushCharacter(character, keypressDelayMs);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void PushTextWithEnter(string input, int keypressDelayMs)
 | 
			
		||||
        {
 | 
			
		||||
            PushText(input, keypressDelayMs);
 | 
			
		||||
            PushKey(ConsoleKey.Enter, keypressDelayMs);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void PushCharacter(char input, int keypressDelayMs)
 | 
			
		||||
        {
 | 
			
		||||
            var delay = keypressDelayMs + _random.Next((int)(keypressDelayMs * -.2), (int)(keypressDelayMs * .2));
 | 
			
		||||
 | 
			
		||||
            switch (input)
 | 
			
		||||
            {
 | 
			
		||||
                case '↑':
 | 
			
		||||
                    PushKey(ConsoleKey.UpArrow, keypressDelayMs);
 | 
			
		||||
                    break;
 | 
			
		||||
                case '↓':
 | 
			
		||||
                    PushKey(ConsoleKey.DownArrow, keypressDelayMs);
 | 
			
		||||
                    break;
 | 
			
		||||
                case '↲':
 | 
			
		||||
                    PushKey(ConsoleKey.Enter, keypressDelayMs);
 | 
			
		||||
                    break;
 | 
			
		||||
                case '¦':
 | 
			
		||||
                    _input.Enqueue((null, delay));
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    var control = char.IsUpper(input);
 | 
			
		||||
                    _input.Enqueue((new ConsoleKeyInfo(input, (ConsoleKey)input, false, false, control), delay));
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void PushKey(ConsoleKey input, int keypressDelayMs)
 | 
			
		||||
        {
 | 
			
		||||
            var delay = keypressDelayMs + _random.Next((int)(keypressDelayMs * -.2), (int)(keypressDelayMs * .2));
 | 
			
		||||
            _input.Enqueue((new ConsoleKeyInfo((char)input, input, false, false, false), delay));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ConsoleKeyInfo? ReadKey(bool intercept)
 | 
			
		||||
        {
 | 
			
		||||
            if (_input.Count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                throw new InvalidOperationException("No input available.");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var result = _input.Dequeue();
 | 
			
		||||
 | 
			
		||||
            Thread.Sleep(result.Item2);
 | 
			
		||||
            return result.Item1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user