Avoid CHA sequence for ANSI.SYS compatibility. Github user @welash proposed a change in issue #73 in order to improve the linenoise compatibility with older terminal emulators only able to deal with a subset of ANSI sequences, notably ANSI.SYS and VT100 terminals strictly able to handle the original set of VT100 escape sequences. In order to improve the compatibility, the CHA sequence was removed and translated to move 999 positions to the left, then move on the right for the desired number of positions. The CHA sequence was apparently added only with VT220, that's why it is not available everywhere. This commit features almost exactly the change proposed in issue #73 with a small fix for a bug in multi-line editing mode introduced by the patch.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
diff --git a/linenoise.c b/linenoise.c
index e864e46..385932b 100644
--- a/linenoise.c
+++ b/linenoise.c
@@ -56,10 +56,6 @@
* flickering effect with some slow terminal, but the lesser sequences
* the more compatible.
*
- * CHA (Cursor Horizontal Absolute)
- * Sequence: ESC [ n G
- * Effect: moves cursor to column n
- *
* EL (Erase Line)
* Sequence: ESC [ n K
* Effect: if n is 0 or missing, clear from cursor to end of line
@@ -68,7 +64,19 @@
*
* CUF (CUrsor Forward)
* Sequence: ESC [ n C
- * Effect: moves cursor forward of n chars
+ * Effect: moves cursor forward n chars
+ *
+ * CUB (CUrsor Backward)
+ * Sequence: ESC [ n D
+ * Effect: moves cursor backward n chars
+ *
+ * The following is used to get the terminal width if getting
+ * the width with the TIOCGWINSZ ioctl fails
+ *
+ * DSR (Device Status Report)
+ * Sequence: ESC [ 6 n
+ * Effect: reports the current cusor position as ESC [ n ; m R
+ * where n is the row and m is the column
*
* When multi line mode is enabled, we also use an additional escape
* sequence. However multi line editing is disabled by default.
@@ -471,7 +479,7 @@ static void refreshSingleLine(struct linenoiseState *l) {
abInit(&ab);
/* Cursor to left edge */
- snprintf(seq,64,"\x1b[0G");
+ snprintf(seq,64,"\x1b[999D");
abAppend(&ab,seq,strlen(seq));
/* Write the prompt and the current buffer content */
abAppend(&ab,l->prompt,strlen(l->prompt));
@@ -480,7 +488,7 @@ static void refreshSingleLine(struct linenoiseState *l) {
snprintf(seq,64,"\x1b[0K");
abAppend(&ab,seq,strlen(seq));
/* Move cursor to original position. */
- snprintf(seq,64,"\x1b[0G\x1b[%dC", (int)(pos+plen));
+ snprintf(seq,64,"\x1b[999D\x1b[%dC", (int)(pos+plen));
abAppend(&ab,seq,strlen(seq));
if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */
abFree(&ab);
@@ -515,13 +523,13 @@ static void refreshMultiLine(struct linenoiseState *l) {
/* Now for every row clear it, go up. */
for (j = 0; j < old_rows-1; j++) {
lndebug("clear+up");
- snprintf(seq,64,"\x1b[0G\x1b[0K\x1b[1A");
+ snprintf(seq,64,"\x1b[999D\x1b[0K\x1b[1A");
abAppend(&ab,seq,strlen(seq));
}
/* Clean the top line. */
lndebug("clear");
- snprintf(seq,64,"\x1b[0G\x1b[0K");
+ snprintf(seq,64,"\x1b[999D\x1b[0K");
abAppend(&ab,seq,strlen(seq));
/* Write the prompt and the current buffer content */
@@ -536,7 +544,7 @@ static void refreshMultiLine(struct linenoiseState *l) {
{
lndebug("<newline>");
abAppend(&ab,"\n",1);
- snprintf(seq,64,"\x1b[0G");
+ snprintf(seq,64,"\x1b[999D");
abAppend(&ab,seq,strlen(seq));
rows++;
if (rows > (int)l->maxrows) l->maxrows = rows;
@@ -555,7 +563,7 @@ static void refreshMultiLine(struct linenoiseState *l) {
/* Set column. */
lndebug("set col %d", 1+((plen+(int)l->pos) % (int)l->cols));
- snprintf(seq,64,"\x1b[%dG", 1+((plen+(int)l->pos) % (int)l->cols));
+ snprintf(seq,64,"\x1b[999D\x1b[%dC", (plen+(int)l->pos) % (int)l->cols);
abAppend(&ab,seq,strlen(seq));
lndebug("\n");
@@ -904,7 +912,7 @@ void linenoisePrintKeyCodes(void) {
printf("'%c' %02x (%d) (type quit to exit)\n",
isprint(c) ? c : '?', (int)c, (int)c);
- printf("\x1b[0G"); /* Go left edge manually, we are in raw mode. */
+ printf("\x1b[999D"); /* Go left edge manually, we are in raw mode. */
fflush(stdout);
}
disableRawMode(STDIN_FILENO);