]> git.lizzy.rs Git - linenoise.git/blob - linenoise.c
014b2aca3c4969e0a4236ceb01a610832d056dd3
[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
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 #include <termios.h>
100 #include <unistd.h>
101 #include <stdlib.h>
102 #include <stdarg.h>
103 #include <stdio.h>
104 #include <errno.h>
105 #include <string.h>
106 #include <stdlib.h>
107 #include <sys/types.h>
108 #include <sys/ioctl.h>
109 #include <sys/poll.h>
110 #include <unistd.h>
111 #include "linenoise.h"
112
113 #include "linenoise.h"
114 #include "utf8.h"
115
116 #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
117 #define LINENOISE_MAX_LINE 4096
118 static char *unsupported_term[] = {"dumb","cons25",NULL};
119
120 static struct termios orig_termios; /* in order to restore at exit */
121 static int rawmode = 0; /* for atexit() function to check if restore is needed*/
122 static int atexit_registered = 0; /* register atexit just 1 time */
123 static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
124 static int history_len = 0;
125 static char **history = NULL;
126
127 static void linenoiseAtExit(void);
128 static int fd_read(int fd);
129 static void getColumns(int fd, int *cols);
130
131 static int isUnsupportedTerm(void) {
132     char *term = getenv("TERM");
133     int j;
134
135     if (term == NULL) return 0;
136     for (j = 0; unsupported_term[j]; j++)
137         if (!strcasecmp(term,unsupported_term[j])) return 1;
138     return 0;
139 }
140
141 static void freeHistory(void) {
142     if (history) {
143         int j;
144
145         for (j = 0; j < history_len; j++)
146             free(history[j]);
147         free(history);
148     }
149 }
150
151 static int enableRawMode(int fd) {
152     struct termios raw;
153
154     if (!isatty(STDIN_FILENO)) goto fatal;
155     if (!atexit_registered) {
156         atexit(linenoiseAtExit);
157         atexit_registered = 1;
158     }
159     if (tcgetattr(fd,&orig_termios) == -1) goto fatal;
160
161     raw = orig_termios;  /* modify the original mode */
162     /* input modes: no break, no CR to NL, no parity check, no strip char,
163      * no start/stop output control. */
164     raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
165     /* output modes - disable post processing */
166     raw.c_oflag &= ~(OPOST);
167     /* control modes - set 8 bit chars */
168     raw.c_cflag |= (CS8);
169     /* local modes - choing off, canonical off, no extended functions,
170      * no signal chars (^Z,^C) */
171     raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
172     /* control chars - set return condition: min number of bytes and timer.
173      * We want read to return every single byte, without timeout. */
174     raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
175
176     /* put terminal in raw mode after flushing */
177     if (tcsetattr(fd,TCSADRAIN,&raw) < 0) goto fatal;
178     rawmode = 1;
179     return 0;
180
181 fatal:
182     errno = ENOTTY;
183     return -1;
184 }
185
186 static void disableRawMode(int fd) {
187     /* Don't even check the return value as it's too late. */
188     if (rawmode && tcsetattr(fd,TCSADRAIN,&orig_termios) != -1)
189         rawmode = 0;
190 }
191
192 /* At exit we'll try to fix the terminal to the initial conditions. */
193 static void linenoiseAtExit(void) {
194     disableRawMode(STDIN_FILENO);
195     freeHistory();
196 }
197
198 /* Structure to contain the status of the current (being edited) line */
199 struct current {
200     int fd;     /* Terminal fd */
201     char *buf;  /* Current buffer. Always null terminated */
202     int bufmax; /* Size of the buffer, including space for the null termination */
203     int len;    /* Number of bytes in 'buf' */
204     int chars;  /* Number of chars in 'buf' (utf-8 chars) */
205     int pos;    /* Cursor position, measured in chars */
206     int cols;   /* Size of the window, in chars */
207 };
208
209 /* gcc/glibc insists that we care about the return code of write! */
210 #define IGNORE_RC(EXPR) ((EXPR) < 0 ? -1 : 0)
211
212 /* This is fd_printf() on some systems, but use a different
213  * name to avoid conflicts
214  */
215 static void fd_printf(int fd, const char *format, ...)
216 {
217     va_list args;
218     char buf[64];
219     int n;
220
221     va_start(args, format);
222     n = vsnprintf(buf, sizeof(buf), format, args);
223     va_end(args);
224     IGNORE_RC(write(fd, buf, n));
225 }
226
227 static int utf8_getchars(char *buf, int c)
228 {
229 #ifdef USE_UTF8
230     return utf8_fromunicode(buf, c);
231 #else
232     *buf = c;
233     return 1;
234 #endif
235 }
236
237 /**
238  * Returns the unicode character at the given offset,
239  * or -1 if none.
240  */
241 static int get_char(struct current *current, int pos)
242 {
243     if (pos >= 0 && pos < current->chars) {
244         int c;
245         int i = utf8_index(current->buf, pos);
246         (void)utf8_tounicode(current->buf + i, &c);
247         return c;
248     }
249     return -1;
250 }
251
252 static void refreshLine(const char *prompt, struct current *current) {
253     int plen;
254     int pchars;
255     int backup = 0;
256     int i;
257     const char *buf = current->buf;
258     int chars = current->chars;
259     int pos = current->pos;
260     int b;
261     int ch;
262     int n;
263
264     /* Should intercept SIGWINCH. For now, just get the size every time */
265     getColumns(current->fd, &current->cols);
266
267     plen = strlen(prompt);
268     pchars = utf8_strlen(prompt, plen);
269
270     /* Account for a line which is too long to fit in the window.
271      * Note that control chars require an extra column
272      */
273
274     /* How many cols are required to the left of 'pos'?
275      * The prompt, plus one extra for each control char
276      */
277     n = pchars + utf8_strlen(buf, current->len);
278     b = 0;
279     for (i = 0; i < pos; i++) {
280         b += utf8_tounicode(buf + b, &ch);
281         if (ch < ' ') {
282             n++;
283         }
284     }
285
286     /* If too many are need, strip chars off the front of 'buf'
287      * until it fits. Note that if the current char is a control character,
288      * we need one extra col.
289      */
290     if (current->pos < current->chars && get_char(current, current->pos) < ' ') {
291         n++;
292     }
293
294     while (n >= current->cols) {
295         b = utf8_tounicode(buf, &ch);
296         if (ch < ' ') {
297             n--;
298         }
299         n--;
300         buf += b;
301         pos--;
302         chars--;
303     }
304
305     /* Cursor to left edge, then the prompt */
306     fd_printf(current->fd, "\x1b[0G");
307     IGNORE_RC(write(current->fd, prompt, plen));
308
309     /* Now the current buffer content */
310
311     /* Need special handling for control characters.
312      * If we hit 'cols', stop.
313      */
314     b = 0; /* unwritted bytes */
315     n = 0; /* How many control chars were written */
316     for (i = 0; i < chars; i++) {
317         int ch;
318         int w = utf8_tounicode(buf + b, &ch);
319         if (ch < ' ') {
320             n++;
321         }
322         if (pchars + i + n >= current->cols) {
323             break;
324         }
325         if (ch < ' ') {
326             /* A control character, so write the buffer so far */
327             IGNORE_RC(write(current->fd, buf, b));
328             buf += b + w;
329             b = 0;
330             fd_printf(current->fd, "\033[7m^%c\033[0m", ch + '@');
331             if (i < pos) {
332                 backup++;
333             }
334         }
335         else {
336             b += w;
337         }
338     }
339     IGNORE_RC(write(current->fd, buf, b));
340
341     /* Erase to right, move cursor to original position */
342     fd_printf(current->fd, "\x1b[0K" "\x1b[0G\x1b[%dC", pos + pchars + backup);
343 }
344
345 static void set_current(struct current *current, const char *str)
346 {
347     strncpy(current->buf, str, current->bufmax);
348     current->buf[current->bufmax - 1] = 0;
349     current->len = strlen(current->buf);
350     current->pos = current->chars = utf8_strlen(current->buf, current->len);
351 }
352
353 static int has_room(struct current *current, int bytes)
354 {
355     return current->len + bytes < current->bufmax - 1;
356 }
357
358 static int remove_char(struct current *current, int pos)
359 {
360     if (pos >= 0 && pos < current->chars) {
361         int p1, p2;
362         p1 = utf8_index(current->buf, pos);
363         p2 = p1 + utf8_index(current->buf + p1, 1);
364         /* Move the null char too */
365         memmove(current->buf + p1, current->buf + p2, current->len - p2 + 1);
366         current->len -= (p2 - p1);
367         current->chars--;
368         if (current->pos > pos) {
369             current->pos--;
370         }
371         return 1;
372     }
373     return 0;
374 }
375
376 /* XXX: Optimise this later */
377 static int insert_char(struct current *current, int pos, int ch)
378 {
379     char buf[3];
380     int n = utf8_getchars(buf, ch);
381
382     if (has_room(current, n) && pos >= 0 && pos <= current->chars) {
383         int p1, p2;
384         p1 = utf8_index(current->buf, pos);
385         p2 = p1 + n;
386         memmove(current->buf + p2, current->buf + p1, current->len - p1);
387         memcpy(current->buf + p1, buf, n);
388         current->len += n;
389         current->chars++;
390         if (current->pos >= pos) {
391             current->pos++;
392         }
393         return 1;
394     }
395     return 0;
396 }
397
398 #ifndef NO_COMPLETION
399 static linenoiseCompletionCallback *completionCallback = NULL;
400
401 static void beep() {
402     fprintf(stderr, "\x7");
403     fflush(stderr);
404 }
405
406 static void freeCompletions(linenoiseCompletions *lc) {
407     size_t i;
408     for (i = 0; i < lc->len; i++)
409         free(lc->cvec[i]);
410     free(lc->cvec);
411 }
412
413 static int completeLine(const char *prompt, struct current *current) {
414     linenoiseCompletions lc = { 0, NULL };
415     int c = 0;
416
417     completionCallback(current->buf,&lc);
418     if (lc.len == 0) {
419         beep();
420     } else {
421         size_t stop = 0, i = 0;
422
423         while(!stop) {
424             /* Show completion or original buffer */
425             if (i < lc.len) {
426                 struct current tmp = *current;
427                 tmp.buf = lc.cvec[i];
428                 tmp.pos = tmp.len = strlen(tmp.buf);
429                 tmp.chars = utf8_strlen(tmp.buf, tmp.len);
430                 refreshLine(prompt, &tmp);
431             } else {
432                 refreshLine(prompt, current);
433             }
434
435             c = fd_read(current->fd);
436             if (c < 0) {
437                 break;
438             }
439
440             switch(c) {
441                 case '\t': /* tab */
442                     i = (i+1) % (lc.len+1);
443                     if (i == lc.len) beep();
444                     break;
445                 case 27: /* escape */
446                     /* Re-show original buffer */
447                     if (i < lc.len) {
448                         refreshLine(prompt, current);
449                     }
450                     stop = 1;
451                     break;
452                 default:
453                     /* Update buffer and return */
454                     if (i < lc.len) {
455                         set_current(current,lc.cvec[i]);
456                     }
457                     stop = 1;
458                     break;
459             }
460         }
461     }
462
463     freeCompletions(&lc);
464     return c; /* Return last read character */
465 }
466
467 /* Register a callback function to be called for tab-completion. */
468 void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
469     completionCallback = fn;
470 }
471
472 void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
473     lc->cvec = realloc(lc->cvec,sizeof(char*)*(lc->len+1));
474     lc->cvec[lc->len++] = strdup(str);
475 }
476
477 #endif
478
479 /* XXX: Optimise this later */
480 static int remove_chars(struct current *current, int pos, int n)
481 {
482     int removed = 0;
483     while (n-- && remove_char(current, pos)) {
484         removed++;
485     }
486     return removed;
487 }
488
489 /**
490  * Reads a char from 'fd', waiting at most 'timeout' milliseconds.
491  *
492  * A timeout of -1 means to wait forever.
493  *
494  * Returns -1 if no char is received within the time or an error occurs.
495  */
496 static int fd_read_char(int fd, int timeout)
497 {
498     struct pollfd p;
499     unsigned char c;
500
501     p.fd = fd;
502     p.events = POLLIN;
503
504     if (poll(&p, 1, timeout) == 0) {
505         /* timeout */
506         return -1;
507     }
508     if (read(fd, &c, 1) != 1) {
509         return -1;
510     }
511     return c;
512 }
513
514 /**
515  * Reads a complete utf-8 character
516  * and returns the unicode value, or -1 on error.
517  */
518 static int fd_read(int fd)
519 {
520 #ifdef USE_UTF8
521     char buf[4];
522     int n;
523     int i;
524     int c;
525
526     if (read(fd, &buf[0], 1) != 1) {
527         return -1;
528     }
529     n = utf8_charlen(buf[0]);
530     if (n < 1 || n > 3) {
531         return -1;
532     }
533     for (i = 1; i < n; i++) {
534         if (read(fd, &buf[i], 1) != 1) {
535             return -1;
536         }
537     }
538     buf[n] = 0;
539     /* decode and return the character */
540     utf8_tounicode(buf, &c);
541     return c;
542 #else
543     return fd_read_char(fd, -1);
544 #endif
545 }
546
547 static void getColumns(int fd, int *cols) {
548     struct winsize ws;
549
550     if (ioctl(1, TIOCGWINSZ, &ws) == 0 && ws.ws_col != 0) {
551         *cols = ws.ws_col;
552         return;
553     }
554     /* Failed to query the window size. Perhaps we are on a serial terminal.
555      * Try to query the width by sending the cursor as far to the right
556      * and reading back the cursor position.
557      * Note that this is only done once per call to linenoise rather than
558      * every time the line is refreshed for efficiency reasons.
559      */
560     if (*cols == 0) {
561         *cols = 80;
562
563         /* Move cursor far right and report cursor position */
564         fd_printf(fd, "\x1b[999G" "\x1b[6n");
565
566         /* Parse the response: ESC [ rows ; cols R */
567         if (fd_read_char(fd, 100) == 0x1b && fd_read_char(fd, 100) == '[') {
568             int n = 0;
569             while (1) {
570                 int ch = fd_read_char(fd, 100);
571                 if (ch == ';') {
572                     /* Ignore rows */
573                     n = 0;
574                 }
575                 else if (ch == 'R') {
576                     /* Got cols */
577                     if (n != 0 && n < 1000) {
578                         *cols = n;
579                     }
580                     break;
581                 }
582                 else if (ch >= 0 && ch <= '9') {
583                     n = n * 10 + ch - '0';
584                 }
585                 else {
586                     break;
587                 }
588             }
589         }
590     }
591 }
592
593 /* Use -ve numbers here to co-exist with normal unicode chars */
594 enum {
595     SPECIAL_NONE,
596     SPECIAL_UP = -20,
597     SPECIAL_DOWN = -21,
598     SPECIAL_LEFT = -22,
599     SPECIAL_RIGHT = -23,
600     SPECIAL_DELETE = -24,
601 };
602
603 /**
604  * If escape (27) was received, reads subsequent
605  * chars to determine if this is a known special key.
606  *
607  * Returns SPECIAL_NONE if unrecognised, or -1 if EOF.
608  *
609  * If no additional char is received within a short time,
610  * 27 is returned.
611  */
612 static int check_special(int fd)
613 {
614     int c = fd_read_char(fd, 50);
615     int c2;
616
617     if (c < 0) {
618         return 27;
619     }
620
621     c2 = fd_read_char(fd, 50);
622     if (c2 < 0) {
623         return c2;
624     }
625     if (c == '[' || c == 'O') {
626         /* Potential arrow key */
627         switch (c2) {
628             case 'A':
629                 return SPECIAL_UP;
630             case 'B':
631                 return SPECIAL_DOWN;
632             case 'C':
633                 return SPECIAL_RIGHT;
634             case 'D':
635                 return SPECIAL_LEFT;
636         }
637     }
638     if (c == '[' && c2 >= '1' && c2 <= '6') {
639         /* extended escape */
640         int c3 = fd_read_char(fd, 50);
641         if (c2 == '3' && c3 == '~') {
642             /* delete char under cursor */
643             return SPECIAL_DELETE;
644         }
645         while (c3 != -1 && c3 != '~') {
646             /* .e.g \e[12~ or '\e[11;2~   discard the complete sequence */
647             c3 = fd_read_char(fd, 50);
648         }
649     }
650
651     return SPECIAL_NONE;
652 }
653
654 #define ctrl(C) ((C) - '@')
655
656 static int linenoisePrompt(const char *prompt, struct current *current) {
657     int history_index = 0;
658
659     /* The latest history entry is always our current buffer, that
660      * initially is just an empty string. */
661     linenoiseHistoryAdd("");
662
663     set_current(current, "");
664     refreshLine(prompt, current);
665
666     while(1) {
667         int c = fd_read(current->fd);
668
669 #ifndef NO_COMPLETION
670         /* Only autocomplete when the callback is set. It returns < 0 when
671          * there was an error reading from fd. Otherwise it will return the
672          * character that should be handled next. */
673         if (c == 9 && completionCallback != NULL) {
674             c = completeLine(prompt, current);
675             /* Return on errors */
676             if (c < 0) return current->len;
677             /* Read next character when 0 */
678             if (c == 0) continue;
679         }
680 #endif
681
682 process_char:
683         if (c == -1) return current->len;
684         switch(c) {
685         case '\r':    /* enter */
686             history_len--;
687             free(history[history_len]);
688             return current->len;
689         case ctrl('C'):     /* ctrl-c */
690             errno = EAGAIN;
691             return -1;
692         case 127:   /* backspace */
693         case ctrl('H'):
694             if (remove_char(current, current->pos - 1)) {
695                 refreshLine(prompt, current);
696             }
697             break;
698         case ctrl('D'):     /* ctrl-d */
699             if (current->len == 0) {
700                 /* Empty line, so EOF */
701                 history_len--;
702                 free(history[history_len]);
703                 return -1;
704             }
705             /* Otherwise delete char to right of cursor */
706             if (remove_char(current, current->pos)) {
707                 refreshLine(prompt, current);
708             }
709             break;
710         case ctrl('W'):    /* ctrl-w */
711             /* eat any spaces on the left */
712             {
713                 int pos = current->pos;
714                 while (pos > 0 && get_char(current, pos - 1) == ' ') {
715                     pos--;
716                 }
717
718                 /* now eat any non-spaces on the left */
719                 while (pos > 0 && get_char(current, pos - 1) != ' ') {
720                     pos--;
721                 }
722
723                 if (remove_chars(current, pos, current->pos - pos)) {
724                     refreshLine(prompt, current);
725                 }
726             }
727             break;
728         case ctrl('R'):    /* ctrl-r */
729             {
730                 /* Display the reverse-i-search prompt and process chars */
731                 char rbuf[50];
732                 char rprompt[80];
733                 int rchars = 0;
734                 int rlen = 0;
735                 int searchpos = history_len - 1;
736
737                 rbuf[0] = 0;
738                 while (1) {
739                     int n = 0;
740                     const char *p = NULL;
741                     int skipsame = 0;
742                     int searchdir = -1;
743
744                     snprintf(rprompt, sizeof(rprompt), "(reverse-i-search)'%s': ", rbuf);
745                     refreshLine(rprompt, current);
746                     c = fd_read(current->fd);
747                     if (c == ctrl('H') || c == 127) {
748                         if (rchars) {
749                             int p = utf8_index(rbuf, --rchars);
750                             rbuf[p] = 0;
751                             rlen = strlen(rbuf);
752                         }
753                         continue;
754                     }
755                     if (c == 27) {
756                         c = check_special(current->fd);
757                     }
758                     if (c == ctrl('P') || c == SPECIAL_UP) {
759                         /* Search for the previous (earlier) match */
760                         if (searchpos > 0) {
761                             searchpos--;
762                         }
763                         skipsame = 1;
764                     }
765                     else if (c == ctrl('N') || c == SPECIAL_DOWN) {
766                         /* Search for the next (later) match */
767                         if (searchpos < history_len) {
768                             searchpos++;
769                         }
770                         searchdir = 1;
771                         skipsame = 1;
772                     }
773                     else if (c >= ' ') {
774                         if (rlen >= (int)sizeof(rbuf) + 3) {
775                             continue;
776                         }
777
778                         n = utf8_getchars(rbuf + rlen, c);
779                         rlen += n;
780                         rchars++;
781                         rbuf[rlen] = 0;
782
783                         /* Adding a new char resets the search location */
784                         searchpos = history_len - 1;
785                     }
786                     else {
787                         /* Exit from incremental search mode */
788                         break;
789                     }
790
791                     /* Now search through the history for a match */
792                     for (; searchpos >= 0 && searchpos < history_len; searchpos += searchdir) {
793                         p = strstr(history[searchpos], rbuf);
794                         if (p) {
795                             /* Found a match */
796                             if (skipsame && strcmp(history[searchpos], current->buf) == 0) {
797                                 /* But it is identical, so skip it */
798                                 continue;
799                             }
800                             /* Copy the matching line and set the cursor position */
801                             set_current(current,history[searchpos]);
802                             current->pos = utf8_strlen(history[searchpos], p - history[searchpos]);
803                             break;
804                         }
805                     }
806                     if (!p && n) {
807                         /* No match, so don't add it */
808                         rchars--;
809                         rlen -= n;
810                         rbuf[rlen] = 0;
811                     }
812                 }
813                 if (c == ctrl('G') || c == ctrl('C')) {
814                     /* ctrl-g terminates the search with no effect */
815                     set_current(current, "");
816                     c = 0;
817                 }
818                 else if (c == ctrl('J')) {
819                     /* ctrl-j terminates the search leaving the buffer in place */
820                     c = 0;
821                 }
822                 /* Go process the char normally */
823                 refreshLine(prompt, current);
824                 goto process_char;
825             }
826             break;
827         case ctrl('T'):    /* ctrl-t */
828             if (current->pos > 0 && current->pos < current->chars) {
829                 c = get_char(current, current->pos);
830                 remove_char(current, current->pos);
831                 insert_char(current, current->pos - 1, c);
832                 refreshLine(prompt, current);
833             }
834             break;
835         case ctrl('V'):    /* ctrl-v */
836             if (has_room(current, 3)) {
837                 /* Insert the ^V first */
838                 if (insert_char(current, current->pos, c)) {
839                     refreshLine(prompt, current);
840                     /* Now wait for the next char. Can insert anything except \0 */
841                     c = fd_read(current->fd);
842
843                     /* Remove the ^V first */
844                     remove_char(current, current->pos - 1);
845                     if (c != -1) {
846                         /* Insert the actual char */
847                         insert_char(current, current->pos, c);
848                     }
849                     refreshLine(prompt, current);
850                 }
851             }
852             break;
853         case ctrl('B'):     /* ctrl-b */
854         case ctrl('F'):     /* ctrl-f */
855         case ctrl('P'):    /* ctrl-p */
856         case ctrl('N'):    /* ctrl-n */
857         case 27: {   /* escape sequence */
858             int dir = -1;
859             if (c == 27) {
860                 c = check_special(current->fd);
861             }
862             switch (c) {
863                 case ctrl('B'):
864                 case SPECIAL_LEFT:
865                     if (current->pos > 0) {
866                         current->pos--;
867                         refreshLine(prompt, current);
868                     }
869                     break;
870                 case ctrl('F'):
871                 case SPECIAL_RIGHT:
872                     if (current->pos < current->chars) {
873                         current->pos++;
874                         refreshLine(prompt, current);
875                     }
876                     break;
877                 case ctrl('P'):
878                 case SPECIAL_UP:
879                     dir = 1;
880                 case ctrl('N'):
881                 case SPECIAL_DOWN:
882                     if (history_len > 1) {
883                         /* Update the current history entry before to
884                          * overwrite it with tne next one. */
885                         free(history[history_len-1-history_index]);
886                         history[history_len-1-history_index] = strdup(current->buf);
887                         /* Show the new entry */
888                         history_index += dir;
889                         if (history_index < 0) {
890                             history_index = 0;
891                             break;
892                         } else if (history_index >= history_len) {
893                             history_index = history_len-1;
894                             break;
895                         }
896                         set_current(current, history[history_len-1-history_index]);
897                         refreshLine(prompt, current);
898                     }
899                     break;
900
901                 case SPECIAL_DELETE:
902                     if (remove_char(current, current->pos)) {
903                         refreshLine(prompt, current);
904                     }
905                     break;
906             }
907             }
908             break;
909         default:
910             /* Only tab is allowed without ^V */
911             if (c == '\t' || c >= ' ') {
912                 if (insert_char(current, current->pos, c)) {
913                     refreshLine(prompt, current);
914                 }
915             }
916             break;
917         case ctrl('U'): /* Ctrl+u, delete to beginning of line. */
918             if (remove_chars(current, 0, current->pos)) {
919                 refreshLine(prompt, current);
920             }
921             break;
922         case ctrl('K'): /* Ctrl+k, delete from current to end of line. */
923             if (remove_chars(current, current->pos, current->chars - current->pos)) {
924                 refreshLine(prompt, current);
925             }
926             break;
927         case ctrl('A'): /* Ctrl+a, go to the start of the line */
928             current->pos = 0;
929             refreshLine(prompt, current);
930             break;
931         case ctrl('E'): /* ctrl+e, go to the end of the line */
932             current->pos = current->chars;
933             refreshLine(prompt, current);
934             break;
935         case ctrl('L'): /* Ctrl+L, clear screen */
936             /* clear screen */
937             fd_printf(current->fd, "\x1b[H\x1b[2J");
938             refreshLine(prompt, current);
939             break;
940         }
941     }
942     return current->len;
943 }
944
945 static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) {
946     int fd = STDIN_FILENO;
947     int count;
948
949     if (buflen == 0) {
950         errno = EINVAL;
951         return -1;
952     }
953     if (!isatty(STDIN_FILENO)) {
954         if (fgets(buf, buflen, stdin) == NULL) return -1;
955         count = strlen(buf);
956         if (count && buf[count-1] == '\n') {
957             count--;
958             buf[count] = '\0';
959         }
960     } else {
961         struct current current;
962
963         if (enableRawMode(fd) == -1) return -1;
964
965         current.fd = fd;
966         current.buf = buf;
967         current.bufmax = buflen;
968         current.len = 0;
969         current.chars = 0;
970         current.pos = 0;
971         current.cols = 0;
972
973         count = linenoisePrompt(prompt, &current);
974         disableRawMode(fd);
975
976         printf("\n");
977     }
978     return count;
979 }
980
981 char *linenoise(const char *prompt) {
982     char buf[LINENOISE_MAX_LINE];
983     int count;
984
985     if (isUnsupportedTerm()) {
986         size_t len;
987
988         printf("%s",prompt);
989         fflush(stdout);
990         if (fgets(buf,LINENOISE_MAX_LINE,stdin) == NULL) return NULL;
991         len = strlen(buf);
992         while(len && (buf[len-1] == '\n' || buf[len-1] == '\r')) {
993             len--;
994             buf[len] = '\0';
995         }
996         return strdup(buf);
997     } else {
998         count = linenoiseRaw(buf,LINENOISE_MAX_LINE,prompt);
999         if (count == -1) return NULL;
1000         return strdup(buf);
1001     }
1002 }
1003
1004 /* Using a circular buffer is smarter, but a bit more complex to handle. */
1005 int linenoiseHistoryAdd(const char *line) {
1006     char *linecopy;
1007
1008     if (history_max_len == 0) return 0;
1009     if (history == NULL) {
1010         history = malloc(sizeof(char*)*history_max_len);
1011         if (history == NULL) return 0;
1012         memset(history,0,(sizeof(char*)*history_max_len));
1013     }
1014     linecopy = strdup(line);
1015     if (!linecopy) return 0;
1016     if (history_len == history_max_len) {
1017         free(history[0]);
1018         memmove(history,history+1,sizeof(char*)*(history_max_len-1));
1019         history_len--;
1020     }
1021     history[history_len] = linecopy;
1022     history_len++;
1023     return 1;
1024 }
1025
1026 int linenoiseHistorySetMaxLen(int len) {
1027     char **new;
1028
1029     if (len < 1) return 0;
1030     if (history) {
1031         int tocopy = history_len;
1032
1033         new = malloc(sizeof(char*)*len);
1034         if (new == NULL) return 0;
1035         if (len < tocopy) tocopy = len;
1036         memcpy(new,history+(history_max_len-tocopy), sizeof(char*)*tocopy);
1037         free(history);
1038         history = new;
1039     }
1040     history_max_len = len;
1041     if (history_len > history_max_len)
1042         history_len = history_max_len;
1043     return 1;
1044 }
1045
1046 /* Save the history in the specified file. On success 0 is returned
1047  * otherwise -1 is returned. */
1048 int linenoiseHistorySave(char *filename) {
1049     FILE *fp = fopen(filename,"w");
1050     int j;
1051
1052     if (fp == NULL) return -1;
1053     for (j = 0; j < history_len; j++) {
1054         const char *str = history[j];
1055         /* Need to encode backslash, nl and cr */
1056         while (*str) {
1057             if (*str == '\\') {
1058                 fputs("\\\\", fp);
1059             }
1060             else if (*str == '\n') {
1061                 fputs("\\n", fp);
1062             }
1063             else if (*str == '\r') {
1064                 fputs("\\r", fp);
1065             }
1066             else {
1067                 fputc(*str, fp);
1068             }
1069             str++;
1070         }
1071         fputc('\n', fp);
1072     }
1073
1074     fclose(fp);
1075     return 0;
1076 }
1077
1078 /* Load the history from the specified file. If the file does not exist
1079  * zero is returned and no operation is performed.
1080  *
1081  * If the file exists and the operation succeeded 0 is returned, otherwise
1082  * on error -1 is returned. */
1083 int linenoiseHistoryLoad(char *filename) {
1084     FILE *fp = fopen(filename,"r");
1085     char buf[LINENOISE_MAX_LINE];
1086
1087     if (fp == NULL) return -1;
1088
1089     while (fgets(buf,LINENOISE_MAX_LINE,fp) != NULL) {
1090         char *src, *dest;
1091
1092         /* Decode backslash escaped values */
1093         for (src = dest = buf; *src; src++) {
1094             char ch = *src;
1095
1096             if (ch == '\\') {
1097                 src++;
1098                 if (*src == 'n') {
1099                     ch = '\n';
1100                 }
1101                 else if (*src == 'r') {
1102                     ch = '\r';
1103                 } else {
1104                     ch = *src;
1105                 }
1106             }
1107             *dest++ = ch;
1108         }
1109         /* Remove trailing newline */
1110         if (dest != buf && (dest[-1] == '\n' || dest[-1] == '\r')) {
1111             dest--;
1112         }
1113         *dest = 0;
1114
1115         linenoiseHistoryAdd(buf);
1116     }
1117     fclose(fp);
1118     return 0;
1119 }
1120
1121 /* Provide access to the history buffer.
1122  *
1123  * If 'len' is not NULL, the length is stored in *len.
1124  */
1125 char **linenoiseHistory(int *len) {
1126     if (len) {
1127         *len = history_len;
1128     }
1129     return history;
1130 }