/// <summary> /// Reads a line of input text from the underlying console. /// </summary> /// <returns>The line of text, or null if the end of input was /// encountered.</returns> public string ReadLine() { var cursorWasVisible = ConsoleOutput.CursorVisible; var ctrlCWasInput = ConsoleInput.TreatControlCAsInput; try { ConsoleInputOperationResult consoleKeyResult; ConsoleOutput.CursorVisible = true; ConsoleInput.TreatControlCAsInput = true; UpdateCursorSize(); do { // Grab a new key press event. var key = ConsoleInput.ReadKey(true); #if VERBOSE // Log information about the key press. LogKey(key); #endif // Process the event. try { consoleKeyResult = ProcessKey(key); } catch (NotImplementedException) { consoleKeyResult = ConsoleInputOperationResult.Normal; } }while (consoleKeyResult == ConsoleInputOperationResult.Normal); switch (consoleKeyResult) { case ConsoleInputOperationResult.EndOfInputStream: return(null); case ConsoleInputOperationResult.EndOfInputLine: ConsoleOutput.WriteLine(string.Empty); break; } var result = LineInput.Contents; // Add to history. LineInput.SaveToHistory(); // Reset temporary state LineInput.ClearLine(true); return(result); } finally { ConsoleOutput.CursorVisible = cursorWasVisible; ConsoleInput.TreatControlCAsInput = ctrlCWasInput; ConsoleOutput.CursorSize = _defaultCursorSize; } }
internal ConsoleInputOperationResult Process(ConsoleInputOperation op, ConsoleKeyInfo key) { var result = ConsoleInputOperationResult.Normal; switch (op) { case ConsoleInputOperation.NoOp: break; case ConsoleInputOperation.ProcessCharacter: ProcessCharacterKey(key.KeyChar); break; // // Standard readline operations. // case ConsoleInputOperation.AcceptLine: result = ConsoleInputOperationResult.EndOfInputLine; break; case ConsoleInputOperation.EndOfFile: if (string.IsNullOrEmpty(LineInput.Contents)) { ConsoleOutput.WriteLine(string.Empty); result = ConsoleInputOperationResult.EndOfInputStream; } break; case ConsoleInputOperation.BeginningOfLine: LineInput.MoveCursorToStart(); break; case ConsoleInputOperation.EndOfLine: LineInput.MoveCursorToEnd(); break; case ConsoleInputOperation.ForwardChar: LineInput.MoveCursorForward(1); break; case ConsoleInputOperation.BackwardChar: LineInput.MoveCursorBackward(1); break; case ConsoleInputOperation.ClearScreen: LineInput.ClearScreen(); break; case ConsoleInputOperation.PreviousHistory: LineInput.ReplaceWithLastLineInHistory(); break; case ConsoleInputOperation.NextHistory: LineInput.ReplaceWithNextLineInHistory(); break; case ConsoleInputOperation.KillLine: LineInput.CutToEnd(); break; case ConsoleInputOperation.UnixWordRubout: LineInput.DeleteBackwardThroughLastWord(); break; case ConsoleInputOperation.Yank: LineInput.Paste(); break; case ConsoleInputOperation.Abort: LineInput.ClearLine(true); result = ConsoleInputOperationResult.EndOfInputLine; break; case ConsoleInputOperation.ForwardWord: LineInput.MoveCursorForwardOneWord(); break; case ConsoleInputOperation.BackwardWord: LineInput.MoveCursorBackwardOneWord(); break; case ConsoleInputOperation.BeginningOfHistory: LineInput.ReplaceWithOldestLineInHistory(); break; case ConsoleInputOperation.EndOfHistory: LineInput.ReplaceWithYoungestLineInHistory(); break; case ConsoleInputOperation.UpcaseWord: LineInput.TransformCurrentWord(word => word.ToUpper()); break; case ConsoleInputOperation.DowncaseWord: LineInput.TransformCurrentWord(word => word.ToLower()); break; case ConsoleInputOperation.CapitalizeWord: LineInput.TransformCurrentWord(Capitalize); break; case ConsoleInputOperation.KillWord: LineInput.DeleteForwardToNextWord(); break; case ConsoleInputOperation.PossibleCompletions: LineInput.DisplayAllCompletions(); break; case ConsoleInputOperation.InsertCompletions: LineInput.ReplaceCurrentTokenWithAllCompletions(); break; case ConsoleInputOperation.RevertLine: LineInput.ClearLine(false); break; case ConsoleInputOperation.InsertComment: if (CommentCharacter.HasValue) { LineInput.MoveCursorToStart(); LineInput.Insert(CommentCharacter.Value); return(ConsoleInputOperationResult.EndOfInputLine); } break; case ConsoleInputOperation.TabInsert: ProcessCharacterKey('\t'); break; case ConsoleInputOperation.BackwardKillWord: LineInput.DeleteBackwardThroughLastWord(); break; // // Extensions: // case ConsoleInputOperation.CompleteTokenNext: { var lastOpWasCompleteToken = _lastOp.HasValue && ((_lastOp.Value == ConsoleInputOperation.CompleteTokenNext) || (_lastOp.Value == ConsoleInputOperation.CompleteTokenPrevious)); ProcessTabKeyPress(false, lastOpWasCompleteToken); break; } case ConsoleInputOperation.CompleteTokenPrevious: { var lastOpWasCompleteToken = _lastOp.HasValue && ((_lastOp.Value == ConsoleInputOperation.CompleteTokenNext) || (_lastOp.Value == ConsoleInputOperation.CompleteTokenPrevious)); ProcessTabKeyPress(true, lastOpWasCompleteToken); break; } case ConsoleInputOperation.DeletePreviousChar: LineInput.DeletePrecedingChar(); break; case ConsoleInputOperation.DeleteChar: LineInput.Delete(); break; case ConsoleInputOperation.ToggleInsertMode: LineInput.InsertMode = !LineInput.InsertMode; UpdateCursorSize(); break; // // Unimplemented standard readline operations: // case ConsoleInputOperation.ReverseSearchHistory: // TODO: implement ReverseSearchHistory case ConsoleInputOperation.ForwardSearchHistory: // TODO: implement ForwardSearchHistory case ConsoleInputOperation.QuotedInsert: // TODO: implement QuotedInsert case ConsoleInputOperation.TransposeChars: // TODO: implement TransposeChars case ConsoleInputOperation.UnixLineDiscard: // TODO: implement UnixLineDiscard case ConsoleInputOperation.Undo: // TODO: implement Undo case ConsoleInputOperation.SetMark: // TODO: implement SetMark case ConsoleInputOperation.CharacterSearch: // TODO: implement CharacterSearch case ConsoleInputOperation.YankLastArg: // TODO: implement YankLastArg case ConsoleInputOperation.NonIncrementalReverseSearchHistory: // TODO: implement NonIncrementalReverseSearchHistory case ConsoleInputOperation.NonIncrementalForwardSearchHistory: // TODO: implement NonIncrementalForwardSearchHistory case ConsoleInputOperation.YankPop: // TODO: implement YankPop case ConsoleInputOperation.TildeExpand: // TODO: implement TildeExpand case ConsoleInputOperation.YankNthArg: // TODO: implement YankNthArg case ConsoleInputOperation.CharacterSearchBackward: // TODO: implement CharacterSearchBackward break; default: throw new ArgumentOutOfRangeException(nameof(op)); } return(result); }