Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: zsh on short terminals
- X-seq: zsh-workers 23224
- From: Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxx, "David Durrleman" <dualmoo@xxxxxxxxx>
- Subject: Re: zsh on short terminals
- Date: Mon, 19 Mar 2007 22:25:46 +0000
- In-reply-to: <20070319131317.6851b5b2.pws@xxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- References: <1bea19c20703142005t68ccbe91ie9572c97a865f561@xxxxxxxxxxxxxx> <20070319131317.6851b5b2.pws@xxxxxxx>
On Mon, 19 Mar 2007 13:13:17 +0000
Peter Stephenson <pws@xxxxxxx> wrote:
> "David Durrleman" <dualmoo@xxxxxxxxx> wrote:
> > If I run a terminal with less than 3 lines (geometry 80x1 for
> > example), then the first 17 chars of the prompt are not displayed
>
> Yes, it's a bug.
>
> This is a bit horrible. Zsh goes into a special mode when the terminal
> height is less than 3, equivalent to single line mode---that's because it
> can't fit the two extra lines the line editor normally expects to be there
> as a minimum under the prompt. However, it looks like single line mode has
> been allowed to lag behind the normal input mode and hasn't been fixed
> for ages. I don't have time to rewrite it completely, so I'm not sure what
> to do.
Good news! I exaggerated wildly.
Index: Src/Zle/zle_refresh.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_refresh.c,v
retrieving revision 1.46
diff -u -r1.46 zle_refresh.c
--- Src/Zle/zle_refresh.c 13 Jan 2006 17:46:09 -0000 1.46
+++ Src/Zle/zle_refresh.c 19 Mar 2007 22:22:56 -0000
@@ -227,7 +227,8 @@
vcs, vln, /* video cursor position column & line */
vmaxln, /* video maximum number of lines */
winw, winh, rwinh, /* window width & height */
- winpos; /* singlelinezle: line's position in window */
+ winpos, /* singlelinezle: line's position in window */
+ winprompt; /* singlelinezle: part of lprompt showing */
/**/
void
@@ -242,7 +243,8 @@
else
winh = (lines < 2) ? 24 : lines;
rwinh = lines; /* keep the real number of lines */
- winpos = vln = vmaxln = 0;
+ vln = vmaxln = winprompt = 0;
+ winpos = -1;
if (lwinw != winw || lwinh != winh) {
if (nbuf) {
for (ln = 0; ln != lwinh; ln++) {
@@ -1443,21 +1445,12 @@
{
REFRESH_STRING vbuf, vp, /* video buffer and pointer */
*qbuf, /* tmp */
- refreshop = *obuf; /* pointer to old video buffer */
+ refreshop; /* pointer to old video buffer */
int t0, /* tmp */
vsiz, /* size of new video buffer */
- nvcs = 0; /* new video cursor column */
-#ifdef MULTIBYTE_SUPPORT
- int eol = 0; /* has mbrtowc() returned -2? */
- /*
- * converted lprompt and pointer: no WEOF hack here since
- * we always output the full prompt and count its width.
- */
- ZLE_STRING_T lpwbuf, lpwp;
- char *lpptr, /* pointer into multibyte lprompt */
- *lpend; /* end of multibyte lprompt */
- mbstate_t mbs; /* shift state */
-#endif
+ nvcs = 0, /* new video cursor column */
+ owinpos = winpos, /* previous window position */
+ owinprompt = winprompt; /* previous winprompt */
nlnct = 1;
/* generate the new line buffer completely */
@@ -1480,56 +1473,10 @@
tmpcs = 0;
}
- /* only use last part of prompt */
-#ifdef MULTIBYTE_SUPPORT
- /*
- * Convert the entire lprompt so that we know how to count
- * characters.
- */
- lpend = strchr(lpromptbuf, 0);
- /* Worst case number of characters, not null-terminated */
- lpwp = lpwbuf = (ZLE_STRING_T)zalloc((lpend - lpromptbuf)
- * sizeof(*lpwbuf));
- /* Reset shift state, maybe. */
- memset(&mbs, '\0', sizeof mbs);
- for (lpptr = lpromptbuf; lpptr < lpend; ) {
- size_t cnt = eol ? MB_INVALID : mbrtowc(lpwp, lpptr, lpend-lpptr, &mbs);
- switch (cnt) {
- case MB_INCOMPLETE:
- eol = 1;
- /* FALL THROUGH */
- case MB_INVALID:
- memset(&mbs, '\0', sizeof mbs);
- /* FALL THROUGH */
- case 0:
- /* dunno, try to recover */
- lpptr++;
- *lpwp++ = ZWC('?');
- break;
- default:
- /* successfully converted */
- lpptr += cnt;
- lpwp++;
- break;
- }
- }
- if (lpwp - lpwbuf < lpromptw) {
- /* Not enough characters for lpromptw. */
- ZR_memcpy(vbuf, lpwbuf, lpwp - lpwbuf);
- vp = vbuf + (lpwp - lpwbuf);
- while (vp < vbuf + lpromptw)
- *vp++ = ZWC(' ');
- } else {
- ZR_memcpy(vbuf, lpwp - lpromptw, lpromptw);
- vp = vbuf + lpromptw;
- }
- *vp = ZWC('\0');
- zfree(lpwbuf, lpromptw * sizeof(*lpwbuf));
-#else
- memcpy(vbuf, strchr(lpromptbuf, 0) - lpromptw, lpromptw);
- vbuf[lpromptw] = '\0';
+ /* prompt is not directly copied into the video buffer */
+ ZR_memset(vbuf, ZWC(' '), lpromptw);
vp = vbuf + lpromptw;
-#endif
+ *vp = ZWC('\0');
for (t0 = 0; t0 < tmpll; t0++) {
if (tmpline[t0] == ZWC('\t')) {
@@ -1561,6 +1508,8 @@
*vp = ZWC('\0');
/* determine which part of the new line buffer we want for the display */
+ if (winpos == -1)
+ winpos = 0;
if ((winpos && nvcs < winpos + 1) || (nvcs > winpos + winw - 2)) {
if ((winpos = nvcs - ((winw - hasam) / 2)) < 0)
winpos = 0;
@@ -1575,10 +1524,71 @@
zfree(vbuf, vsiz * sizeof(*vbuf));
nvcs -= winpos;
-/* display the `visable' portion of the line buffer */
- for (t0 = 0, vp = *nbuf;;) {
- /* skip past all matching characters */
- for (; *vp && *vp == *refreshop; t0++, vp++, refreshop++) ;
+ if (winpos < lpromptw) {
+ /* skip start of buffer corresponding to prompt */
+ winprompt = lpromptw - winpos;
+ } else {
+ /* don't */
+ winprompt = 0;
+ }
+ if (winpos != owinpos && winprompt) {
+ char *pptr;
+ int skipping = 0, skipchars = winpos;
+ /*
+ * Need to output such part of the left prompt as fits.
+ * Skip the first winpos characters, outputting
+ * any characters marked with %{...%}.
+ */
+ singmoveto(0);
+ MB_METACHARINIT();
+ for (pptr = lpromptbuf; *pptr; ) {
+ if (*pptr == Inpar) {
+ skipping = 1;
+ pptr++;
+ } else if (*pptr == Outpar) {
+ skipping = 0;
+ pptr++;
+ } else {
+ convchar_t cc;
+ int mblen = MB_METACHARLENCONV(pptr, &cc);
+ if (skipping || skipchars == 0)
+ {
+ while (mblen) {
+#ifdef MULTIBYTE_SUPPORT
+ if (cc == WEOF)
+ fputc('?', shout);
+ else
+#endif
+ if (*pptr == Meta) {
+ mblen--;
+ fputc(*++pptr ^ 32, shout);
+ } else {
+ fputc(*pptr, shout);
+ }
+ pptr++;
+ mblen--;
+ }
+ } else {
+ skipchars--;
+ pptr += mblen;
+ }
+ }
+ }
+ vcs = winprompt;
+ }
+
+/* display the `visible' portion of the line buffer */
+ t0 = winprompt;
+ vp = *nbuf + winprompt;
+ refreshop = *obuf + winprompt;
+ for (;;) {
+ /*
+ * Skip past all matching characters, but if there used
+ * to be a prompt here be careful since all manner of
+ * nastiness may be around.
+ */
+ if (vp - *nbuf >= owinprompt)
+ for (; *vp && *vp == *refreshop; t0++, vp++, refreshop++) ;
if (!*vp && !*refreshop)
break;
--
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
Messages sorted by:
Reverse Date,
Date,
Thread,
Author