// Move down one line in the history. private static void MoveDown() { if (historyPosn == 0) { historyPosn = -1; SetCurrent(historySave); } else if (historyPosn > 0) { --historyPosn; SetCurrent(History.GetHistory(historyPosn)); } else { Console.Beep(); } }
// Move up one line in the history. private static void MoveUp() { if (historyPosn == -1) { if (History.Count > 0) { historySave = new String(buffer, 0, length); historyPosn = 0; SetCurrent(History.GetHistory(historyPosn)); } } else if ((historyPosn + 1) < History.Count) { ++historyPosn; SetCurrent(History.GetHistory(historyPosn)); } else { Console.Beep(); } }
// Read the next line of input using line editing. Returns "null" // if an EOF indication is encountered in the input. public static string ReadLine(string prompt, bool password) { if (password) { throw new NotSupportedException(); } ConsoleKeyInfo key; char ch; // Output the prompt. if (prompt != null) { Console.Write(prompt); } // Enter the main character input loop. posn = 0; length = 0; column = 0; lastColumn = 0; overwrite = false; historyPosn = -1; bool ctrlv = false; state = State.MoreInput; do { key = ConsoleExtensions.ReadKey(true); ch = key.KeyChar; if (ctrlv) { ctrlv = false; if ((ch >= 0x0001 && ch <= 0x001F) || ch == 0x007F) { // Insert a control character into the buffer. AddChar(ch); continue; } } if (ch != '\0') { switch (ch) { case '\u0001': { // CTRL-A: move to the home position. MoveHome(); } break; case '\u0002': { // CTRL-B: go back one character. MoveLeft(); } break; case '\u0003': { // CTRL-C encountered in "raw" mode. if (controlCInterrupts) { EndLine(); if (Interrupt != null) { Interrupt(null, EventArgs.Empty); } return(null); } else { CancelLine(prompt); lastWord.Length = 0; } } break; case '\u0004': { // CTRL-D: EOF or delete the current character. if (ControlDIsEOF) { lastWord.Length = 0; // Signal an EOF if the buffer is empty. if (length == 0) { EndLine(); return(null); } } else { Delete(); ResetComplete(State.MoreInput); } } break; case '\u0005': { // CTRL-E: move to the end position. MoveEnd(); } break; case '\u0006': { // CTRL-F: go forward one character. MoveRight(); } break; case '\u0007': { // CTRL-G: ring the terminal bell. Console.Beep(); } break; case '\u0008': case '\u007F': { if (key.Key == ConsoleKey.Delete) { // Delete the character under the cursor. Delete(); } else { // Delete the character before the cursor. Backspace(); } ResetComplete(State.MoreInput); } break; case '\u0009': { // Process a tab. Tab(prompt); } break; case '\u000A': case '\u000D': { // Line termination. EndLine(); ResetComplete(State.Done); lastWord.Length = 0; } break; case '\u000B': { // CTRL-K: erase until the end of the line. EraseToEnd(); } break; case '\u000C': { // CTRL-L: clear screen and redraw. Console.Clear(); Console.Write(prompt); Redraw(); } break; case '\u000E': { // CTRL-N: move down in the history. MoveDown(); } break; case '\u0010': { // CTRL-P: move up in the history. MoveUp(); } break; case '\u0015': { // CTRL-U: erase to the start of the line. EraseToStart(); ResetComplete(State.None); } break; case '\u0016': { // CTRL-V: prefix a control character. ctrlv = true; } break; case '\u0017': { // CTRL-W: erase the previous word. EraseWord(); ResetComplete(State.MoreInput); } break; case '\u0019': { // CTRL-Y: yank the last erased string. if (yankedString != null) { foreach (char ch2 in yankedString) { AddChar(ch2); } } } break; case '\u001A': { // CTRL-Z: Windows end of file indication. if (ControlZIsEOF && length == 0) { EndLine(); return(null); } } break; case '\u001B': { // Escape is "clear line". Clear(); ResetComplete(State.MoreInput); } break; default: { if (ch >= ' ') { // Ordinary character. AddChar(ch); ResetComplete(State.MoreInput); } } break; } } else if (key.Modifiers == (ConsoleModifiers)0) { switch (key.Key) { case ConsoleKey.Backspace: { // Delete the character before the cursor. Backspace(); ResetComplete(State.MoreInput); } break; case ConsoleKey.Delete: { // Delete the character under the cursor. Delete(); ResetComplete(State.MoreInput); } break; case ConsoleKey.Enter: { // Line termination. EndLine(); ResetComplete(State.Done); } break; case ConsoleKey.Escape: { // Clear the current line. Clear(); ResetComplete(State.None); } break; case ConsoleKey.Tab: { // Process a tab. Tab(prompt); } break; case ConsoleKey.LeftArrow: { // Move left one character. MoveLeft(); } break; case ConsoleKey.RightArrow: { // Move right one character. MoveRight(); } break; case ConsoleKey.UpArrow: { // Move up one line in the history. MoveUp(); } break; case ConsoleKey.DownArrow: { // Move down one line in the history. MoveDown(); } break; case ConsoleKey.Home: { // Move to the beginning of the line. MoveHome(); } break; case ConsoleKey.End: { // Move to the end of the line. MoveEnd(); } break; case ConsoleKey.Insert: { // Toggle insert/overwrite mode. overwrite = !overwrite; } break; } } else if ((key.Modifiers & ConsoleModifiers.Alt) != 0) { switch (key.Key) { case ConsoleKey.F: { // ALT-F: move forward a word. MoveForwardWord(); } break; case ConsoleKey.B: { // ALT-B: move backward a word. MoveBackwardWord(); } break; case ConsoleKey.D: { // ALT-D: erase until the end of the word. EraseToEndWord(); } break; case ConsoleKey.Backspace: case ConsoleKey.Delete: { // ALT-DEL: erase until the start of the word. EraseToStartWord(); } break; } } }while (state != State.Done); if (length == 0 && EnterIsDuplicate) { if (History.Count > 0) { return(History.GetHistory(0)); } } return(new String(buffer, 0, length)); }