1/* linenoise.c -- guerrilla line editing library against the idea that a
2 * line editing lib needs to be 20,000 lines of C code.
3 *
4 * You can find the latest source code at:
5 *
6 * http://github.com/antirez/linenoise
7 *
8 * Does a number of crazy assumptions that happen to be true in 99.9999% of
9 * the 2010 UNIX computers around.
10 *
11 * ------------------------------------------------------------------------
12 *
13 * Copyright (c) 2010-2016, Salvatore Sanfilippo <antirez at gmail dot com>
14 * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
15 *
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met:
21 *
22 * * Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 *
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * ------------------------------------------------------------------------
42 *
43 * References:
44 * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
45 * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html
46 *
47 * Todo list:
48 * - Filter bogus Ctrl+<char> combinations.
49 * - Win32 support
50 *
51 * Bloat:
52 * - History search like Ctrl+r in readline?
53 *
54 * List of escape sequences used by this program, we do everything just
55 * with three 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 [ n K
61 * Effect: if n is 0 or missing, clear from cursor to end of line
62 * Effect: if n is 1, clear from beginning of line to cursor
63 * Effect: if n is 2, clear entire line
64 *
65 * CUF (CUrsor Forward)
66 * Sequence: ESC [ n C
67 * Effect: moves cursor forward n chars
68 *
69 * CUB (CUrsor Backward)
70 * Sequence: ESC [ n D
71 * Effect: moves cursor backward n chars
72 *
73 * The following is used to get the terminal width if getting
74 * the width with the TIOCGWINSZ ioctl fails
75 *
76 * DSR (Device Status Report)
77 * Sequence: ESC [ 6 n
78 * Effect: reports the current cusor position as ESC [ n ; m R
79 * where n is the row and m is the column
80 *
81 * When multi line mode is enabled, we also use an additional escape
82 * sequence. However multi line editing is disabled by default.
83 *
84 * CUU (Cursor Up)
85 * Sequence: ESC [ n A
86 * Effect: moves cursor up of n chars.
87 *
88 * CUD (Cursor Down)
89 * Sequence: ESC [ n B
90 * Effect: moves cursor down of n chars.
91 *
92 * When linenoiseClearScreen() is called, two additional escape sequences
93 * are used in order to clear the screen and position the cursor at home
94 * position.
95 *
96 * CUP (Cursor position)
97 * Sequence: ESC [ H
98 * Effect: moves the cursor to upper left corner
99 *
100 * ED (Erase display)
101 * Sequence: ESC [ 2 J
102 * Effect: clear the whole screen
103 *
104 */
105
106#include <termios.h>
107#include <unistd.h>
108#include <stdlib.h>
109#include <stdio.h>
110#include <errno.h>
111#include <string.h>
112#include <stdlib.h>
113#include <ctype.h>
114#include <sys/stat.h>
115#include <sys/types.h>
116#include <sys/ioctl.h>
117#include <unistd.h>
118#include "linenoise.h"
119#include "utf8proc_wrapper.h"
120
121#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
122#define LINENOISE_MAX_LINE 4096
123static char *unsupported_term[] = {"dumb", "cons25", "emacs", NULL};
124static linenoiseCompletionCallback *completionCallback = NULL;
125static linenoiseHintsCallback *hintsCallback = NULL;
126static linenoiseFreeHintsCallback *freeHintsCallback = NULL;
127
128static struct termios orig_termios; /* In order to restore at exit.*/
129static int rawmode = 0; /* For atexit() function to check if restore is needed*/
130static int mlmode = 0; /* Multi line mode. Default is single line. */
131static int atexit_registered = 0; /* Register atexit just 1 time. */
132static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
133static int history_len = 0;
134static char **history = NULL;
135
136/* The linenoiseState structure represents the state during line editing.
137 * We pass this state to functions implementing specific editing
138 * functionalities. */
139struct linenoiseState {
140 int ifd; /* Terminal stdin file descriptor. */
141 int ofd; /* Terminal stdout file descriptor. */
142 char *buf; /* Edited line buffer. */
143 size_t buflen; /* Edited line buffer size. */
144 const char *prompt; /* Prompt to display. */
145 size_t plen; /* Prompt length. */
146 size_t pos; /* Current cursor position. */
147 size_t oldpos; /* Previous refresh cursor position. */
148 size_t len; /* Current edited line length. */
149 size_t cols; /* Number of columns in terminal. */
150 size_t maxrows; /* Maximum num of rows used so far (multiline mode) */
151 int history_index; /* The history index we are currently editing. */
152};
153
154enum KEY_ACTION {
155 KEY_NULL = 0, /* NULL */
156 CTRL_A = 1, /* Ctrl+a */
157 CTRL_B = 2, /* Ctrl-b */
158 CTRL_C = 3, /* Ctrl-c */
159 CTRL_D = 4, /* Ctrl-d */
160 CTRL_E = 5, /* Ctrl-e */
161 CTRL_F = 6, /* Ctrl-f */
162 CTRL_H = 8, /* Ctrl-h */
163 TAB = 9, /* Tab */
164 CTRL_K = 11, /* Ctrl+k */
165 CTRL_L = 12, /* Ctrl+l */
166 ENTER = 13, /* Enter */
167 CTRL_N = 14, /* Ctrl-n */
168 CTRL_P = 16, /* Ctrl-p */
169 CTRL_T = 20, /* Ctrl-t */
170 CTRL_U = 21, /* Ctrl+u */
171 CTRL_W = 23, /* Ctrl+w */
172 ESC = 27, /* Escape */
173 BACKSPACE = 127 /* Backspace */
174};
175
176static void linenoiseAtExit(void);
177int linenoiseHistoryAdd(const char *line);
178static void refreshLine(struct linenoiseState *l);
179
180/* Debugging macro. */
181#if 0
182FILE *lndebug_fp = NULL;
183#define lndebug(...) \
184 do { \
185 if (lndebug_fp == NULL) { \
186 lndebug_fp = fopen("/tmp/lndebug.txt", "a"); \
187 fprintf(lndebug_fp, "[%d %d %d] p: %d, rows: %d, rpos: %d, max: %d, oldmax: %d\n", (int)l->len, \
188 (int)l->pos, (int)l->oldpos, plen, rows, rpos, (int)l->maxrows, old_rows); \
189 } \
190 fprintf(lndebug_fp, ", " __VA_ARGS__); \
191 fflush(lndebug_fp); \
192 } while (0)
193#else
194#define lndebug(fmt, ...)
195#endif
196
197/* ======================= Low level terminal handling ====================== */
198
199/* Set if to use or not the multi line mode. */
200void linenoiseSetMultiLine(int ml) {
201 mlmode = ml;
202}
203
204/* Return true if the terminal name is in the list of terminals we know are
205 * not able to understand basic escape sequences. */
206static int isUnsupportedTerm(void) {
207 char *term = getenv("TERM");
208 int j;
209
210 if (term == NULL)
211 return 0;
212 for (j = 0; unsupported_term[j]; j++)
213 if (!strcasecmp(term, unsupported_term[j]))
214 return 1;
215 return 0;
216}
217
218/* Raw mode: 1960 magic shit. */
219static int enableRawMode(int fd) {
220 struct termios raw;
221
222 if (!isatty(STDIN_FILENO))
223 goto fatal;
224 if (!atexit_registered) {
225 atexit(linenoiseAtExit);
226 atexit_registered = 1;
227 }
228 if (tcgetattr(fd, &orig_termios) == -1)
229 goto fatal;
230
231 raw = orig_termios; /* modify the original mode */
232 /* input modes: no break, no CR to NL, no parity check, no strip char,
233 * no start/stop output control. */
234 raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
235 /* output modes - disable post processing */
236 raw.c_oflag &= ~(OPOST);
237 /* control modes - set 8 bit chars */
238 raw.c_cflag |= (CS8);
239 /* local modes - choing off, canonical off, no extended functions,
240 * no signal chars (^Z,^C) */
241 raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
242 /* control chars - set return condition: min number of bytes and timer.
243 * We want read to return every single byte, without timeout. */
244 raw.c_cc[VMIN] = 1;
245 raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
246
247 /* put terminal in raw mode after flushing */
248 if (tcsetattr(fd, TCSADRAIN, &raw) < 0)
249 goto fatal;
250 rawmode = 1;
251 return 0;
252
253fatal:
254 errno = ENOTTY;
255 return -1;
256}
257
258static void disableRawMode(int fd) {
259 /* Don't even check the return value as it's too late. */
260 if (rawmode && tcsetattr(fd, TCSADRAIN, &orig_termios) != -1)
261 rawmode = 0;
262}
263
264/* Use the ESC [6n escape sequence to query the horizontal cursor position
265 * and return it. On error -1 is returned, on success the position of the
266 * cursor. */
267static int getCursorPosition(int ifd, int ofd) {
268 char buf[32];
269 int cols, rows;
270 unsigned int i = 0;
271
272 /* Report cursor location */
273 if (write(ofd, "\x1b[6n", 4) != 4)
274 return -1;
275
276 /* Read the response: ESC [ rows ; cols R */
277 while (i < sizeof(buf) - 1) {
278 if (read(ifd, buf + i, 1) != 1)
279 break;
280 if (buf[i] == 'R')
281 break;
282 i++;
283 }
284 buf[i] = '\0';
285
286 /* Parse it. */
287 if (buf[0] != ESC || buf[1] != '[')
288 return -1;
289 if (sscanf(buf + 2, "%d;%d", &rows, &cols) != 2)
290 return -1;
291 return cols;
292}
293
294/* Try to get the number of columns in the current terminal, or assume 80
295 * if it fails. */
296static int getColumns(int ifd, int ofd) {
297 struct winsize ws;
298
299 if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) {
300 /* ioctl() failed. Try to query the terminal itself. */
301 int start, cols;
302
303 /* Get the initial position so we can restore it later. */
304 start = getCursorPosition(ifd, ofd);
305 if (start == -1)
306 goto failed;
307
308 /* Go to right margin and get position. */
309 if (write(ofd, "\x1b[999C", 6) != 6)
310 goto failed;
311 cols = getCursorPosition(ifd, ofd);
312 if (cols == -1)
313 goto failed;
314
315 /* Restore position. */
316 if (cols > start) {
317 char seq[32];
318 snprintf(seq, 32, "\x1b[%dD", cols - start);
319 if (write(ofd, seq, strlen(seq)) == -1) {
320 /* Can't recover... */
321 }
322 }
323 return cols;
324 } else {
325 return ws.ws_col;
326 }
327
328failed:
329 return 80;
330}
331
332/* Clear the screen. Used to handle ctrl+l */
333void linenoiseClearScreen(void) {
334 if (write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7) <= 0) {
335 /* nothing to do, just to avoid warning. */
336 }
337}
338
339/* Beep, used for completion when there is nothing to complete or when all
340 * the choices were already shown. */
341static void linenoiseBeep(void) {
342 fprintf(stderr, "\x7");
343 fflush(stderr);
344}
345
346/* ============================== Completion ================================ */
347
348/* Free a list of completion option populated by linenoiseAddCompletion(). */
349static void freeCompletions(linenoiseCompletions *lc) {
350 size_t i;
351 for (i = 0; i < lc->len; i++)
352 free(lc->cvec[i]);
353 if (lc->cvec != NULL)
354 free(lc->cvec);
355}
356
357/* This is an helper function for linenoiseEdit() and is called when the
358 * user types the <tab> key in order to complete the string currently in the
359 * input.
360 *
361 * The state of the editing is encapsulated into the pointed linenoiseState
362 * structure as described in the structure definition. */
363static int completeLine(struct linenoiseState *ls) {
364 linenoiseCompletions lc = {0, NULL};
365 int nread, nwritten;
366 char c = 0;
367
368 completionCallback(ls->buf, &lc);
369 if (lc.len == 0) {
370 linenoiseBeep();
371 } else {
372 size_t stop = 0, i = 0;
373
374 while (!stop) {
375 /* Show completion or original buffer */
376 if (i < lc.len) {
377 struct linenoiseState saved = *ls;
378
379 ls->len = ls->pos = strlen(lc.cvec[i]);
380 ls->buf = lc.cvec[i];
381 refreshLine(ls);
382 ls->len = saved.len;
383 ls->pos = saved.pos;
384 ls->buf = saved.buf;
385 } else {
386 refreshLine(ls);
387 }
388
389 nread = read(ls->ifd, &c, 1);
390 if (nread <= 0) {
391 freeCompletions(&lc);
392 return -1;
393 }
394
395 switch (c) {
396 case 9: /* tab */
397 i = (i + 1) % (lc.len + 1);
398 if (i == lc.len)
399 linenoiseBeep();
400 break;
401 case 27: /* escape */
402 /* Re-show original buffer */
403 if (i < lc.len)
404 refreshLine(ls);
405 stop = 1;
406 break;
407 default:
408 /* Update buffer and return */
409 if (i < lc.len) {
410 nwritten = snprintf(ls->buf, ls->buflen, "%s", lc.cvec[i]);
411 ls->len = ls->pos = nwritten;
412 }
413 stop = 1;
414 break;
415 }
416 }
417 }
418
419 freeCompletions(&lc);
420 return c; /* Return last read character */
421}
422
423/* Register a callback function to be called for tab-completion. */
424void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
425 completionCallback = fn;
426}
427
428/* Register a hits function to be called to show hits to the user at the
429 * right of the prompt. */
430void linenoiseSetHintsCallback(linenoiseHintsCallback *fn) {
431 hintsCallback = fn;
432}
433
434/* Register a function to free the hints returned by the hints callback
435 * registered with linenoiseSetHintsCallback(). */
436void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *fn) {
437 freeHintsCallback = fn;
438}
439
440/* This function is used by the callback function registered by the user
441 * in order to add completion options given the input string when the
442 * user typed <tab>. See the example.c source code for a very easy to
443 * understand example. */
444void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) {
445 size_t len = strlen(str);
446 char *copy, **cvec;
447
448 copy = malloc(len + 1);
449 if (copy == NULL)
450 return;
451 memcpy(copy, str, len + 1);
452 cvec = realloc(lc->cvec, sizeof(char *) * (lc->len + 1));
453 if (cvec == NULL) {
454 free(copy);
455 return;
456 }
457 lc->cvec = cvec;
458 lc->cvec[lc->len++] = copy;
459}
460
461/* =========================== Line editing ================================= */
462
463/* We define a very simple "append buffer" structure, that is an heap
464 * allocated string where we can append to. This is useful in order to
465 * write all the escape sequences in a buffer and flush them to the standard
466 * output in a single call, to avoid flickering effects. */
467struct abuf {
468 char *b;
469 int len;
470};
471
472static void abInit(struct abuf *ab) {
473 ab->b = NULL;
474 ab->len = 0;
475}
476
477static void abAppend(struct abuf *ab, const char *s, int len) {
478 char *new = realloc(ab->b, ab->len + len);
479
480 if (new == NULL)
481 return;
482 memcpy(new + ab->len, s, len);
483 ab->b = new;
484 ab->len += len;
485}
486
487static void abFree(struct abuf *ab) {
488 free(ab->b);
489}
490
491/* Helper of refreshSingleLine() and refreshMultiLine() to show hints
492 * to the right of the prompt. */
493void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) {
494 char seq[64];
495 if (hintsCallback && plen + l->len < l->cols) {
496 int color = -1, bold = 0;
497 char *hint = hintsCallback(l->buf, &color, &bold);
498 if (hint) {
499 int hintlen = strlen(hint);
500 int hintmaxlen = l->cols - (plen + l->len);
501 if (hintlen > hintmaxlen)
502 hintlen = hintmaxlen;
503 if (bold == 1 && color == -1)
504 color = 37;
505 if (color != -1 || bold != 0)
506 snprintf(seq, 64, "\033[%d;%d;49m", bold, color);
507 else
508 seq[0] = '\0';
509 abAppend(ab, seq, strlen(seq));
510 abAppend(ab, hint, hintlen);
511 if (color != -1 || bold != 0)
512 abAppend(ab, "\033[0m", 4);
513 /* Call the function to free the hint returned. */
514 if (freeHintsCallback)
515 freeHintsCallback(hint);
516 }
517 }
518}
519
520static size_t compute_render_width(const char *buf, size_t len) {
521 if (utf8proc_is_valid(buf, len)) {
522 // utf8 in prompt, get render width
523 size_t cpos = 0;
524 size_t render_width = 0;
525 while (cpos < len) {
526 size_t char_render_width = utf8proc_render_width(buf, len, cpos);
527 cpos = utf8proc_next_grapheme_cluster(buf, len, cpos);
528 render_width += char_render_width;
529 }
530 return render_width;
531 } else {
532 // invalid utf8 in prompt, use length in bytes
533 return len;
534 }
535}
536
537/* Single line low level line refresh.
538 *
539 * Rewrite the currently edited line accordingly to the buffer content,
540 * cursor position, and number of columns of the terminal. */
541static void refreshSingleLine(struct linenoiseState *l) {
542 char seq[64];
543 size_t plen = compute_render_width(l->prompt, strlen(l->prompt));
544 int fd = l->ofd;
545 char *buf = l->buf;
546 size_t len = l->len;
547 size_t pos = l->pos;
548 struct abuf ab;
549 size_t render_pos = 0;
550
551 if (utf8proc_is_valid(l->buf, l->len)) {
552 // utf8 in prompt, handle rendering
553 size_t remaining_render_width = l->cols - plen - 1;
554 size_t start_pos = 0;
555 size_t cpos = 0;
556 size_t prev_pos = 0;
557 size_t total_render_width = 0;
558 while (cpos < len) {
559 size_t char_render_width = utf8proc_render_width(buf, len, cpos);
560 prev_pos = cpos;
561 cpos = utf8proc_next_grapheme_cluster(buf, len, cpos);
562 total_render_width += cpos - prev_pos;
563 if (total_render_width >= remaining_render_width) {
564 // character does not fit anymore! we need to figure something out
565 if (prev_pos >= l->pos) {
566 // we passed the cursor: break
567 cpos = prev_pos;
568 break;
569 } else {
570 // we did not pass the cursor yet! remove characters from the start until it fits again
571 while (total_render_width >= remaining_render_width) {
572 size_t start_char_width = utf8proc_render_width(buf, len, start_pos);
573 size_t new_start = utf8proc_next_grapheme_cluster(buf, len, start_pos);
574 total_render_width -= new_start - start_pos;
575 start_pos = new_start;
576 render_pos -= start_char_width;
577 }
578 }
579 }
580 if (prev_pos < l->pos) {
581 render_pos += char_render_width;
582 }
583 }
584 buf = buf + start_pos;
585 len = cpos - start_pos;
586 } else {
587 // invalid UTF8: fallback
588 while ((plen + pos) >= l->cols) {
589 buf++;
590 len--;
591 pos--;
592 }
593 while (plen + len > l->cols) {
594 len--;
595 }
596 render_pos = pos;
597 }
598
599 abInit(&ab);
600 /* Cursor to left edge */
601 snprintf(seq, 64, "\r");
602 abAppend(&ab, seq, strlen(seq));
603 /* Write the prompt and the current buffer content */
604 abAppend(&ab, l->prompt, strlen(l->prompt));
605 abAppend(&ab, buf, len);
606 /* Show hits if any. */
607 refreshShowHints(&ab, l, plen);
608 /* Erase to right */
609 snprintf(seq, 64, "\x1b[0K");
610 abAppend(&ab, seq, strlen(seq));
611 /* Move cursor to original position. */
612 snprintf(seq, 64, "\r\x1b[%dC", (int)(render_pos + plen));
613 abAppend(&ab, seq, strlen(seq));
614 if (write(fd, ab.b, ab.len) == -1) {
615 } /* Can't recover from write error. */
616 abFree(&ab);
617}
618
619/* Multi line low level line refresh.
620 *
621 * Rewrite the currently edited line accordingly to the buffer content,
622 * cursor position, and number of columns of the terminal. */
623static void refreshMultiLine(struct linenoiseState *l) {
624 char seq[64];
625 int plen = strlen(l->prompt);
626 int rows = (plen + l->len + l->cols - 1) / l->cols; /* rows used by current buf. */
627 int rpos = (plen + l->oldpos + l->cols) / l->cols; /* cursor relative row. */
628 int rpos2; /* rpos after refresh. */
629 int col; /* colum position, zero-based. */
630 int old_rows = l->maxrows;
631 int fd = l->ofd, j;
632 struct abuf ab;
633
634 /* Update maxrows if needed. */
635 if (rows > (int)l->maxrows)
636 l->maxrows = rows;
637
638 /* First step: clear all the lines used before. To do so start by
639 * going to the last row. */
640 abInit(&ab);
641 if (old_rows - rpos > 0) {
642 lndebug("go down %d", old_rows - rpos);
643 snprintf(seq, 64, "\x1b[%dB", old_rows - rpos);
644 abAppend(&ab, seq, strlen(seq));
645 }
646
647 /* Now for every row clear it, go up. */
648 for (j = 0; j < old_rows - 1; j++) {
649 lndebug("clear+up");
650 snprintf(seq, 64, "\r\x1b[0K\x1b[1A");
651 abAppend(&ab, seq, strlen(seq));
652 }
653
654 /* Clean the top line. */
655 lndebug("clear");
656 snprintf(seq, 64, "\r\x1b[0K");
657 abAppend(&ab, seq, strlen(seq));
658
659 /* Write the prompt and the current buffer content */
660 abAppend(&ab, l->prompt, strlen(l->prompt));
661 abAppend(&ab, l->buf, l->len);
662
663 /* Show hits if any. */
664 refreshShowHints(&ab, l, plen);
665
666 /* If we are at the very end of the screen with our prompt, we need to
667 * emit a newline and move the prompt to the first column. */
668 if (l->pos && l->pos == l->len && (l->pos + plen) % l->cols == 0) {
669 lndebug("<newline>");
670 abAppend(&ab, "\n", 1);
671 snprintf(seq, 64, "\r");
672 abAppend(&ab, seq, strlen(seq));
673 rows++;
674 if (rows > (int)l->maxrows)
675 l->maxrows = rows;
676 }
677
678 /* Move cursor to right position. */
679 rpos2 = (plen + l->pos + l->cols) / l->cols; /* current cursor relative row. */
680 lndebug("rpos2 %d", rpos2);
681
682 /* Go up till we reach the expected positon. */
683 if (rows - rpos2 > 0) {
684 lndebug("go-up %d", rows - rpos2);
685 snprintf(seq, 64, "\x1b[%dA", rows - rpos2);
686 abAppend(&ab, seq, strlen(seq));
687 }
688
689 /* Set column. */
690 col = (plen + (int)l->pos) % (int)l->cols;
691 lndebug("set col %d", 1 + col);
692 if (col)
693 snprintf(seq, 64, "\r\x1b[%dC", col);
694 else
695 snprintf(seq, 64, "\r");
696 abAppend(&ab, seq, strlen(seq));
697
698 lndebug("\n");
699 l->oldpos = l->pos;
700
701 if (write(fd, ab.b, ab.len) == -1) {
702 } /* Can't recover from write error. */
703 abFree(&ab);
704}
705
706/* Calls the two low level functions refreshSingleLine() or
707 * refreshMultiLine() according to the selected mode. */
708static void refreshLine(struct linenoiseState *l) {
709 if (mlmode)
710 refreshMultiLine(l);
711 else
712 refreshSingleLine(l);
713}
714
715/* Insert the character 'c' at cursor current position.
716 *
717 * On error writing to the terminal -1 is returned, otherwise 0. */
718int linenoiseEditInsert(struct linenoiseState *l, char c) {
719 if (l->len < l->buflen) {
720 if (l->len == l->pos) {
721 l->buf[l->pos] = c;
722 l->pos++;
723 l->len++;
724 l->buf[l->len] = '\0';
725 if ((!mlmode && l->plen + l->len < l->cols && !hintsCallback)) {
726 /* Avoid a full update of the line in the
727 * trivial case. */
728 if (write(l->ofd, &c, 1) == -1)
729 return -1;
730 } else {
731 refreshLine(l);
732 }
733 } else {
734 memmove(l->buf + l->pos + 1, l->buf + l->pos, l->len - l->pos);
735 l->buf[l->pos] = c;
736 l->len++;
737 l->pos++;
738 l->buf[l->len] = '\0';
739 refreshLine(l);
740 }
741 }
742 refreshLine(l);
743 return 0;
744}
745
746static size_t prev_char(struct linenoiseState *l) {
747 return utf8proc_prev_grapheme_cluster(l->buf, l->len, l->pos);
748}
749
750static size_t next_char(struct linenoiseState *l) {
751 return utf8proc_next_grapheme_cluster(l->buf, l->len, l->pos);
752}
753
754/* Move cursor on the left. */
755void linenoiseEditMoveLeft(struct linenoiseState *l) {
756 if (l->pos > 0) {
757 l->pos = prev_char(l);
758 refreshLine(l);
759 }
760}
761
762/* Move cursor on the right. */
763void linenoiseEditMoveRight(struct linenoiseState *l) {
764 if (l->pos != l->len) {
765 l->pos = next_char(l);
766 refreshLine(l);
767 }
768}
769
770/* Move cursor to the start of the line. */
771void linenoiseEditMoveHome(struct linenoiseState *l) {
772 if (l->pos != 0) {
773 l->pos = 0;
774 refreshLine(l);
775 }
776}
777
778/* Move cursor to the end of the line. */
779void linenoiseEditMoveEnd(struct linenoiseState *l) {
780 if (l->pos != l->len) {
781 l->pos = l->len;
782 refreshLine(l);
783 }
784}
785
786/* Substitute the currently edited line with the next or previous history
787 * entry as specified by 'dir'. */
788#define LINENOISE_HISTORY_NEXT 0
789#define LINENOISE_HISTORY_PREV 1
790void linenoiseEditHistoryNext(struct linenoiseState *l, int dir) {
791 if (history_len > 1) {
792 /* Update the current history entry before to
793 * overwrite it with the next one. */
794 free(history[history_len - 1 - l->history_index]);
795 history[history_len - 1 - l->history_index] = strdup(l->buf);
796 /* Show the new entry */
797 l->history_index += (dir == LINENOISE_HISTORY_PREV) ? 1 : -1;
798 if (l->history_index < 0) {
799 l->history_index = 0;
800 return;
801 } else if (l->history_index >= history_len) {
802 l->history_index = history_len - 1;
803 return;
804 }
805 strncpy(l->buf, history[history_len - 1 - l->history_index], l->buflen);
806 l->buf[l->buflen - 1] = '\0';
807 l->len = l->pos = strlen(l->buf);
808 refreshLine(l);
809 }
810}
811
812/* Delete the character at the right of the cursor without altering the cursor
813 * position. Basically this is what happens with the "Delete" keyboard key. */
814void linenoiseEditDelete(struct linenoiseState *l) {
815 if (l->len > 0 && l->pos < l->len) {
816 size_t new_pos = next_char(l);
817 size_t char_sz = new_pos - l->pos;
818 memmove(l->buf + l->pos, l->buf + new_pos, l->len - new_pos);
819 l->len -= char_sz;
820 l->buf[l->len] = '\0';
821 refreshLine(l);
822 }
823}
824
825/* Backspace implementation. */
826void linenoiseEditBackspace(struct linenoiseState *l) {
827 if (l->pos > 0 && l->len > 0) {
828 size_t new_pos = prev_char(l);
829 size_t char_sz = l->pos - new_pos;
830 memmove(l->buf + new_pos, l->buf + l->pos, l->len - l->pos);
831 l->len -= char_sz;
832 l->pos = new_pos;
833 l->buf[l->len] = '\0';
834 refreshLine(l);
835 }
836}
837
838/* Delete the previosu word, maintaining the cursor at the start of the
839 * current word. */
840void linenoiseEditDeletePrevWord(struct linenoiseState *l) {
841 size_t old_pos = l->pos;
842 size_t diff;
843
844 while (l->pos > 0 && l->buf[l->pos - 1] == ' ')
845 l->pos--;
846 while (l->pos > 0 && l->buf[l->pos - 1] != ' ')
847 l->pos--;
848 diff = old_pos - l->pos;
849 memmove(l->buf + l->pos, l->buf + old_pos, l->len - old_pos + 1);
850 l->len -= diff;
851 refreshLine(l);
852}
853
854/* This function is the core of the line editing capability of linenoise.
855 * It expects 'fd' to be already in "raw mode" so that every key pressed
856 * will be returned ASAP to read().
857 *
858 * The resulting string is put into 'buf' when the user type enter, or
859 * when ctrl+d is typed.
860 *
861 * The function returns the length of the current buffer. */
862static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt) {
863 struct linenoiseState l;
864
865 /* Populate the linenoise state that we pass to functions implementing
866 * specific editing functionalities. */
867 l.ifd = stdin_fd;
868 l.ofd = stdout_fd;
869 l.buf = buf;
870 l.buflen = buflen;
871 l.prompt = prompt;
872 l.plen = strlen(prompt);
873 l.oldpos = l.pos = 0;
874 l.len = 0;
875 l.cols = getColumns(stdin_fd, stdout_fd);
876 l.maxrows = 0;
877 l.history_index = 0;
878
879 /* Buffer starts empty. */
880 l.buf[0] = '\0';
881 l.buflen--; /* Make sure there is always space for the nulterm */
882
883 /* The latest history entry is always our current buffer, that
884 * initially is just an empty string. */
885 linenoiseHistoryAdd("");
886
887 if (write(l.ofd, prompt, l.plen) == -1)
888 return -1;
889 while (1) {
890 char c;
891 int nread;
892 char seq[3];
893
894 nread = read(l.ifd, &c, 1);
895 if (nread <= 0)
896 return l.len;
897
898 /* Only autocomplete when the callback is set. It returns < 0 when
899 * there was an error reading from fd. Otherwise it will return the
900 * character that should be handled next. */
901 if (c == 9 && completionCallback != NULL) {
902 c = completeLine(&l);
903 /* Return on errors */
904 if (c < 0)
905 return l.len;
906 /* Read next character when 0 */
907 if (c == 0)
908 continue;
909 }
910
911 switch (c) {
912 case 10:
913 case ENTER: /* enter */
914 history_len--;
915 free(history[history_len]);
916 if (mlmode)
917 linenoiseEditMoveEnd(&l);
918 if (hintsCallback) {
919 /* Force a refresh without hints to leave the previous
920 * line as the user typed it after a newline. */
921 linenoiseHintsCallback *hc = hintsCallback;
922 hintsCallback = NULL;
923 refreshLine(&l);
924 hintsCallback = hc;
925 }
926 return (int)l.len;
927 case CTRL_C: /* ctrl-c */
928 errno = EAGAIN;
929 return -1;
930 case BACKSPACE: /* backspace */
931 case 8: /* ctrl-h */
932 linenoiseEditBackspace(&l);
933 break;
934 case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the
935 line is empty, act as end-of-file. */
936 if (l.len > 0) {
937 linenoiseEditDelete(&l);
938 } else {
939 history_len--;
940 free(history[history_len]);
941 return -1;
942 }
943 break;
944 case CTRL_T: /* ctrl-t, swaps current character with previous. */
945 if (l.pos > 0 && l.pos < l.len) {
946 char temp_buffer[128];
947 int prev_pos = prev_char(&l);
948 int next_pos = next_char(&l);
949 int prev_char_size = l.pos - prev_pos;
950 int cur_char_size = next_pos - l.pos;
951 memcpy(temp_buffer, l.buf + prev_pos, prev_char_size);
952 memmove(l.buf + prev_pos, l.buf + l.pos, cur_char_size);
953 memcpy(l.buf + prev_pos + cur_char_size, temp_buffer, prev_char_size);
954 l.pos = next_pos;
955 refreshLine(&l);
956 }
957 break;
958 case CTRL_B: /* ctrl-b */
959 linenoiseEditMoveLeft(&l);
960 break;
961 case CTRL_F: /* ctrl-f */
962 linenoiseEditMoveRight(&l);
963 break;
964 case CTRL_P: /* ctrl-p */
965 linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV);
966 break;
967 case CTRL_N: /* ctrl-n */
968 linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT);
969 break;
970 case ESC: /* escape sequence */
971 /* Read the next two bytes representing the escape sequence.
972 * Use two calls to handle slow terminals returning the two
973 * chars at different times. */
974 if (read(l.ifd, seq, 1) == -1)
975 break;
976 if (read(l.ifd, seq + 1, 1) == -1)
977 break;
978
979 /* ESC [ sequences. */
980 if (seq[0] == '[') {
981 if (seq[1] >= '0' && seq[1] <= '9') {
982 /* Extended escape, read additional byte. */
983 if (read(l.ifd, seq + 2, 1) == -1)
984 break;
985 if (seq[2] == '~') {
986 switch (seq[1]) {
987 case '3': /* Delete key. */
988 linenoiseEditDelete(&l);
989 break;
990 }
991 }
992 } else {
993 switch (seq[1]) {
994 case 'A': /* Up */
995 linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV);
996 break;
997 case 'B': /* Down */
998 linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT);
999 break;
1000 case 'C': /* Right */
1001 linenoiseEditMoveRight(&l);
1002 break;
1003 case 'D': /* Left */
1004 linenoiseEditMoveLeft(&l);
1005 break;
1006 case 'H': /* Home */
1007 linenoiseEditMoveHome(&l);
1008 break;
1009 case 'F': /* End*/
1010 linenoiseEditMoveEnd(&l);
1011 break;
1012 }
1013 }
1014 }
1015
1016 /* ESC O sequences. */
1017 else if (seq[0] == 'O') {
1018 switch (seq[1]) {
1019 case 'H': /* Home */
1020 linenoiseEditMoveHome(&l);
1021 break;
1022 case 'F': /* End*/
1023 linenoiseEditMoveEnd(&l);
1024 break;
1025 }
1026 }
1027 break;
1028 case CTRL_U: /* Ctrl+u, delete the whole line. */
1029 buf[0] = '\0';
1030 l.pos = l.len = 0;
1031 refreshLine(&l);
1032 break;
1033 case CTRL_K: /* Ctrl+k, delete from current to end of line. */
1034 buf[l.pos] = '\0';
1035 l.len = l.pos;
1036 refreshLine(&l);
1037 break;
1038 case CTRL_A: /* Ctrl+a, go to the start of the line */
1039 linenoiseEditMoveHome(&l);
1040 break;
1041 case CTRL_E: /* ctrl+e, go to the end of the line */
1042 linenoiseEditMoveEnd(&l);
1043 break;
1044 case CTRL_L: /* ctrl+l, clear screen */
1045 linenoiseClearScreen();
1046 refreshLine(&l);
1047 break;
1048 case CTRL_W: /* ctrl+w, delete previous word */
1049 linenoiseEditDeletePrevWord(&l);
1050 break;
1051 default:
1052 if (linenoiseEditInsert(&l, c))
1053 return -1;
1054 break;
1055 }
1056 }
1057 return l.len;
1058}
1059
1060/* This special mode is used by linenoise in order to print scan codes
1061 * on screen for debugging / development purposes. It is implemented
1062 * by the linenoise_example program using the --keycodes option. */
1063void linenoisePrintKeyCodes(void) {
1064 char quit[4];
1065
1066 printf("Linenoise key codes debugging mode.\n"
1067 "Press keys to see scan codes. Type 'quit' at any time to exit.\n");
1068 if (enableRawMode(STDIN_FILENO) == -1)
1069 return;
1070 memset(quit, ' ', 4);
1071 while (1) {
1072 char c;
1073 int nread;
1074
1075 nread = read(STDIN_FILENO, &c, 1);
1076 if (nread <= 0)
1077 continue;
1078 memmove(quit, quit + 1, sizeof(quit) - 1); /* shift string to left. */
1079 quit[sizeof(quit) - 1] = c; /* Insert current char on the right. */
1080 if (memcmp(quit, "quit", sizeof(quit)) == 0)
1081 break;
1082
1083 printf("'%c' %02x (%d) (type quit to exit)\n", isprint(c) ? c : '?', (int)c, (int)c);
1084 printf("\r"); /* Go left edge manually, we are in raw mode. */
1085 fflush(stdout);
1086 }
1087 disableRawMode(STDIN_FILENO);
1088}
1089
1090/* This function calls the line editing function linenoiseEdit() using
1091 * the STDIN file descriptor set in raw mode. */
1092static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) {
1093 int count;
1094
1095 if (buflen == 0) {
1096 errno = EINVAL;
1097 return -1;
1098 }
1099
1100 if (enableRawMode(STDIN_FILENO) == -1)
1101 return -1;
1102 count = linenoiseEdit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt);
1103 disableRawMode(STDIN_FILENO);
1104 printf("\n");
1105 return count;
1106}
1107
1108/* This function is called when linenoise() is called with the standard
1109 * input file descriptor not attached to a TTY. So for example when the
1110 * program using linenoise is called in pipe or with a file redirected
1111 * to its standard input. In this case, we want to be able to return the
1112 * line regardless of its length (by default we are limited to 4k). */
1113static char *linenoiseNoTTY(void) {
1114 char *line = NULL;
1115 size_t len = 0, maxlen = 0;
1116
1117 while (1) {
1118 if (len == maxlen) {
1119 if (maxlen == 0)
1120 maxlen = 16;
1121 maxlen *= 2;
1122 char *oldval = line;
1123 line = realloc(line, maxlen);
1124 if (line == NULL) {
1125 if (oldval)
1126 free(oldval);
1127 return NULL;
1128 }
1129 }
1130 int c = fgetc(stdin);
1131 if (c == EOF || c == '\n') {
1132 if (c == EOF && len == 0) {
1133 free(line);
1134 return NULL;
1135 } else {
1136 line[len] = '\0';
1137 return line;
1138 }
1139 } else {
1140 line[len] = c;
1141 len++;
1142 }
1143 }
1144}
1145
1146/* The high level function that is the main API of the linenoise library.
1147 * This function checks if the terminal has basic capabilities, just checking
1148 * for a blacklist of stupid terminals, and later either calls the line
1149 * editing function or uses dummy fgets() so that you will be able to type
1150 * something even in the most desperate of the conditions. */
1151char *linenoise(const char *prompt) {
1152 char buf[LINENOISE_MAX_LINE];
1153 int count;
1154
1155 if (!isatty(STDIN_FILENO)) {
1156 /* Not a tty: read from file / pipe. In this mode we don't want any
1157 * limit to the line size, so we call a function to handle that. */
1158 return linenoiseNoTTY();
1159 } else if (isUnsupportedTerm()) {
1160 size_t len;
1161
1162 printf("%s", prompt);
1163 fflush(stdout);
1164 if (fgets(buf, LINENOISE_MAX_LINE, stdin) == NULL)
1165 return NULL;
1166 len = strlen(buf);
1167 while (len && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) {
1168 len--;
1169 buf[len] = '\0';
1170 }
1171 return strdup(buf);
1172 } else {
1173 count = linenoiseRaw(buf, LINENOISE_MAX_LINE, prompt);
1174 if (count == -1)
1175 return NULL;
1176 return strdup(buf);
1177 }
1178}
1179
1180/* This is just a wrapper the user may want to call in order to make sure
1181 * the linenoise returned buffer is freed with the same allocator it was
1182 * created with. Useful when the main program is using an alternative
1183 * allocator. */
1184void linenoiseFree(void *ptr) {
1185 free(ptr);
1186}
1187
1188/* ================================ History ================================= */
1189
1190/* Free the history, but does not reset it. Only used when we have to
1191 * exit() to avoid memory leaks are reported by valgrind & co. */
1192static void freeHistory(void) {
1193 if (history) {
1194 int j;
1195
1196 for (j = 0; j < history_len; j++)
1197 free(history[j]);
1198 free(history);
1199 }
1200}
1201
1202/* At exit we'll try to fix the terminal to the initial conditions. */
1203static void linenoiseAtExit(void) {
1204 disableRawMode(STDIN_FILENO);
1205 freeHistory();
1206}
1207
1208/* This is the API call to add a new entry in the linenoise history.
1209 * It uses a fixed array of char pointers that are shifted (memmoved)
1210 * when the history max length is reached in order to remove the older
1211 * entry and make room for the new one, so it is not exactly suitable for huge
1212 * histories, but will work well for a few hundred of entries.
1213 *
1214 * Using a circular buffer is smarter, but a bit more complex to handle. */
1215int linenoiseHistoryAdd(const char *line) {
1216 char *linecopy;
1217
1218 if (history_max_len == 0)
1219 return 0;
1220
1221 /* Initialization on first call. */
1222 if (history == NULL) {
1223 history = malloc(sizeof(char *) * history_max_len);
1224 if (history == NULL)
1225 return 0;
1226 memset(history, 0, (sizeof(char *) * history_max_len));
1227 }
1228
1229 /* Don't add duplicated lines. */
1230 if (history_len && !strcmp(history[history_len - 1], line))
1231 return 0;
1232
1233 /* Add an heap allocated copy of the line in the history.
1234 * If we reached the max length, remove the older line. */
1235 linecopy = strdup(line);
1236 if (!linecopy)
1237 return 0;
1238 if (history_len == history_max_len) {
1239 free(history[0]);
1240 memmove(history, history + 1, sizeof(char *) * (history_max_len - 1));
1241 history_len--;
1242 }
1243 history[history_len] = linecopy;
1244 history_len++;
1245 return 1;
1246}
1247
1248/* Set the maximum length for the history. This function can be called even
1249 * if there is already some history, the function will make sure to retain
1250 * just the latest 'len' elements if the new history length value is smaller
1251 * than the amount of items already inside the history. */
1252int linenoiseHistorySetMaxLen(int len) {
1253 char **new;
1254
1255 if (len < 1)
1256 return 0;
1257 if (history) {
1258 int tocopy = history_len;
1259
1260 new = malloc(sizeof(char *) * len);
1261 if (new == NULL)
1262 return 0;
1263
1264 /* If we can't copy everything, free the elements we'll not use. */
1265 if (len < tocopy) {
1266 int j;
1267
1268 for (j = 0; j < tocopy - len; j++)
1269 free(history[j]);
1270 tocopy = len;
1271 }
1272 memset(new, 0, sizeof(char *) * len);
1273 memcpy(new, history + (history_len - tocopy), sizeof(char *) * tocopy);
1274 free(history);
1275 history = new;
1276 }
1277 history_max_len = len;
1278 if (history_len > history_max_len)
1279 history_len = history_max_len;
1280 return 1;
1281}
1282
1283/* Save the history in the specified file. On success 0 is returned
1284 * otherwise -1 is returned. */
1285int linenoiseHistorySave(const char *filename) {
1286 mode_t old_umask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
1287 FILE *fp;
1288 int j;
1289
1290 fp = fopen(filename, "w");
1291 umask(old_umask);
1292 if (fp == NULL)
1293 return -1;
1294 chmod(filename, S_IRUSR | S_IWUSR);
1295 for (j = 0; j < history_len; j++)
1296 fprintf(fp, "%s\n", history[j]);
1297 fclose(fp);
1298 return 0;
1299}
1300
1301/* Load the history from the specified file. If the file does not exist
1302 * zero is returned and no operation is performed.
1303 *
1304 * If the file exists and the operation succeeded 0 is returned, otherwise
1305 * on error -1 is returned. */
1306int linenoiseHistoryLoad(const char *filename) {
1307 FILE *fp = fopen(filename, "r");
1308 char buf[LINENOISE_MAX_LINE];
1309
1310 if (fp == NULL)
1311 return -1;
1312
1313 while (fgets(buf, LINENOISE_MAX_LINE, fp) != NULL) {
1314 char *p;
1315
1316 p = strchr(buf, '\r');
1317 if (!p)
1318 p = strchr(buf, '\n');
1319 if (p)
1320 *p = '\0';
1321 linenoiseHistoryAdd(buf);
1322 }
1323 fclose(fp);
1324 return 0;
1325}
1326