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

PATCH: even better history-search-{for,back}ward for 3.1.4



"Bart Schaefer" writes:
> Unfortunately, this doesn't work right.

Yeah, that code didn't save enough state.  I've appended a new
patch that does a better job.

> You can do a little better if you also save `hl' and reset the
> search if `histline' differs from the last time through, but
> that's still not quite right.

Cool -- I had the same idea, plus I also decided to save cs and the
search prefix, which allows the code to do a much better job at
figuring out when to start a new search.  It is still possible to
fool it into continuing the last search when the old code would have
started a new one, but it does behave much more like the code in
3.0.5 now.

A known deficiency is that if you use uplineorsearch and pass
through a multi-line history entry, the code will start a new
search, which may not be what you want (if it was searching for
a prefix and not a command name).  This should be easy enough
to fix, though.

> zsh% ech<M-p>
> zsh% echo this is a test<C-p>
> zsh% fc -R historytest<M-p>

I find it humorous that my old code did the right thing in this case
but for the wrong reason.  The new code will still search for "fc ",
but because it properly decided to start a new search.

This patch assumes that you've removed the previous one.

..wayne..

---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
Index: zle_hist.c
@@ -369,55 +369,69 @@
 	feep();
 }
 
+static int histpos, srch_hl, srch_cs = -1;
+static char *srch_str;
+
 /**/
 void
 historysearchbackward(void)
 {
-    int histpos, histmpos, hl = histline;
+    int hl = histline;
     char *s;
 
-    for (histpos = histmpos = 0; histpos < ll && !iblank(line[histpos]);
-	histpos++, histmpos++)
-	if(imeta(line[histpos]))
-	    histmpos++;
+    if (hl == curhist || hl != srch_hl || cs != srch_cs || mark != 0
+     || memcmp(srch_str, line, histpos) != 0) {
+	zfree(srch_str, histpos);
+	for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ;
+	if (histpos < ll)
+	    histpos++;
+	srch_str = zalloc(histpos);
+	memcpy(srch_str, line, histpos);
+    }
     for (;;) {
 	hl--;
 	if (!(s = zle_get_event(hl))) {
 	    feep();
 	    return;
 	}
-	if (metadiffer(s, (char *) line, histpos) < 0 &&
-	    iblank(s[histmpos] == Meta ? s[histmpos+1]^32 : s[histmpos]) &&
-	    metadiffer(s, (char *) line, ll))
+	if (metadiffer(s, srch_str, histpos) < 0 &&
+	    metadiffer(s, srch_str, ll))
 	    break;
     }
     zle_goto_hist(hl);
+    srch_hl = hl;
+    srch_cs = cs;
 }
 
 /**/
 void
 historysearchforward(void)
 {
-    int histpos, histmpos, hl = histline;
+    int hl = histline;
     char *s;
 
-    for (histpos = histmpos = 0; histpos < ll && !iblank(line[histpos]);
-	histpos++, histmpos++)
-	if(imeta(line[histpos]))
-	    histmpos++;
+    if (hl == curhist || hl != srch_hl || cs != srch_cs || mark != 0
+     || memcmp(srch_str, line, histpos) != 0) {
+	zfree(srch_str, histpos);
+	for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ;
+	if (histpos < ll)
+	    histpos++;
+	srch_str = zalloc(histpos);
+	memcpy(srch_str, line, histpos);
+    }
     for (;;) {
 	hl++;
 	if (!(s = zle_get_event(hl))) {
 	    feep();
 	    return;
 	}
-	if (metadiffer(s, (char *) line, histpos) < (histline == curhist) &&
-	    (!s[histmpos] ||
-	     iblank(s[histmpos] == Meta ? s[histmpos+1]^32 : s[histmpos])) &&
-	    metadiffer(s, (char *) line, ll))
+	if (metadiffer(s, srch_str, histpos) < (hl == curhist) &&
+	    metadiffer(s, srch_str, ll))
 	    break;
     }
     zle_goto_hist(hl);
+    srch_hl = hl;
+    srch_cs = cs;
 }
 
 /**/
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---



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