Search code examples
cconsoleuartbare-metal

How to have right arow behavior in a console


I am trying to recreate a line editor in a bare metal environnement : a chip receiving and sending data in an UART.

The UART is linked to a keyboard on input and a screen on output.

To simulate left arrow, i send the character \b. I cannot find how to go right.

About memory solution

For now our system only send back the characters back to the UART to display it on the screen. There is no memory usage.
I thought of some solutions that need to memorize all the text inputed, for example the second part proposed in the @ikegami answer.

My question could then be :
The screen can understand \b as a backward move of the cursor. Is there a similar way to do it forward ? Or am i forced to compute it in the chip ?


Solution

  • \b was probably originally for printers. One could use it to print two characters on top of each other (e.g. A and _ to create an underlined A, or A and A to create a bold A).

    To move forward on a printer, one can simply print a space. Of course, on a terminal, that usually erases the existing character.

    Enter ANSI escape sequences. Maybe these will work for you. For example, printing "\e[C" will move the cursor forward one (up to the limits of the terminal) on some terminals.

    $ perl -e'
       print "abcd";
       print "\e[D\e[D\e[D";  # Go back
       print "e";             # Edit
       print "\e[C\e[C";      # Move forward
       print "f";             # Add more to the end
       print "\e[C";          # Move forward
       print "g\n";           # Add more to the end
    '
    aecdf g
    

    (The choice of language isn't relevant. It's just more compact to demo using Perl.)

    Alternatively, print a space. If that would overwrite a character you don't want overwritten, remember what that character is and print that character instead of a space.

    $ perl -e'
       print "abcd";
       print "\b\b\b";        # Go back
       print "e";             # Edit
       print "cd";            # Move forward
       print "f";             # Add more to the end
       print " ";             # Move forward
       print "g\n";
    '
    aecdf g