public static void Redraw(bool full = false) { lock (DrawLock) { if (full) { Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.White; Console.SetCursorPosition(0, 0); Console.Clear(); _ChannelBuffers[_CurBuffer].Render(); _InputBox.Render(); } else { if (CurrentChannelBuffer.NeedsRender) { CurrentChannelBuffer.Render(); } var size = ConsoleHelper.Size; Graphics.DrawLine(new Point(0, size.Height - 2), new Point(size.Width - 1, size.Height - 2), ' ', ConsoleColor.DarkBlue); Graphics.WriteANSIString(StatusBar, new Point(0, size.Height - 2), ConsoleColor.DarkBlue, ConsoleColor.Gray); _InputBox.Focus(); } } }
static void InputLoop() { Console.InputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8; while (_Running) { try { var key = Console.ReadKey(true); if (key.Modifiers.HasFlag(ConsoleModifiers.Alt)) { switch (key.Key) { case ConsoleKey.D0: case ConsoleKey.D1: case ConsoleKey.D2: case ConsoleKey.D3: case ConsoleKey.D4: case ConsoleKey.D5: case ConsoleKey.D6: case ConsoleKey.D7: case ConsoleKey.D8: case ConsoleKey.D9: case ConsoleKey.Q: case ConsoleKey.W: case ConsoleKey.E: case ConsoleKey.R: case ConsoleKey.T: case ConsoleKey.Y: case ConsoleKey.U: case ConsoleKey.I: case ConsoleKey.O: case ConsoleKey.P: { // Switch buffer int buf = -1; if (key.Key > ConsoleKey.D9) { IReadOnlyDictionary <char, int> _CharMap = new Dictionary <char, int> { { 'q', 10 }, { 'w', 11 }, { 'e', 12 }, { 'r', 13 }, { 't', 14 }, { 'y', 15 }, { 'u', 16 }, { 'i', 17 }, { 'o', 18 }, { 'p', 19 } }; buf = _CharMap[key.KeyChar]; } else { buf = (key.Key - ConsoleKey.D1); if (buf < 0) { buf = 9; } } CurrentBuffer = buf; } break; case ConsoleKey.A: { // Go to activity var buf = _ChannelBuffers .Where(c => c.ChatActivity || c.Highlight) .OrderByDescending(c => (c.Highlight ? 2 : 0) + (c.ChatActivity ? 1 : 0)) .FirstOrDefault(); if (buf != null) { CurrentBuffer = _ChannelBuffers.IndexOf(buf); } } break; case ConsoleKey.H: case ConsoleKey.L: { // Next / Prev var dir = key.Key == ConsoleKey.H ? -1 : 1; var target = CurrentBuffer + dir; if (target < 0) { target = _ChannelBuffers.Count - 1; } else if (target >= _ChannelBuffers.Count) { target = 0; } CurrentBuffer = target; } break; case ConsoleKey.J: case ConsoleKey.K: { // Up / Down var dir = key.Key == ConsoleKey.J ? 1 : -1; CurrentChannelBuffer.Scroll += dir; CurrentChannelBuffer.Render(); } break; } } else { switch (key.Key) { case ConsoleKey.PageUp: case ConsoleKey.PageDown: { var dir = key.Key == ConsoleKey.PageDown ? 1 : -1; CurrentChannelBuffer.Scroll += CurrentChannelBuffer.Size.Height * dir; CurrentChannelBuffer.Render(); } break; case ConsoleKey.Tab: { var inp = _InputBox.Content as string; var completion = TabComplete(inp); if (completion == null || !completion.Found.Any()) { break; } var completions = completion.Found; var firstSpace = completion.TruePrefix.IndexOf(' '); var needsQuotes = firstSpace > -1 && firstSpace < completion.TruePrefix.Length - 1; if (inp.EndsWith("\"", StringComparison.OrdinalIgnoreCase)) { inp = inp.Substring(0, inp.Length - 1); } inp = inp.Substring(0, inp.Length - completion.Prefix.Length); if (inp.EndsWith("\"", StringComparison.OrdinalIgnoreCase)) { inp = inp.Substring(0, inp.Length - 1); } if (completions.Length == 1) { inp += (needsQuotes ? "\"" : "") + completions.First() + (needsQuotes ? "\"" : ""); } else { inp += (needsQuotes ? "\"" : "") + completion.TruePrefix; // TODO: Show available tab-completions } _InputBox.Content = inp; _InputBox.Cursor = inp.Length; _InputBox.Render(); } break; case ConsoleKey.Clear: Redraw(true); break; default: switch (key.KeyChar) { case '\x04': throw new EndOfStreamException(); case '\f': Redraw(true); break; default: _InputBox.PushInput(key); break; } break; } } } catch (EndOfStreamException) { return; } catch (TargetInvocationException ex) { if (ex.InnerException is AggregateException) { var agg = ex.InnerException as AggregateException; foreach (Exception inner in agg.InnerExceptions) { Debug.WriteLine("!! {0}: {1}\n{2}\n", inner.GetType().Name, inner.Message, inner.StackTrace); } } else { Debug.WriteLine(ex.InnerException.ToString()); } } catch (AggregateException ex) { Debug.WriteLine("{0} exception(s) occured running that command;", ex.InnerExceptions.Count); foreach (Exception inner in ex.InnerExceptions) { Debug.WriteLine("!! {0}: {1}\n{2}\n", inner.GetType().Name, inner.Message, inner.StackTrace); } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } } }