/// <summary>
/// Reads a line of text from the console. Any interactions you've configured before calling this method will be in effect.
/// </summary>
/// <param name="initialBuffer">Optionally seed the prompt with an initial value that the end user can modify</param>
/// <returns>a line of text from the console</returns>
public ConsoleString ReadLine(ConsoleString initialBuffer = null)
{
RichCommandLineContext context;
lock (SyncLock)
{
context = new RichCommandLineContext(this.HistoryManager);
context.Console = this.Console;
context.ConsoleStartTop = this.Console.CursorTop;
context.ConsoleStartLeft = this.Console.CursorLeft;
}
if (initialBuffer != null)
{
lock (SyncLock)
{
context.ReplaceConsole(initialBuffer);
}
}
while (true)
{
context.Reset();
context.KeyPressed = this.Console.ReadKey(true);
lock (SyncLock)
{
context.CharacterToWrite = new ConsoleCharacter(context.KeyPressed.KeyChar);
context.BufferPosition = this.Console.CursorLeft - context.ConsoleStartLeft + (this.Console.CursorTop - context.ConsoleStartTop) * this.Console.BufferWidth;
if (context.BufferPosition < 0 || context.BufferPosition > context.Buffer.Count)
{
var message = string.Format("The cursor is not located within the bounds of the buffer. Cursor: {0},{1} Start position: {2},{3} Buffer position: {4} Buffer length: {5}", this.Console.CursorTop, this.Console.CursorLeft, context.ConsoleStartTop, context.ConsoleStartLeft, context.BufferPosition, context.Buffer.Count);
try
{
throw new IndexOutOfRangeException(message);
}
catch (Exception ex)
{
PowerLogger.LogLine(ex.ToString());
throw;
}
}
IKeyHandler handler = null;
if (KeyHandlers.TryGetValue(context.KeyPressed.Key, out handler) == false && IsWriteable(context.KeyPressed))
{
context.WriteCharacterForPressedKey();
DoSyntaxHighlighting(context);
}
else if (handler != null)
{
handler.Handle(context);
if (context.Intercept == false && IsWriteable(context.KeyPressed))
{
context.WriteCharacterForPressedKey();
}
DoSyntaxHighlighting(context);
if (context.IsFinished)
{
this.Console.WriteLine();
break;
}
}
if (AfterReadKey != null)
{
AfterReadKey(context);
}
}
}
return(new ConsoleString(context.Buffer));
}