Linux - moving the console cursor visual

user129186 picture user129186 · Aug 4, 2016 · Viewed 8.2k times · Source

I'm currently designing a CLI interface for linux, and for various reasons I am not able to use ncurses. I am using exclusively C++ and the Qt framework.

Therefore, in order to have a user-friendly interface, I have to run this getch loop in a separate thread:

https://stackoverflow.com/a/912796/3605689

Which basically means I have to implement all basic functionalities (such as backspace) by myself. I have already implemented command completion and command history(like when you press tab or uparrow/downarrow in linux), but I can't figure out how to implement leftarrow/rightarrow (aka seeking through the typeahead).

Normally, I implement it like this: upon every gech which is not equal to -1, I check whether the user has pressed a special key (one that modifies the typeahead somehow). I then clear the stdout using the following function:

void inputobject::clear_line(int nletters)
{
    QTextStream(stdout) << "\033[2K";

    for(int i = 0; i < nletters;i++){
        QTextStream(stdout) << "\b";
    }

    rewind(stdout);
}

And replace it with something else, effectively simulating the typeahead. For example, in the case of backspace, I would save the command call clear_line, and print the command out again, just with one less letter, behaving exactly as a normal console application would.

My real problem is with the cursor, in the case of left/rightarrow, I need to move the cursor visual in order to be able to indicate where in the text is the user seeking:enter image description here

Because of the nature of how I rewrite the given stdout line to simulate the typeahead, it does not really matter where the cursor REALLY is, as long as it stays on the same line - it is just the visual that matters. How can I achieve moving the cursor visual on linux?

Answer

user129186 picture user129186 · Aug 8, 2016

The answer was provided in the comment by Evilruff:

Cursor Movement

ANSI escape sequences allow you to move the cursor around the screen at will. This is more useful for full screen user interfaces generated by shell scripts, but can also be used in prompts. The movement escape sequences are as follows:

  • Position the Cursor: \033[;H Or \033[L;Cf puts the cursor at line L and column C.
  • Move the cursor up N lines: \033[NA
  • Move the cursor down N lines: \033[NB
  • Move the cursor forward N columns: \033[NC
  • Move the cursor backward N columns: \033[ND

  • Clear the screen, move to (0,0): \033[2J

  • Erase to end of line: \033[K

  • Save cursor position: \033[s

  • Restore cursor position: \033[u