about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2006-08-09 22:08:38 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2006-08-09 22:08:38 +0000
commit2983ed3fb3301d1808ae04a3a04389e3cd3fde8a (patch)
treec9a1f5eecc55a14ca9949c6fb07a4c1c2d2bfc09
parent9c33cf443419b74c5769279f4f1043465b62f64b (diff)
downloadzsh-2983ed3fb3301d1808ae04a3a04389e3cd3fde8a.tar.gz
zsh-2983ed3fb3301d1808ae04a3a04389e3cd3fde8a.tar.xz
zsh-2983ed3fb3301d1808ae04a3a04389e3cd3fde8a.zip
22594: Attempt to fix some off-by-one errors for completion lists
that exactly fit the display width
-rw-r--r--ChangeLog11
-rw-r--r--Functions/Example/pushd4
-rw-r--r--Src/Zle/complist.c39
-rw-r--r--Src/Zle/compresult.c1
-rw-r--r--Src/Zle/zle_tricky.c3
5 files changed, 50 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 3326272f1..6399b5ce4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-08-09  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* Functions/Example/pushd: maintain pushdignoredups if it was
+	set on entry to the function.  I have a weird sense of deja vu
+	about this...
+
+	* 22594: Src/Zle/complist.c, Src/Zle/compresult.c,
+	Src/Zle/zle_tricky.c: Attempt to fix some off-by-one errors
+	counting lines when a completion list exactly fits the
+	display width.
+
 2006-08-09  Peter Stephenson  <pws@csr.com>
 
 	* 22593: Doc/Zsh/contrib.yo, Functions/MIME/zsh-mime-handler: add
diff --git a/Functions/Example/pushd b/Functions/Example/pushd
index 965c774bf..bb020c0aa 100644
--- a/Functions/Example/pushd
+++ b/Functions/Example/pushd
@@ -2,6 +2,9 @@
 # pushd +/-n just lifts the selected element to the top of the stack
 # instead of just cycling the stack.
 
+local puid
+[[ -o pushdignoredups ]] && puid=1
+
 emulate -R zsh
 setopt localoptions
 
@@ -9,5 +12,6 @@ if [[ ARGC -eq 1 && "$1" == [+-]<-> ]] then
 	setopt pushdignoredups
 	builtin pushd ~$1
 else
+	[[ -n $puid ]] && setopt pushdignoredups
 	builtin pushd "$@"
 fi
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index df5d78d7e..c8f72c1e3 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -398,6 +398,9 @@ static Cmatch **mtab, **mmtabp;
 static int mtab_been_reallocated;
 static Cmgroup *mgtab, *mgtabp;
 static struct listcols mcolors;
+#ifdef DEBUG
+int mgtabsize;
+#endif
 
 /* Used in mtab/mgtab, for explanations. */
 
@@ -660,7 +663,7 @@ clnicezputs(Listcols colors, char *s, int ml)
 	     * There might be problems with characters of printing width
 	     * greater than one here.
 	     */
-	    if (col >= columns) {
+	    if (col > columns) {
 		ml++;
 		if (mscroll && !--mrestlines && (ask = asklistscroll(ml))) {
 		    mlprinted = ml - oml;
@@ -698,7 +701,7 @@ clnicezputs(Listcols colors, char *s, int ml)
 		return 0;
 	    }
 	    putc(nc, shout);
-	    if (++col == columns) {
+	    if (++col > columns) {
 		ml++;
 		if (mscroll && !--mrestlines && (ask = asklistscroll(ml))) {
 		    mlprinted = ml - oml;
@@ -1037,7 +1040,8 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop)
 		    *stop = 1;
 		    if (stat && n)
 			mfirstl = -1;
-		    return (mlprinted = l + (cc / columns));
+		    mlprinted = l + (cc ? ((cc-1) / columns) : 0);
+		    return mlprinted;
 		}
 	    }
 	}
@@ -1051,7 +1055,8 @@ compprintfmt(char *fmt, int n, int dopr, int doesc, int ml, int *stop)
     if (stat && n)
 	mfirstl = -1;
 
-    return (mlprinted = l + (cc / columns));
+    mlprinted = l + (cc ? ((cc-1) / columns) : 0);
+    return mlprinted;	    
 }
 
 /* This is like zputs(), but allows scrolling. */
@@ -1158,6 +1163,7 @@ compprintlist(int showall)
 			int mm = (mcols * ml), i;
 
 			for (i = mcols; i--; ) {
+			    DPUTS(mm+i >= mgtabsize, "BUG: invalid position");
 			    mtab[mm + i] = mtmark(NULL);
 			    mgtab[mm + i] = mgmark(NULL);
 			}
@@ -1479,22 +1485,29 @@ clprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width)
 
             if (m->flags & CMF_DUMMY) {
                 for (i = mcols; i--; ) {
+		    DPUTS(mm+i >= mgtabsize, "BUG: invalid position");
                     mtab[mm + i] = mtmark(mp);
                     mgtab[mm + i] = mgmark(g);
                 }
             } else {
                 for (i = mcols; i--; ) {
+		    DPUTS(mm+i >= mgtabsize, "BUG: invalid position");
                     mtab[mm + i] = mp;
                     mgtab[mm + i] = g;
                 }
             }
 	}
 	if (!dolist(ml)) {
-	    mlprinted = printfmt(m->disp, 0, 0, 0) / columns;
+	    int nc = printfmt(m->disp, 0, 0, 0);
+	    if (nc)
+		mlprinted = (nc - 1) / columns;
+	    else
+		mlprinted = 0;
 	    return 0;
 	}
 	if (m->gnum == mselect) {
 	    int mm = (mcols * ml);
+	    DPUTS(mm >= mgtabsize, "BUG: invalid position");
 	    mline = ml;
 	    mcol = 0;
 	    mmtabp = mtab + mm;
@@ -1533,22 +1546,29 @@ clprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width)
 
             if (m->flags & CMF_DUMMY) {
                 for (i = (width ? width : mcols); i--; ) {
+		    DPUTS(mx+mm+i >= mgtabsize, "BUG: invalid position");
                     mtab[mx + mm + i] = mtmark(mp);
                     mgtab[mx + mm + i] = mgmark(g);
                 }
             } else {
                 for (i = (width ? width : mcols); i--; ) {
+		    DPUTS(mx+mm+i >= mgtabsize, "BUG: invalid position");
                     mtab[mx + mm + i] = mp;
                     mgtab[mx + mm + i] = g;
                 }
             }
 	}
 	if (!dolist(ml)) {
-	    mlprinted = ZMB_nicewidth(m->disp ? m->disp : m->str) / columns;
+	    int nc = ZMB_nicewidth(m->disp ? m->disp : m->str);
+	    if (nc)
+		mlprinted = (nc-1) / columns;
+	    else
+		mlprinted = 0;
 	    return 0;
 	}
 	if (m->gnum == mselect) {
 	    int mm = mcols * ml;
+	    DPUTS(mx+mm >= mgtabsize, "BUG: invalid position");
 
 	    mcol = mx;
 	    mline = ml;
@@ -1572,7 +1592,7 @@ clprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width)
 	    return 1;
 	}
 	len = ZMB_nicewidth(m->disp ? m->disp : m->str);
-	mlprinted = len / columns;
+	mlprinted = len ? (len-1) / columns : 0;
 
 	if ((g->flags & CGF_FILES) && m->modec) {
 	    if (m->gnum != mselect) {
@@ -1646,6 +1666,7 @@ singledraw()
         tc_downcurs(md1);
     if (mc1)
         tcmultout(TCRIGHT, TCMULTRIGHT, mc1);
+    DPUTS(ml1 * columns + mc1 >= mgtabsize, "BUG: invalid position");
     g = mgtab[ml1 * columns + mc1];
     clprintm(g, mtab[ml1 * columns + mc1], mcc1, ml1, lc1,
              (g->widths ? g->widths[mcc1] : g->width));
@@ -1657,6 +1678,7 @@ singledraw()
         tc_downcurs(md2 - md1);
     if (mc2)
         tcmultout(TCRIGHT, TCMULTRIGHT, mc2);
+    DPUTS(ml2 * columns + mc2 >= mgtabsize, "BUG: invalid position");
     g = mgtab[ml2 * columns + mc2];
     clprintm(g, mtab[ml2 * columns + mc2], mcc2, ml2, lc2,
              (g->widths ? g->widths[mcc2] : g->width));
@@ -1756,6 +1778,9 @@ complistmatches(UNUSED(Hookdef dummy), Chdata dat)
 	memset(mtab, 0, i * sizeof(Cmatch **));
 	free(mgtab);
 	mgtab = (Cmgroup *) zalloc(i * sizeof(Cmgroup));
+#ifdef DEBUG
+	mgtabsize = i;
+#endif
 	memset(mgtab, 0, i * sizeof(Cmgroup));
 	mlastcols = mcols = columns;
 	mlastlines = mlines = listdat.nlines;
diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c
index 887720a2f..e3adc0803 100644
--- a/Src/Zle/compresult.c
+++ b/Src/Zle/compresult.c
@@ -1480,6 +1480,7 @@ calclist(int showall)
 		hidden = 1;
 		while ((sptr = *pp)) {
 		    while (sptr && *sptr) {
+			/* TODO: we need to use wcwidth() here */
 			nlines += (nlptr = strchr(sptr, '\n'))
 			    ? 1 + (nlptr - sptr - 1) / columns
 			    : (ztrlen(sptr) - 1) / columns;
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 4b7d3126d..768d7e34f 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -2074,6 +2074,7 @@ printfmt(char *fmt, int n, int dopr, int doesc)
 
     for (; *p; p++) {
 	/* Handle the `%' stuff (%% == %, %n == <number of matches>). */
+	/* TODO: we need to use wcwidth() to count cc */
 	if (doesc && *p == '%') {
 	    if (*++p) {
 		m = 0;
@@ -2174,7 +2175,7 @@ printfmt(char *fmt, int n, int dopr, int doesc)
 		putc(' ', shout);
 	}
     }
-    return l + (cc / columns);
+    return l + ((cc-1) / columns);
 }
 
 /* This is used to print expansions. */