Search code examples
c#user-interfaceinputconsoleusability

(Closed) C# Console autocomplete / suggest input, Code Improvement


I am currently writing a C# console application. Part of it is, that the user needs to enter a fairly complex system name. To make it easier I wrote a function that uses a string[] keywords and auto completes the string the user is typing in - on the run.

The code is working and acts as expected, but I am curious how the code could be improved (e.g. usability, efficiency). Also, what functionalities are missing, which you'd expect?

Thank you for the feedback!

            if (Keywords.Length == 0)
                throw new Exception("No Keywords set!");

            bool searching          = true;                 // true while looking for the keyword
            Console.CursorVisible   = true;                 // To help users understand where they are typing
            string System           = "";                   // Initialization of output
            string suggestion       = Keywords[0];          // Initialization of default suggestion
            int toClear             = suggestion.Length;    // Get the length of the line that needs to be cleared

            while (searching)
            {
                Console.Write(new String(' ', toClear));    // Clear line
                Console.CursorLeft = 0;                     // Relocate cursor to line start
                Console.Write(System);                      // Write what has been written previously

                if(suggestion != "")                        // If there is a suggestion fitting the entered string,
                {                                           // complete the string in color and reset the cursor
                    int col = Console.CursorLeft;
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.Write(suggestion.Substring(System.Length));
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.CursorLeft      = col;
                }

                string tempInput = Console.ReadKey().KeyChar.ToString();

                if (tempInput.Equals("\r"))                 // Evaluate input:
                {                                           //  -> Enter
                    if (!suggestion.Equals(""))             //     Valid entry?
                    {
                        searching   = false;
                        System      = suggestion;           //      -> use suggestion
                    }
                }
                else if (tempInput.Equals("\b"))            // Deleting last sign
                {
                    if(System.Length>0)
                        System = System.Substring(0, System.Length - 1);
                }
                else                                        // Any other sign is added to the string
                    System      += tempInput;

                // Set length to clear, if suggestion == "", the system string length needs to be cleared
                toClear = (System.Length>suggestion.Length) ? System.Length : suggestion.Length;

                // Reset suggestion. If no match is found, suggestion remains empty
                suggestion = "";

                // Check keywords for suggestion
                for(int i= 0; i<Keywords.Length; i++)
                {
                    if (Keywords[i].StartsWith(System))
                    {
                        suggestion = Keywords[i];
                        break;
                    }
                }
            }

            // reset cursor visibility
            Console.CursorVisible = false;

            return System;

Solution

    1. Do not raise reserved exception types

      if (Keywords.Length == 0)
          throw new Exception("No Keywords set!");
      

      Instead use

      if (Keywords.Length == 0)
          throw new ArgumentException(nameof(Keywords), "No Keywords set!");
      
    2. I would not use System as a variable name. System is a very common namespace.

    3. Not sure is it is due to formatting, but the tabs between assignments are not consistent and make the code harder to read

    4. You calculate the length to clear, but never use it

      // Set length to clear, if suggestion == "", the system string length needs to be cleared toClear = (System.Length>suggestion.Length) ? System.Length : suggestion.Length;