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

Re: zcalc bug



On Fri, May 14, 2004 at 10:23:45AM +0100, Peter Stephenson wrote:
> This would definitely be nice to have.

OK, I created an initial implementation of this today (it was pretty
easy, as I expected).  See if you like it.  It works in my limited
testing (i.e. a modified zcalc works quite nicely), but I may have
missed something.

> Do you think it's easy to keep the state of external files consistent
> while you do that?

I'm not sure what you mean by this.  My code isn't doing anything with
files, so the modified zcalc function still loads the .zcalc_history
file with "fc -R" and its restore function writes it out with "fc -W".
However, no fc calls are needed to save and restore the current history.

It would be possible to change my current, very simple pushhist/pophist
syntax to have pushhist optionally take some parameters to setup the new
history environment, for instance:

pushhist 200 100 ~/.zcalc_history

would be just like this shell code:

pushhist
HISTSIZE=200
SAVEHIST=100
HISTFILE=~/.zcalc_history
[[ -f $HISTFILE ]] && fc -R

And the pophist function could likewise be changed to work like this:

[[ ! -z $HISTFILE && $SAVEHIST > 0 ]] && fc -W
pophist

(Although maybe that should be "pophist -W" or something.)  However,
that may be overkill since it is so easy to code up those extra few
shell lines.

Appended is my patch.

..wayne..
--- Functions/Misc/zcalc	13 May 2004 17:08:31 -0000	1.10
+++ Functions/Misc/zcalc	14 May 2004 23:54:10 -0000
@@ -86,22 +86,16 @@
 emulate -L zsh
 setopt extendedglob
 
-# can't be local since required in EXIT trap
-zcalc_orighist=$HISTFILE
-local temphist=${TMPPREFIX}zcalc_hist.$$ SAVEHIST=$HISTSIZE
-HISTFILE=$temphist
-fc -W
-
-local HISTSIZE=0
-HISTSIZE=$SAVEHIST
+pushhist
+HISTSIZE=200
+SAVEHIST=100
 HISTFILE=~/.zcalc_history
 [[ -f $HISTFILE ]] && fc -R
 
 zcalc_restore() {
     unfunction zcalc_restore
     fc -W
-    HISTFILE=$zcalc_orighist
-    fc -R
+    pophist
 }
 trap zcalc_restore HUP INT QUIT EXIT
 
--- Src/builtin.c	23 Apr 2004 11:17:15 -0000	1.118
+++ Src/builtin.c	14 May 2004 23:54:11 -0000
@@ -100,9 +100,11 @@ static struct builtin builtins[] =
 #endif
 
     BUILTIN("popd", 0, bin_cd, 0, 1, BIN_POPD, NULL, NULL),
+    BUILTIN("pophist", 0, bin_histstack, 0, 1, BIN_POPHIST, NULL, NULL),
     BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "abcC:Df:ilmnNoOpPrRsu:z-", NULL),
     BUILTIN("printf", 0, bin_print, 1, -1, BIN_PRINTF, NULL, NULL),
     BUILTIN("pushd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_PUSHD, "sPL", NULL),
+    BUILTIN("pushhist", 0, bin_histstack, 0, 1, BIN_PUSHHIST, NULL, NULL),
     BUILTIN("pushln", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"),
     BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
     BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "nrl", NULL),
@@ -1448,6 +1450,20 @@ bin_fc(char *nam, char **argv, Options o
     return retval;
 }
 
+/**/
+int
+bin_histstack(char *nam, char **argv, Options ops, int func)
+{
+    /* pushhist/pophist is only permitted in interactive shells */
+    if (!interact) {
+	zwarnnam(nam, "not interactive shell", NULL, 0);
+	return 1;
+    }
+    if (func == BIN_PUSHHIST)
+	return pushhiststack();
+    return pophiststack();
+}
+
 /* History handling functions: these are called by ZLE, as well as  *
  * the actual builtins.  fcgetcomm() gets a history line, specified *
  * either by number or leading string.  fcsubs() performs a given   *
--- Src/hashtable.h	11 Sep 2003 07:00:08 -0000	1.4
+++ Src/hashtable.h	14 May 2004 23:54:12 -0000
@@ -59,6 +59,8 @@
 #define BIN_ENABLE   25
 #define BIN_PRINTF   26
 #define BIN_COMMAND  27
+#define BIN_PUSHHIST 28
+#define BIN_POPHIST  29
 
 /* These currently depend on being 0 and 1. */
 #define BIN_SETOPT    0
--- Src/hist.c	11 May 2004 21:45:36 -0000	1.48
+++ Src/hist.c	14 May 2004 23:54:13 -0000
@@ -30,6 +30,21 @@
 #include "zsh.mdh"
 #include "hist.pro"
 
+struct histsave {
+    char *histfile;
+    HashTable histtab;
+    Histent hist_ring;
+    int curhist;
+    int histlinect;
+    int histsiz;
+    int savehistsiz;
+};
+
+static struct histsave histsave_stack[5];
+static int histsave_stack_len = 0;
+#define MAX_HISTSAVE_PUSH (sizeof histsave_stack / sizeof histsave_stack[0])
+
+
 /* Functions to call for getting/ungetting a character and for history
  * word control. */
 
@@ -2329,3 +2344,72 @@ bufferwords(LinkList list, char *buf, in
 
     return list;
 }
+
+/**/
+int
+pushhiststack(void)
+{
+    struct histsave *h;
+    int curline_in_ring = hist_ring == &curline;
+
+    if (histsave_stack_len == MAX_HISTSAVE_PUSH)
+	return 1;
+
+    if (curline_in_ring)
+	unlinkcurline();
+
+    h = &histsave_stack[histsave_stack_len++];
+
+    h->histfile = ztrdup(getsparam("HISTFILE"));
+    h->histtab = histtab;
+    h->hist_ring = hist_ring;
+    h->curhist = curhist;
+    h->histlinect = histlinect;
+    h->histsiz = histsiz;
+    h->savehistsiz = savehistsiz;
+
+    unsetparam("HISTFILE");
+    histtab = NULL;
+    hist_ring = NULL;
+    curhist = 0;
+    histlinect = 0;
+    histsiz = DEFAULT_HISTSIZE;
+    savehistsiz = 0;
+
+    inithist();
+    if (curline_in_ring)
+	linkcurline();
+
+    return 0;
+}
+
+
+/**/
+int
+pophiststack(void)
+{
+    struct histsave *h;
+    int curline_in_ring = hist_ring == &curline;
+
+    if (histsave_stack_len == 0)
+	return 1;
+
+    if (curline_in_ring)
+	unlinkcurline();
+    deletehashtable(histtab);
+
+    h = &histsave_stack[--histsave_stack_len];
+
+    setsparam("HISTFILE", h->histfile);
+    histtab = h->histtab;
+    hist_ring = h->hist_ring;
+    curhist = h->curhist;
+    histlinect = h->histlinect;
+    histsiz = h->histsiz;
+    savehistsiz = h->savehistsiz;
+
+    if (curline_in_ring)
+	linkcurline();
+
+    return 0;
+}


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