Skip to content

Instantly share code, notes, and snippets.

@benkoshy
Created February 10, 2018 11:11
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save benkoshy/7f6f28e158032534615773a9a1f73a10 to your computer and use it in GitHub Desktop.
Save benkoshy/7f6f28e158032534615773a9a1f73a10 to your computer and use it in GitHub Desktop.
Code Review - AutoCompletion Problem
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/// <summary>
/// Here is the original coder review question
/// https://codereview.stackexchange.com/questions/139172/autocompleting-console-input
/// </summary>

namespace Practice_CodeReview
{
    public class Program
    {
        public static void Main()
        {
            Program p = new Program(new string[4] { "Bar", "Barbec", "Barbecue", "Batman" });
            p.RunProgram();
        }

        private string[] keywords; 

        public Program(string[] keywords)
        {
            this.keywords = keywords;
        }
      
        public void RunProgram()
        {
            StringBuilder builder = new StringBuilder();
            ConsoleKeyInfo capturedCharacter = Console.ReadKey(intercept: true);

            while (EnterIsNotThe(capturedCharacter))
            {
                KeyInput key = KeyInput.GetKey(builder, keywords, capturedCharacter);
                builder = key.UpdateBuilder();
                key.Print();

                capturedCharacter = Console.ReadKey(intercept: true);
            }

            Console.Write(capturedCharacter.KeyChar);
        }

        private static bool EnterIsNotThe(ConsoleKeyInfo capturedCharacter)
        {
            return capturedCharacter.Key != ConsoleKey.Enter;
        }

        public abstract class KeyInput
        {
            StringBuilder builder;
            string[] keyWords;

            public KeyInput(StringBuilder builder, string[] keyWords)
            {
                this.builder = builder;
                this.keyWords = keyWords;
            }

            public abstract StringBuilder UpdateBuilder();

            public abstract void Print();

            #region Factory
            public static KeyInput GetKey(StringBuilder builder, string[] keywords, ConsoleKeyInfo keyInput)
            {
                if (keyInput.Key == ConsoleKey.Tab)
                {
                    KeyInput input = new KeyInput.TabInput(builder, keywords);
                    return input;
                }
                else
                {
                    if (keyInput.Key == ConsoleKey.Backspace && builder.ToString().Length > 0)
                    {
                        // Perform Calculation (nothing here)
                        Program.KeyInput input = new Program.KeyInput.BackspaceInput(builder, keywords);
                        return input;
                    }
                    else
                    {
                        // Perform calculation (nothing here)
                        KeyInput input = new KeyInput.StandardKeyInput(builder, keywords, keyInput.KeyChar);
                        return input;
                    }
                }
            } 
            #endregion

            #region Implementations
            public class TabInput : KeyInput
            {
                string match;
                public TabInput(StringBuilder builder, string[] keyWords) : base(builder, keyWords)
                {
                    // Perform calculation
                    this.match = extractMatch(base.builder);                    
                }

                private string extractMatch(StringBuilder builder)
                {
                    string match = base.keyWords.FirstOrDefault(item => item != builder.ToString() && item.StartsWith(builder.ToString(), true, CultureInfo.InvariantCulture));

                    if (string.IsNullOrEmpty(match))
                    {
                        return "";
                    }
                    else
                    {
                        return match;
                    }
                }

                public override void Print()
                {
                    ClearCurrentLine();

                    Console.Write(match);
                }

                private void ClearCurrentLine()
                {
                    var currentLine = Console.CursorTop;
                    Console.SetCursorPosition(0, Console.CursorTop);
                    Console.Write(new string(' ', Console.WindowWidth));
                    Console.SetCursorPosition(0, currentLine);
                }

                public override StringBuilder UpdateBuilder()
                {
                    // Alter the builder
                    base.builder.Clear();
                    base.builder.Append(match);

                    return base.builder;
                }
            }

            public class StandardKeyInput : KeyInput
            {
                char key;

                public StandardKeyInput(StringBuilder builder, string[] keyWords, char key) : base(builder, keyWords)
                {
                    this.key = key;                    
                }

                public override StringBuilder UpdateBuilder()
                {
                    base.builder.Append(key);
                    return base.builder;

                }

                public override void Print()
                {

                    // Print Reuslts
                    Console.Write(key);
                }
            }

            public class BackspaceInput : KeyInput
            {
                public BackspaceInput(StringBuilder builder, string[] keyWords) : base(builder, keyWords)
                {
                    
                }

                public override StringBuilder UpdateBuilder()
                {
                    // Alter the builder
                    base.builder.Remove(builder.Length - 1, 1);
                    return base.builder;
                }

                public string StringToPrint()
                {                    
                    return base.builder.ToString().Remove(builder.ToString().Length - 1);
                }

                public override void Print()
                {
                    // Print Results
                    ClearCurrentLine();
                    Console.Write(StringToPrint());
                }

                private void ClearCurrentLine()
                {
                    var currentLine = Console.CursorTop;
                    Console.SetCursorPosition(0, Console.CursorTop);
                    Console.Write(new string(' ', Console.WindowWidth));
                    Console.SetCursorPosition(0, currentLine);
                }
            } 
            #endregion
        }
    }
}
@CerebralMischief
Copy link

Thank you for this!

@2652660
Copy link

2652660 commented Aug 20, 2023

Thanks for this! Saved me a butt load. Have you been messing with ML and Robots.txt? I feel you would love the results with some Dynamic JSON/XML and crawling <3

@benkoshy
Copy link
Author

@2652660 sorry mate I have no idea what you mean?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment