void Fail(string message = null, bool lineBreak = true) { var logMessage = ColorSettings.Error + "Fail" + (message == null ? "" : $" : {message}"); Out.Echo(logMessage, lineBreak); Log(logMessage); }
public void Warning(string s, bool lineBreak = false) { lock (Out.Lock) { Out.Echo($"{Colors.Warning}{s}{Colors.Default}", lineBreak); } }
void Info(string message, bool lineBreak = true) { var logMessage = ColorSettings.Log + message; Out.Echo(logMessage, lineBreak); Log(logMessage); }
public void Print(bool printAttributes = false, bool shortPath = false, string prefix = "", string postfix = "", int paddingRight = -1, string linePrefix = "") { var bg = GetCmd(EchoDirectives.b + "", DefaultBackground.ToString().ToLower()); var fg = GetCmd(EchoDirectives.f + "", DefaultForeground.ToString().ToLower()); var color = (IsDirectory) ? NormalDirectoryColorization : FileColorization; if (!IsSystem && IsDirectory && !IsReadOnly) { color += WritableDirectoryColorization; } if (IsSystem && !IsDirectory) { color += SystemColorization + bg; } if (IsSystem && IsDirectory && !IsReadOnly) { color += SystemWritableDirectoryColorization; } if (IsFile && IsReadOnly) { color += ReadOnlyFileColorization; } var endcolor = bg + fg; var r = ""; var attr = ""; string hidden = ""; if (printAttributes) { var dir = IsDirectory ? "d" : "-"; var ro = IsReadOnly ? "r-" : "rw"; var sys = IsSystem ? "s" : "-"; var h = IsHidden ? "h" : "-"; //var c = IsCompressed ? "c" : "-"; var a = IsArchive ? "a" : "-"; var size = (IsDirectory) ? "" : HumanFormatOfSize(((FileInfo)FileSystemInfo).Length, 2); var moddat = FileSystemInfo.LastWriteTime; hidden = IsHidden ? "*" : ""; var dat = (moddat.Year != System.DateTime.Now.Year) ? moddat.Year + "" : ""; var smoddat = $"{dat,4} {moddat.ToString("MMM", CultureInfo.InvariantCulture),-3} {moddat.Day,-2} {moddat.Hour.ToString().PadLeft(2,'0')}:{moddat.Minute.ToString().PadLeft(2,'0')}"; attr = $" {dir}{ro}{sys}{h}{a} {size,10} {smoddat} "; } var name = shortPath ? FileSystemInfo.Name : FileSystemInfo.FullName; var quote = name.Contains(' ') ? "\"" : ""; var pdr = paddingRight - name.Length; if (!string.IsNullOrWhiteSpace(quote)) { pdr -= 2; } var rightspace = (paddingRight > -1) ? endcolor + "".PadRight(pdr > 0?pdr:1, ' ') : ""; r += $"{linePrefix}{attr}{color}{prefix}{quote}{name}{quote}{hidden}{rightspace}{postfix}"; Out.Echo(r + ColorSettings.Default); if (HasError) { Out.Echo($" {ErrorColorization}{GetError()}"); } }
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 void Error(string s, bool lineBreak = false) { lock (Out.Lock) { Out.RedirectToErr = true; Out.Echo($"{Colors.Error}{s}{Colors.Default}", lineBreak); Out.RedirectToErr = false; } }
public string Readln(string prompt = null) { lock (Out.Lock) { if (prompt != null) { Out.Echo(prompt); } } return(sc.ReadLine()); }
static void Main(string[] args) { Out.Echo(ANSI.RIS); Out.ClearScreen(); var commandLineProcessor = new CommandLineProcessor( args, new OrbitalShellCommandLineProcessorSettings()); var commandLineReader = new CommandLineReader( commandLineProcessor); commandLineProcessor.Initialize(); var returnCode = commandLineReader.ReadCommandLine(); Environment.Exit(returnCode); }
/// <summary> /// display a bar of text that wait a text input /// </summary> /// <param name="text"></param> /// <param name="inputMap"></param> /// <returns></returns> public static object InputBar(string text, List <InputMap> inputMaps) { object r = null; Out.Echo($"{Colors.InteractionBar}{text}{ANSI.RSTXTA}"); bool end = false; string input = ""; while (!end) { var c = sc.ReadKey(true); if (!Char.IsControl(c.KeyChar)) { input += c.KeyChar; } bool partialMatch = false; foreach (var inputMap in inputMaps) { var match = inputMap.Match(input, c); if (match == InputMap.ExactMatch) { r = inputMap.Code; end = true; break; } partialMatch |= match == InputMap.PartialMatch; } if (!partialMatch) { input = ""; } System.Diagnostics.Debug.WriteLine($"{input}"); } return(r); }
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 void ProcessCommandLine( string commandLine, ExpressionEvaluationCommandDelegate evalCommandDelegate, bool outputStartNextLine = false, bool enableHistory = false, bool enablePrePostComOutput = true) { if (commandLine != null) { if (outputStartNextLine) { Out.LineBreak(); } ExpressionEvaluationResult expressionEvaluationResult = null; try { sc.CancelKeyPress += CancelKeyPress; CommandLineProcessor.CancellationTokenSource = new CancellationTokenSource(); Out.IsModified = false; Err.IsModified = false; var task = Task.Run <ExpressionEvaluationResult>( () => evalCommandDelegate( CommandLineProcessor.CommandEvaluationContext, commandLine, _prompt == null ? 0 : Out.GetPrint(_prompt).Length, // TODO has no sens with multi line prompt !!! (enablePrePostComOutput && CommandLineProcessor != null) ? CommandLineProcessor.CommandEvaluationContext.ShellEnv.GetValue <string>(ShellEnvironmentVar.settings_clr_comPreAnalysisOutput) : ""), CommandLineProcessor.CancellationTokenSource.Token ); try { try { task.Wait(CommandLineProcessor.CancellationTokenSource.Token); } catch (ThreadInterruptedException) { // get interrupted after send input } expressionEvaluationResult = task.Result; } catch (OperationCanceledException) { //var res = task.Result; expressionEvaluationResult = task.Result; Out.Warningln($"command canceled: {commandLine}"); } finally { } } catch (Exception ex) { LogError(ex); } finally { if (enablePrePostComOutput && CommandLineProcessor != null) { if (Out.IsModified || Err.IsModified) { if (!(Out.CursorLeft == 0 && Out.CursorTop == 0)) { Out.Echo(CommandLineProcessor.CommandEvaluationContext.ShellEnv.GetValue <string>(ShellEnvironmentVar.settings_clr_comPostExecOutModifiedOutput)); } } Out.Echo(CommandLineProcessor.CommandEvaluationContext.ShellEnv.GetValue <string>(ShellEnvironmentVar.settings_clr_comPostExecOutput)); } CommandLineProcessor.CancellationTokenSource.Dispose(); CommandLineProcessor.CancellationTokenSource = null; sc.CancelKeyPress -= CancelKeyPress; } } if (enableHistory && !string.IsNullOrWhiteSpace(commandLine)) { CommandLineProcessor.CmdsHistory.HistoryAppend(commandLine); } }
public static void Print( ConsoleTextWriterWrapper @out, CancellationTokenSource cancellationTokenSource, Table table, bool noBorders = false, bool padLastColumn = true) { @out.EnableFillLineFromCursor = false; @out.HideCur(); var colLengths = new int[table.Columns.Count]; foreach (var rw in table.Rows) { var cols = ((DataRow)rw).ItemArray; for (int i = 0; i < cols.Length; i++) { var s = @out.GetPrint(table.GetFormatedValue(table.Columns[i].ColumnName, cols[i]?.ToString())) ?? ""; colLengths[i] = Math.Max(s.Length, colLengths[i]); var s2 = @out.GetPrint(table.GetFormatedHeader(table.Columns[i].ColumnName)) ?? ""; colLengths[i] = Math.Max(s2.Length, colLengths[i]); } } var colsep = noBorders ? " " : (ColorSettings.TableBorder + " | " + ColorSettings.Default); var colseplength = noBorders ? 0 : 3; var tablewidth = noBorders ? 0 : 3; for (int i = 0; i < table.Columns.Count; i++) { tablewidth += table.Columns[i].ColumnName.PadRight(colLengths[i], ' ').Length + colseplength; } var line = noBorders ? "" : (ColorSettings.TableBorder + "".PadRight(tablewidth, '-')); if (!noBorders) { @out.Echoln(line); } for (int i = 0; i < table.Columns.Count; i++) { if (i == 0) { @out.Echo(colsep); } var col = table.Columns[i]; var colName = (i == table.Columns.Count - 1 && !padLastColumn) ? table.GetFormatedHeader(col.ColumnName) : table.GetFormatedHeader(col.ColumnName).PadRight(colLengths[i], ' '); @out.Echo(ColorSettings.TableColumnName + colName + colsep); } @out.Echoln(); if (!noBorders) { @out.Echoln(line); } foreach (var rw in table.Rows) { if (cancellationTokenSource.IsCancellationRequested) { @out.EnableFillLineFromCursor = true; @out.ShowCur(); @out.Echoln(ColorSettings.Default + ""); return; } var row = (DataRow)rw; var arr = row.ItemArray; for (int i = 0; i < arr.Length; i++) { if (i == 0) { Out.Echo(colsep); } var txt = (arr[i] == null) ? "" : arr[i].ToString(); var fvalue = table.GetFormatedValue(table.Columns[i].ColumnName, txt); var l = Out.GetPrint(fvalue).Length; var spc = (i == arr.Length - 1 && !padLastColumn) ? "" : ("".PadRight(Math.Max(0, colLengths[i] - l), ' ')); @out.Echo(ColorSettings.Default + fvalue + spc + colsep); } @out.Echoln(); } @out.Echoln(line + ColorSettings.Default.ToString()); @out.ShowCur(); @out.EnableFillLineFromCursor = true; }
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); }
static void _Echo( this DataTable table, ConsoleTextWriterWrapper @out, CommandEvaluationContext context, TableFormattingOptions options = null) { options ??= context.ShellEnv.GetValue <TableFormattingOptions>(ShellEnvironmentVar.display_tableFormattingOptions); @out.EnableFillLineFromCursor = false; @out.HideCur(); var colLengths = new int[table.Columns.Count]; foreach (var rw in table.Rows) { var cols = ((DataRow)rw).ItemArray; for (int i = 0; i < cols.Length; i++) { string s, s2; if (table is Table t) { s = @out.GetPrint(t.GetFormatedValue(context, table.Columns[i].ColumnName, cols[i]?.ToString())) ?? ""; colLengths[i] = Math.Max(s.Length, colLengths[i]); s2 = @out.GetPrint(t.GetFormatedHeader(table.Columns[i].ColumnName)) ?? ""; colLengths[i] = Math.Max(s2.Length, colLengths[i]); if (i == cols.Length - 1) { colLengths[i] = s.Length + 2; } } else { s = @out.GetPrint(cols[i]?.ToString()) ?? ""; colLengths[i] = Math.Max(s.Length, colLengths[i]); colLengths[i] = Math.Max(table.Columns[i].ColumnName.Length, colLengths[i]); if (i == cols.Length - 1) { colLengths[i] = 1; } if (i == cols.Length - 1) { colLengths[i] = s.Length + 2; } } } } var colsep = options.NoBorders ? " ".PadLeft(Math.Max(1, options.ColumnRightMargin)) : (context.ShellEnv.Colors.TableBorder + " | " + context.ShellEnv.Colors.Default); var colseplength = options.NoBorders ? 0 : 3; var tablewidth = options.NoBorders ? 0 : 3; for (int i = 0; i < table.Columns.Count; i++) { tablewidth += table.Columns[i].ColumnName.PadRight(colLengths[i], ' ').Length + colseplength; } var line = options.NoBorders ? "" : (context.ShellEnv.Colors.TableBorder + "".PadRight(tablewidth, '-')); if (!options.NoBorders) { @out.Echoln(line); } string fxh(string header) => (table is Table t) ? t.GetFormatedHeader(header) : header; // headers for (int i = 0; i < table.Columns.Count; i++) { if (!options.NoBorders && i == 0) { @out.Echo(colsep); } var col = table.Columns[i]; var colName = (i == table.Columns.Count - 1 && !options.PadLastColumn) ? fxh(col.ColumnName) : fxh(col.ColumnName).PadRight(colLengths[i], ' '); var prfx = (options.NoBorders) ? Uon : ""; var pofx = (options.NoBorders) ? Tdoff : ""; @out.Echo(context.ShellEnv.Colors.TableColumnName + prfx + colName + colsep + pofx); } @out.Echoln(); if (!options.NoBorders) { @out.Echoln(line); } // rows string fhv(string header, string value) => (table is Table t) ? t.GetFormatedValue(context, header, value) : value; foreach (var rw in table.Rows) { if (context.CommandLineProcessor.CancellationTokenSource.IsCancellationRequested) { @out.EnableFillLineFromCursor = true; @out.ShowCur(); @out.Echoln(context.ShellEnv.Colors.Default + ""); return; } var row = (DataRow)rw; var arr = row.ItemArray; for (int i = 0; i < arr.Length; i++) { if (!options.NoBorders && i == 0) { Out.Echo(colsep); } var txt = (arr[i] == null) ? "" : arr[i].ToString(); var fvalue = fhv(table.Columns[i].ColumnName, txt); var o = arr[i]; MethodInfo mi = null; if (((!(o is string)) || table.Columns[i].DataType == typeof(object)) && o != null && (mi = o.GetEchoMethod()) != null) { // value dump via Echo primitive @out.Echo("" + context.ShellEnv.Colors.Default); var p0 = @out.CursorPos; mi.InvokeEcho(o, new EchoEvaluationContext(@out, context, new FormatingOptions(options) { LineBreak = false })); var p1 = @out.CursorPos; if (p1.Y == p0.Y) { var l = p1.X - p0.X; var spc = (i == arr.Length - 1 && !options.PadLastColumn) ? "" : ("".PadRight(Math.Max(0, colLengths[i] - l), ' ')); @out.Echo(spc); } @out.Echo(colsep); } else { // value dump by ToString var l = @out.GetPrint(fvalue).Length; var spc = (i == arr.Length - 1 && !options.PadLastColumn) ? "" : ("".PadRight(Math.Max(0, colLengths[i] - l), ' ')); @out.Echo("" + context.ShellEnv.Colors.Default); @out.Echo(fvalue); @out.Echo(spc + colsep); } } @out.Echoln(); } @out.Echo(line + context.ShellEnv.Colors.Default.ToString()); @out.ShowCur(); @out.EnableFillLineFromCursor = true; }