summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-01-21 17:17:52 -0500
committerJune McEnroe <june@causal.agency>2019-01-21 17:17:52 -0500
commit40fb6999f72894c2dee95908b4d4160a63d98306 (patch)
tree0b8e1fc2ae70bb9879b194d5ce22ed6f4d9f7628
parentRemove pingbot (diff)
downloadsrc-40fb6999f72894c2dee95908b4d4160a63d98306.tar.gz
src-40fb6999f72894c2dee95908b4d4160a63d98306.zip
Save cash history incrementally
Still needs better error and edge case handling, but seems to work.
Diffstat (limited to '')
-rw-r--r--bin/cash/histedit.c53
-rw-r--r--bin/cash/var.c13
-rw-r--r--bin/cash/var.h2
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