public string ReadMyLine(Action <string> printStr, Func <string, string> tabcallback) { var buf = ""; while (true) { var k = Console.ReadKey(true); switch (k.Key) { case ConsoleKey.Tab: if (buf.Length == Console.BufferWidth - 1) { break; } var ret = tabcallback(buf); if (ret == null) { break; } if (!ret.Equals(buf)) { ExtendedConsole.ClearCurrentConsoleLine(); buf = ret; printStr(buf); } break; case ConsoleKey.Enter: return(buf); case ConsoleKey.Escape: buf = string.Empty; ExtendedConsole.ClearCurrentConsoleLine(); Console.SetCursorPosition(0, Console.CursorTop); break; case ConsoleKey.Backspace: if (buf.Length == 0) { break; } buf = buf.Substring(0, buf.Length - 1); Console.CursorLeft--; Console.Write(' '); Console.CursorLeft--; printStr(buf); break; case ConsoleKey.UpArrow: if (CommandHistoryIndex == CommandHistory.Count) { break; } ExtendedConsole.ClearCurrentConsoleLine(); Console.CursorLeft = 0; buf = CommandHistory[CommandHistory.Count - ++CommandHistoryIndex]; printStr(buf); break; case ConsoleKey.DownArrow: if (CommandHistoryIndex == 0) { break; } ExtendedConsole.ClearCurrentConsoleLine(); Console.CursorLeft = 0; buf = --CommandHistoryIndex == 0 ? "" : CommandHistory[CommandHistory.Count - CommandHistoryIndex]; printStr(buf); break; default: if (buf.Length == Console.BufferWidth - 1) { break; } if (char.IsLetterOrDigit(k.KeyChar) || char.IsPunctuation(k.KeyChar) || char.IsWhiteSpace(k.KeyChar) || char.IsSymbol(k.KeyChar)) { buf += k.KeyChar; printStr(buf); } break; } } }