summaryrefslogtreecommitdiff
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.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. */