124

I started to write a terminal text editor, something like the first text editors for UNIX, such as vi. My only goal is to have a good time, but I want to be able to show text in color, so I can have syntax highlighting for editing source code.

How can I achieve this? Is there some special POSIX API for this, or do I have to use ncurses? (I'd rather not)

Any advice? Maybe some textbooks on the UNIX API?

David Guyon
  • 2,759
  • 1
  • 28
  • 40
Nisanio
  • 4,056
  • 5
  • 34
  • 46
  • You can use **[this simple method](https://stackoverflow.com/a/57548072/5623035)** instead. It has some advantages over just printing colors too. – Mojtaba Hosseini Oct 02 '20 at 21:36

4 Answers4

195

This is a little C program that illustrates how you could use color codes:

#include <stdio.h>

#define KNRM  "\x1B[0m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"
#define KYEL  "\x1B[33m"
#define KBLU  "\x1B[34m"
#define KMAG  "\x1B[35m"
#define KCYN  "\x1B[36m"
#define KWHT  "\x1B[37m"

int main()
{
    printf("%sred\n", KRED);
    printf("%sgreen\n", KGRN);
    printf("%syellow\n", KYEL);
    printf("%sblue\n", KBLU);
    printf("%smagenta\n", KMAG);
    printf("%scyan\n", KCYN);
    printf("%swhite\n", KWHT);
    printf("%snormal\n", KNRM);

    return 0;
}
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • 113
    `printf(KMAG "magenta\n");` is much cleaner and faster than using `%s`. –  Feb 26 '11 at 12:43
  • 16
    This sets the default color forever after to this new text color. To set it back to the original employ KNRM. – Schroeder Apr 16 '13 at 22:34
  • Is it possible to use a specific color (perhaps with RGB values like `880000` for dark red, etc.), or are we stuck with the 8 colors in the above example? – Michael Dorst Jul 20 '13 at 07:33
  • There are color codes for darker colors, bold, and other effects I dont remember. But you cant specify RGB values. – karlphillip Jul 20 '13 at 12:13
  • 6
    @Schroeder `#define RESET "\033[0m"`, and then `printf(KMAG "magenta RESET \n");` – mf_ Jan 07 '14 at 19:41
  • 2
    Better yet, `puts( KMAG "magenta" RESET ) ;` – Florian Castellane Sep 22 '16 at 09:40
  • 3
    @mf_ what you typed probably is not what you meant... what you typed won't work because things within quotes aren't handled by the preprocessor. – mah Dec 12 '17 at 23:36
  • if it happens to separate the KMxx from RESET on two printf, printing "\n" in between will not reset the colors. – alsaleem Nov 23 '20 at 20:58
139

Different solution that I find more elegant

Here's another way to do it. Some people will prefer this as the code is a bit cleaner. There are no %s and a RESET color to end the coloration.

#include <stdio.h>

#define RED   "\x1B[31m"
#define GRN   "\x1B[32m"
#define YEL   "\x1B[33m"
#define BLU   "\x1B[34m"
#define MAG   "\x1B[35m"
#define CYN   "\x1B[36m"
#define WHT   "\x1B[37m"
#define RESET "\x1B[0m"

int main() {
  printf(RED "red\n"     RESET);
  printf(GRN "green\n"   RESET);
  printf(YEL "yellow\n"  RESET);
  printf(BLU "blue\n"    RESET);
  printf(MAG "magenta\n" RESET);
  printf(CYN "cyan\n"    RESET);
  printf(WHT "white\n"   RESET);

  return 0;
}

This program gives the following output:

enter image description here


Simple example with multiple colors

This way, it's easy to do something like:

printf("This is " RED "red" RESET " and this is " BLU "blue" RESET "\n");

This line produces the following output:

execution's output

David Guyon
  • 2,759
  • 1
  • 28
  • 40
  • KNRM is the same with RESET, isn't it? – Ziyaddin Sadigov Apr 26 '16 at 08:58
  • That's actually a good question. I guess you're right but I can't explain why. I mean, is it the same exact same code in a different format or different codes that have an identical behavior? – David Guyon Apr 26 '16 at 13:31
  • Yes, according to your example, they are different little bit in format (\x1B and \033) but their behavior is the same. – Ziyaddin Sadigov Apr 26 '16 at 13:37
  • 5
    I found the explaination: the decimal ASCII code 27 is the _escape_ character. The octal version of 27 is 33 (\033) and its hexadecimal version is 1B (\x1B) (ref: http://wiki.bash-hackers.org/scripting/terminalcodes). So yes, there are identical. Well done for finding this mistake and thanks for the feedback. I'll fix it right now ;). – David Guyon Apr 26 '16 at 14:24
  • This syntax is new to me "printf("Name: " NAME);". It does only work with constants? – trinity420 Jul 12 '19 at 22:13
  • 1
    `#define NAME "John Doe"` is a macro that defines a constant `NAME` with value `"John Doe"`, but it is *not* a variable. At compilation time, all occurrences of `NAME` are replaced by its value. Then `printf("Name: " NAME);` is interpreted as `printf("Name: " "John Doe");`. If you want to print a variable (constant or not), you need to specify how the value should be interpreted (e.g. for decimal you specify `%d`). I hope this will make things a bit more clear. – David Guyon Aug 12 '19 at 11:11
20

Use ANSI escape sequences. This article goes into some detail about them. You can use them with printf as well.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
20

You probably want ANSI color codes. Most *nix terminals support them.

nmichaels
  • 49,466
  • 12
  • 107
  • 135