about summary refs log tree commit diff
path: root/Src/Zle/zle_hist.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/zle_hist.c')
-rw-r--r--Src/Zle/zle_hist.c318
1 files changed, 150 insertions, 168 deletions
diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c
index 0064d4ef0..d2b9a3233 100644
--- a/Src/Zle/zle_hist.c
+++ b/Src/Zle/zle_hist.c
@@ -47,27 +47,16 @@ int lastcol;
 /**/
 int histline;
 
-/* the last line in the history (the current one), metafied */
-
-/**/
-char *curhistline;
+#define ZLETEXT(X) ((X)->zle_text ? (X)->zle_text : (X)->text)
 
 /**/
 void
 remember_edits(void)
 {
-    if (histline == curhist) {
-	zsfree(curhistline);
-	curhistline = metafy((char *) line, ll, META_DUP);
-    }
-    else {
-	Histent ent = gethistent(histline);
-
-	if (metadiffer(ent->zle_text ? ent->zle_text : ent->text,
-		       (char *) line, ll)) {
-	    zsfree(ent->zle_text);
-	    ent->zle_text = metafy((char *) line, ll, META_DUP);
-	}
+    Histent ent = quietgethist(histline);
+    if (metadiffer(ZLETEXT(ent), (char *) line, ll)) {
+	zsfree(ent->zle_text);
+	ent->zle_text = metafy((char *) line, ll, META_DUP);
     }
 }
 
@@ -75,11 +64,11 @@ remember_edits(void)
 void
 forget_edits(void)
 {
-    int i;
+    Histent he;
 
-    for (i = 0; i < histentct; i++) {
-	zsfree(histentarr[i].zle_text);
-	histentarr[i].zle_text = NULL;
+    for (he = hist_ring; he; he = up_histent(he)) {
+	zsfree(he->zle_text);
+	he->zle_text = NULL;
     }
 }
 
@@ -87,16 +76,12 @@ forget_edits(void)
 void
 uphistory(void)
 {
-    if (zmult < 0) {
-	zmult = -zmult;
-	downhistory();
-	zmult = -zmult;
-    } else if(!zle_goto_hist(histline - zmult) && isset(HISTBEEP))
+    if (!zle_goto_hist(histline, -zmult) && isset(HISTBEEP))
 	feep();
 }
 
 /**/
-int
+static int
 upline(void)
 {
     int n = zmult;
@@ -159,7 +144,6 @@ viuplineorhistory(void)
     vifirstnonblank();
 }
 
-
 /**/
 void
 uplineorsearch(void)
@@ -181,7 +165,7 @@ uplineorsearch(void)
 }
 
 /**/
-int
+static int
 downline(void)
 {
     int n = zmult;
@@ -268,26 +252,22 @@ downlineorsearch(void)
 void
 acceptlineanddownhistory(void)
 {
-    char *s;
+    Histent he;
 
-    if (!(s = zle_get_event(histline + 1))) {
+    if (!(he = movehistent(quietgethist(histline), 1, HIST_FOREIGN))) {
 	feep();
 	return;
     }
-    pushnode(bufstack, ztrdup(s));
+    pushnode(bufstack, ztrdup(ZLETEXT(he)));
     done = 1;
-    stackhist = histline + 1;
+    stackhist = he->histnum;
 }
 
 /**/
 void
 downhistory(void)
 {
-    if (zmult < 0) {
-	zmult = -zmult;
-	uphistory();
-	zmult = -zmult;
-    } else if(!zle_goto_hist(histline + zmult) && isset(HISTBEEP))
+    if (!zle_goto_hist(histline, zmult) && isset(HISTBEEP))
 	feep();
 }
 
@@ -298,7 +278,7 @@ static char *srch_str;
 void
 historysearchbackward(void)
 {
-    int hl = histline;
+    Histent he;
     int n = zmult;
     char *s;
 
@@ -308,7 +288,7 @@ historysearchbackward(void)
 	zmult = n;
 	return;
     }
-    if (hl == curhist || hl != srch_hl || cs != srch_cs || mark != 0
+    if (histline == curhist || histline != 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++) ;
@@ -317,28 +297,29 @@ historysearchbackward(void)
 	srch_str = zalloc(histpos);
 	memcpy(srch_str, line, histpos);
     }
-    for (;;) {
-	hl--;
-	if (!(s = zle_get_event(hl))) {
-	    feep();
-	    return;
-	}
+    he = quietgethist(histline);
+    while ((he = movehistent(he, -1, hist_skip_flags))) {
+	if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
+	    continue;
+	s = ZLETEXT(he);
 	if (metadiffer(s, srch_str, histpos) < 0 &&
 	    metadiffer(s, srch_str, ll)) {
-	    if (--n <= 0)
-		break;
+	    if (--n <= 0) {
+		zle_setline(he);
+		srch_hl = histline;
+		srch_cs = cs;
+		return;
+	    }
 	}
     }
-    zle_goto_hist(hl);
-    srch_hl = hl;
-    srch_cs = cs;
+    feep();
 }
 
 /**/
 void
 historysearchforward(void)
 {
-    int hl = histline;
+    Histent he;
     int n = zmult;
     char *s;
 
@@ -348,7 +329,7 @@ historysearchforward(void)
 	zmult = n;
 	return;
     }
-    if (hl == curhist || hl != srch_hl || cs != srch_cs || mark != 0
+    if (histline == curhist || histline != 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++) ;
@@ -357,20 +338,22 @@ historysearchforward(void)
 	srch_str = zalloc(histpos);
 	memcpy(srch_str, line, histpos);
     }
-    for (;;) {
-	hl++;
-	if (!(s = zle_get_event(hl))) {
-	    feep();
-	    return;
+    he = quietgethist(histline);
+    while ((he = movehistent(he, 1, hist_skip_flags))) {
+	if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
+	    continue;
+	s = ZLETEXT(he);
+	if (metadiffer(s, srch_str, histpos) < (he->histnum == curhist) &&
+	    metadiffer(s, srch_str, ll)) {
+	    if (--n <= 0) {
+		zle_setline(he);
+		srch_hl = histline;
+		srch_cs = cs;
+		return;
+	    }
 	}
-	if (metadiffer(s, srch_str, histpos) < (hl == curhist) &&
-	    metadiffer(s, srch_str, ll))
-	    if (--n <= 0)
-		break;
     }
-    zle_goto_hist(hl);
-    srch_hl = hl;
-    srch_cs = cs;
+    feep();
 }
 
 /**/
@@ -387,7 +370,7 @@ beginningofbufferorhistory(void)
 void
 beginningofhistory(void)
 {
-    if (!zle_goto_hist(firsthist()) && isset(HISTBEEP))
+    if (!zle_goto_hist(firsthist(), 0) && isset(HISTBEEP))
 	feep();
 }
 
@@ -405,7 +388,7 @@ endofbufferorhistory(void)
 void
 endofhistory(void)
 {
-    zle_goto_hist(curhist);
+    zle_goto_hist(curhist, 0);
 }
 
 /**/
@@ -419,7 +402,7 @@ insertlastword(void)
 /* multiple calls will now search back through the history, pem */
     static char *lastinsert;
     static int lasthist, lastpos;
-    int evhist = curhist - 1, save;
+    int evhist = addhistnum(curhist, -1, HIST_FOREIGN), save;
 
     if (lastinsert) {
 	int lastlen = ztrlen(lastinsert);
@@ -428,7 +411,7 @@ insertlastword(void)
 	if (lastpos <= pos &&
 	    lastlen == pos - lastpos &&
 	    memcmp(lastinsert, (char *)&line[lastpos], lastlen) == 0) {
-	    evhist = --lasthist;
+	    evhist = addhistnum(lasthist, -1, HIST_FOREIGN);
 	    cs = lastpos;
 	    foredel(pos - cs);
 	}
@@ -464,41 +447,37 @@ insertlastword(void)
 }
 
 /**/
-char *
-qgetevent(int ev)
+void
+zle_setline(Histent he)
 {
-    return ((ev == curhist) ? curhistline : quietgetevent(ev));
+    remember_edits();
+    mkundoent();
+    histline = he->histnum;
+    setline(ZLETEXT(he));
+    setlastline();
+    clearlist = 1;
 }
 
 /**/
-char *
-zle_get_event(int ev)
+void
+setlocalhistory(void)
 {
-    Histent ent;
-
-    if (ev == curhist)
-	return curhistline;
-    if (! (ent = quietgethist(ev)))
-	return NULL;
-    if (ent->zle_text)
-	return ent->zle_text;
-    return ent->text;
+    if (zmod.flags & MOD_MULT) {
+	hist_skip_flags = zmult? HIST_FOREIGN : 0;
+    }
+    else {
+	hist_skip_flags ^= HIST_FOREIGN;
+    }
 }
 
 /**/
-static int
-zle_goto_hist(int ev)
+int
+zle_goto_hist(int ev, int n)
 {
-    char *t;
-
-    remember_edits();
-    if(!(t = zle_get_event(ev)))
+    Histent he = movehistent(quietgethist(ev), n, hist_skip_flags);
+    if (!he)
 	return 0;
-    mkundoent();
-    histline = ev;
-    setline(t);
-    setlastline();
-    clearlist = 1;
+    zle_setline(he);
     return 1;
 }
 
@@ -603,6 +582,7 @@ static struct isrch_spot {
 
 static int max_spot = 0;
 
+/**/
 #ifdef MODULE
 
 /**/
@@ -612,6 +592,7 @@ free_isrch_spots(void)
     zfree(isrch_spots, max_spot * sizeof(*isrch_spots));
 }
 
+/**/
 #endif /* MODULE */
 
 /**/
@@ -665,13 +646,15 @@ doisearch(int dir)
     char *okeymap = curkeymapname;
     static char *previous_search = NULL;
     static int previous_search_len = 0;
+    Histent he;
 
     clearlist = 1;
 
     strcpy(ibuf, ISEARCH_PROMPT);
     memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3);
     remember_edits();
-    s = zle_get_event(hl);
+    he = quietgethist(hl);
+    s = ZLETEXT(he);
     selectkeymap("main", 1);
     pos = metalen(s, cs);
     for (;;) {
@@ -705,15 +688,14 @@ doisearch(int dir)
 		if (!skip_line && ((sbuf[0] == '^') ?
 		    (t = metadiffer(s, sbuf + 1, sbptr - 1) < sens ? s : NULL) :
 		    (t = hstrnstr(s, pos, sbuf, sbptr, dir, sens)))) {
-		    zle_goto_hist(hl);
+		    zle_setline(he);
 		    pos = t - s;
 		    cs = ztrsub(t, s) + (dir == 1? sbptr - (sbuf[0]=='^') : 0);
 	    	    nomatch = 0;
 		    statusline = ibuf + NORM_PROMPT_POS;
 		    break;
 		}
-		hl += dir;
-		if (!(s = zle_get_event(hl))) {
+		if (!(he = movehistent(he, dir, hist_skip_flags))) {
 		    if (sbptr == (int)isrch_spots[top_spot-1].len
 		     && (isrch_spots[top_spot-1].flags & ISS_FAILING))
 			top_spot--;
@@ -723,13 +705,17 @@ doisearch(int dir)
 			feep();
 			nomatch = 1;
 		    }
-		    s = last_line;
+		    he = quietgethist(hl);
+		    s = ZLETEXT(he);
 		    skip_line = 0;
 		    statusline = ibuf;
 		    break;
 		}
+		hl = he->histnum;
+		s = ZLETEXT(he);
 		pos = dir == 1? 0 : strlen(s);
-		skip_line = !strcmp(last_line, s);
+		skip_line = isset(HISTFINDNODUPS)? !!(he->flags & HIST_DUP)
+						 : !strcmp(last_line, s);
 	    }
 	} else {
 	    top_spot = 0;
@@ -743,8 +729,9 @@ doisearch(int dir)
 	if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
 	    int i;
 	    get_isrch_spot(0, &hl, &pos, &i, &sbptr, &dir, &nomatch);
-	    s = zle_get_event(hl);
-	    zle_goto_hist(hl);
+	    he = quietgethist(hl);
+	    zle_setline(he);
+	    s = ZLETEXT(he);
 	    cs = i;
 	    break;
 	}
@@ -769,10 +756,11 @@ doisearch(int dir)
 		statusline = ibuf;
 		skip_pos = 1;
 	    }
-	    s = zle_get_event(hl);
+	    he = quietgethist(hl);
+	    s = ZLETEXT(he);
 	    if (nomatch || !sbptr || (sbptr == 1 && sbuf[0] == '^')) {
 		int i = cs;
-		zle_goto_hist(hl);
+		zle_setline(he);
 		cs = i;
 	    }
 	    memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3);
@@ -874,42 +862,35 @@ doisearch(int dir)
 void
 acceptandinfernexthistory(void)
 {
-    int t0;
-    char *s;
+    Histent he;
 
     done = 1;
-    for (t0 = histline - 2;; t0--) {
-	if (!(s = qgetevent(t0)))
+    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);
+	    pushnode(bufstack, ztrdup(ZLETEXT(he)));
+	    stackhist = he->histnum;
 	    return;
-	if (!metadiffer(s, (char *) line, ll))
-	    break;
+	}
     }
-    if (!(s = qgetevent(t0 + 1)))
-	return;
-    pushnode(bufstack, ztrdup(s));
-    stackhist = t0 + 1;
 }
 
 /**/
 void
 infernexthistory(void)
 {
-    int t0;
-    char *s;
+    Histent he;
 
-    for (t0 = histline - 2;; t0--) {
-	if (!(s = qgetevent(t0))) {
-	    feep();
+    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;
 	}
-	if (! metadiffer(s, (char *) line, ll))
-	    break;
     }
-    if (!(s = qgetevent(t0 + 1))) {
-	feep();
-	return;
-    }
-    zle_goto_hist(t0 + 1);
+    feep();
 }
 
 /**/
@@ -925,7 +906,7 @@ vifetchhistory(void)
 	    return;
 	}
     }
-    if (!zle_goto_hist((zmod.flags & MOD_MULT) ? zmult : curhist) &&
+    if (!zle_goto_hist((zmod.flags & MOD_MULT) ? zmult : curhist, 0) &&
 	isset(HISTBEEP))
 	feep();
 }
@@ -1041,7 +1022,8 @@ vihistorysearchbackward(void)
 void
 virepeatsearch(void)
 {
-    int hl = histline, t0;
+    Histent he;
+    int t0;
     int n = zmult;
     char *s;
 
@@ -1054,23 +1036,21 @@ virepeatsearch(void)
 	visrchsense = -visrchsense;
     }
     t0 = strlen(visrchstr);
-    for (;;) {
-	hl += visrchsense;
-	if (!(s = zle_get_event(hl))) {
-	    feep();
-	    return;
-	}
-	if (!metadiffer(s, (char *) line, ll))
-	    continue;
-	if (*visrchstr == '^') {
-	    if (strncmp(s, visrchstr + 1, t0 - 1) != 0)
-		continue;
-	} else if (!hstrnstr(s, 0, visrchstr, t0, 1, 1))
+    he = quietgethist(histline);
+    while ((he = movehistent(he, visrchsense, hist_skip_flags))) {
+	if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
 	    continue;
-	if (--n <= 0)
-	    break;
+	s = ZLETEXT(he);
+	if (metadiffer(s, (char *) line, ll)
+	 && (*visrchstr == '^'? strncmp(s, visrchstr + 1, t0 - 1) == 0
+			      : hstrnstr(s, 0, visrchstr, t0, 1, 1) != 0)) {
+	    if (--n <= 0) {
+		zle_setline(he);
+		return;
+	    }
+	}
     }
-    zle_goto_hist(hl);
+    feep();
 }
 
 /**/
@@ -1090,8 +1070,8 @@ virevrepeatsearch(void)
 void
 historybeginningsearchbackward(void)
 {
+    Histent he;
     int cpos = cs;		/* save cursor position */
-    int hl = histline;
     int n = zmult;
     char *s;
 
@@ -1101,20 +1081,21 @@ historybeginningsearchbackward(void)
 	zmult = n;
 	return;
     }
-    for (;;) {
-	hl--;
-	if (!(s = zle_get_event(hl))) {
-	    feep();
-	    return;
-	}
+    he = quietgethist(histline);
+    while ((he = movehistent(he, -1, hist_skip_flags))) {
+	if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
+	    continue;
+	s = ZLETEXT(he);
 	if (metadiffer(s, (char *)line, cs) < 0 &&
-	    metadiffer(s, (char *)line, ll))
-	    if (--n <= 0)
-		break;
+	    metadiffer(s, (char *)line, ll)) {
+	    if (--n <= 0) {
+		zle_setline(he);
+		cs = cpos;
+		return;
+	    }
+	}
     }
-
-    zle_goto_hist(hl);
-    cs = cpos;
+    feep();
 }
 
 /* Extra function added by A.R. Iano-Fletcher.	*/
@@ -1124,8 +1105,8 @@ historybeginningsearchbackward(void)
 void
 historybeginningsearchforward(void)
 {
+    Histent he;
     int cpos = cs;		/* save cursor position */
-    int hl = histline;
     int n = zmult;
     char *s;
 
@@ -1135,18 +1116,19 @@ historybeginningsearchforward(void)
 	zmult = n;
 	return;
     }
-    for (;;) {
-	hl++;
-	if (!(s = zle_get_event(hl))) {
-	    feep();
-	    return;
+    he = quietgethist(histline);
+    while ((he = movehistent(he, 1, hist_skip_flags))) {
+	if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP)
+	    continue;
+	s = ZLETEXT(he);
+	if (metadiffer(s, (char *)line, cs) < (he->histnum == curhist) &&
+	    metadiffer(s, (char *)line, ll)) {
+	    if (--n <= 0) {
+		zle_setline(he);
+		cs = cpos;
+		return;
+	    }
 	}
-	if (metadiffer(s, (char *)line, cs) < (hl == curhist) &&
-	    metadiffer(s, (char *)line, ll))
-	    if (--n <= 0)
-		break;
     }
-
-    zle_goto_hist(hl);
-    cs = cpos;
+    feep();
 }