]> git.lizzy.rs Git - linenoise.git/blob - linenoise.c
ab61d34a9569df7f02f5fd50edb641b37cc72769
[linenoise.git] / linenoise.c
1 /* linenoise.c -- guerrilla line editing library against the idea that a
2  * line editing lib needs to be 20,000 lines of C code.
3  *
4  * You can find the latest source code at:
5  *
6  *   http://github.com/antirez/linenoise
7  *
8  * Does a number of crazy assumptions that happen to be true in 99.9999% of
9  * the 2010 UNIX computers around.
10  *
11  * ------------------------------------------------------------------------
12  *
13  * Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
14  * Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
15  *
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met:
21  *
22  *  *  Redistributions of source code must retain the above copyright
23  *     notice, this list of conditions and the following disclaimer.
24  *
25  *  *  Redistributions in binary form must reproduce the above copyright
26  *     notice, this list of conditions and the following disclaimer in the
27  *     documentation and/or other materials provided with the distribution.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * ------------------------------------------------------------------------
42  *
43  * References:
44  * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
45  * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html
46  *
47  * Todo list:
48  * - Win32 support
49  * - Save and load history containing newlines
50  *
51  * Bloat:
52  * - Completion?
53  *
54  * List of escape sequences used by this program, we do everything just
55  * a few sequences. In order to be so cheap we may have some
56  * flickering effect with some slow terminal, but the lesser sequences
57  * the more compatible.
58  *
59  * CHA (Cursor Horizontal Absolute)
60  *    Sequence: ESC [ n G
61  *    Effect: moves cursor to column n (1 based)
62  *
63  * EL (Erase Line)
64  *    Sequence: ESC [ n K
65  *    Effect: if n is 0 or missing, clear from cursor to end of line
66  *    Effect: if n is 1, clear from beginning of line to cursor
67  *    Effect: if n is 2, clear entire line
68  *
69  * CUF (CUrsor Forward)
70  *    Sequence: ESC [ n C
71  *    Effect: moves cursor forward of n chars
72  *
73  * The following are used to clear the screen: ESC [ H ESC [ 2 J
74  * This is actually composed of two sequences:
75  *
76  * cursorhome
77  *    Sequence: ESC [ H
78  *    Effect: moves the cursor to upper left corner
79  *
80  * ED2 (Clear entire screen)
81  *    Sequence: ESC [ 2 J
82  *    Effect: clear the whole screen
83  *
84  * == For highlighting control characters, we also use the following two ==
85  * SO (enter StandOut)
86  *    Sequence: ESC [ 7 m
87  *    Effect: Uses some standout mode such as reverse video
88  *
89  * SE (Standout End)
90  *    Sequence: ESC [ 0 m
91  *    Effect: Exit standout mode
92  *
93  * == Only used if TIOCGWINSZ fails ==
94  * DSR/CPR (Report cursor position)
95  *    Sequence: ESC [ 6 n
96  *    Effect: reports current cursor position as ESC [ NNN ; MMM R
97  */
98
99 #ifdef __MINGW32__
100 #include <windows.h>
101 #include <fcntl.h>
102 #define USE_WINCONSOLE
103 #else
104 #include <termios.h>
105 #include <sys/ioctl.h>
106 #include <sys/poll.h>
107 #define USE_TERMIOS
108 #endif
109
110 #include <unistd.h>
111 #include <stdlib.h>
112 #include <stdarg.h>
113 #include <stdio.h>
114 #include <errno.h>
115 #include <string.h>
116 #include <stdlib.h>
117 #include <sys/types.h>
118 #include <unistd.h>
119
120 #include "linenoise.h"
121 #include "utf8.h"
122
123 #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
124 #define LINENOISE_MAX_LINE 4096
125
126 #define ctrl(C) ((C) - '@')
127
128 /* Use -ve numbers here to co-exist with normal unicode chars */
129 enum {
130     SPECIAL_NONE,
131     SPECIAL_UP = -20,
132     SPECIAL_DOWN = -21,
133     SPECIAL_LEFT = -22,
134     SPECIAL_RIGHT = -23,
135     SPECIAL_DELETE = -24,
136     SPECIAL_HOME = -25,
137     SPECIAL_END = -26,
138 };
139
140 static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
141 static int history_len = 0;
142 static char **history = NULL;
143
144 /* Structure to contain the status of the current (being edited) line */
145 struct current {
146     char *buf;  /* Current buffer. Always null terminated */
147     int bufmax; /* Size of the buffer, including space for the null termination */
148     int len;    /* Number of bytes in 'buf' */
149     int chars;  /* Number of chars in 'buf' (utf-8 chars) */
150     int pos;    /* Cursor position, measured in chars */
151     int cols;   /* Size of the window, in chars */
152     const char *prompt;
153 #if defined(USE_TERMIOS)
154     int fd;     /* Terminal fd */
155 #elif defined(USE_WINCONSOLE)
156     HANDLE outh; /* Console output handle */
157     HANDLE inh; /* Console input handle */
158     int rows;   /* Screen rows */
159     int x;      /* Current column during output */
160     int y;      /* Current row */
161 #endif
162 };
163
164 static int fd_read(struct current *current);
165 static int getWindowSize(struct current *current);
166
167 void linenoiseHistoryFree(void) {
168     if (history) {
169         int j;
170
171         for (j = 0; j < history_len; j++)
172             free(history[j]);
173         free(history);
174         history = NULL;
175     }
176 }
177
178 #if defined(USE_TERMIOS)
179 static void linenoiseAtExit(void);
180 static struct termios orig_termios; /* in order to restore at exit */
181 static int rawmode = 0; /* for atexit() function to check if restore is needed*/
182 static int atexit_registered = 0; /* register atexit just 1 time */
183
184 static const char *unsupported_term[] = {"dumb","cons25",NULL};
185
186 static int isUnsupportedTerm(void) {
187     char *term = getenv("TERM");
188
189     if (term) {
190         int j;
191         for (j = 0; unsupported_term[j]; j++) {
192             if (strcasecmp(term, unsupported_term[j]) == 0) {
193                 return 1;
194             }
195         }
196     }
197     return 0;
198 }
199
200 static int enableRawMode(struct current *current) {
201     struct termios raw;
202
203     current->fd = STDIN_FILENO;
204
205     if (!isatty(current->fd) || isUnsupportedTerm() ||
206         tcgetattr(current->fd, &orig_termios) == -1) {
207 fatal:
208         errno = ENOTTY;
209         return -1;
210     }
211
212     if (!atexit_registered) {
213         atexit(linenoiseAtExit);
214         atexit_registered = 1;
215     }
216
217     raw = orig_termios;  /* modify the original mode */
218     /* input modes: no break, no CR to NL, no parity check, no strip char,
219      * no start/stop output control. */
220     raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
221     /* output modes - disable post processing */
222     raw.c_oflag &= ~(OPOST);
223     /* control modes - set 8 bit chars */
224     raw.c_cflag |= (CS8);
225     /* local modes - choing off, canonical off, no extended functions,
226      * no signal chars (^Z,^C) */
227     raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
228     /* control chars - set return condition: min number of bytes and timer.
229      * We want read to return every single byte, without timeout. */
230     raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
231
232     /* put terminal in raw mode after flushing */
233     if (tcsetattr(current->fd,TCSADRAIN,&raw) < 0) {
234         goto fatal;
235     }
236     rawmode = 1;
237
238     current->cols = 0;
239     return 0;
240 }
241
242 static void disableRawMode(struct current *current) {
243     /* Don't even check the return value as it's too late. */
244     if (rawmode && tcsetattr(current->fd,TCSADRAIN,&orig_termios) != -1)
245         rawmode = 0;
246 }
247
248 /* At exit we'll try to fix the terminal to the initial conditions. */
249 static void linenoiseAtExit(void) {
250     if (rawmode) {
251         tcsetattr(STDIN_FILENO, TCSADRAIN, &orig_termios);
252     }
253     linenoiseHistoryFree();
254 }
255
256 /* gcc/glibc insists that we care about the return code of write! */
257 #define IGNORE_RC(EXPR) if (EXPR) {}
258
259 /* This is fdprintf() on some systems, but use a different
260  * name to avoid conflicts
261  */
262 static void fd_printf(int fd, const char *format, ...)
263 {
264     va_list args;
265     char buf[64];
266     int n;
267
268     va_start(args, format);
269     n = vsnprintf(buf, sizeof(buf), format, args);
270     va_end(args);
271     IGNORE_RC(write(fd, buf, n));
272 }
273
274 static void clearScreen(struct current *current)
275 {
276     fd_printf(current->fd, "\x1b[H\x1b[2J");
277 }
278
279 static void cursorToLeft(struct current *current)
280 {
281     fd_printf(current->fd, "\x1b[1G");
282 }
283
284 static int outputChars(struct current *current, const char *buf, int len)
285 {
286     return write(current->fd, buf, len);
287 }
288
289 static void outputControlChar(struct current *current, char ch)
290 {
291     fd_printf(current->fd, "\033[7m^%c\033[0m", ch);
292 }
293
294 static void eraseEol(struct current *current)
295 {
296     fd_printf(current->fd, "\x1b[0K");
297 }
298
299 static void setCursorPos(struct current *current, int x)
300 {
301     fd_printf(current->fd, "\x1b[1G\x1b[%dC", x);
302 }
303
304 /**
305  * Reads a char from 'fd', waiting at most 'timeout' milliseconds.
306  *
307  * A timeout of -1 means to wait forever.
308  *
309  * Returns -1 if no char is received within the time or an error occurs.
310  */
311 static int fd_read_char(int fd, int timeout)
312 {
313     struct pollfd p;
314     unsigned char c;
315
316     p.fd = fd;
317     p.events = POLLIN;
318
319     if (poll(&p, 1, timeout) == 0) {
320         /* timeout */
321         return -1;
322     }
323     if (read(fd, &c, 1) != 1) {
324         return -1;
325     }
326     return c;
327 }
328
329 /**
330  * Reads a complete utf-8 character
331  * and returns the unicode value, or -1 on error.
332  */
333 static int fd_read(struct current *current)
334 {
335 #ifdef USE_UTF8
336     char buf[4];
337     int n;
338     int i;
339     int c;
340
341     if (read(current->fd, &buf[0], 1) != 1) {
342         return -1;
343     }
344     n = utf8_charlen(buf[0]);
345     if (n < 1 || n > 3) {
346         return -1;
347     }
348     for (i = 1; i < n; i++) {
349         if (read(current->fd, &buf[i], 1) != 1) {
350             return -1;
351         }
352     }
353     buf[n] = 0;
354     /* decode and return the character */
355     utf8_tounicode(buf, &c);
356     return c;
357 #else
358     return fd_read_char(current->fd, -1);
359 #endif
360 }
361
362 static int getWindowSize(struct current *current)
363 {
364     struct winsize ws;
365
366     if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col != 0) {
367         current->cols = ws.ws_col;
368         return 0;
369     }
370
371     /* Failed to query the window size. Perhaps we are on a serial terminal.
372      * Try to query the width by sending the cursor as far to the right
373      * and reading back the cursor position.
374      * Note that this is only done once per call to linenoise rather than
375      * every time the line is refreshed for efficiency reasons.
376      */
377     if (current->cols == 0) {
378         current->cols = 80;
379
380         /* Move cursor far right and report cursor position */
381         fd_printf(current->fd, "\x1b[999G" "\x1b[6n");
382
383         /* Parse the response: ESC [ rows ; cols R */
384         if (fd_read_char(current->fd, 100) == 0x1b && fd_read_char(current->fd, 100) == '[') {
385             int n = 0;
386             while (1) {
387                 int ch = fd_read_char(current->fd, 100);
388                 if (ch == ';') {
389                     /* Ignore rows */
390                     n = 0;
391                 }
392                 else if (ch == 'R') {
393                     /* Got cols */
394                     if (n != 0 && n < 1000) {
395                         current->cols = n;
396                     }
397                     break;
398                 }
399                 else if (ch >= 0 && ch <= '9') {
400                     n = n * 10 + ch - '0';
401                 }
402                 else {
403                     break;
404                 }
405             }
406         }
407     }
408     return 0;
409 }
410
411 /**
412  * If escape (27) was received, reads subsequent
413  * chars to determine if this is a known special key.
414  *
415  * Returns SPECIAL_NONE if unrecognised, or -1 if EOF.
416  *
417  * If no additional char is received within a short time,
418  * 27 is returned.
419  */
420 static int check_special(int fd)
421 {
422     int c = fd_read_char(fd, 50);
423     int c2;
424
425     if (c < 0) {
426         return 27;
427     }
428
429     c2 = fd_read_char(fd, 50);
430     if (c2 < 0) {
431         return c2;
432     }
433     if (c == '[' || c == 'O') {
434         /* Potential arrow key */
435         switch (c2) {
436             case 'A':
437                 return SPECIAL_UP;
438             case 'B':
439                 return SPECIAL_DOWN;
440             case 'C':
441                 return SPECIAL_RIGHT;
442             case 'D':
443                 return SPECIAL_LEFT;
444             case 'F':
445                 return SPECIAL_END;
446             case 'H':
447                 return SPECIAL_HOME;
448         }
449     }
450     if (c == '[' && c2 >= '1' && c2 <= '6') {
451         /* extended escape */
452         int c3 = fd_read_char(fd, 50);
453         if (c2 == '3' && c3 == '~') {
454             /* delete char under cursor */
455             return SPECIAL_DELETE;
456         }
457         while (c3 != -1 && c3 != '~') {
458             /* .e.g \e[12~ or '\e[11;2~   discard the complete sequence */
459             c3 = fd_read_char(fd, 50);
460         }
461     }
462
463     return SPECIAL_NONE;
464 }
465 #elif defined(USE_WINCONSOLE)
466
467 static DWORD orig_consolemode = 0;
468
469 static int enableRawMode(struct current *current) {
470     DWORD n;
471     INPUT_RECORD irec;
472
473     current->outh = GetStdHandle(STD_OUTPUT_HANDLE);
474     current->inh = GetStdHandle(STD_INPUT_HANDLE);
475
476     if (!PeekConsoleInput(current->inh, &irec, 1, &n)) {
477         return -1;
478     }
479     if (getWindowSize(current) != 0) {
480         return -1;
481     }
482     if (GetConsoleMode(current->inh, &orig_consolemode)) {
483         SetConsoleMode(current->inh, ENABLE_PROCESSED_INPUT);
484     }
485     return 0;
486 }
487
488 static void disableRawMode(struct current *current)
489 {
490     SetConsoleMode(current->inh, orig_consolemode);
491 }
492
493 static void clearScreen(struct current *current)
494 {
495     COORD topleft = { 0, 0 };
496     DWORD n;
497
498     FillConsoleOutputCharacter(current->outh, ' ',
499         current->cols * current->rows, topleft, &n);
500     FillConsoleOutputAttribute(current->outh,
501         FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN,
502         current->cols * current->rows, topleft, &n);
503     SetConsoleCursorPosition(current->outh, topleft);
504 }
505
506 static void cursorToLeft(struct current *current)
507 {
508     COORD pos = { 0, current->y };
509     DWORD n;
510
511     FillConsoleOutputAttribute(current->outh,
512         FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, current->cols, pos, &n);
513     current->x = 0;
514 }
515
516 static int outputChars(struct current *current, const char *buf, int len)
517 {
518     COORD pos = { current->x, current->y };
519     WriteConsoleOutputCharacter(current->outh, buf, len, pos, 0);
520     current->x += len;
521     return 0;
522 }
523
524 static void outputControlChar(struct current *current, char ch)
525 {
526     COORD pos = { current->x, current->y };
527     DWORD n;
528
529     FillConsoleOutputAttribute(current->outh, BACKGROUND_INTENSITY, 2, pos, &n);
530     outputChars(current, "^", 1);
531     outputChars(current, &ch, 1);
532 }
533
534 static void eraseEol(struct current *current)
535 {
536     COORD pos = { current->x, current->y };
537     DWORD n;
538
539     FillConsoleOutputCharacter(current->outh, ' ', current->cols - current->x, pos, &n);
540 }
541
542 static void setCursorPos(struct current *current, int x)
543 {
544     COORD pos = { x, current->y };
545
546     SetConsoleCursorPosition(current->outh, pos);
547     current->x = x;
548 }
549
550 static int fd_read(struct current *current)
551 {
552     while (1) {
553         INPUT_RECORD irec;
554         DWORD n;
555         if (WaitForSingleObject(current->inh, INFINITE) != WAIT_OBJECT_0) {
556             break;
557         }
558         if (!ReadConsoleInput (current->inh, &irec, 1, &n)) {
559             break;
560         }
561         if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown) {
562             KEY_EVENT_RECORD *k = &irec.Event.KeyEvent;
563             if (k->dwControlKeyState & ENHANCED_KEY) {
564                 switch (k->wVirtualKeyCode) {
565                  case VK_LEFT:
566                     return SPECIAL_LEFT;
567                  case VK_RIGHT:
568                     return SPECIAL_RIGHT;
569                  case VK_UP:
570                     return SPECIAL_UP;
571                  case VK_DOWN:
572                     return SPECIAL_DOWN;
573                  case VK_DELETE:
574                     return SPECIAL_DELETE;
575                  case VK_HOME:
576                     return SPECIAL_HOME;
577                  case VK_END:
578                     return SPECIAL_END;
579                 }
580             }
581             /* Note that control characters are already translated in AsciiChar */
582             else {
583 #ifdef USE_UTF8
584                 return k->uChar.UnicodeChar;
585 #else
586                 return k->uChar.AsciiChar;
587 #endif
588             }
589         }
590     }
591     return -1;
592 }
593
594 static int getWindowSize(struct current *current)
595 {
596     CONSOLE_SCREEN_BUFFER_INFO info;
597     if (!GetConsoleScreenBufferInfo(current->outh, &info)) {
598         return -1;
599     }
600     current->cols = info.dwSize.X;
601     current->rows = info.dwSize.Y;
602     if (current->cols <= 0 || current->rows <= 0) {
603         current->cols = 80;
604         return -1;
605     }
606     current->y = info.dwCursorPosition.Y;
607     current->x = info.dwCursorPosition.X;
608     return 0;
609 }
610 #endif
611
612 static int utf8_getchars(char *buf, int c)
613 {
614 #ifdef USE_UTF8
615     return utf8_fromunicode(buf, c);
616 #else
617     *buf = c;
618     return 1;
619 #endif
620 }
621
622 /**
623  * Returns the unicode character at the given offset,
624  * or -1 if none.
625  */
626 static int get_char(struct current *current, int pos)
627 {
628     if (pos >= 0 && pos < current->chars) {
629         int c;
630         int i = utf8_index(current->buf, pos);
631         (void)utf8_tounicode(current->buf + i, &c);
632         return c;
633     }
634     return -1;
635 }
636
637 static void refreshLine(const char *prompt, struct current *current)
638 {
639     int plen;
640     int pchars;
641     int backup = 0;
642     int i;
643     const char *buf = current->buf;
644     int chars = current->chars;
645     int pos = current->pos;
646     int b;
647     int ch;
648     int n;
649
650     /* Should intercept SIGWINCH. For now, just get the size every time */
651     getWindowSize(current);
652
653     plen = strlen(prompt);
654     pchars = utf8_strlen(prompt, plen);
655
656     /* Account for a line which is too long to fit in the window.
657      * Note that control chars require an extra column
658      */
659
660     /* How many cols are required to the left of 'pos'?
661      * The prompt, plus one extra for each control char
662      */
663     n = pchars + utf8_strlen(buf, current->len);
664     b = 0;
665     for (i = 0; i < pos; i++) {
666         b += utf8_tounicode(buf + b, &ch);
667         if (ch < ' ') {
668             n++;
669         }
670     }
671
672     /* If too many are need, strip chars off the front of 'buf'
673      * until it fits. Note that if the current char is a control character,
674      * we need one extra col.
675      */
676     if (current->pos < current->chars && get_char(current, current->pos) < ' ') {
677         n++;
678     }
679
680     while (n >= current->cols) {
681         b = utf8_tounicode(buf, &ch);
682         if (ch < ' ') {
683             n--;
684         }
685         n--;
686         buf += b;
687         pos--;
688         chars--;
689     }
690
691     /* Cursor to left edge, then the prompt */
692     cursorToLeft(current);
693     outputChars(current, prompt, plen);
694
695     /* Now the current buffer content */
696
697     /* Need special handling for control characters.
698      * If we hit 'cols', stop.
699      */
700     b = 0; /* unwritted bytes */
701     n = 0; /* How many control chars were written */
702     for (i = 0; i < chars; i++) {
703         int ch;
704         int w = utf8_tounicode(buf + b, &ch);
705         if (ch < ' ') {
706             n++;
707         }
708         if (pchars + i + n >= current->cols) {
709             break;
710         }
711         if (ch < ' ') {
712             /* A control character, so write the buffer so far */
713             outputChars(current, buf, b);
714             buf += b + w;
715             b = 0;
716             outputControlChar(current, ch + '@');
717             if (i < pos) {
718                 backup++;
719             }
720         }
721         else {
722             b += w;
723         }
724     }
725     outputChars(current, buf, b);
726
727     /* Erase to right, move cursor to original position */
728     eraseEol(current);
729     setCursorPos(current, pos + pchars + backup);
730 }
731
732 static void set_current(struct current *current, const char *str)
733 {
734     strncpy(current->buf, str, current->bufmax);
735     current->buf[current->bufmax - 1] = 0;
736     current->len = strlen(current->buf);
737     current->pos = current->chars = utf8_strlen(current->buf, current->len);
738 }
739
740 static int has_room(struct current *current, int bytes)
741 {
742     return current->len + bytes < current->bufmax - 1;
743 }
744
745 /**
746  * Removes the char at 'pos'.
747  *
748  * Returns 1 if the line needs to be refreshed, 2 if not
749  * and 0 if nothing was removed
750  */
751 static int remove_char(struct current *current, int pos)
752 {
753     if (pos >= 0 && pos < current->chars) {
754         int p1, p2;
755         int ret = 1;
756         p1 = utf8_index(current->buf, pos);
757         p2 = p1 + utf8_index(current->buf + p1, 1);
758
759 #ifdef USE_TERMIOS
760         /* optimise remove char in the case of removing the last char */
761         if (current->pos == pos + 1 && current->pos == current->chars) {
762             if (current->buf[pos] >= ' ' && utf8_strlen(current->prompt, -1) + utf8_strlen(current->buf, current->len) < current->cols - 1) {
763                 ret = 2;
764                 fd_printf(current->fd, "\b \b");
765             }
766         }
767 #endif
768
769         /* Move the null char too */
770         memmove(current->buf + p1, current->buf + p2, current->len - p2 + 1);
771         current->len -= (p2 - p1);
772         current->chars--;
773
774         if (current->pos > pos) {
775             current->pos--;
776         }
777         return ret;
778     }
779     return 0;
780 }
781
782 /**
783  * Insert 'ch' at position 'pos'
784  *
785  * Returns 1 if the line needs to be refreshed, 2 if not
786  * and 0 if nothing was inserted (no room)
787  */
788 static int insert_char(struct current *current, int pos, int ch)
789 {
790     char buf[3];
791     int n = utf8_getchars(buf, ch);
792
793     if (has_room(current, n) && pos >= 0 && pos <= current->chars) {
794         int p1, p2;
795         int ret = 1;
796         p1 = utf8_index(current->buf, pos);
797         p2 = p1 + n;
798
799 #ifdef USE_TERMIOS
800         /* optimise the case where adding a single char to the end and no scrolling is needed */
801         if (current->pos == pos && current->chars == pos) {
802             if (ch >= ' ' && utf8_strlen(current->prompt, -1) + utf8_strlen(current->buf, current->len) < current->cols - 1) {
803                 IGNORE_RC(write(current->fd, buf, n));
804                 ret = 2;
805             }
806         }
807 #endif
808
809         memmove(current->buf + p2, current->buf + p1, current->len - p1);
810         memcpy(current->buf + p1, buf, n);
811         current->len += n;
812
813         current->chars++;
814         if (current->pos >= pos) {
815             current->pos++;
816         }
817         return ret;
818     }
819     return 0;
820 }
821
822 /**
823  * Returns 0 if no chars were removed or non-zero otherwise.
824  */
825 static int remove_chars(struct current *current, int pos, int n)
826 {
827     int removed = 0;
828     while (n-- && remove_char(current, pos)) {
829         removed++;
830     }
831     return removed;
832 }
833
834 #ifndef NO_COMPLETION
835 static linenoiseCompletionCallback *completionCallback = NULL;
836
837 static void beep() {
838 #ifdef USE_TERMIOS
839     fprintf(stderr, "\x7");
840     fflush(stderr);
841 #endif
842 }
843
844 static void freeCompletions(linenoiseCompletions *lc) {
845     size_t i;
846     for (i = 0; i < lc->len; i++)
847         free(lc->cvec[i]);
848     free(lc->cvec);
849 }
850
851 static int completeLine(struct current *current) {
852     linenoiseCompletions lc = { 0, NULL };
853     int c = 0;
854
855     completionCallback(current->buf,&lc);
856     if (lc.len == 0) {
857         beep();
858     } else {
859         size_t stop = 0, i = 0;
860
861         while(!stop) {
862             /* Show completion or original buffer */
863             if (i < lc.len) {
864                 struct current tmp = *current;
865                 tmp.buf = lc.cvec[i];
866                 tmp.pos = tmp.len = strlen(tmp.buf);
867                 tmp.chars = utf8_strlen(tmp.buf, tmp.len);
868                 refreshLine(current->prompt, &tmp);
869             } else {
870                 refreshLine(current->prompt, current);
871             }
872
873             c = fd_read(current);
874             if (c == -1) {
875                 break;
876             }
877
878             switch(c) {
879                 case '\t': /* tab */
880                     i = (i+1) % (lc.len+1);
881                     if (i == lc.len) beep();
882                     break;
883                 case 27: /* escape */
884                     /* Re-show original buffer */
885                     if (i < lc.len) {
886                         refreshLine(current->prompt, current);
887                     }
888                     stop = 1;
889                     break;
890                 default:
891                     /* Update buffer and return */
892                     if (i < lc.len) {
893                         set_current(current,lc.cvec[i]);
894                     }
895                     stop = 1;
896                     break;
897             }
898         }
899     }
900
901     freeCompletions(&lc);
902     return c; /* Return last read character */
903 }
904
905 /* Register a callback function to be called for tab-completion. */
906 void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
907     completionCallback = fn;
908 }
909
910 void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
911     lc->cvec = (char **)realloc(lc->cvec,sizeof(char*)*(lc->len+1));
912     lc->cvec[lc->len++] = strdup(str);
913 }
914
915 #endif
916
917 static int linenoisePrompt(struct current *current) {
918     int history_index = 0;
919
920     /* The latest history entry is always our current buffer, that
921      * initially is just an empty string. */
922     linenoiseHistoryAdd("");
923
924     set_current(current, "");
925     refreshLine(current->prompt, current);
926
927     while(1) {
928         int dir = -1;
929         int c = fd_read(current);
930
931 #ifndef NO_COMPLETION
932         /* Only autocomplete when the callback is set. It returns < 0 when
933          * there was an error reading from fd. Otherwise it will return the
934          * character that should be handled next. */
935         if (c == 9 && completionCallback != NULL) {
936             c = completeLine(current);
937             /* Return on errors */
938             if (c < 0) return current->len;
939             /* Read next character when 0 */
940             if (c == 0) continue;
941         }
942 #endif
943
944 process_char:
945         if (c == -1) return current->len;
946 #ifdef USE_TERMIOS
947         if (c == 27) {   /* escape sequence */
948             c = check_special(current->fd);
949         }
950 #endif
951         switch(c) {
952         case '\r':    /* enter */
953             history_len--;
954             free(history[history_len]);
955             return current->len;
956         case ctrl('C'):     /* ctrl-c */
957             errno = EAGAIN;
958             return -1;
959         case 127:   /* backspace */
960         case ctrl('H'):
961             if (remove_char(current, current->pos - 1) == 1) {
962                 refreshLine(current->prompt, current);
963             }
964             break;
965         case ctrl('D'):     /* ctrl-d */
966             if (current->len == 0) {
967                 /* Empty line, so EOF */
968                 history_len--;
969                 free(history[history_len]);
970                 return -1;
971             }
972             /* Otherwise delete char to right of cursor */
973             if (remove_char(current, current->pos)) {
974                 refreshLine(current->prompt, current);
975             }
976             break;
977         case ctrl('W'):    /* ctrl-w */
978             /* eat any spaces on the left */
979             {
980                 int pos = current->pos;
981                 while (pos > 0 && get_char(current, pos - 1) == ' ') {
982                     pos--;
983                 }
984
985                 /* now eat any non-spaces on the left */
986                 while (pos > 0 && get_char(current, pos - 1) != ' ') {
987                     pos--;
988                 }
989
990                 if (remove_chars(current, pos, current->pos - pos)) {
991                     refreshLine(current->prompt, current);
992                 }
993             }
994             break;
995         case ctrl('R'):    /* ctrl-r */
996             {
997                 /* Display the reverse-i-search prompt and process chars */
998                 char rbuf[50];
999                 char rprompt[80];
1000                 int rchars = 0;
1001                 int rlen = 0;
1002                 int searchpos = history_len - 1;
1003
1004                 rbuf[0] = 0;
1005                 while (1) {
1006                     int n = 0;
1007                     const char *p = NULL;
1008                     int skipsame = 0;
1009                     int searchdir = -1;
1010
1011                     snprintf(rprompt, sizeof(rprompt), "(reverse-i-search)'%s': ", rbuf);
1012                     refreshLine(rprompt, current);
1013                     c = fd_read(current);
1014                     if (c == ctrl('H') || c == 127) {
1015                         if (rchars) {
1016                             int p = utf8_index(rbuf, --rchars);
1017                             rbuf[p] = 0;
1018                             rlen = strlen(rbuf);
1019                         }
1020                         continue;
1021                     }
1022 #ifdef USE_TERMIOS
1023                     if (c == 27) {
1024                         c = check_special(current->fd);
1025                     }
1026 #endif
1027                     if (c == ctrl('P') || c == SPECIAL_UP) {
1028                         /* Search for the previous (earlier) match */
1029                         if (searchpos > 0) {
1030                             searchpos--;
1031                         }
1032                         skipsame = 1;
1033                     }
1034                     else if (c == ctrl('N') || c == SPECIAL_DOWN) {
1035                         /* Search for the next (later) match */
1036                         if (searchpos < history_len) {
1037                             searchpos++;
1038                         }
1039                         searchdir = 1;
1040                         skipsame = 1;
1041                     }
1042                     else if (c >= ' ') {
1043                         if (rlen >= (int)sizeof(rbuf) + 3) {
1044                             continue;
1045                         }
1046
1047                         n = utf8_getchars(rbuf + rlen, c);
1048                         rlen += n;
1049                         rchars++;
1050                         rbuf[rlen] = 0;
1051
1052                         /* Adding a new char resets the search location */
1053                         searchpos = history_len - 1;
1054                     }
1055                     else {
1056                         /* Exit from incremental search mode */
1057                         break;
1058                     }
1059
1060                     /* Now search through the history for a match */
1061                     for (; searchpos >= 0 && searchpos < history_len; searchpos += searchdir) {
1062                         p = strstr(history[searchpos], rbuf);
1063                         if (p) {
1064                             /* Found a match */
1065                             if (skipsame && strcmp(history[searchpos], current->buf) == 0) {
1066                                 /* But it is identical, so skip it */
1067                                 continue;
1068                             }
1069                             /* Copy the matching line and set the cursor position */
1070                             set_current(current,history[searchpos]);
1071                             current->pos = utf8_strlen(history[searchpos], p - history[searchpos]);
1072                             break;
1073                         }
1074                     }
1075                     if (!p && n) {
1076                         /* No match, so don't add it */
1077                         rchars--;
1078                         rlen -= n;
1079                         rbuf[rlen] = 0;
1080                     }
1081                 }
1082                 if (c == ctrl('G') || c == ctrl('C')) {
1083                     /* ctrl-g terminates the search with no effect */
1084                     set_current(current, "");
1085                     c = 0;
1086                 }
1087                 else if (c == ctrl('J')) {
1088                     /* ctrl-j terminates the search leaving the buffer in place */
1089                     c = 0;
1090                 }
1091                 /* Go process the char normally */
1092                 refreshLine(current->prompt, current);
1093                 goto process_char;
1094             }
1095             break;
1096         case ctrl('T'):    /* ctrl-t */
1097             if (current->pos > 0 && current->pos < current->chars) {
1098                 c = get_char(current, current->pos);
1099                 remove_char(current, current->pos);
1100                 insert_char(current, current->pos - 1, c);
1101                 refreshLine(current->prompt, current);
1102             }
1103             break;
1104         case ctrl('V'):    /* ctrl-v */
1105             if (has_room(current, 3)) {
1106                 /* Insert the ^V first */
1107                 if (insert_char(current, current->pos, c)) {
1108                     refreshLine(current->prompt, current);
1109                     /* Now wait for the next char. Can insert anything except \0 */
1110                     c = fd_read(current);
1111
1112                     /* Remove the ^V first */
1113                     remove_char(current, current->pos - 1);
1114                     if (c != -1) {
1115                         /* Insert the actual char */
1116                         insert_char(current, current->pos, c);
1117                     }
1118                     refreshLine(current->prompt, current);
1119                 }
1120             }
1121             break;
1122         case ctrl('B'):
1123         case SPECIAL_LEFT:
1124             if (current->pos > 0) {
1125                 current->pos--;
1126                 refreshLine(current->prompt, current);
1127             }
1128             break;
1129         case ctrl('F'):
1130         case SPECIAL_RIGHT:
1131             if (current->pos < current->chars) {
1132                 current->pos++;
1133                 refreshLine(current->prompt, current);
1134             }
1135             break;
1136         case ctrl('P'):
1137         case SPECIAL_UP:
1138             dir = 1;
1139         case ctrl('N'):
1140         case SPECIAL_DOWN:
1141             if (history_len > 1) {
1142                 /* Update the current history entry before to
1143                  * overwrite it with tne next one. */
1144                 free(history[history_len-1-history_index]);
1145                 history[history_len-1-history_index] = strdup(current->buf);
1146                 /* Show the new entry */
1147                 history_index += dir;
1148                 if (history_index < 0) {
1149                     history_index = 0;
1150                     break;
1151                 } else if (history_index >= history_len) {
1152                     history_index = history_len-1;
1153                     break;
1154                 }
1155                 set_current(current, history[history_len-1-history_index]);
1156                 refreshLine(current->prompt, current);
1157             }
1158             break;
1159
1160         case SPECIAL_DELETE:
1161             if (remove_char(current, current->pos) == 1) {
1162                 refreshLine(current->prompt, current);
1163             }
1164             break;
1165         case SPECIAL_HOME:
1166             current->pos = 0;
1167             refreshLine(current->prompt, current);
1168             break;
1169         case SPECIAL_END:
1170             current->pos = current->chars;
1171             refreshLine(current->prompt, current);
1172             break;
1173         default:
1174             /* Only tab is allowed without ^V */
1175             if (c == '\t' || c >= ' ') {
1176                 if (insert_char(current, current->pos, c) == 1) {
1177                     refreshLine(current->prompt, current);
1178                 }
1179             }
1180             break;
1181         case ctrl('U'): /* Ctrl+u, delete to beginning of line. */
1182             if (remove_chars(current, 0, current->pos)) {
1183                 refreshLine(current->prompt, current);
1184             }
1185             break;
1186         case ctrl('K'): /* Ctrl+k, delete from current to end of line. */
1187             if (remove_chars(current, current->pos, current->chars - current->pos)) {
1188                 refreshLine(current->prompt, current);
1189             }
1190             break;
1191         case ctrl('A'): /* Ctrl+a, go to the start of the line */
1192             current->pos = 0;
1193             refreshLine(current->prompt, current);
1194             break;
1195         case ctrl('E'): /* ctrl+e, go to the end of the line */
1196             current->pos = current->chars;
1197             refreshLine(current->prompt, current);
1198             break;
1199         case ctrl('L'): /* Ctrl+L, clear screen */
1200             /* clear screen */
1201             clearScreen(current);
1202             /* Force recalc of window size for serial terminals */
1203             current->cols = 0;
1204             refreshLine(current->prompt, current);
1205             break;
1206         }
1207     }
1208     return current->len;
1209 }
1210
1211 char *linenoise(const char *prompt)
1212 {
1213     int count;
1214     struct current current;
1215     char buf[LINENOISE_MAX_LINE];
1216
1217     if (enableRawMode(&current) == -1) {
1218         printf("%s", prompt);
1219         fflush(stdout);
1220         if (fgets(buf, sizeof(buf), stdin) == NULL) {
1221                 return NULL;
1222         }
1223         count = strlen(buf);
1224         if (count && buf[count-1] == '\n') {
1225             count--;
1226             buf[count] = '\0';
1227         }
1228     }
1229     else
1230     {
1231         current.buf = buf;
1232         current.bufmax = sizeof(buf);
1233         current.len = 0;
1234         current.chars = 0;
1235         current.pos = 0;
1236         current.prompt = prompt;
1237
1238         count = linenoisePrompt(&current);
1239         disableRawMode(&current);
1240         printf("\n");
1241         if (count == -1) {
1242             return NULL;
1243         }
1244     }
1245     return strdup(buf);
1246 }
1247
1248 /* Using a circular buffer is smarter, but a bit more complex to handle. */
1249 int linenoiseHistoryAdd(const char *line) {
1250     char *linecopy;
1251
1252     if (history_max_len == 0) return 0;
1253     if (history == NULL) {
1254         history = (char **)malloc(sizeof(char*)*history_max_len);
1255         if (history == NULL) return 0;
1256         memset(history,0,(sizeof(char*)*history_max_len));
1257     }
1258     linecopy = strdup(line);
1259     if (!linecopy) return 0;
1260     if (history_len == history_max_len) {
1261         free(history[0]);
1262         memmove(history,history+1,sizeof(char*)*(history_max_len-1));
1263         history_len--;
1264     }
1265     history[history_len] = linecopy;
1266     history_len++;
1267     return 1;
1268 }
1269
1270 int linenoiseHistorySetMaxLen(int len) {
1271     char **newHistory;
1272
1273     if (len < 1) return 0;
1274     if (history) {
1275         int tocopy = history_len;
1276
1277         newHistory = (char **)malloc(sizeof(char*)*len);
1278         if (newHistory == NULL) return 0;
1279         if (len < tocopy) tocopy = len;
1280         memcpy(newHistory,history+(history_max_len-tocopy), sizeof(char*)*tocopy);
1281         free(history);
1282         history = newHistory;
1283     }
1284     history_max_len = len;
1285     if (history_len > history_max_len)
1286         history_len = history_max_len;
1287     return 1;
1288 }
1289
1290 /* Save the history in the specified file. On success 0 is returned
1291  * otherwise -1 is returned. */
1292 int linenoiseHistorySave(const char *filename) {
1293     FILE *fp = fopen(filename,"w");
1294     int j;
1295
1296     if (fp == NULL) return -1;
1297     for (j = 0; j < history_len; j++) {
1298         const char *str = history[j];
1299         /* Need to encode backslash, nl and cr */
1300         while (*str) {
1301             if (*str == '\\') {
1302                 fputs("\\\\", fp);
1303             }
1304             else if (*str == '\n') {
1305                 fputs("\\n", fp);
1306             }
1307             else if (*str == '\r') {
1308                 fputs("\\r", fp);
1309             }
1310             else {
1311                 fputc(*str, fp);
1312             }
1313             str++;
1314         }
1315         fputc('\n', fp);
1316     }
1317
1318     fclose(fp);
1319     return 0;
1320 }
1321
1322 /* Load the history from the specified file. If the file does not exist
1323  * zero is returned and no operation is performed.
1324  *
1325  * If the file exists and the operation succeeded 0 is returned, otherwise
1326  * on error -1 is returned. */
1327 int linenoiseHistoryLoad(const char *filename) {
1328     FILE *fp = fopen(filename,"r");
1329     char buf[LINENOISE_MAX_LINE];
1330
1331     if (fp == NULL) return -1;
1332
1333     while (fgets(buf,LINENOISE_MAX_LINE,fp) != NULL) {
1334         char *src, *dest;
1335
1336         /* Decode backslash escaped values */
1337         for (src = dest = buf; *src; src++) {
1338             char ch = *src;
1339
1340             if (ch == '\\') {
1341                 src++;
1342                 if (*src == 'n') {
1343                     ch = '\n';
1344                 }
1345                 else if (*src == 'r') {
1346                     ch = '\r';
1347                 } else {
1348                     ch = *src;
1349                 }
1350             }
1351             *dest++ = ch;
1352         }
1353         /* Remove trailing newline */
1354         if (dest != buf && (dest[-1] == '\n' || dest[-1] == '\r')) {
1355             dest--;
1356         }
1357         *dest = 0;
1358
1359         linenoiseHistoryAdd(buf);
1360     }
1361     fclose(fp);
1362     return 0;
1363 }
1364
1365 /* Provide access to the history buffer.
1366  *
1367  * If 'len' is not NULL, the length is stored in *len.
1368  */
1369 char **linenoiseHistory(int *len) {
1370     if (len) {
1371         *len = history_len;
1372     }
1373     return history;
1374 }