zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.stephenson@samsung.com>
To: zsh-workers@zsh.org
Subject: Re: Finer control over what gets written to the history file
Date: Wed, 16 Oct 2013 11:04:12 +0100	[thread overview]
Message-ID: <20131016110412.7a14d25e@pwslap01u.europe.root.pri> (raw)
In-Reply-To: <20131016095524.1340a535@pwslap01u.europe.root.pri>

On Wed, 16 Oct 2013 09:55:24 +0100
Peter Stephenson <p.stephenson@samsung.com> wrote:
> We could unify the approaches and add a flag for this to histent (we've
> got plenty of spare bits at the moment).  So e.g. zshaddhistory could
> return 2 to say "keep this internally but don't save it".  I haven't
> looked, but it shouldn't be too hard to combine with the HIST_FOREIGN
> and HIST_TMPSTORE logic.

It turns out this is indeed extremely easy, even if it doesn't solve
Bart's problem without an extra measure of clairvoyance.  So there might
be some merit in having it available.

I'm guessing that anyone already using this mechanism would naturally
return status 1, so making 2 special isn't a big incompatibility, but
I've noted it anyway.

diff --git a/Doc/Zsh/func.yo b/Doc/Zsh/func.yo
index 1f58df8..6e9cfee 100644
--- a/Doc/Zsh/func.yo
+++ b/Doc/Zsh/func.yo
@@ -264,9 +264,16 @@ Executed when a history line has been read interactively, but
 before it is executed.  The sole argument is the complete history
 line (so that any terminating newline will still be present).
 
-If any of the hook functions return a non-zero value the history
-line will not be saved, although it lingers in the history until the
-next line is executed, allowing you to reuse or edit it immediately.
+If any of the hook functions returns status 1 (or any non-zero value
+other than 2, though this is not guaranteed for future versions of the
+shell) the history line will not be saved, although it lingers in the
+history until the next line is executed, allowing you to reuse or edit
+it immediately.
+
+If any of the hook functions returns status 2 the history line
+will be saved on the internal history list, but not written to
+the history file.  In case of a conflict, the first non-zero status
+value is taken.
 
 A hook function may call `tt(fc -p) var(...)' to switch the history
 context so that the history is saved in a different file from the
diff --git a/README b/README
index 2a22f42..8ddad6e 100644
--- a/README
+++ b/README
@@ -28,6 +28,17 @@ Zsh is a shell with lots of features.  For a list of some of these, see the
 file FEATURES, and for the latest changes see NEWS.  For more
 details, see the documentation.
 
+Incompatibilities between 5.0.2 and 5.0.3
+-----------------------------------------
+
+The "zshaddhistory" hook mechanism documented in the zshmisc manual page
+has been upgraded so that a hook returning status 2 causes a history
+line to be saved on the internal history list but not written to the
+history file.  Previously any non-zero status return would cause
+the line not to be saved on the history at all.  It is recommended
+to use status 1 for this (indeed most shell users would naturally do
+so).
+
 Incompatibilities between 5.0.0 and 5.0.2
 -----------------------------------------
 
diff --git a/Src/hist.c b/Src/hist.c
index ed95609..fa5bdbb 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -1226,7 +1226,15 @@ mod_export int
 hend(Eprog prog)
 {
     LinkList hookargs = newlinklist();
-    int flag, save = 1, hookret, stack_pos = histsave_stack_pos;
+    int flag, hookret, stack_pos = histsave_stack_pos;
+    /*
+     * save:
+     * 0: don't save
+     * 1: save normally
+     * -1: save temporarily, delete after next line
+     * -2: save internally but mark for not writing
+     */
+    int save = 1;
     char *hf;
 
     DPUTS(stophist != 2 && !(inbufflags & INP_ALIAS) && !chline,
@@ -1279,7 +1287,11 @@ hend(Eprog prog)
 	}
 	if (chwordpos <= 2)
 	    save = 0;
-	else if (hookret || should_ignore_line(prog))
+	else if (should_ignore_line(prog))
+	    save = -1;
+	else if (hookret == 2)
+	    save = -2;
+	else if (hookret)
 	    save = -1;
     }
     if (flag & (HISTFLAG_DONE | HISTFLAG_RECALL)) {
@@ -1325,7 +1337,12 @@ hend(Eprog prog)
 	    if (isset(HISTREDUCEBLANKS))
 		histreduceblanks();
 	}
-	newflags = save > 0? 0 : HIST_TMPSTORE;
+	if (save == -1)
+	    newflags = HIST_TMPSTORE;
+	else if (save == -2)
+	    newflags = HIST_NOWRITE;
+	else
+	    newflags = 0;
 	if ((isset(HISTIGNOREDUPS) || isset(HISTIGNOREALLDUPS)) && save > 0
 	 && hist_ring && histstrcmp(chline, hist_ring->node.nam) == 0) {
 	    /* This history entry compares the same as the previous.
@@ -2590,7 +2607,7 @@ savehistfile(char *fn, int err, int writeflags)
 	     || he->node.flags & HIST_TMPSTORE)
 		continue;
 	    if (writeflags & HFILE_SKIPOLD) {
-		if (he->node.flags & HIST_OLD)
+		if (he->node.flags & (HIST_OLD|HIST_NOWRITE))
 		    continue;
 		he->node.flags |= HIST_OLD;
 		if (writeflags & HFILE_USE_OPTIONS)
diff --git a/Src/zsh.h b/Src/zsh.h
index a46898d..a935d23 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1894,6 +1894,7 @@ struct histent {
 #define HIST_DUP	0x00000008	/* Command duplicates a later line */
 #define HIST_FOREIGN	0x00000010	/* Command came from another shell */
 #define HIST_TMPSTORE	0x00000020	/* Kill when user enters another cmd */
+#define HIST_NOWRITE	0x00000040	/* Keep internally but don't write */
 
 #define GETHIST_UPWARD  (-1)
 #define GETHIST_DOWNWARD  1

pws


  parent reply	other threads:[~2013-10-16 10:04 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-15 16:41 Bart Schaefer
2013-10-15 16:58 ` Peter Stephenson
2013-10-16  0:34   ` Bart Schaefer
2013-10-16  8:55     ` Peter Stephenson
2013-10-16  9:20       ` Peter Stephenson
2013-10-17 14:20         ` Bart Schaefer
2013-10-17 14:28           ` Peter Stephenson
2013-10-16 10:04       ` Peter Stephenson [this message]
2013-10-16  5:25   ` Bart Schaefer
2013-10-16  8:35     ` Peter Stephenson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20131016110412.7a14d25e@pwslap01u.europe.root.pri \
    --to=p.stephenson@samsung.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).