0

I'm not sure how to word the question itself but what I mean is making console look like this:

enter image description here

"this" would be having the input cursor all the way down and prefixed with a string or character.

>

And not moving the cursor down if Console.ReadLine() is empty. enter image description here

It needs to be a xplatform application and I can't be using any native windows dll loading and things alike to make it possible (assuming that windows offers anything like that).

I'm not sure if that's achievable but if it please let me know how I can achieve it! Thank you.

Edit: If it's not possible having input cursor all the way down then just having it prefixed with > would work as well. Sadly, I don't know how to achieve either.

Yucked
  • 311
  • 1
  • 2
  • 10

2 Answers2

0

It's entirely possible

The colored font text and the big font title can be achieved with 'Colorful Console' and I highly recommend it.

When I'm building a console based solution and I want nice formatting that's what I'm using. Their site is nice as it demo what it can do. However there is a canveat with the maximum amount of different color you can display at any given time. That limit is 16 diferent color.

This project also allow you to use FIGlet font, that is the big title in red 'FourFort'. Some are included already but you can find more on the internet and can create your own.

http://colorfulconsole.com/

The licence type is MIT and you can find them on Github https://github.com/tomakita/Colorful.Console/blob/master/LICENSE.md

I compile in net core for both Windows and Linux without any problem

The other part, as I see it is to override some console behavior.

You could just write to the console with Console.Write and output that char so it prepend everything.

or

You can capture the input one character at the time, in a loop that will break only if a certain sequence is entered like 'Enter'. If you erease the input after you capture and then append it to what you kept from previous iteration you could create the illusion of that prefix '>'

Update

I wrote a proof of concept describing the second idea I proposed. Any 'static' content must be added in 'historyInput' variable. Here is the code:

using System;

namespace BeautifyConsoleSO
{
    class Program
    {
        static void Main(string[] args)
        {
            char inputPrefix = '>';
            bool flag = false;
            string historyInput = string.Empty;
            string currentInput = string.Empty;

            historyInput += "Hello World!";

            Console.WriteLine(historyInput);
            Console.Write(inputPrefix);

            while(flag != true)
            {
                ConsoleKeyInfo input = Console.ReadKey();

                switch(input.Key)
                {
                    case ConsoleKey.Spacebar:
                        currentInput += ' ';
                        break;
                    case ConsoleKey.Enter:
                        historyInput += Environment.NewLine;
                        historyInput += currentInput;
                        currentInput = string.Empty;
                        break;
                    case ConsoleKey.Backspace:
                        if(currentInput.Length > 0)
                        {
                            if (!currentInput[currentInput.Length - 1].Equals(' '))
                            {
                                currentInput = currentInput.Remove(currentInput.Length - 1);
                            }
                            else
                            {
                                currentInput = currentInput.Remove(currentInput.Length - 2);
                            }
                        }
                        break;
                    default:
                        currentInput += input.KeyChar;
                        break;
                }

                Console.Clear();
                Console.WriteLine(historyInput);
                Console.Write("{0}{1}", inputPrefix, currentInput);

            }

            Console.ReadLine();
        }

    }
}

It's not perfect however; it has some flickering effect. If I think of something better I will update it again.

Update 2

Here is a variant; Console.Clear() generate the flickering. This one limit the refresh by filing the equivalent of the console height with new line. I also added the count number in the cursor prefix, to demo it better.

using System;
using System.Linq;

namespace BeautifyConsoleSO
{
    class Program
    {
        static void Main(string[] args)
        {
            char inputPrefix = '>';
            bool flag = false;
            int clearConsoleRefreshSpeed = 100;
            int clearConsoleTick = 0;
            string historyInput = string.Empty;
            string currentInput = string.Empty;

            string fix = string.Concat(Enumerable.Repeat(Environment.NewLine, Console.WindowHeight));
            Console.WriteLine(fix);

            historyInput += "Hello World!";

            Console.WriteLine(historyInput);
            Console.Write(inputPrefix);

            while(flag != true)
            {
                ConsoleKeyInfo input = Console.ReadKey();

                switch(input.Key)
                {
                    case ConsoleKey.Spacebar:
                        currentInput += ' ';
                        break;
                    case ConsoleKey.Enter:
                        historyInput += Environment.NewLine;
                        historyInput += currentInput;
                        currentInput = string.Empty;
                        break;
                    case ConsoleKey.Backspace:
                        if(currentInput.Length > 0)
                        {
                            if (!currentInput[currentInput.Length - 1].Equals(' '))
                            {
                                currentInput = currentInput.Remove(currentInput.Length - 1);
                            }
                            else
                            {
                                currentInput = currentInput.Remove(currentInput.Length - 2);
                            }
                        }
                        break;
                    default:
                        currentInput += input.KeyChar;
                        break;
                }

                // attempt to fix flickering associated with Console.Clear()
                Console.WriteLine(fix);

                Console.WriteLine(historyInput);
                Console.Write("{0}{1}", clearConsoleTick + " " +  inputPrefix, currentInput);

                clearConsoleTick++;

                if(clearConsoleTick % clearConsoleRefreshSpeed == 0)
                {
                    Console.Clear();
                    Console.WriteLine(fix);
                }
            }

            Console.ReadLine();
        }

    }
}

I don't want to spam this answer but a third variant of this proof of concept could be achieved capturing each line instead of every character on a line.

  • Colorful.Console wasn't that much of a problem but thank you! – Yucked Jan 17 '20 at 16:36
  • @Yucked this comment is meant for your own answer below but I don't have enough point; keep in mind that if you plan to run your program in terminal GUI and not from ssh (tty terminal) you might suffer a performance penality on Console.SetCursorPosition on Linux system. This issue doesn't apply to Microsoft or Apple operating system. Check this for detail https://github.com/dotnet/corefx/issues/32174 –  Jan 17 '20 at 21:42
  • Hey it seems that it was fixed https://github.com/dotnet/corefx/pull/36049 – Yucked Jan 18 '20 at 04:07
0

So the answers I found were:

How can I put a string character before Console.ReadLine() Console application

Can Console.Clear be used to only clear a line instead of whole console?

Basically this bit:

// Prefix with >
                Console.Write("> ", Color.Crimson);

                var readInput = Console.ReadLine();

// Don't add a new line if input is empty
                if (string.IsNullOrWhiteSpace(readInput)) {
                    Console.SetCursorPosition(0, Console.CursorTop);
                    Console.Write(new string(' ', Console.WindowWidth)); 
                    Console.SetCursorPosition(0, Console.CursorTop - 1);
                    continue;
                }
Yucked
  • 311
  • 1
  • 2
  • 10