Fossil SCM

Update the built-in copy of linenoise to the latest from the GitHub repository ([https://github.com/antirez/linenoise])

drh 2017-12-21 03:12 trunk
Commit 6cf508f6a3835d9d89599b0271ec0589c3040e80ed2e719296ddae861b938178
2 files changed +125 -69 +5
+125 -69
--- src/linenoise.c
+++ src/linenoise.c
@@ -1,9 +1,7 @@
1
-/* linenoise.c -- VERSION 1.0
2
- *
3
- * Guerrilla line editing library against the idea that a line editing lib
4
- * needs to be 20,000 lines of C code.
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.
53
*
64
* You can find the latest source code at:
75
*
86
* http://github.com/antirez/linenoise
97
*
@@ -10,11 +8,11 @@
108
* Does a number of crazy assumptions that happen to be true in 99.9999% of
119
* the 2010 UNIX computers around.
1210
*
1311
* ------------------------------------------------------------------------
1412
*
15
- * Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com>
13
+ * Copyright (c) 2010-2016, Salvatore Sanfilippo <antirez at gmail dot com>
1614
* Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
1715
*
1816
* All rights reserved.
1917
*
2018
* Redistribution and use in source and binary forms, with or without
@@ -105,27 +103,28 @@
105103
*
106104
*/
107105
108106
#include <termios.h>
109107
#include <unistd.h>
110
-#include <stdarg.h>
111108
#include <stdlib.h>
112109
#include <stdio.h>
113110
#include <errno.h>
114111
#include <string.h>
115112
#include <stdlib.h>
116113
#include <ctype.h>
114
+#include <sys/stat.h>
117115
#include <sys/types.h>
118116
#include <sys/ioctl.h>
119117
#include <unistd.h>
120118
#include "linenoise.h"
121
-#include "sqlite3.h"
122119
123120
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
124121
#define LINENOISE_MAX_LINE 4096
125
-static const char *unsupported_term[] = {"dumb","cons25","emacs",NULL};
122
+static char *unsupported_term[] = {"dumb","cons25","emacs",NULL};
126123
static linenoiseCompletionCallback *completionCallback = NULL;
124
+static linenoiseHintsCallback *hintsCallback = NULL;
125
+static linenoiseFreeHintsCallback *freeHintsCallback = NULL;
127126
128127
static struct termios orig_termios; /* In order to restore at exit.*/
129128
static int rawmode = 0; /* For atexit() function to check if restore is needed*/
130129
static int mlmode = 0; /* Multi line mode. Default is single line. */
131130
static int atexit_registered = 0; /* Register atexit just 1 time. */
@@ -178,58 +177,26 @@
178177
static void refreshLine(struct linenoiseState *l);
179178
180179
/* Debugging macro. */
181180
#if 0
182181
FILE *lndebug_fp = NULL;
183
-#define lndebug(fmt, arg1) \
182
+#define lndebug(...) \
184183
do { \
185184
if (lndebug_fp == NULL) { \
186185
lndebug_fp = fopen("/tmp/lndebug.txt","a"); \
187186
fprintf(lndebug_fp, \
188187
"[%d %d %d] p: %d, rows: %d, rpos: %d, max: %d, oldmax: %d\n", \
189188
(int)l->len,(int)l->pos,(int)l->oldpos,plen,rows,rpos, \
190189
(int)l->maxrows,old_rows); \
191190
} \
192
- fprintf(lndebug_fp, ", " fmt, arg1); \
191
+ fprintf(lndebug_fp, ", " __VA_ARGS__); \
193192
fflush(lndebug_fp); \
194193
} while (0)
195194
#else
196
-#define lndebug(fmt, arg1)
195
+#define lndebug(fmt, ...)
197196
#endif
198197
199
-/* =========================== C89 compatibility ============================ */
200
-
201
-/* snprintf() is not C89, but sqlite3_vsnprintf() can be adapted. */
202
-static int linenoiseSnprintf(char *str, size_t size, const char *format, ...) {
203
- va_list ap;
204
- int result;
205
-
206
- va_start(ap,format);
207
- result = (int)strlen(sqlite3_vsnprintf((int)size,str,format,ap));
208
- va_end(ap);
209
-
210
- return result;
211
-}
212
-#undef snprintf
213
-#define snprintf linenoiseSnprintf
214
-
215
-/* strdup() is technically not standard C89 despite being in POSIX. */
216
-static char *linenoiseStrdup(const char *s) {
217
- size_t size = strlen(s)+1;
218
- char *result = malloc(size);
219
-
220
- if (result) memcpy(result,s,size);
221
-
222
- return result;
223
-}
224
-#undef strdup
225
-#define strdup linenoiseStrdup
226
-
227
-/* strcasecmp() is not standard C89. SQLite offers a direct replacement. */
228
-#undef strcasecmp
229
-#define strcasecmp sqlite3_stricmp
230
-
231198
/* ======================= Low level terminal handling ====================== */
232199
233200
/* Set if to use or not the multi line mode. */
234201
void linenoiseSetMultiLine(int ml) {
235202
mlmode = ml;
@@ -245,11 +212,11 @@
245212
for (j = 0; unsupported_term[j]; j++)
246213
if (!strcasecmp(term,unsupported_term[j])) return 1;
247214
return 0;
248215
}
249216
250
-/* Raw mode */
217
+/* Raw mode: 1960 magic shit. */
251218
static int enableRawMode(int fd) {
252219
struct termios raw;
253220
254221
if (!isatty(STDIN_FILENO)) goto fatal;
255222
if (!atexit_registered) {
@@ -315,11 +282,10 @@
315282
}
316283
317284
/* Try to get the number of columns in the current terminal, or assume 80
318285
* if it fails. */
319286
static int getColumns(int ifd, int ofd) {
320
-#if !defined(__sun__)
321287
struct winsize ws;
322288
323289
if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) {
324290
/* ioctl() failed. Try to query the terminal itself. */
325291
int start, cols;
@@ -345,11 +311,10 @@
345311
} else {
346312
return ws.ws_col;
347313
}
348314
349315
failed:
350
-#endif
351316
return 80;
352317
}
353318
354319
/* Clear the screen. Used to handle ctrl+l */
355320
void linenoiseClearScreen(void) {
@@ -442,10 +407,22 @@
442407
443408
/* Register a callback function to be called for tab-completion. */
444409
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
445410
completionCallback = fn;
446411
}
412
+
413
+/* Register a hits function to be called to show hits to the user at the
414
+ * right of the prompt. */
415
+void linenoiseSetHintsCallback(linenoiseHintsCallback *fn) {
416
+ hintsCallback = fn;
417
+}
418
+
419
+/* Register a function to free the hints returned by the hints callback
420
+ * registered with linenoiseSetHintsCallback(). */
421
+void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *fn) {
422
+ freeHintsCallback = fn;
423
+}
447424
448425
/* This function is used by the callback function registered by the user
449426
* in order to add completion options given the input string when the
450427
* user typed <tab>. See the example.c source code for a very easy to
451428
* understand example. */
@@ -491,10 +468,34 @@
491468
}
492469
493470
static void abFree(struct abuf *ab) {
494471
free(ab->b);
495472
}
473
+
474
+/* Helper of refreshSingleLine() and refreshMultiLine() to show hints
475
+ * to the right of the prompt. */
476
+void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) {
477
+ char seq[64];
478
+ if (hintsCallback && plen+l->len < l->cols) {
479
+ int color = -1, bold = 0;
480
+ char *hint = hintsCallback(l->buf,&color,&bold);
481
+ if (hint) {
482
+ int hintlen = strlen(hint);
483
+ int hintmaxlen = l->cols-(plen+l->len);
484
+ if (hintlen > hintmaxlen) hintlen = hintmaxlen;
485
+ if (bold == 1 && color == -1) color = 37;
486
+ if (color != -1 || bold != 0)
487
+ snprintf(seq,64,"\033[%d;%d;49m",bold,color);
488
+ abAppend(ab,seq,strlen(seq));
489
+ abAppend(ab,hint,hintlen);
490
+ if (color != -1 || bold != 0)
491
+ abAppend(ab,"\033[0m",4);
492
+ /* Call the function to free the hint returned. */
493
+ if (freeHintsCallback) freeHintsCallback(hint);
494
+ }
495
+ }
496
+}
496497
497498
/* Single line low level line refresh.
498499
*
499500
* Rewrite the currently edited line accordingly to the buffer content,
500501
* cursor position, and number of columns of the terminal. */
@@ -521,10 +522,12 @@
521522
snprintf(seq,64,"\r");
522523
abAppend(&ab,seq,strlen(seq));
523524
/* Write the prompt and the current buffer content */
524525
abAppend(&ab,l->prompt,strlen(l->prompt));
525526
abAppend(&ab,buf,len);
527
+ /* Show hits if any. */
528
+ refreshShowHints(&ab,l,plen);
526529
/* Erase to right */
527530
snprintf(seq,64,"\x1b[0K");
528531
abAppend(&ab,seq,strlen(seq));
529532
/* Move cursor to original position. */
530533
snprintf(seq,64,"\r\x1b[%dC", (int)(pos+plen));
@@ -560,31 +563,34 @@
560563
abAppend(&ab,seq,strlen(seq));
561564
}
562565
563566
/* Now for every row clear it, go up. */
564567
for (j = 0; j < old_rows-1; j++) {
565
- lndebug("clear+up", 0);
568
+ lndebug("clear+up");
566569
snprintf(seq,64,"\r\x1b[0K\x1b[1A");
567570
abAppend(&ab,seq,strlen(seq));
568571
}
569572
570573
/* Clean the top line. */
571
- lndebug("clear", 0);
574
+ lndebug("clear");
572575
snprintf(seq,64,"\r\x1b[0K");
573576
abAppend(&ab,seq,strlen(seq));
574577
575578
/* Write the prompt and the current buffer content */
576579
abAppend(&ab,l->prompt,strlen(l->prompt));
577580
abAppend(&ab,l->buf,l->len);
578581
582
+ /* Show hits if any. */
583
+ refreshShowHints(&ab,l,plen);
584
+
579585
/* If we are at the very end of the screen with our prompt, we need to
580586
* emit a newline and move the prompt to the first column. */
581587
if (l->pos &&
582588
l->pos == l->len &&
583589
(l->pos+plen) % l->cols == 0)
584590
{
585
- lndebug("<newline>", 0);
591
+ lndebug("<newline>");
586592
abAppend(&ab,"\n",1);
587593
snprintf(seq,64,"\r");
588594
abAppend(&ab,seq,strlen(seq));
589595
rows++;
590596
if (rows > (int)l->maxrows) l->maxrows = rows;
@@ -608,11 +614,11 @@
608614
snprintf(seq,64,"\r\x1b[%dC", col);
609615
else
610616
snprintf(seq,64,"\r");
611617
abAppend(&ab,seq,strlen(seq));
612618
613
- lndebug("\n", 0);
619
+ lndebug("\n");
614620
l->oldpos = l->pos;
615621
616622
if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */
617623
abFree(&ab);
618624
}
@@ -634,11 +640,11 @@
634640
if (l->len == l->pos) {
635641
l->buf[l->pos] = c;
636642
l->pos++;
637643
l->len++;
638644
l->buf[l->len] = '\0';
639
- if ((!mlmode && l->plen+l->len < l->cols) /* || mlmode */) {
645
+ if ((!mlmode && l->plen+l->len < l->cols && !hintsCallback)) {
640646
/* Avoid a full update of the line in the
641647
* trivial case. */
642648
if (write(l->ofd,&c,1) == -1) return -1;
643649
} else {
644650
refreshLine(l);
@@ -808,10 +814,18 @@
808814
switch(c) {
809815
case ENTER: /* enter */
810816
history_len--;
811817
free(history[history_len]);
812818
if (mlmode) linenoiseEditMoveEnd(&l);
819
+ if (hintsCallback) {
820
+ /* Force a refresh without hints to leave the previous
821
+ * line as the user typed it after a newline. */
822
+ linenoiseHintsCallback *hc = hintsCallback;
823
+ hintsCallback = NULL;
824
+ refreshLine(&l);
825
+ hintsCallback = hc;
826
+ }
813827
return (int)l.len;
814828
case CTRL_C: /* ctrl-c */
815829
errno = EAGAIN;
816830
return -1;
817831
case BACKSPACE: /* backspace */
@@ -954,11 +968,11 @@
954968
memmove(quit,quit+1,sizeof(quit)-1); /* shift string to left. */
955969
quit[sizeof(quit)-1] = c; /* Insert current char on the right. */
956970
if (memcmp(quit,"quit",sizeof(quit)) == 0) break;
957971
958972
printf("'%c' %02x (%d) (type quit to exit)\n",
959
- isprint((int)c) ? c : '?', (int)c, (int)c);
973
+ isprint(c) ? c : '?', (int)c, (int)c);
960974
printf("\r"); /* Go left edge manually, we are in raw mode. */
961975
fflush(stdout);
962976
}
963977
disableRawMode(STDIN_FILENO);
964978
}
@@ -970,27 +984,53 @@
970984
971985
if (buflen == 0) {
972986
errno = EINVAL;
973987
return -1;
974988
}
975
- if (!isatty(STDIN_FILENO)) {
976
- /* Not a tty: read from file / pipe. */
977
- if (fgets(buf, buflen, stdin) == NULL) return -1;
978
- count = strlen(buf);
979
- if (count && buf[count-1] == '\n') {
980
- count--;
981
- buf[count] = '\0';
982
- }
983
- } else {
984
- /* Interactive editing. */
985
- if (enableRawMode(STDIN_FILENO) == -1) return -1;
986
- count = linenoiseEdit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt);
987
- disableRawMode(STDIN_FILENO);
988
- printf("\n");
989
- }
989
+
990
+ if (enableRawMode(STDIN_FILENO) == -1) return -1;
991
+ count = linenoiseEdit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt);
992
+ disableRawMode(STDIN_FILENO);
993
+ printf("\n");
990994
return count;
991995
}
996
+
997
+/* This function is called when linenoise() is called with the standard
998
+ * input file descriptor not attached to a TTY. So for example when the
999
+ * program using linenoise is called in pipe or with a file redirected
1000
+ * to its standard input. In this case, we want to be able to return the
1001
+ * line regardless of its length (by default we are limited to 4k). */
1002
+static char *linenoiseNoTTY(void) {
1003
+ char *line = NULL;
1004
+ size_t len = 0, maxlen = 0;
1005
+
1006
+ while(1) {
1007
+ if (len == maxlen) {
1008
+ if (maxlen == 0) maxlen = 16;
1009
+ maxlen *= 2;
1010
+ char *oldval = line;
1011
+ line = realloc(line,maxlen);
1012
+ if (line == NULL) {
1013
+ if (oldval) free(oldval);
1014
+ return NULL;
1015
+ }
1016
+ }
1017
+ int c = fgetc(stdin);
1018
+ if (c == EOF || c == '\n') {
1019
+ if (c == EOF && len == 0) {
1020
+ free(line);
1021
+ return NULL;
1022
+ } else {
1023
+ line[len] = '\0';
1024
+ return line;
1025
+ }
1026
+ } else {
1027
+ line[len] = c;
1028
+ len++;
1029
+ }
1030
+ }
1031
+}
9921032
9931033
/* The high level function that is the main API of the linenoise library.
9941034
* This function checks if the terminal has basic capabilities, just checking
9951035
* for a blacklist of stupid terminals, and later either calls the line
9961036
* editing function or uses dummy fgets() so that you will be able to type
@@ -997,11 +1037,15 @@
9971037
* something even in the most desperate of the conditions. */
9981038
char *linenoise(const char *prompt) {
9991039
char buf[LINENOISE_MAX_LINE];
10001040
int count;
10011041
1002
- if (isUnsupportedTerm()) {
1042
+ if (!isatty(STDIN_FILENO)) {
1043
+ /* Not a tty: read from file / pipe. In this mode we don't want any
1044
+ * limit to the line size, so we call a function to handle that. */
1045
+ return linenoiseNoTTY();
1046
+ } else if (isUnsupportedTerm()) {
10031047
size_t len;
10041048
10051049
printf("%s",prompt);
10061050
fflush(stdout);
10071051
if (fgets(buf,LINENOISE_MAX_LINE,stdin) == NULL) return NULL;
@@ -1015,10 +1059,18 @@
10151059
count = linenoiseRaw(buf,LINENOISE_MAX_LINE,prompt);
10161060
if (count == -1) return NULL;
10171061
return strdup(buf);
10181062
}
10191063
}
1064
+
1065
+/* This is just a wrapper the user may want to call in order to make sure
1066
+ * the linenoise returned buffer is freed with the same allocator it was
1067
+ * created with. Useful when the main program is using an alternative
1068
+ * allocator. */
1069
+void linenoiseFree(void *ptr) {
1070
+ free(ptr);
1071
+}
10201072
10211073
/* ================================ History ================================= */
10221074
10231075
/* Free the history, but does not reset it. Only used when we have to
10241076
* exit() to avoid memory leaks are reported by valgrind & co. */
@@ -1107,14 +1159,18 @@
11071159
}
11081160
11091161
/* Save the history in the specified file. On success 0 is returned
11101162
* otherwise -1 is returned. */
11111163
int linenoiseHistorySave(const char *filename) {
1112
- FILE *fp = fopen(filename,"w");
1164
+ mode_t old_umask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
1165
+ FILE *fp;
11131166
int j;
11141167
1168
+ fp = fopen(filename,"w");
1169
+ umask(old_umask);
11151170
if (fp == NULL) return -1;
1171
+ chmod(filename,S_IRUSR|S_IWUSR);
11161172
for (j = 0; j < history_len; j++)
11171173
fprintf(fp,"%s\n",history[j]);
11181174
fclose(fp);
11191175
return 0;
11201176
}
11211177
--- src/linenoise.c
+++ src/linenoise.c
@@ -1,9 +1,7 @@
1 /* linenoise.c -- VERSION 1.0
2 *
3 * Guerrilla line editing library against the idea that a line editing lib
4 * needs to be 20,000 lines of C code.
5 *
6 * You can find the latest source code at:
7 *
8 * http://github.com/antirez/linenoise
9 *
@@ -10,11 +8,11 @@
10 * Does a number of crazy assumptions that happen to be true in 99.9999% of
11 * the 2010 UNIX computers around.
12 *
13 * ------------------------------------------------------------------------
14 *
15 * Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com>
16 * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
17 *
18 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
@@ -105,27 +103,28 @@
105 *
106 */
107
108 #include <termios.h>
109 #include <unistd.h>
110 #include <stdarg.h>
111 #include <stdlib.h>
112 #include <stdio.h>
113 #include <errno.h>
114 #include <string.h>
115 #include <stdlib.h>
116 #include <ctype.h>
 
117 #include <sys/types.h>
118 #include <sys/ioctl.h>
119 #include <unistd.h>
120 #include "linenoise.h"
121 #include "sqlite3.h"
122
123 #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
124 #define LINENOISE_MAX_LINE 4096
125 static const char *unsupported_term[] = {"dumb","cons25","emacs",NULL};
126 static linenoiseCompletionCallback *completionCallback = NULL;
 
 
127
128 static struct termios orig_termios; /* In order to restore at exit.*/
129 static int rawmode = 0; /* For atexit() function to check if restore is needed*/
130 static int mlmode = 0; /* Multi line mode. Default is single line. */
131 static int atexit_registered = 0; /* Register atexit just 1 time. */
@@ -178,58 +177,26 @@
178 static void refreshLine(struct linenoiseState *l);
179
180 /* Debugging macro. */
181 #if 0
182 FILE *lndebug_fp = NULL;
183 #define lndebug(fmt, arg1) \
184 do { \
185 if (lndebug_fp == NULL) { \
186 lndebug_fp = fopen("/tmp/lndebug.txt","a"); \
187 fprintf(lndebug_fp, \
188 "[%d %d %d] p: %d, rows: %d, rpos: %d, max: %d, oldmax: %d\n", \
189 (int)l->len,(int)l->pos,(int)l->oldpos,plen,rows,rpos, \
190 (int)l->maxrows,old_rows); \
191 } \
192 fprintf(lndebug_fp, ", " fmt, arg1); \
193 fflush(lndebug_fp); \
194 } while (0)
195 #else
196 #define lndebug(fmt, arg1)
197 #endif
198
199 /* =========================== C89 compatibility ============================ */
200
201 /* snprintf() is not C89, but sqlite3_vsnprintf() can be adapted. */
202 static int linenoiseSnprintf(char *str, size_t size, const char *format, ...) {
203 va_list ap;
204 int result;
205
206 va_start(ap,format);
207 result = (int)strlen(sqlite3_vsnprintf((int)size,str,format,ap));
208 va_end(ap);
209
210 return result;
211 }
212 #undef snprintf
213 #define snprintf linenoiseSnprintf
214
215 /* strdup() is technically not standard C89 despite being in POSIX. */
216 static char *linenoiseStrdup(const char *s) {
217 size_t size = strlen(s)+1;
218 char *result = malloc(size);
219
220 if (result) memcpy(result,s,size);
221
222 return result;
223 }
224 #undef strdup
225 #define strdup linenoiseStrdup
226
227 /* strcasecmp() is not standard C89. SQLite offers a direct replacement. */
228 #undef strcasecmp
229 #define strcasecmp sqlite3_stricmp
230
231 /* ======================= Low level terminal handling ====================== */
232
233 /* Set if to use or not the multi line mode. */
234 void linenoiseSetMultiLine(int ml) {
235 mlmode = ml;
@@ -245,11 +212,11 @@
245 for (j = 0; unsupported_term[j]; j++)
246 if (!strcasecmp(term,unsupported_term[j])) return 1;
247 return 0;
248 }
249
250 /* Raw mode */
251 static int enableRawMode(int fd) {
252 struct termios raw;
253
254 if (!isatty(STDIN_FILENO)) goto fatal;
255 if (!atexit_registered) {
@@ -315,11 +282,10 @@
315 }
316
317 /* Try to get the number of columns in the current terminal, or assume 80
318 * if it fails. */
319 static int getColumns(int ifd, int ofd) {
320 #if !defined(__sun__)
321 struct winsize ws;
322
323 if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) {
324 /* ioctl() failed. Try to query the terminal itself. */
325 int start, cols;
@@ -345,11 +311,10 @@
345 } else {
346 return ws.ws_col;
347 }
348
349 failed:
350 #endif
351 return 80;
352 }
353
354 /* Clear the screen. Used to handle ctrl+l */
355 void linenoiseClearScreen(void) {
@@ -442,10 +407,22 @@
442
443 /* Register a callback function to be called for tab-completion. */
444 void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
445 completionCallback = fn;
446 }
 
 
 
 
 
 
 
 
 
 
 
 
447
448 /* This function is used by the callback function registered by the user
449 * in order to add completion options given the input string when the
450 * user typed <tab>. See the example.c source code for a very easy to
451 * understand example. */
@@ -491,10 +468,34 @@
491 }
492
493 static void abFree(struct abuf *ab) {
494 free(ab->b);
495 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
496
497 /* Single line low level line refresh.
498 *
499 * Rewrite the currently edited line accordingly to the buffer content,
500 * cursor position, and number of columns of the terminal. */
@@ -521,10 +522,12 @@
521 snprintf(seq,64,"\r");
522 abAppend(&ab,seq,strlen(seq));
523 /* Write the prompt and the current buffer content */
524 abAppend(&ab,l->prompt,strlen(l->prompt));
525 abAppend(&ab,buf,len);
 
 
526 /* Erase to right */
527 snprintf(seq,64,"\x1b[0K");
528 abAppend(&ab,seq,strlen(seq));
529 /* Move cursor to original position. */
530 snprintf(seq,64,"\r\x1b[%dC", (int)(pos+plen));
@@ -560,31 +563,34 @@
560 abAppend(&ab,seq,strlen(seq));
561 }
562
563 /* Now for every row clear it, go up. */
564 for (j = 0; j < old_rows-1; j++) {
565 lndebug("clear+up", 0);
566 snprintf(seq,64,"\r\x1b[0K\x1b[1A");
567 abAppend(&ab,seq,strlen(seq));
568 }
569
570 /* Clean the top line. */
571 lndebug("clear", 0);
572 snprintf(seq,64,"\r\x1b[0K");
573 abAppend(&ab,seq,strlen(seq));
574
575 /* Write the prompt and the current buffer content */
576 abAppend(&ab,l->prompt,strlen(l->prompt));
577 abAppend(&ab,l->buf,l->len);
578
 
 
 
579 /* If we are at the very end of the screen with our prompt, we need to
580 * emit a newline and move the prompt to the first column. */
581 if (l->pos &&
582 l->pos == l->len &&
583 (l->pos+plen) % l->cols == 0)
584 {
585 lndebug("<newline>", 0);
586 abAppend(&ab,"\n",1);
587 snprintf(seq,64,"\r");
588 abAppend(&ab,seq,strlen(seq));
589 rows++;
590 if (rows > (int)l->maxrows) l->maxrows = rows;
@@ -608,11 +614,11 @@
608 snprintf(seq,64,"\r\x1b[%dC", col);
609 else
610 snprintf(seq,64,"\r");
611 abAppend(&ab,seq,strlen(seq));
612
613 lndebug("\n", 0);
614 l->oldpos = l->pos;
615
616 if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */
617 abFree(&ab);
618 }
@@ -634,11 +640,11 @@
634 if (l->len == l->pos) {
635 l->buf[l->pos] = c;
636 l->pos++;
637 l->len++;
638 l->buf[l->len] = '\0';
639 if ((!mlmode && l->plen+l->len < l->cols) /* || mlmode */) {
640 /* Avoid a full update of the line in the
641 * trivial case. */
642 if (write(l->ofd,&c,1) == -1) return -1;
643 } else {
644 refreshLine(l);
@@ -808,10 +814,18 @@
808 switch(c) {
809 case ENTER: /* enter */
810 history_len--;
811 free(history[history_len]);
812 if (mlmode) linenoiseEditMoveEnd(&l);
 
 
 
 
 
 
 
 
813 return (int)l.len;
814 case CTRL_C: /* ctrl-c */
815 errno = EAGAIN;
816 return -1;
817 case BACKSPACE: /* backspace */
@@ -954,11 +968,11 @@
954 memmove(quit,quit+1,sizeof(quit)-1); /* shift string to left. */
955 quit[sizeof(quit)-1] = c; /* Insert current char on the right. */
956 if (memcmp(quit,"quit",sizeof(quit)) == 0) break;
957
958 printf("'%c' %02x (%d) (type quit to exit)\n",
959 isprint((int)c) ? c : '?', (int)c, (int)c);
960 printf("\r"); /* Go left edge manually, we are in raw mode. */
961 fflush(stdout);
962 }
963 disableRawMode(STDIN_FILENO);
964 }
@@ -970,27 +984,53 @@
970
971 if (buflen == 0) {
972 errno = EINVAL;
973 return -1;
974 }
975 if (!isatty(STDIN_FILENO)) {
976 /* Not a tty: read from file / pipe. */
977 if (fgets(buf, buflen, stdin) == NULL) return -1;
978 count = strlen(buf);
979 if (count && buf[count-1] == '\n') {
980 count--;
981 buf[count] = '\0';
982 }
983 } else {
984 /* Interactive editing. */
985 if (enableRawMode(STDIN_FILENO) == -1) return -1;
986 count = linenoiseEdit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt);
987 disableRawMode(STDIN_FILENO);
988 printf("\n");
989 }
990 return count;
991 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
992
993 /* The high level function that is the main API of the linenoise library.
994 * This function checks if the terminal has basic capabilities, just checking
995 * for a blacklist of stupid terminals, and later either calls the line
996 * editing function or uses dummy fgets() so that you will be able to type
@@ -997,11 +1037,15 @@
997 * something even in the most desperate of the conditions. */
998 char *linenoise(const char *prompt) {
999 char buf[LINENOISE_MAX_LINE];
1000 int count;
1001
1002 if (isUnsupportedTerm()) {
 
 
 
 
1003 size_t len;
1004
1005 printf("%s",prompt);
1006 fflush(stdout);
1007 if (fgets(buf,LINENOISE_MAX_LINE,stdin) == NULL) return NULL;
@@ -1015,10 +1059,18 @@
1015 count = linenoiseRaw(buf,LINENOISE_MAX_LINE,prompt);
1016 if (count == -1) return NULL;
1017 return strdup(buf);
1018 }
1019 }
 
 
 
 
 
 
 
 
1020
1021 /* ================================ History ================================= */
1022
1023 /* Free the history, but does not reset it. Only used when we have to
1024 * exit() to avoid memory leaks are reported by valgrind & co. */
@@ -1107,14 +1159,18 @@
1107 }
1108
1109 /* Save the history in the specified file. On success 0 is returned
1110 * otherwise -1 is returned. */
1111 int linenoiseHistorySave(const char *filename) {
1112 FILE *fp = fopen(filename,"w");
 
1113 int j;
1114
 
 
1115 if (fp == NULL) return -1;
 
1116 for (j = 0; j < history_len; j++)
1117 fprintf(fp,"%s\n",history[j]);
1118 fclose(fp);
1119 return 0;
1120 }
1121
--- src/linenoise.c
+++ src/linenoise.c
@@ -1,9 +1,7 @@
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 *
@@ -10,11 +8,11 @@
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
@@ -105,27 +103,28 @@
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
120 #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
121 #define LINENOISE_MAX_LINE 4096
122 static char *unsupported_term[] = {"dumb","cons25","emacs",NULL};
123 static linenoiseCompletionCallback *completionCallback = NULL;
124 static linenoiseHintsCallback *hintsCallback = NULL;
125 static linenoiseFreeHintsCallback *freeHintsCallback = NULL;
126
127 static struct termios orig_termios; /* In order to restore at exit.*/
128 static int rawmode = 0; /* For atexit() function to check if restore is needed*/
129 static int mlmode = 0; /* Multi line mode. Default is single line. */
130 static int atexit_registered = 0; /* Register atexit just 1 time. */
@@ -178,58 +177,26 @@
177 static void refreshLine(struct linenoiseState *l);
178
179 /* Debugging macro. */
180 #if 0
181 FILE *lndebug_fp = NULL;
182 #define lndebug(...) \
183 do { \
184 if (lndebug_fp == NULL) { \
185 lndebug_fp = fopen("/tmp/lndebug.txt","a"); \
186 fprintf(lndebug_fp, \
187 "[%d %d %d] p: %d, rows: %d, rpos: %d, max: %d, oldmax: %d\n", \
188 (int)l->len,(int)l->pos,(int)l->oldpos,plen,rows,rpos, \
189 (int)l->maxrows,old_rows); \
190 } \
191 fprintf(lndebug_fp, ", " __VA_ARGS__); \
192 fflush(lndebug_fp); \
193 } while (0)
194 #else
195 #define lndebug(fmt, ...)
196 #endif
197
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198 /* ======================= Low level terminal handling ====================== */
199
200 /* Set if to use or not the multi line mode. */
201 void linenoiseSetMultiLine(int ml) {
202 mlmode = ml;
@@ -245,11 +212,11 @@
212 for (j = 0; unsupported_term[j]; j++)
213 if (!strcasecmp(term,unsupported_term[j])) return 1;
214 return 0;
215 }
216
217 /* Raw mode: 1960 magic shit. */
218 static int enableRawMode(int fd) {
219 struct termios raw;
220
221 if (!isatty(STDIN_FILENO)) goto fatal;
222 if (!atexit_registered) {
@@ -315,11 +282,10 @@
282 }
283
284 /* Try to get the number of columns in the current terminal, or assume 80
285 * if it fails. */
286 static int getColumns(int ifd, int ofd) {
 
287 struct winsize ws;
288
289 if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) {
290 /* ioctl() failed. Try to query the terminal itself. */
291 int start, cols;
@@ -345,11 +311,10 @@
311 } else {
312 return ws.ws_col;
313 }
314
315 failed:
 
316 return 80;
317 }
318
319 /* Clear the screen. Used to handle ctrl+l */
320 void linenoiseClearScreen(void) {
@@ -442,10 +407,22 @@
407
408 /* Register a callback function to be called for tab-completion. */
409 void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
410 completionCallback = fn;
411 }
412
413 /* Register a hits function to be called to show hits to the user at the
414 * right of the prompt. */
415 void linenoiseSetHintsCallback(linenoiseHintsCallback *fn) {
416 hintsCallback = fn;
417 }
418
419 /* Register a function to free the hints returned by the hints callback
420 * registered with linenoiseSetHintsCallback(). */
421 void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *fn) {
422 freeHintsCallback = fn;
423 }
424
425 /* This function is used by the callback function registered by the user
426 * in order to add completion options given the input string when the
427 * user typed <tab>. See the example.c source code for a very easy to
428 * understand example. */
@@ -491,10 +468,34 @@
468 }
469
470 static void abFree(struct abuf *ab) {
471 free(ab->b);
472 }
473
474 /* Helper of refreshSingleLine() and refreshMultiLine() to show hints
475 * to the right of the prompt. */
476 void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) {
477 char seq[64];
478 if (hintsCallback && plen+l->len < l->cols) {
479 int color = -1, bold = 0;
480 char *hint = hintsCallback(l->buf,&color,&bold);
481 if (hint) {
482 int hintlen = strlen(hint);
483 int hintmaxlen = l->cols-(plen+l->len);
484 if (hintlen > hintmaxlen) hintlen = hintmaxlen;
485 if (bold == 1 && color == -1) color = 37;
486 if (color != -1 || bold != 0)
487 snprintf(seq,64,"\033[%d;%d;49m",bold,color);
488 abAppend(ab,seq,strlen(seq));
489 abAppend(ab,hint,hintlen);
490 if (color != -1 || bold != 0)
491 abAppend(ab,"\033[0m",4);
492 /* Call the function to free the hint returned. */
493 if (freeHintsCallback) freeHintsCallback(hint);
494 }
495 }
496 }
497
498 /* Single line low level line refresh.
499 *
500 * Rewrite the currently edited line accordingly to the buffer content,
501 * cursor position, and number of columns of the terminal. */
@@ -521,10 +522,12 @@
522 snprintf(seq,64,"\r");
523 abAppend(&ab,seq,strlen(seq));
524 /* Write the prompt and the current buffer content */
525 abAppend(&ab,l->prompt,strlen(l->prompt));
526 abAppend(&ab,buf,len);
527 /* Show hits if any. */
528 refreshShowHints(&ab,l,plen);
529 /* Erase to right */
530 snprintf(seq,64,"\x1b[0K");
531 abAppend(&ab,seq,strlen(seq));
532 /* Move cursor to original position. */
533 snprintf(seq,64,"\r\x1b[%dC", (int)(pos+plen));
@@ -560,31 +563,34 @@
563 abAppend(&ab,seq,strlen(seq));
564 }
565
566 /* Now for every row clear it, go up. */
567 for (j = 0; j < old_rows-1; j++) {
568 lndebug("clear+up");
569 snprintf(seq,64,"\r\x1b[0K\x1b[1A");
570 abAppend(&ab,seq,strlen(seq));
571 }
572
573 /* Clean the top line. */
574 lndebug("clear");
575 snprintf(seq,64,"\r\x1b[0K");
576 abAppend(&ab,seq,strlen(seq));
577
578 /* Write the prompt and the current buffer content */
579 abAppend(&ab,l->prompt,strlen(l->prompt));
580 abAppend(&ab,l->buf,l->len);
581
582 /* Show hits if any. */
583 refreshShowHints(&ab,l,plen);
584
585 /* If we are at the very end of the screen with our prompt, we need to
586 * emit a newline and move the prompt to the first column. */
587 if (l->pos &&
588 l->pos == l->len &&
589 (l->pos+plen) % l->cols == 0)
590 {
591 lndebug("<newline>");
592 abAppend(&ab,"\n",1);
593 snprintf(seq,64,"\r");
594 abAppend(&ab,seq,strlen(seq));
595 rows++;
596 if (rows > (int)l->maxrows) l->maxrows = rows;
@@ -608,11 +614,11 @@
614 snprintf(seq,64,"\r\x1b[%dC", col);
615 else
616 snprintf(seq,64,"\r");
617 abAppend(&ab,seq,strlen(seq));
618
619 lndebug("\n");
620 l->oldpos = l->pos;
621
622 if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */
623 abFree(&ab);
624 }
@@ -634,11 +640,11 @@
640 if (l->len == l->pos) {
641 l->buf[l->pos] = c;
642 l->pos++;
643 l->len++;
644 l->buf[l->len] = '\0';
645 if ((!mlmode && l->plen+l->len < l->cols && !hintsCallback)) {
646 /* Avoid a full update of the line in the
647 * trivial case. */
648 if (write(l->ofd,&c,1) == -1) return -1;
649 } else {
650 refreshLine(l);
@@ -808,10 +814,18 @@
814 switch(c) {
815 case ENTER: /* enter */
816 history_len--;
817 free(history[history_len]);
818 if (mlmode) linenoiseEditMoveEnd(&l);
819 if (hintsCallback) {
820 /* Force a refresh without hints to leave the previous
821 * line as the user typed it after a newline. */
822 linenoiseHintsCallback *hc = hintsCallback;
823 hintsCallback = NULL;
824 refreshLine(&l);
825 hintsCallback = hc;
826 }
827 return (int)l.len;
828 case CTRL_C: /* ctrl-c */
829 errno = EAGAIN;
830 return -1;
831 case BACKSPACE: /* backspace */
@@ -954,11 +968,11 @@
968 memmove(quit,quit+1,sizeof(quit)-1); /* shift string to left. */
969 quit[sizeof(quit)-1] = c; /* Insert current char on the right. */
970 if (memcmp(quit,"quit",sizeof(quit)) == 0) break;
971
972 printf("'%c' %02x (%d) (type quit to exit)\n",
973 isprint(c) ? c : '?', (int)c, (int)c);
974 printf("\r"); /* Go left edge manually, we are in raw mode. */
975 fflush(stdout);
976 }
977 disableRawMode(STDIN_FILENO);
978 }
@@ -970,27 +984,53 @@
984
985 if (buflen == 0) {
986 errno = EINVAL;
987 return -1;
988 }
989
990 if (enableRawMode(STDIN_FILENO) == -1) return -1;
991 count = linenoiseEdit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt);
992 disableRawMode(STDIN_FILENO);
993 printf("\n");
 
 
 
 
 
 
 
 
 
 
994 return count;
995 }
996
997 /* This function is called when linenoise() is called with the standard
998 * input file descriptor not attached to a TTY. So for example when the
999 * program using linenoise is called in pipe or with a file redirected
1000 * to its standard input. In this case, we want to be able to return the
1001 * line regardless of its length (by default we are limited to 4k). */
1002 static char *linenoiseNoTTY(void) {
1003 char *line = NULL;
1004 size_t len = 0, maxlen = 0;
1005
1006 while(1) {
1007 if (len == maxlen) {
1008 if (maxlen == 0) maxlen = 16;
1009 maxlen *= 2;
1010 char *oldval = line;
1011 line = realloc(line,maxlen);
1012 if (line == NULL) {
1013 if (oldval) free(oldval);
1014 return NULL;
1015 }
1016 }
1017 int c = fgetc(stdin);
1018 if (c == EOF || c == '\n') {
1019 if (c == EOF && len == 0) {
1020 free(line);
1021 return NULL;
1022 } else {
1023 line[len] = '\0';
1024 return line;
1025 }
1026 } else {
1027 line[len] = c;
1028 len++;
1029 }
1030 }
1031 }
1032
1033 /* The high level function that is the main API of the linenoise library.
1034 * This function checks if the terminal has basic capabilities, just checking
1035 * for a blacklist of stupid terminals, and later either calls the line
1036 * editing function or uses dummy fgets() so that you will be able to type
@@ -997,11 +1037,15 @@
1037 * something even in the most desperate of the conditions. */
1038 char *linenoise(const char *prompt) {
1039 char buf[LINENOISE_MAX_LINE];
1040 int count;
1041
1042 if (!isatty(STDIN_FILENO)) {
1043 /* Not a tty: read from file / pipe. In this mode we don't want any
1044 * limit to the line size, so we call a function to handle that. */
1045 return linenoiseNoTTY();
1046 } else if (isUnsupportedTerm()) {
1047 size_t len;
1048
1049 printf("%s",prompt);
1050 fflush(stdout);
1051 if (fgets(buf,LINENOISE_MAX_LINE,stdin) == NULL) return NULL;
@@ -1015,10 +1059,18 @@
1059 count = linenoiseRaw(buf,LINENOISE_MAX_LINE,prompt);
1060 if (count == -1) return NULL;
1061 return strdup(buf);
1062 }
1063 }
1064
1065 /* This is just a wrapper the user may want to call in order to make sure
1066 * the linenoise returned buffer is freed with the same allocator it was
1067 * created with. Useful when the main program is using an alternative
1068 * allocator. */
1069 void linenoiseFree(void *ptr) {
1070 free(ptr);
1071 }
1072
1073 /* ================================ History ================================= */
1074
1075 /* Free the history, but does not reset it. Only used when we have to
1076 * exit() to avoid memory leaks are reported by valgrind & co. */
@@ -1107,14 +1159,18 @@
1159 }
1160
1161 /* Save the history in the specified file. On success 0 is returned
1162 * otherwise -1 is returned. */
1163 int linenoiseHistorySave(const char *filename) {
1164 mode_t old_umask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
1165 FILE *fp;
1166 int j;
1167
1168 fp = fopen(filename,"w");
1169 umask(old_umask);
1170 if (fp == NULL) return -1;
1171 chmod(filename,S_IRUSR|S_IWUSR);
1172 for (j = 0; j < history_len; j++)
1173 fprintf(fp,"%s\n",history[j]);
1174 fclose(fp);
1175 return 0;
1176 }
1177
--- src/linenoise.h
+++ src/linenoise.h
@@ -47,14 +47,19 @@
4747
size_t len;
4848
char **cvec;
4949
} linenoiseCompletions;
5050
5151
typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
52
+typedef char*(linenoiseHintsCallback)(const char *, int *color, int *bold);
53
+typedef void(linenoiseFreeHintsCallback)(void *);
5254
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
55
+void linenoiseSetHintsCallback(linenoiseHintsCallback *);
56
+void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *);
5357
void linenoiseAddCompletion(linenoiseCompletions *, const char *);
5458
5559
char *linenoise(const char *prompt);
60
+void linenoiseFree(void *ptr);
5661
int linenoiseHistoryAdd(const char *line);
5762
int linenoiseHistorySetMaxLen(int len);
5863
int linenoiseHistorySave(const char *filename);
5964
int linenoiseHistoryLoad(const char *filename);
6065
void linenoiseClearScreen(void);
6166
--- src/linenoise.h
+++ src/linenoise.h
@@ -47,14 +47,19 @@
47 size_t len;
48 char **cvec;
49 } linenoiseCompletions;
50
51 typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
 
 
52 void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
 
 
53 void linenoiseAddCompletion(linenoiseCompletions *, const char *);
54
55 char *linenoise(const char *prompt);
 
56 int linenoiseHistoryAdd(const char *line);
57 int linenoiseHistorySetMaxLen(int len);
58 int linenoiseHistorySave(const char *filename);
59 int linenoiseHistoryLoad(const char *filename);
60 void linenoiseClearScreen(void);
61
--- src/linenoise.h
+++ src/linenoise.h
@@ -47,14 +47,19 @@
47 size_t len;
48 char **cvec;
49 } linenoiseCompletions;
50
51 typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
52 typedef char*(linenoiseHintsCallback)(const char *, int *color, int *bold);
53 typedef void(linenoiseFreeHintsCallback)(void *);
54 void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
55 void linenoiseSetHintsCallback(linenoiseHintsCallback *);
56 void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *);
57 void linenoiseAddCompletion(linenoiseCompletions *, const char *);
58
59 char *linenoise(const char *prompt);
60 void linenoiseFree(void *ptr);
61 int linenoiseHistoryAdd(const char *line);
62 int linenoiseHistorySetMaxLen(int len);
63 int linenoiseHistorySave(const char *filename);
64 int linenoiseHistoryLoad(const char *filename);
65 void linenoiseClearScreen(void);
66

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button