about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2013-10-17 10:14:25 +0100
committerPeter Stephenson <pws@zsh.org>2013-10-17 10:14:25 +0100
commit73ececfd01bc137366d25940d90a34aaa2cdb02e (patch)
treedb9a9969a06a81fe1efafa38829e6e1a44f5eddc
parenta8f736b4cf8d186af4aea6f48ae7a5335d9ad8bb (diff)
downloadzsh-73ececfd01bc137366d25940d90a34aaa2cdb02e.tar.gz
zsh-73ececfd01bc137366d25940d90a34aaa2cdb02e.tar.xz
zsh-73ececfd01bc137366d25940d90a34aaa2cdb02e.zip
31830: New feature for zshaddhistory hooks.
If the first non-zero return status is 2, save the line on the
internal history list, but don't write it out.
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/func.yo13
-rw-r--r--README11
-rw-r--r--Src/hist.c25
-rw-r--r--Src/zsh.h1
5 files changed, 49 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 5f9adbc59..0493ab5ec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-10-17  Peter Stephenson  <p.stephenson@samsung.com>
+
+	* 31830: Doc/Zsh/func.yo, README, Src/hist.c, Src/zsh.h:
+	If a zshaddhistory hook returns status 2, save the line on
+	the internal history but don't write it out.
+
 2013-10-16  Peter Stephenson  <p.w.stephenson@ntlworld.com>
 
 	* Users/18033: Doc/Zsh/builtins.yo, Doc/Zsh/jobs.yo,
diff --git a/Doc/Zsh/func.yo b/Doc/Zsh/func.yo
index 1f58df86a..6e9cfeee9 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 2a22f42df..8ddad6e4e 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 ed9560952..fa5bdbb3c 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 a46898d7d..a935d23ad 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