void WaitAndProcessKeyPress() { var end = false; _beginOfLineCurPos = new Point(0, _Y); while (!end && !_exitAll) { var c = sc.ReadKey(true); _lastKeyInfo = c; var(id, left, top, right, bottom) = Console.ActualWorkArea(false); var printable = false; bool printOnlyCursorInfo = true; switch (c.Key) { case ConsoleKey.LeftArrow: lock (Console.ConsoleLock) { var p = Context.Out.CursorPos; if (_splitedLineIndex == 0) { if (p.X > 0) { Context.Out.CursorLeft = p.X - 1; } } else { var x = p.X - 1; if (x < left) { Context.Out.SetCursorPosConstraintedInWorkArea(right - 1, p.Y - 1, true, true, false); _splitedLineIndex--; } else { Context.Out.CursorLeft = x; } } _X = Context.Out.CursorLeft; _Y = Context.Out.CursorTop; } break; case ConsoleKey.RightArrow: lock (Console.ConsoleLock) { var line = _text[_currentLine]; var spl = Context.Out.GetIndexLineSplitsInWorkAreaConstraintedString(line, _beginOfLineCurPos, Context.Out.CursorPos.X, Context.Out.CursorPos.Y, true, false, !_rawMode); var index = spl.CursorIndex; var curY = Context.Out.CursorTop; if (index < spl.PrintSequences.TextLength) { Context.Out.SetCursorPosConstraintedInWorkArea(Context.Out.CursorLeft + 1, Context.Out.CursorTop, true, true, false); } _X = Context.Out.CursorLeft; _Y = Context.Out.CursorTop; if (Context.Out.CursorTop > curY) { _splitedLineIndex++; } } break; case ConsoleKey.DownArrow: lock (Console.ConsoleLock) { if (_currentLine < _text.Count - 1) { if (_linesSplits[_currentLine] == null) { _linesSplits[_currentLine] = GetLineSplits(_currentLine, 0, _Y); } if (_splitedLineIndex == _linesSplits[_currentLine].Count - 1) { _splitedLineIndex = 0; _currentLine++; _X = 0; _Y++; _beginOfLineCurPos.X = _X; _beginOfLineCurPos.Y = _Y; } else { _Y++; _splitedLineIndex++; } if (_Y < _barY) { Context.Out.SetCursorPos(_X, _Y); } else { _Y = _barY - 1; if (_splitedLineIndex == 0) { _beginOfLineCurPos.Y = _Y; } Scroll(-1); Context.Out.SetCursorPos(_X, _Y); } } #if dbg System.Diagnostics.Debug.WriteLine($"SCROLL DOWN: _lastVisibleLineIndex={_lastVisibleLineIndex} _splitedLastVisibleLineIndex={_splitedLastVisibleLineIndex} line={_text[_lastVisibleLineIndex]}"); #endif } break; case ConsoleKey.UpArrow: lock (Console.ConsoleLock) { if (_currentLine > 0 || _splitedLineIndex > 0) { if (_splitedLineIndex == 0) { _X = 0; _Y--; _currentLine--; _beginOfLineCurPos.X = _X; _beginOfLineCurPos.Y = _Y - (_linesSplits[_currentLine].Count - 1); _splitedLineIndex = _linesSplits[_currentLine].Count - 1; } else { _splitedLineIndex--; _Y--; } if (_Y >= 0) { Context.Out.SetCursorPos(_X, _Y); } else { _Y = 0; _beginOfLineCurPos.Y = _Y - (_linesSplits[_currentLine].Count - 1); Scroll(1); Context.Out.SetCursorPos(_X, _Y); } } #if dbg System.Diagnostics.Debug.WriteLine($"SCROLL UP: _lastVisibleLineIndex={_lastVisibleLineIndex} _splitedLastVisibleLineIndex={_splitedLastVisibleLineIndex} line={_text[_lastVisibleLineIndex]}"); #endif } break; case ConsoleKey.F1: OpenHelp(); break; default: printable = true; break; } if (c.Key == _cmdKey) { if (!_barVisible) { ToggleBarVisibility(); } if (_cmdInput) { if (_cmdBarIndex == _maxCmdBarIndex) { _cmdInput = false; printable = false; _statusText = null; printOnlyCursorInfo = false; _cmdInput = false; _cmdBarIndex = 0; if (_barVisible) { ToggleBarVisibility(); } } else { _cmdBarIndex++; } } else { _cmdInput = true; } if (_cmdInput) { printable = false; _statusText = _pressCmdKeyText + " " + GetBarIndex(); printOnlyCursorInfo = false; _cmdInput = true; } } if (printable) { if (_cmdInput) { var hideBar = true; switch (c.Key) { case ConsoleKey.I: // show file info bar hideBar = false; _statusText = null; _cmdInput = false; printOnlyCursorInfo = false; lock (Console.ConsoleLock) { BackupCursorPos(); EmptyInfoBar(); RestoreCursorPos(); } break; case ConsoleKey.V: // toggle bar vis ToggleBarVisibility(); break; case ConsoleKey.T: // file top break; case ConsoleKey.B: // file bottom break; case ConsoleKey.A: // previous page break; case ConsoleKey.Z: // next page break; case ConsoleKey.C: // clear editor if (_readOnly) { hideBar = false; break; } ClearCurrentEditor(); hideBar = false; printOnlyCursorInfo = false; break; case ConsoleKey.N: // new file ClearCurrentEditor(true); hideBar = false; printOnlyCursorInfo = false; break; case ConsoleKey.S: // save file if (_readOnly) { hideBar = false; break; } SaveFile(); break; case ConsoleKey.L: // load file break; case ConsoleKey.R: _rawMode = !_rawMode; _statusText = "raw mode is " + (_rawMode ? "enabled" : "disabled"); hideBar = false; printOnlyCursorInfo = false; RefreshEditor(); break; case ConsoleKey.X: // exit all _exitAll = true; break; case ConsoleKey.Q: // quit current editor - unstack to previous file if any, else exit CheckFileSaveDialog(); if (_editorBackups.Count == 0) { end = true; } else { hideBar = false; printOnlyCursorInfo = false; RestorePreviousFile(); } break; default: // invalid hideBar = false; _statusText = $"{Bred}Invalid comand key: '{c.Key}'.{Context.ShellEnv.Colors.Default} {_pressCmdKeyText} " + GetBarIndex(); printOnlyCursorInfo = false; break; } if (hideBar) { if (_barVisible) { ToggleBarVisibility(); } _cmdInput = false; printOnlyCursorInfo = false; } } } lock (Console.ConsoleLock) { BackupCursorPos(); DisplayInfoBar(false, printOnlyCursorInfo); RestoreCursorPos(); Context.Out.ShowCur(); printOnlyCursorInfo = true; } } Exit(); }