Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Update linenoise to the latest version
Baptiste Daroussin committed 6 years ago
commit 1e5846f59081ea129889ba8e1685643486f580c2
parent ec7dd7e
2 files changed +121 -22
modified external/linenoise/linenoise.c
@@ -1,7 +1,5 @@
-
/* linenoise.c -- VERSION 1.0
-
 *
-
 * Guerrilla line editing library against the idea that a line editing lib
-
 * needs to be 20,000 lines of C code.
+
/* linenoise.c -- guerrilla line editing library against the idea that a
+
 * line editing lib needs to be 20,000 lines of C code.
 *
 * You can find the latest source code at:
 *
@@ -12,7 +10,7 @@
 *
 * ------------------------------------------------------------------------
 *
-
 * Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com>
+
 * Copyright (c) 2010-2016, Salvatore Sanfilippo <antirez at gmail dot com>
 * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
 *
 * All rights reserved.
@@ -113,6 +111,7 @@
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
+
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
@@ -122,6 +121,8 @@
#define LINENOISE_MAX_LINE 4096
static char *unsupported_term[] = {"dumb","cons25","emacs",NULL};
static linenoiseCompletionCallback *completionCallback = NULL;
+
static linenoiseHintsCallback *hintsCallback = NULL;
+
static linenoiseFreeHintsCallback *freeHintsCallback = NULL;

static struct termios orig_termios; /* In order to restore at exit.*/
static int rawmode = 0; /* For atexit() function to check if restore is needed*/
@@ -409,6 +410,18 @@ void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
    completionCallback = fn;
}

+
/* Register a hits function to be called to show hits to the user at the
+
 * right of the prompt. */
+
void linenoiseSetHintsCallback(linenoiseHintsCallback *fn) {
+
    hintsCallback = fn;
+
}
+

+
/* Register a function to free the hints returned by the hints callback
+
 * registered with linenoiseSetHintsCallback(). */
+
void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *fn) {
+
    freeHintsCallback = fn;
+
}
+

/* This function is used by the callback function registered by the user
 * in order to add completion options given the input string when the
 * user typed <tab>. See the example.c source code for a very easy to
@@ -458,6 +471,32 @@ static void abFree(struct abuf *ab) {
    free(ab->b);
}

+
/* Helper of refreshSingleLine() and refreshMultiLine() to show hints
+
 * to the right of the prompt. */
+
void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) {
+
    char seq[64];
+
    if (hintsCallback && plen+l->len < l->cols) {
+
        int color = -1, bold = 0;
+
        char *hint = hintsCallback(l->buf,&color,&bold);
+
        if (hint) {
+
            int hintlen = strlen(hint);
+
            int hintmaxlen = l->cols-(plen+l->len);
+
            if (hintlen > hintmaxlen) hintlen = hintmaxlen;
+
            if (bold == 1 && color == -1) color = 37;
+
            if (color != -1 || bold != 0)
+
                snprintf(seq,64,"\033[%d;%d;49m",bold,color);
+
            else
+
                seq[0] = '\0';
+
            abAppend(ab,seq,strlen(seq));
+
            abAppend(ab,hint,hintlen);
+
            if (color != -1 || bold != 0)
+
                abAppend(ab,"\033[0m",4);
+
            /* Call the function to free the hint returned. */
+
            if (freeHintsCallback) freeHintsCallback(hint);
+
        }
+
    }
+
}
+

/* Single line low level line refresh.
 *
 * Rewrite the currently edited line accordingly to the buffer content,
@@ -487,6 +526,8 @@ static void refreshSingleLine(struct linenoiseState *l) {
    /* Write the prompt and the current buffer content */
    abAppend(&ab,l->prompt,strlen(l->prompt));
    abAppend(&ab,buf,len);
+
    /* Show hits if any. */
+
    refreshShowHints(&ab,l,plen);
    /* Erase to right */
    snprintf(seq,64,"\x1b[0K");
    abAppend(&ab,seq,strlen(seq));
@@ -540,6 +581,9 @@ static void refreshMultiLine(struct linenoiseState *l) {
    abAppend(&ab,l->prompt,strlen(l->prompt));
    abAppend(&ab,l->buf,l->len);

+
    /* Show hits if any. */
+
    refreshShowHints(&ab,l,plen);
+

    /* If we are at the very end of the screen with our prompt, we need to
     * emit a newline and move the prompt to the first column. */
    if (l->pos &&
@@ -600,7 +644,7 @@ int linenoiseEditInsert(struct linenoiseState *l, char c) {
            l->pos++;
            l->len++;
            l->buf[l->len] = '\0';
-
            if ((!mlmode && l->plen+l->len < l->cols) /* || mlmode */) {
+
            if ((!mlmode && l->plen+l->len < l->cols && !hintsCallback)) {
                /* Avoid a full update of the line in the
                 * trivial case. */
                if (write(l->ofd,&c,1) == -1) return -1;
@@ -774,6 +818,14 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
            history_len--;
            free(history[history_len]);
            if (mlmode) linenoiseEditMoveEnd(&l);
+
            if (hintsCallback) {
+
                /* Force a refresh without hints to leave the previous
+
                 * line as the user typed it after a newline. */
+
                linenoiseHintsCallback *hc = hintsCallback;
+
                hintsCallback = NULL;
+
                refreshLine(&l);
+
                hintsCallback = hc;
+
            }
            return (int)l.len;
        case CTRL_C:     /* ctrl-c */
            errno = EAGAIN;
@@ -936,22 +988,48 @@ static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) {
        errno = EINVAL;
        return -1;
    }
-
    if (!isatty(STDIN_FILENO)) {
-
        /* Not a tty: read from file / pipe. */
-
        if (fgets(buf, buflen, stdin) == NULL) return -1;
-
        count = strlen(buf);
-
        if (count && buf[count-1] == '\n') {
-
            count--;
-
            buf[count] = '\0';
+

+
    if (enableRawMode(STDIN_FILENO) == -1) return -1;
+
    count = linenoiseEdit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt);
+
    disableRawMode(STDIN_FILENO);
+
    printf("\n");
+
    return count;
+
}
+

+
/* This function is called when linenoise() is called with the standard
+
 * input file descriptor not attached to a TTY. So for example when the
+
 * program using linenoise is called in pipe or with a file redirected
+
 * to its standard input. In this case, we want to be able to return the
+
 * line regardless of its length (by default we are limited to 4k). */
+
static char *linenoiseNoTTY(void) {
+
    char *line = NULL;
+
    size_t len = 0, maxlen = 0;
+

+
    while(1) {
+
        if (len == maxlen) {
+
            if (maxlen == 0) maxlen = 16;
+
            maxlen *= 2;
+
            char *oldval = line;
+
            line = realloc(line,maxlen);
+
            if (line == NULL) {
+
                if (oldval) free(oldval);
+
                return NULL;
+
            }
+
        }
+
        int c = fgetc(stdin);
+
        if (c == EOF || c == '\n') {
+
            if (c == EOF && len == 0) {
+
                free(line);
+
                return NULL;
+
            } else {
+
                line[len] = '\0';
+
                return line;
+
            }
+
        } else {
+
            line[len] = c;
+
            len++;
        }
-
    } else {
-
        /* Interactive editing. */
-
        if (enableRawMode(STDIN_FILENO) == -1) return -1;
-
        count = linenoiseEdit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt);
-
        disableRawMode(STDIN_FILENO);
-
        printf("\n");
    }
-
    return count;
}

/* The high level function that is the main API of the linenoise library.
@@ -963,7 +1041,11 @@ char *linenoise(const char *prompt) {
    char buf[LINENOISE_MAX_LINE];
    int count;

-
    if (isUnsupportedTerm()) {
+
    if (!isatty(STDIN_FILENO)) {
+
        /* Not a tty: read from file / pipe. In this mode we don't want any
+
         * limit to the line size, so we call a function to handle that. */
+
        return linenoiseNoTTY();
+
    } else if (isUnsupportedTerm()) {
        size_t len;

        printf("%s",prompt);
@@ -982,6 +1064,14 @@ char *linenoise(const char *prompt) {
    }
}

+
/* This is just a wrapper the user may want to call in order to make sure
+
 * the linenoise returned buffer is freed with the same allocator it was
+
 * created with. Useful when the main program is using an alternative
+
 * allocator. */
+
void linenoiseFree(void *ptr) {
+
    free(ptr);
+
}
+

/* ================================ History ================================= */

/* Free the history, but does not reset it. Only used when we have to
@@ -1073,10 +1163,14 @@ int linenoiseHistorySetMaxLen(int len) {
/* Save the history in the specified file. On success 0 is returned
 * otherwise -1 is returned. */
int linenoiseHistorySave(const char *filename) {
-
    FILE *fp = fopen(filename,"w");
+
    mode_t old_umask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
+
    FILE *fp;
    int j;

+
    fp = fopen(filename,"w");
+
    umask(old_umask);
    if (fp == NULL) return -1;
+
    chmod(filename,S_IRUSR|S_IWUSR);
    for (j = 0; j < history_len; j++)
        fprintf(fp,"%s\n",history[j]);
    fclose(fp);
modified external/linenoise/linenoise.h
@@ -49,10 +49,15 @@ typedef struct linenoiseCompletions {
} linenoiseCompletions;

typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
+
typedef char*(linenoiseHintsCallback)(const char *, int *color, int *bold);
+
typedef void(linenoiseFreeHintsCallback)(void *);
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
+
void linenoiseSetHintsCallback(linenoiseHintsCallback *);
+
void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *);
void linenoiseAddCompletion(linenoiseCompletions *, const char *);

char *linenoise(const char *prompt);
+
void linenoiseFree(void *ptr);
int linenoiseHistoryAdd(const char *line);
int linenoiseHistorySetMaxLen(int len);
int linenoiseHistorySave(const char *filename);