From 99628c1af8ab2a2af4f2baf7039c08acdf0974ce Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 7 Jul 2010 18:44:53 +0200 Subject: [PATCH] redis-cli history saved across sessions --- src/linenoise.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ src/linenoise.h | 4 +++- src/redis-cli.c | 9 +++++++++ 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/linenoise.c b/src/linenoise.c index 0c04d03f..b7c6b732 100644 --- a/src/linenoise.c +++ b/src/linenoise.c @@ -69,7 +69,6 @@ * */ -#include "fmacros.h" #include #include #include @@ -81,13 +80,14 @@ #include #include +#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100 #define LINENOISE_MAX_LINE 4096 static char *unsupported_term[] = {"dumb","cons25",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*/ static int atexit_registered = 0; /* register atexit just 1 time */ -static int history_max_len = 100; +static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN; static int history_len = 0; char **history = NULL; @@ -219,11 +219,10 @@ static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt) if (nread <= 0) return len; switch(c) { case 13: /* enter */ - history_len--; - return len; case 4: /* ctrl-d */ history_len--; - return (len == 0) ? -1 : (int)len; + free(history[history_len]); + return (len == 0 && c == 4) ? -1 : (int)len; case 3: /* ctrl-c */ errno = EAGAIN; return -1; @@ -396,7 +395,7 @@ int linenoiseHistoryAdd(const char *line) { char *linecopy; if (history_max_len == 0) return 0; - if (history == 0) { + if (history == NULL) { history = malloc(sizeof(char*)*history_max_len); if (history == NULL) return 0; memset(history,0,(sizeof(char*)*history_max_len)); @@ -404,6 +403,7 @@ int linenoiseHistoryAdd(const char *line) { linecopy = strdup(line); if (!linecopy) return 0; if (history_len == history_max_len) { + free(history[0]); memmove(history,history+1,sizeof(char*)*(history_max_len-1)); history_len--; } @@ -431,3 +431,39 @@ int linenoiseHistorySetMaxLen(int len) { history_len = history_max_len; return 1; } + +/* Save the history in the specified file. On success 0 is returned + * otherwise -1 is returned. */ +int linenoiseHistorySave(char *filename) { + FILE *fp = fopen(filename,"w"); + int j; + + if (fp == NULL) return -1; + for (j = 0; j < history_len; j++) + fprintf(fp,"%s\n",history[j]); + fclose(fp); + return 0; +} + +/* Load the history from the specified file. If the file does not exist + * zero is returned and no operation is performed. + * + * If the file exists and the operation succeeded 0 is returned, otherwise + * on error -1 is returned. */ +int linenoiseHistoryLoad(char *filename) { + FILE *fp = fopen(filename,"r"); + char buf[LINENOISE_MAX_LINE]; + + if (fp == NULL) return -1; + + while (fgets(buf,LINENOISE_MAX_LINE,fp) != NULL) { + char *p; + + p = strchr(buf,'\r'); + if (!p) p = strchr(buf,'\n'); + if (p) *p = '\0'; + linenoiseHistoryAdd(buf); + } + fclose(fp); + return 0; +} diff --git a/src/linenoise.h b/src/linenoise.h index ff45e2c4..0d76aea9 100644 --- a/src/linenoise.h +++ b/src/linenoise.h @@ -35,7 +35,9 @@ #define __LINENOISE_H char *linenoise(const char *prompt); -int linenoiseHistoryAdd(char *line); +int linenoiseHistoryAdd(const char *line); int linenoiseHistorySetMaxLen(int len); +int linenoiseHistorySave(char *filename); +int linenoiseHistoryLoad(char *filename); #endif /* __LINENOISE_H */ diff --git a/src/redis-cli.c b/src/redis-cli.c index 1d00fb87..dac82862 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -61,6 +61,7 @@ static struct config { int pubsub_mode; int raw_output; char *auth; + char *historyfile; } config; static int cliReadReply(int fd); @@ -439,6 +440,7 @@ static void repl() { if (line[0] != '\0') { argv = splitArguments(line,&argc); linenoiseHistoryAdd(line); + if (config.historyfile) linenoiseHistorySave(config.historyfile); if (argc > 0) { if (strcasecmp(argv[0],"quit") == 0 || strcasecmp(argv[0],"exit") == 0) @@ -472,6 +474,13 @@ int main(int argc, char **argv) { config.pubsub_mode = 0; config.raw_output = 0; config.auth = NULL; + config.historyfile = NULL; + + if (getenv("HOME") != NULL) { + config.historyfile = malloc(256); + snprintf(config.historyfile,256,"%s/.rediscli_history",getenv("HOME")); + linenoiseHistoryLoad(config.historyfile); + } firstarg = parseOptions(argc,argv); argc -= firstarg; -- 2.45.2