public void CleanUpReadln() { if (_inputReaderThread != null) { lock (ConsoleLock) { var(id, left, top, right, bottom) = ActualWorkArea(); Out.SetCursorPosConstraintedInWorkArea(_beginOfLineCurPos); var txt = _inputReaderStringBuilder.ToString(); var slines = Out.GetWorkAreaStringSplits(txt, _beginOfLineCurPos).Splits; var enableConstraintConsolePrintInsideWorkArea = EnableConstraintConsolePrintInsideWorkArea; EnableConstraintConsolePrintInsideWorkArea = false; foreach (var sline in slines) { if (sline.Y >= top && sline.Y <= bottom) { Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint("".PadLeft(right - sline.X, ' ')); } } EnableConstraintConsolePrintInsideWorkArea = enableConstraintConsolePrintInsideWorkArea; Out.SetCursorPosConstraintedInWorkArea(_beginOfLineCurPos); _inputReaderStringBuilder.Clear(); } } }
void Initialize(ExpressionEvaluationCommandDelegate evalCommandDelegate = null) { if (evalCommandDelegate == null && CommandLineProcessor != null) { _evalCommandDelegate = CommandLineProcessor.Eval; } ViewSizeChanged += (o, e) => { if (_inputReaderThread != null) { lock (ConsoleLock) { Out.Echo(_prompt); _beginOfLineCurPos = Out.CursorPos; Out.ConsolePrint(_inputReaderStringBuilder.ToString()); } } }; WorkAreaScrolled += (o, e) => { if (_inputReaderThread != null) { lock (ConsoleLock) { _beginOfLineCurPos.X += e.DeltaX; _beginOfLineCurPos.Y += e.DeltaY; var p = Out.CursorPos; var(id, left, top, width, height) = ActualWorkArea(); var txt = _inputReaderStringBuilder.ToString(); if (!string.IsNullOrWhiteSpace(txt)) { var index = Out.GetIndexInWorkAreaConstraintedString(txt, _beginOfLineCurPos, p); var slines = Out.GetWorkAreaStringSplits(txt, _beginOfLineCurPos).Splits; if (Out.CursorTop == slines.Min(o => o.Y)) { Out.CursorLeft = left; Out.Echo(_prompt); } var enableConstraintConsolePrintInsideWorkArea = EnableConstraintConsolePrintInsideWorkArea; EnableConstraintConsolePrintInsideWorkArea = false; foreach (var sline in slines) { if (sline.Y >= top && sline.Y <= height) { Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint("".PadLeft(width - sline.X, ' ')); Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint(sline.Text); } } EnableConstraintConsolePrintInsideWorkArea = enableConstraintConsolePrintInsideWorkArea; Out.SetCursorPos(p); } } } }; }
public CommandVoidResult History( CommandEvaluationContext context, [Option("i", "invoke the command at the entry number in the history list", true, true)] int num, [Option("c", "clear the loaded history list")] bool clear, [Option("w", "write history lines to the history file (content of the file is replaced)")] [OptionRequireParameter("file")] bool writeToFile, [Option("a", "append history lines to the history file")] [OptionRequireParameter("file")] bool appendToFile, [Option("r", "read the history file and append the content to the history list")] [OptionRequireParameter("file")] bool readFromFile, [Option("n", "read the history file and append the content not already in the history list to the history list")] [OptionRequireParameter("file")] bool appendFromFile, [Parameter(1, "file", true)] FilePath file ) { var hist = context.CommandLineProcessor.CmdsHistory.History; var max = hist.Count().ToString().Length; int i = 1; var f = DefaultForegroundCmd; if (num > 0) { if (num < 1 || num > hist.Count) { Errorln($"history entry number out of range (1..{hist.Count})"); return(new CommandVoidResult(ReturnCode.Error)); } var h = hist[num - 1]; context.CommandLineProcessor.CommandLineReader.SendNextInput(h); return(new CommandVoidResult()); } if (clear) { context.CommandLineProcessor.CmdsHistory.ClearHistory(); return(new CommandVoidResult()); } if (appendToFile || readFromFile || appendFromFile || writeToFile) { file ??= context.CommandLineProcessor.CmdsHistory.FilePath; if (file.CheckPathExists()) { if (writeToFile) { File.Delete(context.CommandLineProcessor.CmdsHistory.FilePath.FullName); File.AppendAllLines(file.FullName, hist); } if (appendToFile) { File.AppendAllLines(file.FullName, hist); } if (readFromFile) { var lines = File.ReadAllLines(file.FullName); foreach (var line in lines) { context.CommandLineProcessor.CmdsHistory.HistoryAppend(line); } context.CommandLineProcessor.CmdsHistory.HistorySetIndex(-1, false); } if (appendFromFile) { var lines = File.ReadAllLines(file.FullName); foreach (var line in lines) { if (!context.CommandLineProcessor.CmdsHistory.HistoryContains(line)) { context.CommandLineProcessor.CmdsHistory.HistoryAppend(line); } } context.CommandLineProcessor.CmdsHistory.HistorySetIndex(-1, false); } } return(new CommandVoidResult()); } foreach (var h in hist) { if (context.CommandLineProcessor.CancellationTokenSource.IsCancellationRequested) { break; } var hp = $" {ColorSettings.Numeric}{i.ToString().PadRight(max + 2, ' ')}{f}"; context.Out.Echo(hp); Out.ConsolePrint(h, true); i++; } return(new CommandVoidResult()); }
public int BeginReadln( AsyncCallback asyncCallback, string prompt = null, bool waitForReaderExited = true, bool loop = true ) { _waitForReaderExited = waitForReaderExited; prompt ??= _defaultPrompt; _prompt = prompt; bool noWorkArea = !InWorkArea; Point?lastInputPos = null; var hm = CommandLineProcessor?.ModuleManager?.ModuleHookManager; var context = CommandLineProcessor?.CommandEvaluationContext; _inputReaderThread = new Thread(() => { try { var isRunning = true; while (isRunning) { if (!loop) { isRunning = false; } _inputReaderStringBuilder ??= new StringBuilder(); if (!_readingStarted) { lock (ConsoleLock) { hm?.InvokeHooks(context, Hooks.PromptOutputBegin); var _beginPromptPos = Out.CursorPos; Out.Echo(prompt); hm?.InvokeHooks(context, Hooks.PromptOutputEnd); _beginOfLineCurPos = Out.CursorPos; lastInputPos = _beginOfLineCurPos; Out.ConsoleCursorPosBackup(); #if FIX_LOW_ANSI // TODO only if compatibility mode is enabled OR never (check the best) Thread.Sleep(25); Out.ConsoleCursorPosRestore(); #endif _readingStarted = true; } } var eol = false; try { while (!eol) { ConsoleKeyInfo c; var printed = false; string printedStr = ""; var(id, left, top, right, bottom) = ActualWorkArea(); if (sc.IsInputRedirected) { _sentInput = sc.In.ReadToEnd(); isRunning = false; } if (_sentInput == null) { c = sc.ReadKey(true); #if dbg System.Diagnostics.Debug.WriteLine($"{c.KeyChar}={c.Key}"); #endif #region handle special keys - edition mode, movement if (!_ignoreNextKey) { // normally the cursor has moved of 1 character right or left var cPos = Out.CursorPos; if (lastInputPos.HasValue && lastInputPos.Value != cPos) { int dx = Math.Abs(cPos.X - lastInputPos.Value.X); int dy = Math.Abs(cPos.Y - lastInputPos.Value.Y); if (dx > 1 || dy > 1) { // restore the good position Out.CursorPos = new Point( lastInputPos.Value.X + 1, lastInputPos.Value.Y); } } lastInputPos = Out.CursorPos; (id, left, top, right, bottom) = ActualWorkArea(); switch (c.Key) { /// <summary> /// CR: default end of input /// </summary> case ConsoleKey.Enter: eol = true; break; /// <summary> /// ESC : clean-up input and set cursor at begin of line (after prompt) /// </summary> case ConsoleKey.Escape: //Out.HideCur(); CleanUpReadln(); lastInputPos = _beginOfLineCurPos; //Out.ShowCur(); break; /// <summary> /// HOME : set cursor position at begin of input (just after prompt) /// </summary> case ConsoleKey.Home: lock (ConsoleLock) { Out.SetCursorPosConstraintedInWorkArea(_beginOfLineCurPos); lastInputPos = _beginOfLineCurPos; } break; /// <summary> /// END : set cursor position at end of input /// </summary> case ConsoleKey.End: lock (ConsoleLock) { var slines = Out.GetWorkAreaStringSplits(_inputReaderStringBuilder.ToString(), _beginOfLineCurPos); var sline = slines.Splits.Last(); Out.SetCursorPosConstraintedInWorkArea(sline.X + sline.Length, sline.Y); lastInputPos = Out.CursorPos; } break; case ConsoleKey.Tab: lock (ConsoleLock) { printedStr = "".PadLeft(TabLength, ' '); printed = true; } break; case ConsoleKey.LeftArrow: lock (ConsoleLock) { var p = Out.CursorPos; if (p.Y == _beginOfLineCurPos.Y) { if (p.X > _beginOfLineCurPos.X) { Out.CursorLeft = p.X - 1; } } else { var x = p.X - 1; if (x < left) { Out.SetCursorPosConstraintedInWorkArea(right - 1, p.Y - 1); } else { Out.CursorLeft = x; } } } break; case ConsoleKey.RightArrow: lock (ConsoleLock) { var txt = _inputReaderStringBuilder.ToString(); var index = Out.GetIndexInWorkAreaConstraintedString(txt, _beginOfLineCurPos, Out.CursorPos); if (index < txt.Length) { Out.SetCursorPosConstraintedInWorkArea(Out.CursorLeft + 1, Out.CursorTop); } } break; case ConsoleKey.Backspace: lock (ConsoleLock) { var txt = _inputReaderStringBuilder.ToString(); var index = Out.GetIndexInWorkAreaConstraintedString(txt, _beginOfLineCurPos, Out.CursorPos) - 1; var x = Out.CursorLeft - 1; var y = Out.CursorTop; if (index >= 0) { _inputReaderStringBuilder.Remove(index, 1); _inputReaderStringBuilder.Append(" "); Out.HideCur(); Out.SetCursorPosConstraintedInWorkArea(ref x, ref y); var slines = Out.GetWorkAreaStringSplits(_inputReaderStringBuilder.ToString(), _beginOfLineCurPos).Splits; var enableConstraintConsolePrintInsideWorkArea = EnableConstraintConsolePrintInsideWorkArea; EnableConstraintConsolePrintInsideWorkArea = false; foreach (var sline in slines) { if (sline.Y >= top && sline.Y <= bottom) { Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint("".PadLeft(right - sline.X, ' ')); Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint(sline.Text); } } _inputReaderStringBuilder.Remove(_inputReaderStringBuilder.Length - 1, 1); EnableConstraintConsolePrintInsideWorkArea = enableConstraintConsolePrintInsideWorkArea; Out.SetCursorPos(x, y); Out.ShowCur(); } } break; case ConsoleKey.Delete: lock (ConsoleLock) { var txt = _inputReaderStringBuilder.ToString(); var index = Out.GetIndexInWorkAreaConstraintedString(txt, _beginOfLineCurPos, Out.CursorPos); var x = Out.CursorLeft; var y = Out.CursorTop; if (index >= 0 && index < txt.Length) { _inputReaderStringBuilder.Remove(index, 1); _inputReaderStringBuilder.Append(" "); Out.HideCur(); Out.SetCursorPosConstraintedInWorkArea(ref x, ref y); var slines = Out.GetWorkAreaStringSplits(_inputReaderStringBuilder.ToString(), _beginOfLineCurPos).Splits; var enableConstraintConsolePrintInsideWorkArea = EnableConstraintConsolePrintInsideWorkArea; EnableConstraintConsolePrintInsideWorkArea = false; foreach (var sline in slines) { if (sline.Y >= top && sline.Y <= bottom) { Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint("".PadLeft(right - sline.X, ' ')); Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint(sline.Text); } } _inputReaderStringBuilder.Remove(_inputReaderStringBuilder.Length - 1, 1); EnableConstraintConsolePrintInsideWorkArea = enableConstraintConsolePrintInsideWorkArea; Out.SetCursorPos(x, y); Out.ShowCur(); } } break; case ConsoleKey.UpArrow: lock (ConsoleLock) { if (Out.CursorTop == _beginOfLineCurPos.Y) { var h = CommandLineProcessor.CmdsHistory.GetBackwardHistory(); if (h != null) { Out.HideCur(); CleanUpReadln(); _inputReaderStringBuilder.Append(h); Out.ConsolePrint(h); lastInputPos = Out.CursorPos; Out.ShowCur(); } } else { Out.SetCursorPosConstraintedInWorkArea( (Out.CursorTop - 1) == _beginOfLineCurPos.Y ? Math.Max(_beginOfLineCurPos.X, Out.CursorLeft) : Out.CursorLeft, Out.CursorTop - 1); } } break; case ConsoleKey.DownArrow: lock (ConsoleLock) { var slines = Out.GetWorkAreaStringSplits(_inputReaderStringBuilder.ToString(), _beginOfLineCurPos).Splits; if (Out.CursorTop == slines.Max(o => o.Y)) { var fh = CommandLineProcessor.CmdsHistory.GetForwardHistory(); if (fh != null) { Out.HideCur(); CleanUpReadln(); _inputReaderStringBuilder.Append(fh); Out.ConsolePrint(fh); lastInputPos = Out.CursorPos; Out.ShowCur(); } } else { var sline = slines.Where(o => o.Y == Out.CursorTop + 1).FirstOrDefault(); // BUG: ici sline est null if (sline.Text != null) { Out.SetCursorPosConstraintedInWorkArea(Math.Min(Out.CursorLeft, sline.X + sline.Length), Out.CursorTop + 1); } } } break; default: printedStr = c.KeyChar + ""; printed = true; break; } } else { _ignoreNextKey = false; } #endregion } else { printedStr = _sentInput; _sentInput = null; printed = true; eol = printedStr.EndsWith(Environment.NewLine); if (eol) { printedStr = printedStr.Trim(); } } if (printed) { var index = 0; var insert = false; lock (ConsoleLock) { var x0 = Out.CursorLeft; var y0 = Out.CursorTop; var txt = _inputReaderStringBuilder.ToString(); index = Out.GetIndexInWorkAreaConstraintedString(txt, _beginOfLineCurPos, x0, y0); insert = index - txt.Length < 0; if (insert) { Out.HideCur(); var x = x0; var y = y0; Out.SetCursorPosConstraintedInWorkArea(ref x, ref y); _inputReaderStringBuilder.Insert(index, printedStr); var slines = Out.GetWorkAreaStringSplits(_inputReaderStringBuilder.ToString(), _beginOfLineCurPos).Splits; var enableConstraintConsolePrintInsideWorkArea = EnableConstraintConsolePrintInsideWorkArea; EnableConstraintConsolePrintInsideWorkArea = false; foreach (var sline in slines) { if (sline.Y >= top && sline.Y <= bottom) { Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint(sline.Text); } } EnableConstraintConsolePrintInsideWorkArea = enableConstraintConsolePrintInsideWorkArea; x += printedStr.Length; Out.SetCursorPosConstraintedInWorkArea(ref x, ref y); Out.ShowCur(); } if (!insert) { _inputReaderStringBuilder.Append(printedStr); Out.ConsolePrint(printedStr, false); } } } if (eol) { break; } } } catch /*(Exception inputProcessingException)*/ { // input processing crashed : re-engage prompt, mute error } // process input var s = _inputReaderStringBuilder.ToString(); _inputReaderStringBuilder.Clear(); // put the cursor at the end of the input try { var slines = Out.GetWorkAreaStringSplits(s, _beginOfLineCurPos).Splits; if (slines.Count() > 0) { var sline = slines.Last(); Out.CursorPos = new Point(/*(sline.Text.Length==0)?0:*/ sline.Text.Length + sline.X, sline.Y); } } catch (Exception) { } var _enableConstraintConsolePrintInsideWorkArea = EnableConstraintConsolePrintInsideWorkArea; if (noWorkArea) { EnableConstraintConsolePrintInsideWorkArea = false; } asyncCallback?.Invoke( new BeginReadlnAsyncResult(s) ); if (noWorkArea) { EnableConstraintConsolePrintInsideWorkArea = _enableConstraintConsolePrintInsideWorkArea; } _readingStarted = false; if (_nextPrompt != null) { prompt = _prompt = _nextPrompt; _nextPrompt = null; } } } catch (ThreadInterruptedException) { // normal end } catch (Exception inputStreamReaderThreadException) { LogException(inputStreamReaderThreadException, "input stream reader crashed"); } }) { Name = "input stream reader" }; _inputReaderThread.Start(); if (waitForReaderExited) { _inputReaderThread.Join(); } return((int)ReturnCode.OK); }
public int BeginReadln( AsyncCallback asyncCallback, string prompt = null, bool waitForReaderExited = true, bool loop = true ) { _waitForReaderExited = waitForReaderExited; prompt ??= _defaultPrompt; _prompt = prompt; bool noWorkArea = !InWorkArea; _inputReaderThread = new Thread(() => { try { var isRunning = true; while (isRunning) { if (!loop) { isRunning = false; } _inputReaderStringBuilder ??= new StringBuilder(); if (!_readingStarted) { lock (ConsoleLock) { Out.Echo(prompt); _beginOfLineCurPos = Out.CursorPos; } _readingStarted = true; } var eol = false; while (!eol) { ConsoleKeyInfo c; var printed = false; string printedStr = ""; var(id, left, top, right, bottom) = ActualWorkArea(); if (sc.IsInputRedirected) { _sentInput = sc.In.ReadToEnd(); isRunning = false; } if (_sentInput == null) { c = sc.ReadKey(true); #if dbg System.Diagnostics.Debug.WriteLine($"{c.KeyChar}={c.Key}"); #endif #region handle special keys - edition mode, movement if (!_ignoreNextKey) { (id, left, top, right, bottom) = ActualWorkArea(); switch (c.Key) { case ConsoleKey.Enter: eol = true; break; case ConsoleKey.Escape: Out.HideCur(); CleanUpReadln(); Out.ShowCur(); break; case ConsoleKey.Home: lock (ConsoleLock) { Out.SetCursorPosConstraintedInWorkArea(_beginOfLineCurPos); } break; case ConsoleKey.End: lock (ConsoleLock) { var slines = Out.GetWorkAreaStringSplits(_inputReaderStringBuilder.ToString(), _beginOfLineCurPos); var sline = slines.Splits.Last(); Out.SetCursorPosConstraintedInWorkArea(sline.X + sline.Length, sline.Y); } break; case ConsoleKey.Tab: lock (ConsoleLock) { printedStr = "".PadLeft(TabLength, ' '); printed = true; } break; case ConsoleKey.LeftArrow: lock (ConsoleLock) { var p = Out.CursorPos; if (p.Y == _beginOfLineCurPos.Y) { if (p.X > _beginOfLineCurPos.X) { Out.CursorLeft = p.X - 1; } } else { var x = p.X - 1; if (x < left) { Out.SetCursorPosConstraintedInWorkArea(right - 1, p.Y - 1); } else { Out.CursorLeft = x; } } } break; case ConsoleKey.RightArrow: lock (ConsoleLock) { var txt = _inputReaderStringBuilder.ToString(); var index = Out.GetIndexInWorkAreaConstraintedString(txt, _beginOfLineCurPos, Out.CursorPos); if (index < txt.Length) { Out.SetCursorPosConstraintedInWorkArea(Out.CursorLeft + 1, Out.CursorTop); } } break; case ConsoleKey.Backspace: lock (ConsoleLock) { var txt = _inputReaderStringBuilder.ToString(); var index = Out.GetIndexInWorkAreaConstraintedString(txt, _beginOfLineCurPos, Out.CursorPos) - 1; var x = Out.CursorLeft - 1; var y = Out.CursorTop; if (index >= 0) { _inputReaderStringBuilder.Remove(index, 1); _inputReaderStringBuilder.Append(" "); Out.HideCur(); Out.SetCursorPosConstraintedInWorkArea(ref x, ref y); var slines = Out.GetWorkAreaStringSplits(_inputReaderStringBuilder.ToString(), _beginOfLineCurPos).Splits; var enableConstraintConsolePrintInsideWorkArea = EnableConstraintConsolePrintInsideWorkArea; EnableConstraintConsolePrintInsideWorkArea = false; foreach (var sline in slines) { if (sline.Y >= top && sline.Y <= bottom) { Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint("".PadLeft(right - sline.X, ' ')); Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint(sline.Text); } } _inputReaderStringBuilder.Remove(_inputReaderStringBuilder.Length - 1, 1); EnableConstraintConsolePrintInsideWorkArea = enableConstraintConsolePrintInsideWorkArea; Out.SetCursorPos(x, y); Out.ShowCur(); } } break; case ConsoleKey.Delete: lock (ConsoleLock) { var txt = _inputReaderStringBuilder.ToString(); var index = Out.GetIndexInWorkAreaConstraintedString(txt, _beginOfLineCurPos, Out.CursorPos); var x = Out.CursorLeft; var y = Out.CursorTop; if (index >= 0 && index < txt.Length) { _inputReaderStringBuilder.Remove(index, 1); _inputReaderStringBuilder.Append(" "); Out.HideCur(); Out.SetCursorPosConstraintedInWorkArea(ref x, ref y); var slines = Out.GetWorkAreaStringSplits(_inputReaderStringBuilder.ToString(), _beginOfLineCurPos).Splits; var enableConstraintConsolePrintInsideWorkArea = EnableConstraintConsolePrintInsideWorkArea; EnableConstraintConsolePrintInsideWorkArea = false; foreach (var sline in slines) { if (sline.Y >= top && sline.Y <= bottom) { Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint("".PadLeft(right - sline.X, ' ')); Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint(sline.Text); } } _inputReaderStringBuilder.Remove(_inputReaderStringBuilder.Length - 1, 1); EnableConstraintConsolePrintInsideWorkArea = enableConstraintConsolePrintInsideWorkArea; Out.SetCursorPos(x, y); Out.ShowCur(); } } break; case ConsoleKey.UpArrow: lock (ConsoleLock) { if (Out.CursorTop == _beginOfLineCurPos.Y) { var h = CommandLineProcessor.CmdsHistory.GetBackwardHistory(); if (h != null) { Out.HideCur(); CleanUpReadln(); _inputReaderStringBuilder.Append(h); Out.ConsolePrint(h); Out.ShowCur(); } } else { Out.SetCursorPosConstraintedInWorkArea( (Out.CursorTop - 1) == _beginOfLineCurPos.Y ? Math.Max(_beginOfLineCurPos.X, Out.CursorLeft) : Out.CursorLeft, Out.CursorTop - 1); } } break; case ConsoleKey.DownArrow: lock (ConsoleLock) { var slines = Out.GetWorkAreaStringSplits(_inputReaderStringBuilder.ToString(), _beginOfLineCurPos).Splits; if (Out.CursorTop == slines.Max(o => o.Y)) { var fh = CommandLineProcessor.CmdsHistory.GetForwardHistory(); if (fh != null) { Out.HideCur(); CleanUpReadln(); _inputReaderStringBuilder.Append(fh); Out.ConsolePrint(fh); Out.ShowCur(); } } else { var sline = slines.Where(o => o.Y == Out.CursorTop + 1).FirstOrDefault(); // BUG: ici sline est null if (sline.Text != null) { Out.SetCursorPosConstraintedInWorkArea(Math.Min(Out.CursorLeft, sline.X + sline.Length), Out.CursorTop + 1); } } } break; default: printedStr = c.KeyChar + ""; printed = true; break; } } else { _ignoreNextKey = false; } #endregion } else { printedStr = _sentInput; _sentInput = null; printed = true; eol = printedStr.EndsWith(Environment.NewLine); if (eol) { printedStr = printedStr.Trim(); } } if (printed) { var index = 0; var insert = false; lock (ConsoleLock) { var x0 = Out.CursorLeft; var y0 = Out.CursorTop; var txt = _inputReaderStringBuilder.ToString(); index = Out.GetIndexInWorkAreaConstraintedString(txt, _beginOfLineCurPos, x0, y0); insert = index - txt.Length < 0; if (insert) { Out.HideCur(); var x = x0; var y = y0; Out.SetCursorPosConstraintedInWorkArea(ref x, ref y); _inputReaderStringBuilder.Insert(index, printedStr); var slines = Out.GetWorkAreaStringSplits(_inputReaderStringBuilder.ToString(), _beginOfLineCurPos).Splits; var enableConstraintConsolePrintInsideWorkArea = EnableConstraintConsolePrintInsideWorkArea; EnableConstraintConsolePrintInsideWorkArea = false; foreach (var sline in slines) { if (sline.Y >= top && sline.Y <= bottom) { Out.SetCursorPos(sline.X, sline.Y); Out.ConsolePrint(sline.Text); } } EnableConstraintConsolePrintInsideWorkArea = enableConstraintConsolePrintInsideWorkArea; x += printedStr.Length; Out.SetCursorPosConstraintedInWorkArea(ref x, ref y); Out.ShowCur(); } if (!insert) { _inputReaderStringBuilder.Append(printedStr); Out.ConsolePrint(printedStr, false); } } } if (eol) { break; } } // process input var s = _inputReaderStringBuilder.ToString(); _inputReaderStringBuilder.Clear(); if (noWorkArea) { EnableConstraintConsolePrintInsideWorkArea = false; } asyncCallback?.Invoke( new BeginReadlnAsyncResult(s) ); if (noWorkArea) { EnableConstraintConsolePrintInsideWorkArea = true; } _readingStarted = false; if (_nextPrompt != null) { prompt = _prompt = _nextPrompt; _nextPrompt = null; } } } catch (ThreadInterruptedException) { } catch (Exception ex) { LogException(ex, "input stream reader crashed"); } }) { Name = "input stream reader" }; _inputReaderThread.Start(); if (waitForReaderExited) { _inputReaderThread.Join(); } return((int)ReturnCode.OK); }