Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH-3.1.5-pws-4: for BUG: long prompts tangle ZLE



Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> typed:
:On Dec 10,  9:00pm, Phil Pennock wrote:
:} Subject: BUG: long prompts tangle ZLE
:} If the prompt length is 80 characters (on an 80-char width term) then
:}  (a) the last character is not printed, or at least overwritten with a
:}      space;
:}  (b) more seriously, typing a command does not scroll the line up, but
:}      instead overwrites the start of the line.
:I can confirm this; in fact, it's weirder than Phil says -- if the prompt
:exactly fills the width of the screen, then the last character is not
:printed and the first character typed goes at the far right of the screen;
:the second character typed causes the first character to be re-echoed at
:the left edge (on top of the first character of the prompt) and then the
:second character appears next to it.
:A ctrl-L clears all this up until the next prompt is printed.
:None of this happens in 3.0.5.  Geoff, did we lose some zle_refresh code
:in the transition?

Don't think so - didn't prompt handling change or something?  It just
needs a four line fix - it's hidden inside a naming change because those
prompt variable names were giving me the irrits when I was trying to track
this down.  Oh, the diff is against Peter's patch release 4, but should
apply fairly well to vanilla 3.1.5


*** Src/Zle/zle_refresh.c.org	Sat Oct 31 01:56:14 1998
--- Src/Zle/zle_refresh.c	Sun Dec 20 19:34:36 1998
***************
*** 33,39 ****
  /* Expanded prompts */
  
  /**/
! char *lpptbuf, *rpptbuf;
  
  /* Text attributes after displaying prompts */
  
--- 33,39 ----
  /* Expanded prompts */
  
  /**/
! char *lpromptbuf, *rpromptbuf;
  
  /* Text attributes after displaying prompts */
  
***************
*** 77,93 ****
  /* Oct/Nov 94: <mason> some code savagely redesigned to fix several bugs -
     refreshline() & tc_rightcurs() majorly rewritten; zrefresh() fixed -
     I've put my fingers into just about every routine in here -
!    any queries about updates to mason@xxxxxxxxxxxxx */
  
  static char **nbuf = NULL,	/* new video buffer line-by-line char array */
      **obuf = NULL;		/* old video buffer line-by-line char array */
  static int more_start,		/* more text before start of screen?	    */
      more_end,			/* more stuff after end of screen?	    */
-     lppth,			/* lines taken up by the prompt		    */
      olnct,			/* previous number of lines		    */
      ovln,			/* previous video cursor position line	    */
!     pptw, rpw,                  /* prompt widths on screen                  */
!     rppth,			/* right prompt height                      */
      vcs, vln,			/* video cursor position column & line	    */
      vmaxln,			/* video maximum number of lines	    */
      winw, winh, rwinh,		/* window width & height		    */
--- 77,93 ----
  /* Oct/Nov 94: <mason> some code savagely redesigned to fix several bugs -
     refreshline() & tc_rightcurs() majorly rewritten; zrefresh() fixed -
     I've put my fingers into just about every routine in here -
!    any queries about updates to mason@xxxxxxxxxxxxxxx */
  
  static char **nbuf = NULL,	/* new video buffer line-by-line char array */
      **obuf = NULL;		/* old video buffer line-by-line char array */
  static int more_start,		/* more text before start of screen?	    */
      more_end,			/* more stuff after end of screen?	    */
      olnct,			/* previous number of lines		    */
      ovln,			/* previous video cursor position line	    */
!     lpromptw, rpromptw,		/* prompt widths on screen                  */
!     lprompth,			/* lines taken up by the prompt		    */
!     rprompth,			/* right prompt height                      */
      vcs, vln,			/* video cursor position column & line	    */
      vmaxln,			/* video maximum number of lines	    */
      winw, winh, rwinh,		/* window width & height		    */
***************
*** 100,106 ****
      int ln;
      static int lwinw = -1, lwinh = -1;	/* last window width & height */
   
-     genprompts();
      winw = columns;  /* terminal width */
      if (termflags & TERM_SHORT)
  	winh = 1;
--- 100,105 ----
***************
*** 132,144 ****
  	    *obuf[ln] = '\0';
      }
  
!     if (pptw) {
!     	memset(nbuf[0], ' ', pptw);
! 	memset(obuf[0], ' ', pptw);
! 	nbuf[0][pptw] = obuf[0][pptw] = '\0';
      }
  
!     vcs = pptw;
      olnct = nlnct = 0;
      if (showinglist > 0)
  	showinglist = -2;
--- 131,146 ----
  	    *obuf[ln] = '\0';
      }
  
!     countprompt(lpromptbuf, &lpromptw, &lprompth);
!     countprompt(rpromptbuf, &rpromptw, &rprompth);
! 
!     if (lpromptw) {
!     	memset(nbuf[0], ' ', lpromptw);
! 	memset(obuf[0], ' ', lpromptw);
! 	nbuf[0][lpromptw] = obuf[0][lpromptw] = '\0';
      }
  
!     vcs = lpromptw;
      olnct = nlnct = 0;
      if (showinglist > 0)
  	showinglist = -2;
***************
*** 289,300 ****
              olnct = t0;
          if (termflags & TERM_SHORT)
              vcs = 0;
!         else if (!clearflag && lpptbuf[0])
!             zputs(lpptbuf, shout);
  	if (clearflag) {
  	    zputc('\r', shout);
  	    vcs = 0;
! 	    moveto(0, pptw);
  	}
  	fflush(shout);
  	clearf = clearflag;
--- 291,305 ----
              olnct = t0;
          if (termflags & TERM_SHORT)
              vcs = 0;
!         else if (!clearflag && lpromptbuf[0]) {
!             zputs(lpromptbuf, shout);
! 	    if (lpromptw == 0)
! 		zputs("\n", shout);	/* works with both hasam and !hasam */
! 	}
  	if (clearflag) {
  	    zputc('\r', shout);
  	    vcs = 0;
! 	    moveto(0, lpromptw);
  	}
  	fflush(shout);
  	clearf = clearflag;
***************
*** 326,332 ****
      if (!*nbuf)
  	*nbuf = (char *)zalloc(winw + 2);
  
!     s = (unsigned char *)(nbuf[ln = 0] + pptw);
      t = line;
      sen = (unsigned char *)(*nbuf + winw);
      for (; t < line+ll; t++) {
--- 331,337 ----
      if (!*nbuf)
  	*nbuf = (char *)zalloc(winw + 2);
  
!     s = (unsigned char *)(nbuf[ln = 0] + lpromptw);
      t = line;
      sen = (unsigned char *)(*nbuf + winw);
      for (; t < line+ll; t++) {
***************
*** 425,439 ****
  
  /* determine whether the right-prompt exists and can fit on the screen */
      if (!more_start)
! 	put_rpmpt = rppth == 1 && rpptbuf[0] && !strchr(rpptbuf, '\t') &&
! 	    (int)strlen(nbuf[0]) + rpw < winw - 1;
      else {
  /* insert >.... on first line if there is more text before start of screen */
! 	memset(nbuf[0], ' ', pptw);
! 	t0 = winw - pptw;
  	t0 = t0 > 5 ? 5 : t0;
! 	strncpy(nbuf[0] + pptw, ">....", t0);
! 	memset(nbuf[0] + pptw + t0, ' ', winw - t0 - pptw);
  	nbuf[0][winw] = nbuf[0][winw + 1] = '\0';
      }
  
--- 430,445 ----
  
  /* determine whether the right-prompt exists and can fit on the screen */
      if (!more_start)
! 	put_rpmpt = rprompth == 1 && rpromptbuf[0] &&
! 	    !strchr(rpromptbuf, '\t') &&
! 	    (int)strlen(nbuf[0]) + rpromptw < winw - 1;
      else {
  /* insert >.... on first line if there is more text before start of screen */
! 	memset(nbuf[0], ' ', lpromptw);
! 	t0 = winw - lpromptw;
  	t0 = t0 > 5 ? 5 : t0;
! 	strncpy(nbuf[0] + lpromptw, ">....", t0);
! 	memset(nbuf[0] + lpromptw + t0, ' ', winw - t0 - lpromptw);
  	nbuf[0][winw] = nbuf[0][winw + 1] = '\0';
      }
  
***************
*** 477,484 ****
  
      /* output the right-prompt if appropriate */
  	if (put_rpmpt && !ln && !oput_rpmpt) {
! 	    moveto(0, winw - 1 - rpw);
! 	    zputs(rpptbuf, shout);
  	    vcs = winw - 1;
  	/* reset character attributes to that set by the main prompt */
  	    txtchange = pmpt_attr;
--- 483,490 ----
  
      /* output the right-prompt if appropriate */
  	if (put_rpmpt && !ln && !oput_rpmpt) {
! 	    moveto(0, winw - 1 - rpromptw);
! 	    zputs(rpromptbuf, shout);
  	    vcs = winw - 1;
  	/* reset character attributes to that set by the main prompt */
  	    txtchange = pmpt_attr;
***************
*** 659,670 ****
  /* 2c: if we're on the first line, start checking at the end of the prompt;
     we shouldn't be doing anything within the prompt */
  
!     if (ln == 0 && pptw) {
! 	i = pptw - ccs;
  	j = strlen(ol);
  	nl += i;
  	ol += (i > j ? j : i);	/* if ol is too short, point it to '\0' */
! 	ccs = pptw;
      }
  
  /* 3: main display loop - write out the buffer using whatever tricks we can */
--- 665,676 ----
  /* 2c: if we're on the first line, start checking at the end of the prompt;
     we shouldn't be doing anything within the prompt */
  
!     if (ln == 0 && lpromptw) {
! 	i = lpromptw - ccs;
  	j = strlen(ol);
  	nl += i;
  	ol += (i > j ? j : i);	/* if ol is too short, point it to '\0' */
! 	ccs = lpromptw;
      }
  
  /* 3: main display loop - write out the buffer using whatever tricks we can */
***************
*** 893,913 ****
  
  /* otherwise _carefully_ write the contents of the video buffer.
     if we're anywhere in the prompt, goto the left column and write the whole
!    prompt out unless ztrlen(lpptbuf) == pptw : we can cheat then */
!     if (vln == 0 && i < pptw) {
! 	if (strlen(lpptbuf) == pptw)
! 	    fputs(lpptbuf + i, shout);
! 	else if (tccan(TCRIGHT) && (tclen[TCRIGHT] * ct <= ztrlen(lpptbuf)))
  	    /* it is cheaper to send TCRIGHT than reprint the whole prompt */
! 	    for (ct = pptw - i; ct--; )
  		tcout(TCRIGHT);
          else {
  	    if (i != 0)
  		zputc('\r', shout);
! 	    tc_upcurs(lppth - 1);
! 	    zputs(lpptbuf, shout);
  	}
! 	i = pptw;
  	ct = cl - i;
      }
  
--- 899,921 ----
  
  /* otherwise _carefully_ write the contents of the video buffer.
     if we're anywhere in the prompt, goto the left column and write the whole
!    prompt out unless ztrlen(lpromptbuf) == lpromptw : we can cheat then */
!     if (vln == 0 && i < lpromptw) {
! 	if (strlen(lpromptbuf) == lpromptw)
! 	    fputs(lpromptbuf + i, shout);
! 	else if (tccan(TCRIGHT) && (tclen[TCRIGHT] * ct <= ztrlen(lpromptbuf)))
  	    /* it is cheaper to send TCRIGHT than reprint the whole prompt */
! 	    for (ct = lpromptw - i; ct--; )
  		tcout(TCRIGHT);
          else {
  	    if (i != 0)
  		zputc('\r', shout);
! 	    tc_upcurs(lprompth - 1);
! 	    zputs(lpromptbuf, shout);
! 	    if (lpromptw == 0)
! 		zputs("\n", shout);	/* works with both hasam and !hasam */
  	}
! 	i = lpromptw;
  	ct = cl - i;
      }
  
***************
*** 969,975 ****
  {
      moveto(0, 0);
      zputc('\r', shout);		/* extra care */
!     tc_upcurs(lppth - 1);
      resetneeded = 1;
      clearflag = 0;
  }
--- 977,983 ----
  {
      moveto(0, 0);
      zputc('\r', shout);		/* extra care */
!     tc_upcurs(lprompth - 1);
      resetneeded = 1;
      clearflag = 0;
  }
***************
*** 987,993 ****
  
      nlnct = 1;
  /* generate the new line buffer completely */
!     for (vsiz = 1 + pptw, t0 = 0; t0 != ll; t0++, vsiz++)
  	if (line[t0] == '\t')
  	    vsiz = (vsiz | 7) + 1;
  	else if (icntrl(line[t0]))
--- 995,1001 ----
  
      nlnct = 1;
  /* generate the new line buffer completely */
!     for (vsiz = 1 + lpromptw, t0 = 0; t0 != ll; t0++, vsiz++)
  	if (line[t0] == '\t')
  	    vsiz = (vsiz | 7) + 1;
  	else if (icntrl(line[t0]))
***************
*** 1002,1010 ****
  	cs = 0;
      }
  
!     memcpy(vbuf, strchr(lpptbuf, 0) - pptw, pptw); /* only use last part of prompt */
!     vbuf[pptw] = '\0';
!     vp = vbuf + pptw;
  
      for (t0 = 0; t0 != ll; t0++) {
  	if (line[t0] == '\t')
--- 1010,1019 ----
  	cs = 0;
      }
  
!     /* only use last part of prompt */
!     memcpy(vbuf, strchr(lpromptbuf, 0) - lpromptw, lpromptw);
!     vbuf[lpromptw] = '\0';
!     vp = vbuf + lpromptw;
  
      for (t0 = 0; t0 != ll; t0++) {
  	if (line[t0] == '\t')
***************
*** 1103,1116 ****
  		vcs++;
  	    }
      }
- }
- 
- /* recheck size of prompts */
- 
- /**/
- static void
- genprompts(void)
- {
-     countprompt(lpptbuf, &pptw, &lppth);
-     countprompt(rpptbuf, &rpw, &rppth);
  }
--- 1112,1115 ----

*** Src/Zle/zle_main.c.org	Thu Dec 17 22:17:03 1998
--- Src/Zle/zle_main.c	Sun Dec 20 18:51:31 1998
***************
*** 443,451 ****
      insmode = unset(OVERSTRIKE);
      eofsent = 0;
      resetneeded = 0;
!     lpptbuf = promptexpand(lp, 1, NULL, NULL);
      pmpt_attr = txtchange;
!     rpptbuf = promptexpand(rp, 1, NULL, NULL);
      rpmpt_attr = txtchange;
      histallowed = ha;
      PERMALLOC {
--- 443,451 ----
      insmode = unset(OVERSTRIKE);
      eofsent = 0;
      resetneeded = 0;
!     lpromptbuf = promptexpand(lp, 1, NULL, NULL);
      pmpt_attr = txtchange;
!     rpromptbuf = promptexpand(rp, 1, NULL, NULL);
      rpmpt_attr = txtchange;
      histallowed = ha;
      PERMALLOC {
***************
*** 529,536 ****
  	statusline = NULL;
  	invalidatelist();
  	trashzle();
! 	free(lpptbuf);
! 	free(rpptbuf);
  	zleactive = 0;
  	alarm(0);
      } LASTALLOC;
--- 529,536 ----
  	statusline = NULL;
  	invalidatelist();
  	trashzle();
! 	free(lpromptbuf);
! 	free(rpromptbuf);
  	zleactive = 0;
  	alarm(0);
      } LASTALLOC;


-- 
Geoff Wing   <gcw@xxxxxxxxx>            Mobile : 0412 162 441
Work URL: http://www.primenet.com.au/   Ego URL: http://pobox.com/~gcw/



Messages sorted by: Reverse Date, Date, Thread, Author