]> git.lizzy.rs Git - linenoise.git/blob - linenoise.c
Clear some warnings and errors with GCC and MSVC.
[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/msteveb/linenoise
7  *   (forked from http://github.com/antirez/linenoise)
8  *
9  * Does a number of crazy assumptions that happen to be true in 99.9999% of
10  * the 2010 UNIX computers around.
11  *
12  * ------------------------------------------------------------------------
13  *
14  * Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
15  * Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
16  * Copyright (c) 2011, Steve Bennett <steveb at workware dot net dot au>
17  *
18  * All rights reserved.
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted provided that the following conditions are
22  * met:
23  *
24  *  *  Redistributions of source code must retain the above copyright
25  *     notice, this list of conditions and the following disclaimer.
26  *
27  *  *  Redistributions in binary form must reproduce the above copyright
28  *     notice, this list of conditions and the following disclaimer in the
29  *     documentation and/or other materials provided with the distribution.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  * ------------------------------------------------------------------------
44  *
45  * References:
46  * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
47  * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html
48  *
49  * Bloat:
50  * - Completion?
51  *
52  * Unix/termios
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  * EL (Erase Line)
60  *    Sequence: ESC [ 0 K
61  *    Effect: clear from cursor to end of line
62  *
63  * CUF (CUrsor Forward)
64  *    Sequence: ESC [ n C
65  *    Effect: moves cursor forward n chars
66  *
67  * CR (Carriage Return)
68  *    Sequence: \r
69  *    Effect: moves cursor to column 1
70  *
71  * The following are used to clear the screen: ESC [ H ESC [ 2 J
72  * This is actually composed of two sequences:
73  *
74  * cursorhome
75  *    Sequence: ESC [ H
76  *    Effect: moves the cursor to upper left corner
77  *
78  * ED2 (Clear entire screen)
79  *    Sequence: ESC [ 2 J
80  *    Effect: clear the whole screen
81  *
82  * == For highlighting control characters, we also use the following two ==
83  * SO (enter StandOut)
84  *    Sequence: ESC [ 7 m
85  *    Effect: Uses some standout mode such as reverse video
86  *
87  * SE (Standout End)
88  *    Sequence: ESC [ 0 m
89  *    Effect: Exit standout mode
90  *
91  * == Only used if TIOCGWINSZ fails ==
92  * DSR/CPR (Report cursor position)
93  *    Sequence: ESC [ 6 n
94  *    Effect: reports current cursor position as ESC [ NNN ; MMM R
95  *
96  * == Only used in multiline mode ==
97  * CUU (Cursor Up)
98  *    Sequence: ESC [ n A
99  *    Effect: moves cursor up n chars.
100  *
101  * CUD (Cursor Down)
102  *    Sequence: ESC [ n B
103  *    Effect: moves cursor down n chars.
104  *
105  * win32/console
106  * -------------
107  * If __MINGW32__ is defined, the win32 console API is used.
108  * This could probably be made to work for the msvc compiler too.
109  * This support based in part on work by Jon Griffiths.
110  */
111
112 #ifdef _WIN32 /* Windows platform, either MinGW or Visual Studio (MSVC) */
113 #include <windows.h>
114 #include <fcntl.h>
115 #define USE_WINCONSOLE
116 #ifdef __MINGW32__
117 #define HAVE_UNISTD_H
118 #else
119 /* Microsoft headers don't like old POSIX names */
120 #define strdup _strdup
121 #define snprintf _snprintf
122 #endif
123 #else
124 #include <termios.h>
125 #include <sys/ioctl.h>
126 #include <poll.h>
127 #define USE_TERMIOS
128 #define HAVE_UNISTD_H
129 #endif
130
131 #ifdef HAVE_UNISTD_H
132 #include <unistd.h>
133 #endif
134 #include <stdlib.h>
135 #include <stdarg.h>
136 #include <stdio.h>
137 #include <assert.h>
138 #include <errno.h>
139 #include <string.h>
140 #include <signal.h>
141 #include <stdlib.h>
142 #include <sys/types.h>
143
144 #include "linenoise.h"
145 #ifndef STRINGBUF_H
146 #include "stringbuf.h"
147 #endif
148 #include "utf8.h"
149
150 #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
151
152 #define ctrl(C) ((C) - '@')
153
154 /* Use -ve numbers here to co-exist with normal unicode chars */
155 enum {
156     SPECIAL_NONE,
157     /* don't use -1 here since that indicates error */
158     SPECIAL_UP = -20,
159     SPECIAL_DOWN = -21,
160     SPECIAL_LEFT = -22,
161     SPECIAL_RIGHT = -23,
162     SPECIAL_DELETE = -24,
163     SPECIAL_HOME = -25,
164     SPECIAL_END = -26,
165     SPECIAL_INSERT = -27,
166     SPECIAL_PAGE_UP = -28,
167     SPECIAL_PAGE_DOWN = -29,
168
169     /* Some handy names for other special keycodes */
170     CHAR_ESCAPE = 27,
171     CHAR_DELETE = 127,
172 };
173
174 static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
175 static int history_len = 0;
176 static char **history = NULL;
177
178 /* Structure to contain the status of the current (being edited) line */
179 struct current {
180     stringbuf *buf; /* Current buffer. Always null terminated */
181     int pos;    /* Cursor position, measured in chars */
182     int cols;   /* Size of the window, in chars */
183     int nrows;  /* How many rows are being used in multiline mode (>= 1) */
184     int rpos;   /* The current row containing the cursor - multiline mode only */
185     int colsright; /* refreshLine() cached cols for insert_char() optimisation */
186     int colsleft;  /* refreshLine() cached cols for remove_char() optimisation */
187     const char *prompt;
188     stringbuf *capture; /* capture buffer, or NULL for none. Always null terminated */
189     stringbuf *output;  /* used only during refreshLine() - output accumulator */
190 #if defined(USE_TERMIOS)
191     int fd;     /* Terminal fd */
192 #elif defined(USE_WINCONSOLE)
193     HANDLE outh; /* Console output handle */
194     HANDLE inh; /* Console input handle */
195     int rows;   /* Screen rows */
196     int x;      /* Current column during output */
197     int y;      /* Current row */
198 #ifdef USE_UTF8
199     #define UBUF_MAX_CHARS 132
200     WORD ubuf[UBUF_MAX_CHARS + 1];  /* Accumulates utf16 output - one extra for final surrogate pairs */
201     int ubuflen;      /* length used in ubuf */
202     int ubufcols;     /* how many columns are represented by the chars in ubuf? */
203 #endif
204 #endif
205 };
206
207 static int fd_read(struct current *current);
208 static int getWindowSize(struct current *current);
209 static void cursorDown(struct current *current, int n);
210 static void cursorUp(struct current *current, int n);
211 static void eraseEol(struct current *current);
212 static void refreshLine(struct current *current);
213 static void refreshLineAlt(struct current *current, const char *prompt, const char *buf, int cursor_pos);
214 static void setCursorPos(struct current *current, int x);
215 static void setOutputHighlight(struct current *current, const int *props, int nprops);
216 static void set_current(struct current *current, const char *str);
217
218 void linenoiseHistoryFree(void) {
219     if (history) {
220         int j;
221
222         for (j = 0; j < history_len; j++)
223             free(history[j]);
224         free(history);
225         history = NULL;
226         history_len = 0;
227     }
228 }
229
230 typedef enum {
231     EP_START,   /* looking for ESC */
232     EP_ESC,     /* looking for [ */
233     EP_DIGITS,  /* parsing digits */
234     EP_PROPS,   /* parsing digits or semicolons */
235     EP_END,     /* ok */
236     EP_ERROR,   /* error */
237 } ep_state_t;
238
239 struct esc_parser {
240     ep_state_t state;
241     int props[5];   /* properties are stored here */
242     int maxprops;   /* size of the props[] array */
243     int numprops;   /* number of properties found */
244     int termchar;   /* terminator char, or 0 for any alpha */
245     int current;    /* current (partial) property value */
246 };
247
248 /**
249  * Initialise the escape sequence parser at *parser.
250  *
251  * If termchar is 0 any alpha char terminates ok. Otherwise only the given
252  * char terminates successfully.
253  * Run the parser state machine with calls to parseEscapeSequence() for each char.
254  */
255 static void initParseEscapeSeq(struct esc_parser *parser, int termchar)
256 {
257     parser->state = EP_START;
258     parser->maxprops = sizeof(parser->props) / sizeof(*parser->props);
259     parser->numprops = 0;
260     parser->current = 0;
261     parser->termchar = termchar;
262 }
263
264 /**
265  * Pass character 'ch' into the state machine to parse:
266  *   'ESC' '[' <digits> (';' <digits>)* <termchar>
267  *
268  * The first character must be ESC.
269  * Returns the current state. The state machine is done when it returns either EP_END
270  * or EP_ERROR.
271  *
272  * On EP_END, the "property/attribute" values can be read from parser->props[]
273  * of length parser->numprops.
274  */
275 static int parseEscapeSequence(struct esc_parser *parser, int ch)
276 {
277     switch (parser->state) {
278         case EP_START:
279             parser->state = (ch == '\x1b') ? EP_ESC : EP_ERROR;
280             break;
281         case EP_ESC:
282             parser->state = (ch == '[') ? EP_DIGITS : EP_ERROR;
283             break;
284         case EP_PROPS:
285             if (ch == ';') {
286                 parser->state = EP_DIGITS;
287 donedigits:
288                 if (parser->numprops + 1 < parser->maxprops) {
289                     parser->props[parser->numprops++] = parser->current;
290                     parser->current = 0;
291                 }
292                 break;
293             }
294             /* fall through */
295         case EP_DIGITS:
296             if (ch >= '0' && ch <= '9') {
297                 parser->current = parser->current * 10 + (ch - '0');
298                 parser->state = EP_PROPS;
299                 break;
300             }
301             /* must be terminator */
302             if (parser->termchar != ch) {
303                 if (parser->termchar != 0 || !((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))) {
304                     parser->state = EP_ERROR;
305                     break;
306                 }
307             }
308             parser->state = EP_END;
309             goto donedigits;
310         case EP_END:
311             parser->state = EP_ERROR;
312             break;
313         case EP_ERROR:
314             break;
315     }
316     return parser->state;
317 }
318
319 /*#define DEBUG_REFRESHLINE*/
320
321 #ifdef DEBUG_REFRESHLINE
322 #define DRL(ARGS...) fprintf(dfh, ARGS)
323 static FILE *dfh;
324
325 static void DRL_CHAR(int ch)
326 {
327     if (ch < ' ') {
328         DRL("^%c", ch + '@');
329     }
330     else if (ch > 127) {
331         DRL("\\u%04x", ch);
332     }
333     else {
334         DRL("%c", ch);
335     }
336 }
337 static void DRL_STR(const char *str)
338 {
339     while (*str) {
340         int ch;
341         int n = utf8_tounicode(str, &ch);
342         str += n;
343         DRL_CHAR(ch);
344     }
345 }
346 #else
347 #define DRL(...)
348 #define DRL_CHAR(ch)
349 #define DRL_STR(str)
350 #endif
351
352 #if defined(USE_WINCONSOLE)
353 #include "linenoise-win32.c"
354 #endif
355
356 #if defined(USE_TERMIOS)
357 static void linenoiseAtExit(void);
358 static struct termios orig_termios; /* in order to restore at exit */
359 static int rawmode = 0; /* for atexit() function to check if restore is needed*/
360 static int atexit_registered = 0; /* register atexit just 1 time */
361
362 static const char *unsupported_term[] = {"dumb","cons25","emacs",NULL};
363
364 static int isUnsupportedTerm(void) {
365     char *term = getenv("TERM");
366
367     if (term) {
368         int j;
369         for (j = 0; unsupported_term[j]; j++) {
370             if (strcmp(term, unsupported_term[j]) == 0) {
371                 return 1;
372             }
373         }
374     }
375     return 0;
376 }
377
378 static int enableRawMode(struct current *current) {
379     struct termios raw;
380
381     current->fd = STDIN_FILENO;
382     current->cols = 0;
383
384     if (!isatty(current->fd) || isUnsupportedTerm() ||
385         tcgetattr(current->fd, &orig_termios) == -1) {
386 fatal:
387         errno = ENOTTY;
388         return -1;
389     }
390
391     if (!atexit_registered) {
392         atexit(linenoiseAtExit);
393         atexit_registered = 1;
394     }
395
396     raw = orig_termios;  /* modify the original mode */
397     /* input modes: no break, no CR to NL, no parity check, no strip char,
398      * no start/stop output control. */
399     raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
400     /* output modes - actually, no need to disable post processing */
401     /*raw.c_oflag &= ~(OPOST);*/
402     /* control modes - set 8 bit chars */
403     raw.c_cflag |= (CS8);
404     /* local modes - choing off, canonical off, no extended functions,
405      * no signal chars (^Z,^C) */
406     raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
407     /* control chars - set return condition: min number of bytes and timer.
408      * We want read to return every single byte, without timeout. */
409     raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
410
411     /* put terminal in raw mode after flushing */
412     if (tcsetattr(current->fd,TCSADRAIN,&raw) < 0) {
413         goto fatal;
414     }
415     rawmode = 1;
416     return 0;
417 }
418
419 static void disableRawMode(struct current *current) {
420     /* Don't even check the return value as it's too late. */
421     if (rawmode && tcsetattr(current->fd,TCSADRAIN,&orig_termios) != -1)
422         rawmode = 0;
423 }
424
425 /* At exit we'll try to fix the terminal to the initial conditions. */
426 static void linenoiseAtExit(void) {
427     if (rawmode) {
428         tcsetattr(STDIN_FILENO, TCSADRAIN, &orig_termios);
429     }
430     linenoiseHistoryFree();
431 }
432
433 /* gcc/glibc insists that we care about the return code of write!
434  * Clarification: This means that a void-cast like "(void) (EXPR)"
435  * does not work.
436  */
437 #define IGNORE_RC(EXPR) if (EXPR) {}
438
439 /**
440  * Output bytes directly, or accumulate output (if current->output is set)
441  */
442 static void outputChars(struct current *current, const char *buf, int len)
443 {
444     if (len < 0) {
445         len = strlen(buf);
446     }
447     if (current->output) {
448         sb_append_len(current->output, buf, len);
449     }
450     else {
451         IGNORE_RC(write(current->fd, buf, len));
452     }
453 }
454
455 /* Like outputChars, but using printf-style formatting
456  */
457 static void outputFormatted(struct current *current, const char *format, ...)
458 {
459     va_list args;
460     char buf[64];
461     int n;
462
463     va_start(args, format);
464     n = vsnprintf(buf, sizeof(buf), format, args);
465     /* This will never happen because we are sure to use outputFormatted() only for short sequences */
466     assert(n < (int)sizeof(buf));
467     va_end(args);
468     outputChars(current, buf, n);
469 }
470
471 static void cursorToLeft(struct current *current)
472 {
473     outputChars(current, "\r", -1);
474 }
475
476 static void setOutputHighlight(struct current *current, const int *props, int nprops)
477 {
478     outputChars(current, "\x1b[", -1);
479     while (nprops--) {
480         outputFormatted(current, "%d%c", *props, (nprops == 0) ? 'm' : ';');
481         props++;
482     }
483 }
484
485 static void eraseEol(struct current *current)
486 {
487     outputChars(current, "\x1b[0K", -1);
488 }
489
490 static void setCursorPos(struct current *current, int x)
491 {
492     if (x == 0) {
493         cursorToLeft(current);
494     }
495     else {
496         outputFormatted(current, "\r\x1b[%dC", x);
497     }
498 }
499
500 static void cursorUp(struct current *current, int n)
501 {
502     if (n) {
503         outputFormatted(current, "\x1b[%dA", n);
504     }
505 }
506
507 static void cursorDown(struct current *current, int n)
508 {
509     if (n) {
510         outputFormatted(current, "\x1b[%dB", n);
511     }
512 }
513
514 void linenoiseClearScreen(void)
515 {
516     IGNORE_RC(write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7));
517 }
518
519 /**
520  * Reads a char from 'fd', waiting at most 'timeout' milliseconds.
521  *
522  * A timeout of -1 means to wait forever.
523  *
524  * Returns -1 if no char is received within the time or an error occurs.
525  */
526 static int fd_read_char(int fd, int timeout)
527 {
528     struct pollfd p;
529     unsigned char c;
530
531     p.fd = fd;
532     p.events = POLLIN;
533
534     if (poll(&p, 1, timeout) == 0) {
535         /* timeout */
536         return -1;
537     }
538     if (read(fd, &c, 1) != 1) {
539         return -1;
540     }
541     return c;
542 }
543
544 /**
545  * Reads a complete utf-8 character
546  * and returns the unicode value, or -1 on error.
547  */
548 static int fd_read(struct current *current)
549 {
550 #ifdef USE_UTF8
551     char buf[MAX_UTF8_LEN];
552     int n;
553     int i;
554     int c;
555
556     if (read(current->fd, &buf[0], 1) != 1) {
557         return -1;
558     }
559     n = utf8_charlen(buf[0]);
560     if (n < 1) {
561         return -1;
562     }
563     for (i = 1; i < n; i++) {
564         if (read(current->fd, &buf[i], 1) != 1) {
565             return -1;
566         }
567     }
568     /* decode and return the character */
569     utf8_tounicode(buf, &c);
570     return c;
571 #else
572     return fd_read_char(current->fd, -1);
573 #endif
574 }
575
576
577 /**
578  * Stores the current cursor column in '*cols'.
579  * Returns 1 if OK, or 0 if failed to determine cursor pos.
580  */
581 static int queryCursor(struct current *current, int* cols)
582 {
583     struct esc_parser parser;
584     int ch;
585
586     /* Should not be buffering this output, it needs to go immediately */
587     assert(current->output == NULL);
588
589     /* control sequence - report cursor location */
590     outputChars(current, "\x1b[6n", -1);
591
592     /* Parse the response: ESC [ rows ; cols R */
593     initParseEscapeSeq(&parser, 'R');
594     while ((ch = fd_read_char(current->fd, 100)) > 0) {
595         switch (parseEscapeSequence(&parser, ch)) {
596             default:
597                 continue;
598             case EP_END:
599                 if (parser.numprops == 2 && parser.props[1] < 1000) {
600                     *cols = parser.props[1];
601                     return 1;
602                 }
603                 break;
604             case EP_ERROR:
605                 break;
606         }
607         /* failed */
608         break;
609     }
610     return 0;
611 }
612
613 /**
614  * Updates current->cols with the current window size (width)
615  */
616 static int getWindowSize(struct current *current)
617 {
618     struct winsize ws;
619
620     if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 && ws.ws_col != 0) {
621         current->cols = ws.ws_col;
622         return 0;
623     }
624
625     /* Failed to query the window size. Perhaps we are on a serial terminal.
626      * Try to query the width by sending the cursor as far to the right
627      * and reading back the cursor position.
628      * Note that this is only done once per call to linenoise rather than
629      * every time the line is refreshed for efficiency reasons.
630      *
631      * In more detail, we:
632      * (a) request current cursor position,
633      * (b) move cursor far right,
634      * (c) request cursor position again,
635      * (d) at last move back to the old position.
636      * This gives us the width without messing with the externally
637      * visible cursor position.
638      */
639
640     if (current->cols == 0) {
641         int here;
642
643         /* If anything fails => default 80 */
644         current->cols = 80;
645
646         /* (a) */
647         if (queryCursor (current, &here)) {
648             /* (b) */
649             setCursorPos(current, 999);
650
651             /* (c). Note: If (a) succeeded, then (c) should as well.
652              * For paranoia we still check and have a fallback action
653              * for (d) in case of failure..
654              */
655             if (queryCursor (current, &current->cols)) {
656                 /* (d) Reset the cursor back to the original location. */
657                 if (current->cols > here) {
658                     setCursorPos(current, here);
659                 }
660             }
661         }
662     }
663
664     return 0;
665 }
666
667 /**
668  * If CHAR_ESCAPE was received, reads subsequent
669  * chars to determine if this is a known special key.
670  *
671  * Returns SPECIAL_NONE if unrecognised, or -1 if EOF.
672  *
673  * If no additional char is received within a short time,
674  * CHAR_ESCAPE is returned.
675  */
676 static int check_special(int fd)
677 {
678     int c = fd_read_char(fd, 50);
679     int c2;
680
681     if (c < 0) {
682         return CHAR_ESCAPE;
683     }
684
685     c2 = fd_read_char(fd, 50);
686     if (c2 < 0) {
687         return c2;
688     }
689     if (c == '[' || c == 'O') {
690         /* Potential arrow key */
691         switch (c2) {
692             case 'A':
693                 return SPECIAL_UP;
694             case 'B':
695                 return SPECIAL_DOWN;
696             case 'C':
697                 return SPECIAL_RIGHT;
698             case 'D':
699                 return SPECIAL_LEFT;
700             case 'F':
701                 return SPECIAL_END;
702             case 'H':
703                 return SPECIAL_HOME;
704         }
705     }
706     if (c == '[' && c2 >= '1' && c2 <= '8') {
707         /* extended escape */
708         c = fd_read_char(fd, 50);
709         if (c == '~') {
710             switch (c2) {
711                 case '2':
712                     return SPECIAL_INSERT;
713                 case '3':
714                     return SPECIAL_DELETE;
715                 case '5':
716                     return SPECIAL_PAGE_UP;
717                 case '6':
718                     return SPECIAL_PAGE_DOWN;
719                 case '7':
720                     return SPECIAL_HOME;
721                 case '8':
722                     return SPECIAL_END;
723             }
724         }
725         while (c != -1 && c != '~') {
726             /* .e.g \e[12~ or '\e[11;2~   discard the complete sequence */
727             c = fd_read_char(fd, 50);
728         }
729     }
730
731     return SPECIAL_NONE;
732 }
733 #endif
734
735 static void clearOutputHighlight(struct current *current)
736 {
737     int nohighlight = 0;
738     setOutputHighlight(current, &nohighlight, 1);
739 }
740
741 static void outputControlChar(struct current *current, char ch)
742 {
743     int reverse = 7;
744     setOutputHighlight(current, &reverse, 1);
745     outputChars(current, "^", 1);
746     outputChars(current, &ch, 1);
747     clearOutputHighlight(current);
748 }
749
750 #ifndef utf8_getchars
751 static int utf8_getchars(char *buf, int c)
752 {
753 #ifdef USE_UTF8
754     return utf8_fromunicode(buf, c);
755 #else
756     *buf = c;
757     return 1;
758 #endif
759 }
760 #endif
761
762 /**
763  * Returns the unicode character at the given offset,
764  * or -1 if none.
765  */
766 static int get_char(struct current *current, int pos)
767 {
768     if (pos >= 0 && pos < sb_chars(current->buf)) {
769         int c;
770         int i = utf8_index(sb_str(current->buf), pos);
771         (void)utf8_tounicode(sb_str(current->buf) + i, &c);
772         return c;
773     }
774     return -1;
775 }
776
777 static int char_display_width(int ch)
778 {
779     if (ch < ' ') {
780         /* control chars take two positions */
781         return 2;
782     }
783     else {
784         return utf8_width(ch);
785     }
786 }
787
788 #ifndef NO_COMPLETION
789 static linenoiseCompletionCallback *completionCallback = NULL;
790 static void *completionUserdata = NULL;
791 static int showhints = 1;
792 static linenoiseHintsCallback *hintsCallback = NULL;
793 static linenoiseFreeHintsCallback *freeHintsCallback = NULL;
794 static void *hintsUserdata = NULL;
795
796 static void beep() {
797 #ifdef USE_TERMIOS
798     fprintf(stderr, "\x7");
799     fflush(stderr);
800 #endif
801 }
802
803 static void freeCompletions(linenoiseCompletions *lc) {
804     size_t i;
805     for (i = 0; i < lc->len; i++)
806         free(lc->cvec[i]);
807     free(lc->cvec);
808 }
809
810 static int completeLine(struct current *current) {
811     linenoiseCompletions lc = { 0, NULL };
812     int c = 0;
813
814     completionCallback(sb_str(current->buf),&lc,completionUserdata);
815     if (lc.len == 0) {
816         beep();
817     } else {
818         size_t stop = 0, i = 0;
819
820         while(!stop) {
821             /* Show completion or original buffer */
822             if (i < lc.len) {
823                 int chars = utf8_strlen(lc.cvec[i], -1);
824                 refreshLineAlt(current, current->prompt, lc.cvec[i], chars);
825             } else {
826                 refreshLine(current);
827             }
828
829             c = fd_read(current);
830             if (c == -1) {
831                 break;
832             }
833
834             switch(c) {
835                 case '\t': /* tab */
836                     i = (i+1) % (lc.len+1);
837                     if (i == lc.len) beep();
838                     break;
839                 case CHAR_ESCAPE: /* escape */
840                     /* Re-show original buffer */
841                     if (i < lc.len) {
842                         refreshLine(current);
843                     }
844                     stop = 1;
845                     break;
846                 default:
847                     /* Update buffer and return */
848                     if (i < lc.len) {
849                         set_current(current,lc.cvec[i]);
850                     }
851                     stop = 1;
852                     break;
853             }
854         }
855     }
856
857     freeCompletions(&lc);
858     return c; /* Return last read character */
859 }
860
861 /* Register a callback function to be called for tab-completion.
862    Returns the prior callback so that the caller may (if needed)
863    restore it when done. */
864 linenoiseCompletionCallback * linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn, void *userdata) {
865     linenoiseCompletionCallback * old = completionCallback;
866     completionCallback = fn;
867     completionUserdata = userdata;
868     return old;
869 }
870
871 void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
872     lc->cvec = (char **)realloc(lc->cvec,sizeof(char*)*(lc->len+1));
873     lc->cvec[lc->len++] = strdup(str);
874 }
875
876 void linenoiseSetHintsCallback(linenoiseHintsCallback *callback, void *userdata)
877 {
878     hintsCallback = callback;
879     hintsUserdata = userdata;
880 }
881
882 void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *callback)
883 {
884     freeHintsCallback = callback;
885 }
886
887 #endif
888
889
890 static const char *reduceSingleBuf(const char *buf, int availcols, int *cursor_pos)
891 {
892     /* We have availcols columns available.
893      * If necessary, strip chars off the front of buf until *cursor_pos
894      * fits within availcols
895      */
896     int needcols = 0;
897     int pos = 0;
898     int new_cursor_pos = *cursor_pos;
899     const char *pt = buf;
900
901     DRL("reduceSingleBuf: availcols=%d, cursor_pos=%d\n", availcols, *cursor_pos);
902
903     while (*pt) {
904         int ch;
905         int n = utf8_tounicode(pt, &ch);
906         pt += n;
907
908         needcols += char_display_width(ch);
909
910         /* If we need too many cols, strip
911          * chars off the front of buf to make it fit.
912          * We keep 3 extra cols to the right of the cursor.
913          * 2 for possible wide chars, 1 for the last column that
914          * can't be used.
915          */
916         while (needcols >= availcols - 3) {
917             n = utf8_tounicode(buf, &ch);
918             buf += n;
919             needcols -= char_display_width(ch);
920             DRL_CHAR(ch);
921
922             /* and adjust the apparent cursor position */
923             new_cursor_pos--;
924
925             if (buf == pt) {
926                 /* can't remove more than this */
927                 break;
928             }
929         }
930
931         if (pos++ == *cursor_pos) {
932             break;
933         }
934
935     }
936     DRL("<snip>");
937     DRL_STR(buf);
938     DRL("\nafter reduce, needcols=%d, new_cursor_pos=%d\n", needcols, new_cursor_pos);
939
940     /* Done, now new_cursor_pos contains the adjusted cursor position
941      * and buf points to he adjusted start
942      */
943     *cursor_pos = new_cursor_pos;
944     return buf;
945 }
946
947 static int mlmode = 0;
948
949 void linenoiseSetMultiLine(int enableml)
950 {
951     mlmode = enableml;
952 }
953
954 /* Helper of refreshSingleLine() and refreshMultiLine() to show hints
955  * to the right of the prompt.
956  * Returns 1 if a hint was shown, or 0 if not
957  * If 'display' is 0, does no output. Just returns the appropriate return code.
958  */
959 static int refreshShowHints(struct current *current, const char *buf, int availcols, int display)
960 {
961     int rc = 0;
962     if (showhints && hintsCallback && availcols > 0) {
963         int bold = 0;
964         int color = -1;
965         char *hint = hintsCallback(buf, &color, &bold, hintsUserdata);
966         if (hint) {
967             rc = 1;
968             if (display) {
969                 const char *pt;
970                 if (bold == 1 && color == -1) color = 37;
971                 if (bold || color > 0) {
972                     int props[3] = { bold, color, 49 }; /* bold, color, fgnormal */
973                     setOutputHighlight(current, props, 3);
974                 }
975                 DRL("<hint bold=%d,color=%d>", bold, color);
976                 pt = hint;
977                 while (*pt) {
978                     int ch;
979                     int n = utf8_tounicode(pt, &ch);
980                     int width = char_display_width(ch);
981
982                     if (width >= availcols) {
983                         DRL("<hinteol>");
984                         break;
985                     }
986                     DRL_CHAR(ch);
987
988                     availcols -= width;
989                     outputChars(current, pt, n);
990                     pt += n;
991                 }
992                 if (bold || color > 0) {
993                     clearOutputHighlight(current);
994                 }
995                 /* Call the function to free the hint returned. */
996                 if (freeHintsCallback) freeHintsCallback(hint, hintsUserdata);
997             }
998         }
999     }
1000     return rc;
1001 }
1002
1003 #ifdef USE_TERMIOS
1004 static void refreshStart(struct current *current)
1005 {
1006     /* We accumulate all output here */
1007     assert(current->output == NULL);
1008     current->output = sb_alloc();
1009 }
1010
1011 static void refreshEnd(struct current *current)
1012 {
1013     /* Output everything at once */
1014     IGNORE_RC(write(current->fd, sb_str(current->output), sb_len(current->output)));
1015     sb_free(current->output);
1016     current->output = NULL;
1017 }
1018
1019 static void refreshStartChars(struct current *current)
1020 {
1021     (void)current;
1022 }
1023
1024 static void refreshNewline(struct current *current)
1025 {
1026     DRL("<nl>");
1027     outputChars(current, "\n", 1);
1028 }
1029
1030 static void refreshEndChars(struct current *current)
1031 {
1032     (void)current;
1033 }
1034 #endif
1035
1036 static void refreshLineAlt(struct current *current, const char *prompt, const char *buf, int cursor_pos)
1037 {
1038     int i;
1039     const char *pt;
1040     int displaycol;
1041     int displayrow;
1042     int visible;
1043     int currentpos;
1044     int notecursor;
1045     int cursorcol = 0;
1046     int cursorrow = 0;
1047     int hint;
1048     struct esc_parser parser;
1049
1050 #ifdef DEBUG_REFRESHLINE
1051     dfh = fopen("linenoise.debuglog", "a");
1052 #endif
1053
1054     /* Should intercept SIGWINCH. For now, just get the size every time */
1055     getWindowSize(current);
1056
1057     refreshStart(current);
1058
1059     DRL("wincols=%d, cursor_pos=%d, nrows=%d, rpos=%d\n", current->cols, cursor_pos, current->nrows, current->rpos);
1060
1061     /* Here is the plan:
1062      * (a) move the the bottom row, going down the appropriate number of lines
1063      * (b) move to beginning of line and erase the current line
1064      * (c) go up one line and do the same, until we have erased up to the first row
1065      * (d) output the prompt, counting cols and rows, taking into account escape sequences
1066      * (e) output the buffer, counting cols and rows
1067      *   (e') when we hit the current pos, save the cursor position
1068      * (f) move the cursor to the saved cursor position
1069      * (g) save the current cursor row and number of rows
1070      */
1071
1072     /* (a) - The cursor is currently at row rpos */
1073     cursorDown(current, current->nrows - current->rpos - 1);
1074     DRL("<cud=%d>", current->nrows - current->rpos - 1);
1075
1076     /* (b), (c) - Erase lines upwards until we get to the first row */
1077     for (i = 0; i < current->nrows; i++) {
1078         if (i) {
1079             DRL("<cup>");
1080             cursorUp(current, 1);
1081         }
1082         DRL("<clearline>");
1083         cursorToLeft(current);
1084         eraseEol(current);
1085     }
1086     DRL("\n");
1087
1088     /* (d) First output the prompt. control sequences don't take up display space */
1089     pt = prompt;
1090     displaycol = 0; /* current display column */
1091     displayrow = 0; /* current display row */
1092     visible = 1;
1093
1094     refreshStartChars(current);
1095
1096     while (*pt) {
1097         int width;
1098         int ch;
1099         int n = utf8_tounicode(pt, &ch);
1100
1101         if (visible && ch == CHAR_ESCAPE) {
1102             /* The start of an escape sequence, so not visible */
1103             visible = 0;
1104             initParseEscapeSeq(&parser, 'm');
1105             DRL("<esc-seq-start>");
1106         }
1107
1108         if (ch == '\n' || ch == '\r') {
1109             /* treat both CR and NL the same and force wrap */
1110             refreshNewline(current);
1111             displaycol = 0;
1112             displayrow++;
1113         }
1114         else {
1115             width = visible * utf8_width(ch);
1116
1117             displaycol += width;
1118             if (displaycol >= current->cols) {
1119                 /* need to wrap to the next line because of newline or if it doesn't fit
1120                  * XXX this is a problem in single line mode
1121                  */
1122                 refreshNewline(current);
1123                 displaycol = width;
1124                 displayrow++;
1125             }
1126
1127             DRL_CHAR(ch);
1128 #ifdef USE_WINCONSOLE
1129             if (visible) {
1130                 outputChars(current, pt, n);
1131             }
1132 #else
1133             outputChars(current, pt, n);
1134 #endif
1135         }
1136         pt += n;
1137
1138         if (!visible) {
1139             switch (parseEscapeSequence(&parser, ch)) {
1140                 case EP_END:
1141                     visible = 1;
1142                     setOutputHighlight(current, parser.props, parser.numprops);
1143                     DRL("<esc-seq-end,numprops=%d>", parser.numprops);
1144                     break;
1145                 case EP_ERROR:
1146                     DRL("<esc-seq-err>");
1147                     visible = 1;
1148                     break;
1149             }
1150         }
1151     }
1152
1153     /* Now we are at the first line with all lines erased */
1154     DRL("\nafter prompt: displaycol=%d, displayrow=%d\n", displaycol, displayrow);
1155
1156
1157     /* (e) output the buffer, counting cols and rows */
1158     if (mlmode == 0) {
1159         /* In this mode we may need to trim chars from the start of the buffer until the
1160          * cursor fits in the window.
1161          */
1162         pt = reduceSingleBuf(buf, current->cols - displaycol, &cursor_pos);
1163     }
1164     else {
1165         pt = buf;
1166     }
1167
1168     currentpos = 0;
1169     notecursor = -1;
1170
1171     while (*pt) {
1172         int ch;
1173         int n = utf8_tounicode(pt, &ch);
1174         int width = char_display_width(ch);
1175
1176         if (currentpos == cursor_pos) {
1177             /* (e') wherever we output this character is where we want the cursor */
1178             notecursor = 1;
1179         }
1180
1181         if (displaycol + width >= current->cols) {
1182             if (mlmode == 0) {
1183                 /* In single line mode stop once we print as much as we can on one line */
1184                 DRL("<slmode>");
1185                 break;
1186             }
1187             /* need to wrap to the next line since it doesn't fit */
1188             refreshNewline(current);
1189             displaycol = 0;
1190             displayrow++;
1191         }
1192
1193         if (notecursor == 1) {
1194             /* (e') Save this position as the current cursor position */
1195             cursorcol = displaycol;
1196             cursorrow = displayrow;
1197             notecursor = 0;
1198             DRL("<cursor>");
1199         }
1200
1201         displaycol += width;
1202
1203         if (ch < ' ') {
1204             outputControlChar(current, ch + '@');
1205         }
1206         else {
1207             outputChars(current, pt, n);
1208         }
1209         DRL_CHAR(ch);
1210         if (width != 1) {
1211             DRL("<w=%d>", width);
1212         }
1213
1214         pt += n;
1215         currentpos++;
1216     }
1217
1218     /* If we didn't see the cursor, it is at the current location */
1219     if (notecursor) {
1220         DRL("<cursor>");
1221         cursorcol = displaycol;
1222         cursorrow = displayrow;
1223     }
1224
1225     DRL("\nafter buf: displaycol=%d, displayrow=%d, cursorcol=%d, cursorrow=%d\n", displaycol, displayrow, cursorcol, cursorrow);
1226
1227     /* (f) show hints */
1228     hint = refreshShowHints(current, buf, current->cols - displaycol, 1);
1229
1230     /* Remember how many many cols are available for insert optimisation */
1231     if (prompt == current->prompt && hint == 0) {
1232         current->colsright = current->cols - displaycol;
1233         current->colsleft = displaycol;
1234     }
1235     else {
1236         /* Can't optimise */
1237         current->colsright = 0;
1238         current->colsleft = 0;
1239     }
1240     DRL("\nafter hints: colsleft=%d, colsright=%d\n\n", current->colsleft, current->colsright);
1241
1242     refreshEndChars(current);
1243
1244     /* (g) move the cursor to the correct place */
1245     cursorUp(current, displayrow - cursorrow);
1246     setCursorPos(current, cursorcol);
1247
1248     /* (h) Update the number of rows if larger, but never reduce this */
1249     if (displayrow >= current->nrows) {
1250         current->nrows = displayrow + 1;
1251     }
1252     /* And remember the row that the cursor is on */
1253     current->rpos = cursorrow;
1254
1255     refreshEnd(current);
1256
1257 #ifdef DEBUG_REFRESHLINE
1258     fclose(dfh);
1259 #endif
1260 }
1261
1262 static void refreshLine(struct current *current)
1263 {
1264     refreshLineAlt(current, current->prompt, sb_str(current->buf), current->pos);
1265 }
1266
1267 static void set_current(struct current *current, const char *str)
1268 {
1269     sb_clear(current->buf);
1270     sb_append(current->buf, str);
1271     current->pos = sb_chars(current->buf);
1272 }
1273
1274 /**
1275  * Removes the char at 'pos'.
1276  *
1277  * Returns 1 if the line needs to be refreshed, 2 if not
1278  * and 0 if nothing was removed
1279  */
1280 static int remove_char(struct current *current, int pos)
1281 {
1282     if (pos >= 0 && pos < sb_chars(current->buf)) {
1283         int offset = utf8_index(sb_str(current->buf), pos);
1284         int nbytes = utf8_index(sb_str(current->buf) + offset, 1);
1285         int rc = 1;
1286
1287         /* Now we try to optimise in the simple but very common case that:
1288          * - outputChars() can be used directly (not win32)
1289          * - we are removing the char at EOL
1290          * - the buffer is not empty
1291          * - there are columns available to the left
1292          * - the char being deleted is not a wide or utf-8 character
1293          * - no hints are being shown
1294          */
1295         if (current->output && current->pos == pos + 1 && current->pos == sb_chars(current->buf) && pos > 0) {
1296 #ifdef USE_UTF8
1297             /* Could implement utf8_prev_len() but simplest just to not optimise this case */
1298             char last = sb_str(current->buf)[offset];
1299 #else
1300             char last = 0;
1301 #endif
1302             if (current->colsleft > 0 && (last & 0x80) == 0) {
1303                 /* Have cols on the left and not a UTF-8 char or continuation */
1304                 /* Yes, can optimise */
1305                 current->colsleft--;
1306                 current->colsright++;
1307                 rc = 2;
1308             }
1309         }
1310
1311         sb_delete(current->buf, offset, nbytes);
1312
1313         if (current->pos > pos) {
1314             current->pos--;
1315         }
1316         if (rc == 2) {
1317             if (refreshShowHints(current, sb_str(current->buf), current->colsright, 0)) {
1318                 /* A hint needs to be shown, so can't optimise after all */
1319                 rc = 1;
1320             }
1321             else {
1322                 /* optimised output */
1323                 outputChars(current, "\b \b", 3);
1324             }
1325         }
1326         return rc;
1327         return 1;
1328     }
1329     return 0;
1330 }
1331
1332 /**
1333  * Insert 'ch' at position 'pos'
1334  *
1335  * Returns 1 if the line needs to be refreshed, 2 if not
1336  * and 0 if nothing was inserted (no room)
1337  */
1338 static int insert_char(struct current *current, int pos, int ch)
1339 {
1340     if (pos >= 0 && pos <= sb_chars(current->buf)) {
1341         char buf[MAX_UTF8_LEN + 1];
1342         int offset = utf8_index(sb_str(current->buf), pos);
1343         int n = utf8_getchars(buf, ch);
1344         int rc = 1;
1345
1346         /* null terminate since sb_insert() requires it */
1347         buf[n] = 0;
1348
1349         /* Now we try to optimise in the simple but very common case that:
1350          * - outputChars() can be used directly (not win32)
1351          * - we are inserting at EOL
1352          * - there are enough columns available
1353          * - no hints are being shown
1354          */
1355         if (current->output && pos == current->pos && pos == sb_chars(current->buf)) {
1356             int width = char_display_width(ch);
1357             if (current->colsright > width) {
1358                 /* Yes, can optimise */
1359                 current->colsright -= width;
1360                 current->colsleft -= width;
1361                 rc = 2;
1362             }
1363         }
1364         sb_insert(current->buf, offset, buf);
1365         if (current->pos >= pos) {
1366             current->pos++;
1367         }
1368         if (rc == 2) {
1369             if (refreshShowHints(current, sb_str(current->buf), current->colsright, 0)) {
1370                 /* A hint needs to be shown, so can't optimise after all */
1371                 rc = 1;
1372             }
1373             else {
1374                 /* optimised output */
1375                 outputChars(current, buf, n);
1376             }
1377         }
1378         return rc;
1379     }
1380     return 0;
1381 }
1382
1383 /**
1384  * Captures up to 'n' characters starting at 'pos' for the cut buffer.
1385  *
1386  * This replaces any existing characters in the cut buffer.
1387  */
1388 static void capture_chars(struct current *current, int pos, int nchars)
1389 {
1390     if (pos >= 0 && (pos + nchars - 1) < sb_chars(current->buf)) {
1391         int offset = utf8_index(sb_str(current->buf), pos);
1392         int nbytes = utf8_index(sb_str(current->buf) + offset, nchars);
1393
1394         if (nbytes > 0) {
1395             if (current->capture) {
1396                 sb_clear(current->capture);
1397             }
1398             else {
1399                 current->capture = sb_alloc();
1400             }
1401             sb_append_len(current->capture, sb_str(current->buf) + offset, nbytes);
1402         }
1403     }
1404 }
1405
1406 /**
1407  * Removes up to 'n' characters at cursor position 'pos'.
1408  *
1409  * Returns 0 if no chars were removed or non-zero otherwise.
1410  */
1411 static int remove_chars(struct current *current, int pos, int n)
1412 {
1413     int removed = 0;
1414
1415     /* First save any chars which will be removed */
1416     capture_chars(current, pos, n);
1417
1418     while (n-- && remove_char(current, pos)) {
1419         removed++;
1420     }
1421     return removed;
1422 }
1423 /**
1424  * Inserts the characters (string) 'chars' at the cursor position 'pos'.
1425  *
1426  * Returns 0 if no chars were inserted or non-zero otherwise.
1427  */
1428 static int insert_chars(struct current *current, int pos, const char *chars)
1429 {
1430     int inserted = 0;
1431
1432     while (*chars) {
1433         int ch;
1434         int n = utf8_tounicode(chars, &ch);
1435         if (insert_char(current, pos, ch) == 0) {
1436             break;
1437         }
1438         inserted++;
1439         pos++;
1440         chars += n;
1441     }
1442     return inserted;
1443 }
1444
1445 /**
1446  * Returns the keycode to process, or 0 if none.
1447  */
1448 static int reverseIncrementalSearch(struct current *current)
1449 {
1450     /* Display the reverse-i-search prompt and process chars */
1451     char rbuf[50];
1452     char rprompt[80];
1453     int rchars = 0;
1454     int rlen = 0;
1455     int searchpos = history_len - 1;
1456     int c;
1457
1458     rbuf[0] = 0;
1459     while (1) {
1460         int n = 0;
1461         const char *p = NULL;
1462         int skipsame = 0;
1463         int searchdir = -1;
1464
1465         snprintf(rprompt, sizeof(rprompt), "(reverse-i-search)'%s': ", rbuf);
1466         refreshLineAlt(current, rprompt, sb_str(current->buf), current->pos);
1467         c = fd_read(current);
1468         if (c == ctrl('H') || c == CHAR_DELETE) {
1469             if (rchars) {
1470                 int p_ind = utf8_index(rbuf, --rchars);
1471                 rbuf[p_ind] = 0;
1472                 rlen = strlen(rbuf);
1473             }
1474             continue;
1475         }
1476 #ifdef USE_TERMIOS
1477         if (c == CHAR_ESCAPE) {
1478             c = check_special(current->fd);
1479         }
1480 #endif
1481         if (c == ctrl('P') || c == SPECIAL_UP) {
1482             /* Search for the previous (earlier) match */
1483             if (searchpos > 0) {
1484                 searchpos--;
1485             }
1486             skipsame = 1;
1487         }
1488         else if (c == ctrl('N') || c == SPECIAL_DOWN) {
1489             /* Search for the next (later) match */
1490             if (searchpos < history_len) {
1491                 searchpos++;
1492             }
1493             searchdir = 1;
1494             skipsame = 1;
1495         }
1496         else if (c >= ' ') {
1497             /* >= here to allow for null terminator */
1498             if (rlen >= (int)sizeof(rbuf) - MAX_UTF8_LEN) {
1499                 continue;
1500             }
1501
1502             n = utf8_getchars(rbuf + rlen, c);
1503             rlen += n;
1504             rchars++;
1505             rbuf[rlen] = 0;
1506
1507             /* Adding a new char resets the search location */
1508             searchpos = history_len - 1;
1509         }
1510         else {
1511             /* Exit from incremental search mode */
1512             break;
1513         }
1514
1515         /* Now search through the history for a match */
1516         for (; searchpos >= 0 && searchpos < history_len; searchpos += searchdir) {
1517             p = strstr(history[searchpos], rbuf);
1518             if (p) {
1519                 /* Found a match */
1520                 if (skipsame && strcmp(history[searchpos], sb_str(current->buf)) == 0) {
1521                     /* But it is identical, so skip it */
1522                     continue;
1523                 }
1524                 /* Copy the matching line and set the cursor position */
1525                 set_current(current,history[searchpos]);
1526                 current->pos = utf8_strlen(history[searchpos], p - history[searchpos]);
1527                 break;
1528             }
1529         }
1530         if (!p && n) {
1531             /* No match, so don't add it */
1532             rchars--;
1533             rlen -= n;
1534             rbuf[rlen] = 0;
1535         }
1536     }
1537     if (c == ctrl('G') || c == ctrl('C')) {
1538         /* ctrl-g terminates the search with no effect */
1539         set_current(current, "");
1540         c = 0;
1541     }
1542     else if (c == ctrl('J')) {
1543         /* ctrl-j terminates the search leaving the buffer in place */
1544         c = 0;
1545     }
1546
1547     /* Go process the char normally */
1548     refreshLine(current);
1549     return c;
1550 }
1551
1552 static int linenoiseEdit(struct current *current) {
1553     int history_index = 0;
1554
1555     /* The latest history entry is always our current buffer, that
1556      * initially is just an empty string. */
1557     linenoiseHistoryAdd("");
1558
1559     set_current(current, "");
1560     refreshLine(current);
1561
1562     while(1) {
1563         int dir = -1;
1564         int c = fd_read(current);
1565
1566 #ifndef NO_COMPLETION
1567         /* Only autocomplete when the callback is set. It returns < 0 when
1568          * there was an error reading from fd. Otherwise it will return the
1569          * character that should be handled next. */
1570         if (c == '\t' && current->pos == sb_chars(current->buf) && completionCallback != NULL) {
1571             c = completeLine(current);
1572         }
1573 #endif
1574         if (c == ctrl('R')) {
1575             /* reverse incremental search will provide an alternative keycode or 0 for none */
1576             c = reverseIncrementalSearch(current);
1577             /* go on to process the returned char normally */
1578         }
1579
1580 #ifdef USE_TERMIOS
1581         if (c == CHAR_ESCAPE) {   /* escape sequence */
1582             c = check_special(current->fd);
1583         }
1584 #endif
1585         if (c == -1) {
1586             /* Return on errors */
1587             return sb_len(current->buf);
1588         }
1589
1590         switch(c) {
1591         case SPECIAL_NONE:
1592             break;
1593         case '\r':    /* enter/CR */
1594         case '\n':    /* LF */
1595             history_len--;
1596             free(history[history_len]);
1597             current->pos = sb_chars(current->buf);
1598             if (mlmode || hintsCallback) {
1599                 showhints = 0;
1600                 refreshLine(current);
1601                 showhints = 1;
1602             }
1603             return sb_len(current->buf);
1604         case ctrl('C'):     /* ctrl-c */
1605             errno = EAGAIN;
1606             return -1;
1607         case ctrl('Z'):     /* ctrl-z */
1608 #ifdef SIGTSTP
1609             /* send ourselves SIGSUSP */
1610             disableRawMode(current);
1611             raise(SIGTSTP);
1612             /* and resume */
1613             enableRawMode(current);
1614             refreshLine(current);
1615 #endif
1616             continue;
1617         case CHAR_DELETE:   /* backspace */
1618         case ctrl('H'):
1619             if (remove_char(current, current->pos - 1) == 1) {
1620                 refreshLine(current);
1621             }
1622             break;
1623         case ctrl('D'):     /* ctrl-d */
1624             if (sb_len(current->buf) == 0) {
1625                 /* Empty line, so EOF */
1626                 history_len--;
1627                 free(history[history_len]);
1628                 return -1;
1629             }
1630             /* Otherwise fall through to delete char to right of cursor */
1631         case SPECIAL_DELETE:
1632             if (remove_char(current, current->pos) == 1) {
1633                 refreshLine(current);
1634             }
1635             break;
1636         case SPECIAL_INSERT:
1637             /* Ignore. Expansion Hook.
1638              * Future possibility: Toggle Insert/Overwrite Modes
1639              */
1640             break;
1641         case ctrl('W'):    /* ctrl-w, delete word at left. save deleted chars */
1642             /* eat any spaces on the left */
1643             {
1644                 int pos = current->pos;
1645                 while (pos > 0 && get_char(current, pos - 1) == ' ') {
1646                     pos--;
1647                 }
1648
1649                 /* now eat any non-spaces on the left */
1650                 while (pos > 0 && get_char(current, pos - 1) != ' ') {
1651                     pos--;
1652                 }
1653
1654                 if (remove_chars(current, pos, current->pos - pos)) {
1655                     refreshLine(current);
1656                 }
1657             }
1658             break;
1659         case ctrl('T'):    /* ctrl-t */
1660             if (current->pos > 0 && current->pos <= sb_chars(current->buf)) {
1661                 /* If cursor is at end, transpose the previous two chars */
1662                 int fixer = (current->pos == sb_chars(current->buf));
1663                 c = get_char(current, current->pos - fixer);
1664                 remove_char(current, current->pos - fixer);
1665                 insert_char(current, current->pos - 1, c);
1666                 refreshLine(current);
1667             }
1668             break;
1669         case ctrl('V'):    /* ctrl-v */
1670             /* Insert the ^V first */
1671             if (insert_char(current, current->pos, c)) {
1672                 refreshLine(current);
1673                 /* Now wait for the next char. Can insert anything except \0 */
1674                 c = fd_read(current);
1675
1676                 /* Remove the ^V first */
1677                 remove_char(current, current->pos - 1);
1678                 if (c > 0) {
1679                     /* Insert the actual char, can't be error or null */
1680                     insert_char(current, current->pos, c);
1681                 }
1682                 refreshLine(current);
1683             }
1684             break;
1685         case ctrl('B'):
1686         case SPECIAL_LEFT:
1687             if (current->pos > 0) {
1688                 current->pos--;
1689                 refreshLine(current);
1690             }
1691             break;
1692         case ctrl('F'):
1693         case SPECIAL_RIGHT:
1694             if (current->pos < sb_chars(current->buf)) {
1695                 current->pos++;
1696                 refreshLine(current);
1697             }
1698             break;
1699         case SPECIAL_PAGE_UP:
1700           dir = history_len - history_index - 1; /* move to start of history */
1701           goto history_navigation;
1702         case SPECIAL_PAGE_DOWN:
1703           dir = -history_index; /* move to 0 == end of history, i.e. current */
1704           goto history_navigation;
1705         case ctrl('P'):
1706         case SPECIAL_UP:
1707             dir = 1;
1708           goto history_navigation;
1709         case ctrl('N'):
1710         case SPECIAL_DOWN:
1711 history_navigation:
1712             if (history_len > 1) {
1713                 /* Update the current history entry before to
1714                  * overwrite it with tne next one. */
1715                 free(history[history_len - 1 - history_index]);
1716                 history[history_len - 1 - history_index] = strdup(sb_str(current->buf));
1717                 /* Show the new entry */
1718                 history_index += dir;
1719                 if (history_index < 0) {
1720                     history_index = 0;
1721                     break;
1722                 } else if (history_index >= history_len) {
1723                     history_index = history_len - 1;
1724                     break;
1725                 }
1726                 set_current(current, history[history_len - 1 - history_index]);
1727                 refreshLine(current);
1728             }
1729             break;
1730         case ctrl('A'): /* Ctrl+a, go to the start of the line */
1731         case SPECIAL_HOME:
1732             current->pos = 0;
1733             refreshLine(current);
1734             break;
1735         case ctrl('E'): /* ctrl+e, go to the end of the line */
1736         case SPECIAL_END:
1737             current->pos = sb_chars(current->buf);
1738             refreshLine(current);
1739             break;
1740         case ctrl('U'): /* Ctrl+u, delete to beginning of line, save deleted chars. */
1741             if (remove_chars(current, 0, current->pos)) {
1742                 refreshLine(current);
1743             }
1744             break;
1745         case ctrl('K'): /* Ctrl+k, delete from current to end of line, save deleted chars. */
1746             if (remove_chars(current, current->pos, sb_chars(current->buf) - current->pos)) {
1747                 refreshLine(current);
1748             }
1749             break;
1750         case ctrl('Y'): /* Ctrl+y, insert saved chars at current position */
1751             if (current->capture && insert_chars(current, current->pos, sb_str(current->capture))) {
1752                 refreshLine(current);
1753             }
1754             break;
1755         case ctrl('L'): /* Ctrl+L, clear screen */
1756             linenoiseClearScreen();
1757             /* Force recalc of window size for serial terminals */
1758             current->cols = 0;
1759             current->rpos = 0;
1760             refreshLine(current);
1761             break;
1762         default:
1763             /* Only tab is allowed without ^V */
1764             if (c == '\t' || c >= ' ') {
1765                 if (insert_char(current, current->pos, c) == 1) {
1766                     refreshLine(current);
1767                 }
1768             }
1769             break;
1770         }
1771     }
1772     return sb_len(current->buf);
1773 }
1774
1775 int linenoiseColumns(void)
1776 {
1777     struct current current;
1778     current.output = NULL;
1779     enableRawMode (&current);
1780     getWindowSize (&current);
1781     disableRawMode (&current);
1782     return current.cols;
1783 }
1784
1785 /**
1786  * Reads a line from the file handle (without the trailing NL or CRNL)
1787  * and returns it in a stringbuf.
1788  * Returns NULL if no characters are read before EOF or error.
1789  *
1790  * Note that the character count will *not* be correct for lines containing
1791  * utf8 sequences. Do not rely on the character count.
1792  */
1793 static stringbuf *sb_getline(FILE *fh)
1794 {
1795     stringbuf *sb = sb_alloc();
1796     int c;
1797     int n = 0;
1798
1799     while ((c = getc(fh)) != EOF) {
1800         char ch;
1801         n++;
1802         if (c == '\r') {
1803             /* CRLF -> LF */
1804             continue;
1805         }
1806         if (c == '\n' || c == '\r') {
1807             break;
1808         }
1809         ch = c;
1810         /* ignore the effect of character count for partial utf8 sequences */
1811         sb_append_len(sb, &ch, 1);
1812     }
1813     if (n == 0) {
1814         sb_free(sb);
1815         return NULL;
1816     }
1817     return sb;
1818 }
1819
1820 char *linenoise(const char *prompt)
1821 {
1822     int count;
1823     struct current current;
1824     stringbuf *sb;
1825
1826     memset(&current, 0, sizeof(current));
1827
1828     if (enableRawMode(&current) == -1) {
1829         printf("%s", prompt);
1830         fflush(stdout);
1831         sb = sb_getline(stdin);
1832     }
1833     else {
1834         current.buf = sb_alloc();
1835         current.pos = 0;
1836         current.nrows = 1;
1837         current.prompt = prompt;
1838
1839         count = linenoiseEdit(&current);
1840
1841         disableRawMode(&current);
1842         printf("\n");
1843
1844         sb_free(current.capture);
1845         if (count == -1) {
1846             sb_free(current.buf);
1847             return NULL;
1848         }
1849         sb = current.buf;
1850     }
1851     return sb ? sb_to_string(sb) : NULL;
1852 }
1853
1854 /* Using a circular buffer is smarter, but a bit more complex to handle. */
1855 int linenoiseHistoryAddAllocated(char *line) {
1856
1857     if (history_max_len == 0) {
1858 notinserted:
1859         free(line);
1860         return 0;
1861     }
1862     if (history == NULL) {
1863         history = (char **)calloc(sizeof(char*), history_max_len);
1864     }
1865
1866     /* do not insert duplicate lines into history */
1867     if (history_len > 0 && strcmp(line, history[history_len - 1]) == 0) {
1868         goto notinserted;
1869     }
1870
1871     if (history_len == history_max_len) {
1872         free(history[0]);
1873         memmove(history,history+1,sizeof(char*)*(history_max_len-1));
1874         history_len--;
1875     }
1876     history[history_len] = line;
1877     history_len++;
1878     return 1;
1879 }
1880
1881 int linenoiseHistoryAdd(const char *line) {
1882     return linenoiseHistoryAddAllocated(strdup(line));
1883 }
1884
1885 int linenoiseHistoryGetMaxLen(void) {
1886     return history_max_len;
1887 }
1888
1889 int linenoiseHistorySetMaxLen(int len) {
1890     char **newHistory;
1891
1892     if (len < 1) return 0;
1893     if (history) {
1894         int tocopy = history_len;
1895
1896         newHistory = (char **)calloc(sizeof(char*), len);
1897
1898         /* If we can't copy everything, free the elements we'll not use. */
1899         if (len < tocopy) {
1900             int j;
1901
1902             for (j = 0; j < tocopy-len; j++) free(history[j]);
1903             tocopy = len;
1904         }
1905         memcpy(newHistory,history+(history_len-tocopy), sizeof(char*)*tocopy);
1906         free(history);
1907         history = newHistory;
1908     }
1909     history_max_len = len;
1910     if (history_len > history_max_len)
1911         history_len = history_max_len;
1912     return 1;
1913 }
1914
1915 /* Save the history in the specified file. On success 0 is returned
1916  * otherwise -1 is returned. */
1917 int linenoiseHistorySave(const char *filename) {
1918     FILE *fp = fopen(filename,"w");
1919     int j;
1920
1921     if (fp == NULL) return -1;
1922     for (j = 0; j < history_len; j++) {
1923         const char *str = history[j];
1924         /* Need to encode backslash, nl and cr */
1925         while (*str) {
1926             if (*str == '\\') {
1927                 fputs("\\\\", fp);
1928             }
1929             else if (*str == '\n') {
1930                 fputs("\\n", fp);
1931             }
1932             else if (*str == '\r') {
1933                 fputs("\\r", fp);
1934             }
1935             else {
1936                 fputc(*str, fp);
1937             }
1938             str++;
1939         }
1940         fputc('\n', fp);
1941     }
1942
1943     fclose(fp);
1944     return 0;
1945 }
1946
1947 /* Load the history from the specified file.
1948  *
1949  * If the file does not exist or can't be opened, no operation is performed
1950  * and -1 is returned.
1951  * Otherwise 0 is returned.
1952  */
1953 int linenoiseHistoryLoad(const char *filename) {
1954     FILE *fp = fopen(filename,"r");
1955     stringbuf *sb;
1956
1957     if (fp == NULL) return -1;
1958
1959     while ((sb = sb_getline(fp)) != NULL) {
1960         /* Take the stringbuf and decode backslash escaped values */
1961         char *buf = sb_to_string(sb);
1962         char *dest = buf;
1963         const char *src;
1964
1965         for (src = buf; *src; src++) {
1966             char ch = *src;
1967
1968             if (ch == '\\') {
1969                 src++;
1970                 if (*src == 'n') {
1971                     ch = '\n';
1972                 }
1973                 else if (*src == 'r') {
1974                     ch = '\r';
1975                 } else {
1976                     ch = *src;
1977                 }
1978             }
1979             *dest++ = ch;
1980         }
1981         *dest = 0;
1982
1983         linenoiseHistoryAddAllocated(buf);
1984     }
1985     fclose(fp);
1986     return 0;
1987 }
1988
1989 /* Provide access to the history buffer.
1990  *
1991  * If 'len' is not NULL, the length is stored in *len.
1992  */
1993 char **linenoiseHistory(int *len) {
1994     if (len) {
1995         *len = history_len;
1996     }
1997     return history;
1998 }