From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28802 invoked from network); 9 Aug 2006 22:05:07 -0000 X-Spam-Checker-Version: SpamAssassin 3.1.4 (2006-07-25) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00, FORGED_RCVD_HELO autolearn=ham version=3.1.4 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 9 Aug 2006 22:05:07 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 32922 invoked from network); 9 Aug 2006 22:04:58 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 9 Aug 2006 22:04:58 -0000 Received: (qmail 12829 invoked by alias); 9 Aug 2006 22:04:54 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 22594 Received: (qmail 12818 invoked from network); 9 Aug 2006 22:04:53 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 9 Aug 2006 22:04:53 -0000 Received: (qmail 32656 invoked from network); 9 Aug 2006 22:04:53 -0000 Received: from mtaout01-winn.ispmail.ntl.com (81.103.221.47) by a.mx.sunsite.dk with SMTP; 9 Aug 2006 22:04:51 -0000 Received: from aamtaout01-winn.ispmail.ntl.com ([81.103.221.35]) by mtaout01-winn.ispmail.ntl.com with ESMTP id <20060809220448.SMEW15018.mtaout01-winn.ispmail.ntl.com@aamtaout01-winn.ispmail.ntl.com> for ; Wed, 9 Aug 2006 23:04:48 +0100 Received: from pwslaptop.csr.com ([81.107.41.155]) by aamtaout01-winn.ispmail.ntl.com with SMTP id <20060809220447.QDFX644.aamtaout01-winn.ispmail.ntl.com@pwslaptop.csr.com> for ; Wed, 9 Aug 2006 23:04:47 +0100 Date: Wed, 9 Aug 2006 23:04:45 +0100 From: Peter Stephenson To: zsh-workers@sunsite.dk Subject: Re: PATCH: complist with long display lines Message-Id: <20060809230445.6eb66ce0.p.w.stephenson@ntlworld.com> In-Reply-To: <060807101946.ZM19622@torch.brasslantern.com> References: <200608071540.k77FeWcL020899@news01.csr.com> <060807101946.ZM19622@torch.brasslantern.com> X-Mailer: Sylpheed version 2.2.6 (GTK+ 2.8.20; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Mon, 07 Aug 2006 10:19:46 -0700 Bart Schaefer wrote: > Now, about zsh-workers/21842 ... There was only one catch in the completion code, catch 22, and that stated that a concern for one's sanity in the face of complexities that were both real and immediate was the product of a rational mind. The main completion code doesn't count an extra line for the screen for strings that exactly fit the screen width: see the chunk of code in compresult.c where I've added the note that it should count character widths properly, as well as elsewhere in calclist(). This appears to be correctly reflected in the way the display appears. The complist code, however, adds 1 to the count of lines (variously held in ml and mlprinted) if the number of columns just reaches the screen width. As it only allocates the number of lines that the main completion code tells it, this causes bad array addressing. I've tried to fix this consistently by doing the same every time the number of columns printed is divided the screen width, however I haven't the first clue what part of the process most of those apply to. The same mistake seems to appear somewhere else, I think, and with some trepidation I've changed an occurrence in printfmt() in zle_tricky.c; you'll see that it does subtract the 1 further up in the bit where it's found a newline. *IMPORTANT*: please don't ask me if this is really correct as I'll crawl into a hole in the ground. However, do continue to report any reproducible problems, which is the only way we're ever going to sort this mess out. The DPUTS() should check that the array accesses are in range. If these go off there's another counting problem. On my xterm (Fedora Core 5, package xterm-213-1.FC5) a line that fits the width exactly doesn't show the last character. This doesn't happen with either gnome-terminal or konsole, so I'm assuming it's Somebody Else's Problem. (It's triggered by a termcap CLEAREOL at the end of the line; xterm moves the cursor back over the character it's just printed to avoid moving onto the next line, but doesn't seem to realise that's just cosmetic and so deletes the character when clearing the line. We *could* work around this but I'm hanged if I can be bothered.) Index: Src/Zle/complist.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/complist.c,v retrieving revision 1.87 diff -u -r1.87 complist.c --- Src/Zle/complist.c 7 Aug 2006 15:58:44 -0000 1.87 +++ Src/Zle/complist.c 9 Aug 2006 22:03:26 -0000 @@ -398,6 +398,9 @@ 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 @@ * 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 @@ 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 @@ *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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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; Index: Src/Zle/compresult.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/compresult.c,v retrieving revision 1.63 diff -u -r1.63 compresult.c --- Src/Zle/compresult.c 1 Aug 2006 21:28:04 -0000 1.63 +++ Src/Zle/compresult.c 9 Aug 2006 22:03:28 -0000 @@ -1480,6 +1480,7 @@ 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; Index: Src/Zle/zle_tricky.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_tricky.c,v retrieving revision 1.70 diff -u -r1.70 zle_tricky.c --- Src/Zle/zle_tricky.c 3 Aug 2006 15:37:50 -0000 1.70 +++ Src/Zle/zle_tricky.c 9 Aug 2006 22:03:29 -0000 @@ -2074,6 +2074,7 @@ 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 @@ putc(' ', shout); } } - return l + (cc / columns); + return l + ((cc-1) / columns); } /* This is used to print expansions. */ -- Peter Stephenson Web page now at http://homepage.ntlworld.com/p.w.stephenson/