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