From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2743 invoked by alias); 15 Oct 2013 16:40:45 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 31823 Received: (qmail 25404 invoked from network); 15 Oct 2013 16:40:38 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 From: Bart Schaefer Message-id: <131015094100.ZM2399@torch.brasslantern.com> Date: Tue, 15 Oct 2013 09:41:00 -0700 X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-workers@zsh.org Subject: Finer control over what gets written to the history file MIME-version: 1.0 Content-type: text/plain; charset=us-ascii 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) continue; + if (histpat && + pattry(histpat, metafy(he->node.nam, -1, META_HEAPDUP))) { + continue; + } if (writeflags & HFILE_SKIPOLD) { if (he->node.flags & HIST_OLD) continue;