From 0c407935140531f4c6417faec8e7de3b2cccb619 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Mon, 21 Jan 2019 17:17:52 -0500 Subject: Save cash history incrementally Still needs better error and edge case handling, but seems to work. --- bin/cash/histedit.c | 53 ++++++++++++++++++++++++++++++++++++++++++----------- bin/cash/var.c | 13 ++++++++++--- bin/cash/var.h | 2 ++ 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/bin/cash/histedit.c b/bin/cash/histedit.c index 156800a1..08339a00 100644 --- a/bin/cash/histedit.c +++ b/bin/cash/histedit.c @@ -68,6 +68,10 @@ History *hist; /* history cookie */ EditLine *el; /* editline cookie */ int displayhist; static FILE *el_in, *el_out, *el_err; +static HistEvent he_saved; + +static void history_load(const char *hf); +static void history_save(const char *hf); static char *fc_replace(const char *, char *, char *); static int not_fcnumber(const char *); @@ -92,9 +96,10 @@ histedit(void) hist = history_init(); INTON; - if (hist != NULL) + if (hist != NULL) { sethistsize(histsizeval()); - else + sethistfile(histfileval()); + } else out2fmt_flush("sh: can't initialize history\n"); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ @@ -146,19 +151,14 @@ bad: el_source(el, NULL); } } else { - HistEvent he; - const char *hf; - INTOFF; if (el) { /* no editing if not interactive */ el_end(el); el = NULL; } if (hist) { - hf = lookupvar("HISTFILE"); - if (hf != NULL && *hf != '\0') - if (history(hist, &he, H_SAVE, hf) == -1) - out2fmt_flush("sh: can't save history\n"); + if (*histfileval() != '\0') + history_save(histfileval()); history_end(hist); hist = NULL; } @@ -170,12 +170,43 @@ bad: void sethistfile(const char *hf) { + if (hist != NULL && hf != NULL && *hf != '\0') + history_load(hf); +} + + +static void +history_load(const char *hf) { HistEvent he; + const char *ehf; - if (hist != NULL && hf != NULL && *hf != '\0') - history(hist, &he, H_LOAD, hf); + ehf = expandstr(hf); + if (ehf == NULL) + return; + if (history(hist, &he, H_LOAD, ehf) == -1) + warning("%s: %s", he.str, ehf); + else + history(hist, &he_saved, H_FIRST); +} + + +static void +history_save(const char *hf) { + HistEvent he; + const char *ehf; + + ehf = expandstr(hf); + if (ehf == NULL) + return; + if (he_saved.num == 0) + history(hist, &he_saved, H_LAST); + else + history(hist, &he_saved, H_NEXT_EVENT, he_saved.num + 1); + if (history(hist, &he, H_SAVE_INCR, ehf, he_saved.num) == -1) + warning("%s: %s", he.str, ehf); } + void sethistsize(const char *hs) { diff --git a/bin/cash/var.c b/bin/cash/var.c index 26c39eb4..70e05385 100644 --- a/bin/cash/var.c +++ b/bin/cash/var.c @@ -108,10 +108,17 @@ struct localvar *localvars; int forcelocal; static const struct varinit varinit[] = { - { &venv, 0, "ENV=${XDG_CONFIG_HOME:-${HOME}/.config}/cash/env.sh", NULL }, + { + &venv, 0, + "ENV=${XDG_CONFIG_HOME:-${HOME}/.config}/cash/env.sh", + NULL, + }, #ifndef NO_HISTORY - { &vhistfile, VUNSET, "HISTFILE=", - sethistfile }, + { + &vhistfile, 0, + "HISTFILE=${XDG_DATA_HOME:-${HOME}/.local/share}/cash/history", + sethistfile, + }, { &vhistsize, VUNSET, "HISTSIZE=", sethistsize }, #endif diff --git a/bin/cash/var.h b/bin/cash/var.h index 31f9dcc7..1e6420fd 100644 --- a/bin/cash/var.h +++ b/bin/cash/var.h @@ -85,6 +85,7 @@ extern struct var vrps1; extern struct var vrps2; extern struct var vdisvfork; #ifndef NO_HISTORY +extern struct var vhistfile; extern struct var vhistsize; extern struct var vterm; #endif @@ -112,6 +113,7 @@ extern int initial_localeisutf8; #define rps2val() (vrps2.text + 5) #define optindval() (voptind.text + 7) #ifndef NO_HISTORY +#define histfileval() (vhistfile.text + 9) #define histsizeval() (vhistsize.text + 9) #define termval() (vterm.text + 5) #endif -- cgit 1.4.1