diff options
author | Glauber Campinho <[email protected]> | 2017-08-17 02:23:22 +0200 |
---|---|---|
committer | Glauber Campinho <[email protected]> | 2017-08-21 17:05:35 +0200 |
commit | 6a179d28022b46c287a3e075561f97aa85208e31 (patch) | |
tree | 6facc3413fd1ac1805c32a18a183e5938355ec3d /erts/emulator/drivers/unix | |
parent | f392006644991074d2c4d5055773409c5e0503d7 (diff) | |
download | otp-6a179d28022b46c287a3e075561f97aa85208e31.tar.gz otp-6a179d28022b46c287a3e075561f97aa85208e31.tar.bz2 otp-6a179d28022b46c287a3e075561f97aa85208e31.zip |
Fix ANSI support in the console
The ANSI support doesn't work properly with edlin, the issue can be noticed when you try to use the history of the shell and the prompt prefix has ANSI (https://github.com/elixir-lang/elixir/issues/6448). The problem is that when a `\e` character appears, it handles it like a new line, dropping the buffer before it.
The solution is to always add the `\e` to the buffer like a regular character and handle it when writing the buffer instead.
Diffstat (limited to 'erts/emulator/drivers/unix')
-rw-r--r-- | erts/emulator/drivers/unix/ttsl_drv.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c index bce097d944..f3c1aa1c4a 100644 --- a/erts/emulator/drivers/unix/ttsl_drv.c +++ b/erts/emulator/drivers/unix/ttsl_drv.c @@ -1094,15 +1094,13 @@ static int insert_buf(byte *s, int n) lbuf[lpos++] = (CONTROL_TAG | ((Uint32) ch)); ch = 0; } while (lpos % 8); - } else if (ch == '\e' || ch == '\n' || ch == '\r') { + } else if (ch == '\e') { + lbuf[lpos++] = (CONTROL_TAG | ((Uint32) ch)); + } else if (ch == '\n' || ch == '\r') { write_buf(lbuf + buffpos, lpos - buffpos); - if (ch == '\e') { - outc('\e'); - } else { outc('\r'); if (ch == '\n') outc('\n'); - } if (llen > lpos) { memcpy(lbuf, lbuf + lpos, llen - lpos); } @@ -1150,14 +1148,17 @@ static int write_buf(Uint32 *s, int n) } --n; ++s; - } - else if (*s == (CONTROL_TAG | ((Uint32) '\t'))) { + } else if (*s == (CONTROL_TAG | ((Uint32) '\t'))) { outc(lastput = ' '); --n; s++; while (n > 0 && *s == CONTROL_TAG) { outc(lastput = ' '); --n; s++; } + } else if (*s == (CONTROL_TAG | ((Uint32) '\e'))) { + outc('\e'); + --n; + ++s; } else if (*s & CONTROL_TAG) { outc('^'); outc(lastput = ((byte) ((*s == 0177) ? '?' : *s | 0x40))); |