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

Re: accept-and-infer-next-history is broken?



On Thu, 24 May 2001, Bart Schaefer wrote:
> infer-next-history is OK:
> But accept-and is not:

Actually they both appear to share the same bug, but it gets tickled by
where you are in the history.  Since accept-and-infer-next-history
leaves you up in the history list while just infer-next-history + CR
does not, you don't usually notice the bug with just infer-next-history
(unless you try to use it multiple times in a row).

So, I think that the proper solution is to modify the algorithm like
this:

  if (we have a line in the history below us
   && the current line is unchanged from the history version) {
      use the next line;
  else
      search from the bottom of the history for a match and infer;

This means that a-a-i-n-h works just like accept-line-and-down-history
after the first inferred line.  An alternate approach would be to just
always start the search from the bottom of the history.  Thoughts?

The attached patch implements my pseudo-code above.  It also unifies the
infer algorithm in a single support function.

Another change I made was to have the code ignore the transient edits in
the history list when it is searching for and storing the inferred line
(also affecting accept-line-and-down-history).  I've been bitten by
this before:  I've searched for a line I need, I decide to put a line I
encountered on the way into the kill ring with Ctrl-U, continued on to
find the real command I wanted to run, and then pressed Ctrl-O to use
accept-line-and-down-history.  If the line I deleted was actually next
in the history, I get an empty line as the inferred next history line,
not the actual next history line.

Finally, I changed the function to be like a-l-a-down-history in that it
does not set "done = 1" if the infer fails.

..wayne..
Index: Src/Zle/zle_hist.c
--- Src/Zle/zle_hist.c	2000/02/23 15:18:49	1.1.1.14
+++ Src/Zle/zle_hist.c	2001/05/25 20:42:36
@@ -252,7 +252,7 @@
 
     if (!(he = movehistent(quietgethist(histline), 1, HIST_FOREIGN)))
 	return 1;
-    zpushnode(bufstack, ztrdup(ZLETEXT(he)));
+    zpushnode(bufstack, ztrdup(he->text));
     done = 1;
     stackhist = he->histnum;
     return 0;
@@ -891,23 +891,36 @@
 	kungetct = savekeys;
 }
 
+static Histent
+infernexthist(char **args)
+{
+    Histent he;
+
+    if (!(he = quietgethist(histline)))
+	return NULL;
+    if (!metadiffer(he->text, (char *)line, ll)
+     && (he = movehistent(he, 1, HIST_FOREIGN)) != NULL)
+	return he;
+    for (he = movehistent(hist_ring, -2, HIST_FOREIGN);
+	 he; he = movehistent(he, -1, HIST_FOREIGN)) {
+	if (!metadiffer(he->text, (char *) line, ll))
+	    return movehistent(he, 1, HIST_FOREIGN);
+    }
+    return NULL;
+}
+
 /**/
 int
 acceptandinfernexthistory(char **args)
 {
     Histent he;
 
+    if (!(he = infernexthist(args)))
+	return 1;
+    zpushnode(bufstack, ztrdup(he->text));
     done = 1;
-    for (he = movehistent(quietgethist(histline), -2, HIST_FOREIGN);
-	 he; he = movehistent(he, -1, HIST_FOREIGN)) {
-	if (!metadiffer(ZLETEXT(he), (char *) line, ll)) {
-	    he = movehistent(he, 1, HIST_FOREIGN);
-	    zpushnode(bufstack, ztrdup(ZLETEXT(he)));
-	    stackhist = he->histnum;
-	    return 0;
-	}
-    }
-    return 1;
+    stackhist = he->histnum;
+    return 0;
 }
 
 /**/
@@ -916,15 +929,11 @@
 {
     Histent he;
 
-    for (he = movehistent(quietgethist(histline), -2, HIST_FOREIGN);
-	 he; he = movehistent(he, -1, HIST_FOREIGN)) {
-	if (!metadiffer(ZLETEXT(he), (char *) line, ll)) {
-	    he = movehistent(he, 1, HIST_FOREIGN);
-	    zle_setline(he);
-	    return 0;
-	}
-    }
-    return 1;
+    if (!(he = infernexthist(args)))
+	return 1;
+
+    zle_setline(he);
+    return 0;
 }
 
 /**/


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