Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Finer control over what gets written to the history file

I often find myself running a lot of similar but not quite identical
commands to test some obscure bug or otherwise experiment with a shell
construct.  This stuff tends to push useful history out of the history
file when I exit from the shell, if I don't remember to use my "die"
alias that disables history and other exit-time operations.

It'd be nice to be able to selectively exclude those from history after
the fact, also without having to remember to type a leading space on
every such line.

[[ ASIDE:  I'd always assumed that those useful history entries would be
salvaged by exiting from some other shell window later, but it turns out
that for some time now (I've lost track of exactly when) history saving
is optimized to only write the stuff that's new since the current shell
was started.  This means all the old stuff that I assumed was going to
be merged back into the history file is actually discarded instead, and
it means that if you change HISTFILE interactively you're likely to lose
a lot of your old history as well, unless you explicitly "fc -W". ]]

The following patch adds a HISTORY_IGNORE parameter, like CORRECT_IGNORE
except that it applies to writing lines into the history file.  I have
not written doc yet because I wanted to get this reviewed, particularly
for memory management -- I'm not sure whether using META_HEAPDUP here
means that a copy of the history is sometimes going to end up on the
top-level (and hence effectively "permanent") heap and thus be "leaked"
for practical purposes.  Maybe heap push/pop is needed?

Does anyone else think this is useful?  I considered instead applying it
at the point where HIST_IGNORE_DUPS is calculated, but that removes the
command from the runtime history which I usually don't want.

diff --git a/Src/hist.c b/Src/hist.c
index ed95609..46b488f 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -2583,12 +2583,25 @@ savehistfile(char *fn, int err, int writeflags)
     if (out) {
+	char *history_ignore;
+	Patprog histpat = NULL;
+	if ((history_ignore = getsparam("HISTORY_IGNORE")) != NULL) {
+	    tokenize(history_ignore = dupstring(history_ignore));
+	    remnulargs(history_ignore);
+	    histpat = patcompile(history_ignore, 0, NULL);
+	}
 	ret = 0;
 	for (; he && he->histnum <= xcurhist; he = down_histent(he)) {
 	    if ((writeflags & HFILE_SKIPDUPS && he->node.flags & HIST_DUP)
 	     || (writeflags & HFILE_SKIPFOREIGN && he->node.flags & HIST_FOREIGN)
 	     || he->node.flags & HIST_TMPSTORE)
+	    if (histpat &&
+		pattry(histpat, metafy(he->node.nam, -1, META_HEAPDUP))) {
+		continue;
+	    }
 	    if (writeflags & HFILE_SKIPOLD) {
 		if (he->node.flags & HIST_OLD)

Messages sorted by: Reverse Date, Date, Thread, Author