Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to colorize the prompt of an editline application

I am trying to colorize the prompt of an application powered by libedit, but I the color simply does not show up. Any ideas what I'm doing wrong here?

#include <iostream>
#include <histedit.h>

char* prompt(EditLine *e)
{
  static char p[] = "\1\033[36m\1:::\1\033[0m\1 ";
  return p;
}

int main(int argc, char* argv[])
{
  EditLine* el = el_init(argv[0], stdin, stdout, stderr);
  el_set(el, EL_PROMPT_ESC, &prompt, '\1');
  el_set(el, EL_EDITOR, "vi");

  while (1)
  {
    int count;
    char const* line = el_gets(el, &count);

    if (count > 0)
      std::cout << line;
  }

  el_end(el);

  return 0;
}

Compiled with

clang++ editline.cc -ledit && ./a.out

and shows unfortunately just the uncolored prompt of:

:::     
like image 247
mavam Avatar asked Jan 20 '14 17:01

mavam


2 Answers

Editline doesn't support colour prompts. There is a patch implementing them.

Interestingly, during screen update editline renders the image first in a memory buffer, diffs with the previous frame and then emits commands to fix the difference. The commands are moveto(x,y), delete(n), insert(text).

This design allows for a simpler code. For instance, insert command in the editor can and actually does redraw the entire screen but the resulting sequence of terminal draw commands is minimal.

Unfortunately, since a text undergoes complex transformations before reaching the terminal, some information is lost in translation, like the colour.

like image 106
Nick Zavaritsky Avatar answered Sep 19 '22 00:09

Nick Zavaritsky


\1 is used as a stop/start literal character, so that seems to be the correct behavior.

\1\033[36m\1:::\1\033[0m\1
|          |   |         |
|          |   |_Start   |_Stop
|          |
|_Start    |_Stop

EL_PROMPT_ESC, char *(*f)(EditLine *), char c Same as EL_PROMPT, but the c argument indicates the start/stop literal prompt character.

     If a start/stop literal character is found in the prompt, the
     character itself is not printed, but characters after it are
     printed directly to the terminal without affecting the state
     of the current line.  A subsequent second start/stop literal
     character ends this behavior.  This is typically used to
     embed literal escape sequences that change the color/style of
     the terminal in the prompt.  0 unsets it.

The man page states using 0 to unset the color, but it's a little unclear what they mean.

Maybe try the escape sequence like this:

\1\033[36m:::\033[0m\1

Since the \1 is possibly terminating the color from being used, whereas \[ ... \] would be the normal terminators in bash.

like image 20
l'L'l Avatar answered Sep 21 '22 00:09

l'L'l