From 2983ed3fb3301d1808ae04a3a04389e3cd3fde8a Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 9 Aug 2006 22:08:38 +0000 Subject: 22594: Attempt to fix some off-by-one errors for completion lists that exactly fit the display width --- ChangeLog | 11 +++++++++++ Functions/Example/pushd | 4 ++++ Src/Zle/complist.c | 39 ++++++++++++++++++++++++++++++++------- Src/Zle/compresult.c | 1 + Src/Zle/zle_tricky.c | 3 ++- 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 + + * 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 * 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 == ). */ + /* 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. */ -- cgit 1.4.1