static UserAssetTokenAction? SelectInteractive(ref QueryToken token, QueryDescription qd, SubTokensOptions options, bool allowRemoveToken, bool allowReGenerate) { var top = Console.CursorTop; try { if (Console.Out == null) throw new InvalidOperationException("Impossible to synchronize without interactive Console"); var subTokens = token.SubTokens(qd, options).OrderBy(a => a.Parent != null).ThenBy(a => a.Key).ToList(); int startingIndex = 0; SafeConsole.WriteLineColor(ConsoleColor.Cyan, " " + token.Try(a => a.FullKey())); bool isRoot = token == null; retry: int maxElements = Console.LargestWindowHeight - 11; subTokens.Skip(startingIndex).Take(maxElements) .Select((s, i) => "- {1,2}: {2} ".FormatWith(i + " ", i + startingIndex, ((isRoot && s.Parent != null) ? "-" : "") + s.Key)).ToConsole(); Console.WriteLine(); int remaining = subTokens.Count - startingIndex - maxElements; if (remaining > 0) SafeConsole.WriteLineColor(ConsoleColor.White, "- +: Show more values ({0} remaining)", remaining); if (token != null) { SafeConsole.WriteLineColor(ConsoleColor.White, "- b: Back"); SafeConsole.WriteLineColor(ConsoleColor.Green, "- c: Confirm"); } SafeConsole.WriteLineColor(ConsoleColor.Yellow, "- s: Skip entity"); if (allowRemoveToken) SafeConsole.WriteLineColor(ConsoleColor.DarkRed, "- r: Remove token"); if (allowReGenerate) SafeConsole.WriteLineColor(ConsoleColor.Magenta, "- g: Generate from default template"); SafeConsole.WriteLineColor(ConsoleColor.Red, "- d: Delete entity"); while (true) { string answer = Console.ReadLine(); if (answer == null) throw new InvalidOperationException("Impossible to synchronize interactively without Console"); answer = answer.ToLower(); if (answer == "+" && remaining > 0) { startingIndex += maxElements; goto retry; } if (answer == "s") return UserAssetTokenAction.SkipEntity; if (answer == "r" && allowRemoveToken) return UserAssetTokenAction.RemoveToken; if (answer == "d") return UserAssetTokenAction.DeleteEntity; if (answer == "g") return UserAssetTokenAction.ReGenerateEntity; if (token != null) { if (answer == "c") return UserAssetTokenAction.Confirm; if (answer == "b") { token = token.Parent; return null; } } int option = 0; if (int.TryParse(answer, out option)) { token = subTokens[option]; return null; } Console.WriteLine("Error"); } } finally { Clean(top, Console.CursorTop); } }