27

There are several libraries like ncurses that assist in making command-line GUIs.

Simply put, how do they work?

My first thought was that ncurses intercepts all keyboard input, and draws each "frame" by outputting it line-by-line normally. Closer inspection, however, reveals that each new frame overwrites the previous one. How does it modify lines that have already been outputted? Furthermore, how does it handle color?

EDIT: The same question applies to anything with a "fancy" interface, like vim and emacs.

Maxpm
  • 24,113
  • 33
  • 111
  • 170

2 Answers2

25

Text terminals have command sequences that do things like move the cursor to a particular position on the screen, insert characters, delete lines etc.

Each terminal type is different and has its own set of command sequences. ncurses has a databse (see terminfo for details)

Internally ncurses maintains 2 views of the screen: the current contents and what the screen should look like after the current pending changes are applied. Once the program requests a screen redraw, ncurses calculates an efficient way to update the screen to look like the desired view. The exact characters/command sequences output depend on what terminal type is in use.

jmunsch
  • 22,771
  • 11
  • 93
  • 114
Craig
  • 4,750
  • 22
  • 21
  • 3
    So you mean if one was to control the terminal without ncurses (which aims to be device-independent, but suppose I don't care about that), I could directly write to standard output these control characters, and I can change text already shown on any part of the screen even though most command line programs just print text below the prompt? – huggie Feb 13 '19 at 08:39
  • 3
    @huggie yes, but you would have to know what type of terminal your program is running on. Ncurses handles that automatically. – altermetax Sep 20 '20 at 17:27
6

curses (and ncurses, too, I think) works by moving the cursor around on the screen. There are control sequences to do such things. Take a look at the code again and you'll see them. These sequences are not ASCII control characters, they are strings starting with (umm...) ESC, maybe. Have a look here for a higher-level explanation.

Pete Wilson
  • 8,610
  • 6
  • 39
  • 51
  • Most terminals support (some of) the [ANSI escape sequences](https://en.wikipedia.org/wiki/ANSI_escape_code). They start with `\033[` where `\033` is indeed ESC. You can play around at your own terminal using `echo -e` to print a few of them and see what happens. (`reset` (type blindly and hit enter) will be your friend if you've managed to set the terminal to invisible…) – 5gon12eder Sep 21 '14 at 10:44