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

hopefully a better zle_refresh patch



Heyla, this is hopefully a better patch for zle_refresh.c
Changes are:
1)  moveto(): less redundant output (more efficient)
2)  refreshline(): if clearing in a line, then make new line buffer reflect
                    this, so next time the old line buffer does too.
3)  refreshline(): be stricter for Peter, re: cut-and-paste with automargin.
		    the code is better structured here now. also fixes 
		    condition where ln > nlnct - 1

With 2, there are now situations where the code is much more efficient.
One example is when typing ^V^J^V^J0123456
Previously when typing the numbers, the whole line was reprinted for each
number (unless you type really fast), so you got lots of useless spaces 
outputted.
With 3, col_cleareol set to -2 when don't want CLEAREOL used (on the line).
                            -1 when it can be used, but not currently set.
I'm still looking over the use of  clearflag  and also the use of CLEAREOD,
but this current patch should work (better).

Anyway, this is a patch on vanilla beta13.


*** zle_refresh.c.~1~	Fri Dec 22 09:44:43 1995
--- zle_refresh.c	Wed Mar 13 19:33:09 1996
***************
*** 41,47 ****
  /* Oct/Nov 94: <mason> some code savagely redesigned to fix several bugs -
     refreshline() & tc_rightcurs() majorly rewritten; refresh() fixed -
     I've put my fingers into just about every routine in here -
!    any queries about updates to mason@xxxxxxxxxxxxxxxxxxx */
  
  char **nbuf = NULL,		/* new video buffer line-by-line char array */
      **obuf = NULL;		/* old video buffer line-by-line char array */
--- 41,47 ----
  /* Oct/Nov 94: <mason> some code savagely redesigned to fix several bugs -
     refreshline() & tc_rightcurs() majorly rewritten; refresh() fixed -
     I've put my fingers into just about every routine in here -
!    any queries about updates to mason@xxxxxxxxxxxxx */
  
  char **nbuf = NULL,		/* new video buffer line-by-line char array */
      **obuf = NULL;		/* old video buffer line-by-line char array */
***************
*** 56,62 ****
      winpos;			/* singlelinezle: line's position in window */
  static unsigned pmpt_attr = 0,	/* text attributes after displaying prompt  */
      rpmpt_attr = 0;		/* text attributes after displaying rprompt */
- static char am_char = ' ';	/* first col char if needed for automargin  */
  
  /**/
  void
--- 56,61 ----
***************
*** 103,109 ****
  
      vcs = pptw;
      olnct = nlnct = 0;
!     if(showinglist > 0)
  	showinglist = -2;
  }
  
--- 102,108 ----
  
      vcs = pptw;
      olnct = nlnct = 0;
!     if (showinglist > 0)
  	showinglist = -2;
  }
  
***************
*** 172,178 ****
       * that was called from the end of refresh(), then we don't need to do   *
       * anything.  All this `inlist' code is actually unnecessary, but it     *
       * improves speed a little in a common case.                             */
!     if(inlist)
  	return;
  
  #ifdef HAVE_SELECT
--- 171,177 ----
       * that was called from the end of refresh(), then we don't need to do   *
       * anything.  All this `inlist' code is actually unnecessary, but it     *
       * improves speed a little in a common case.                             */
!     if (inlist)
  	return;
  
  #ifdef HAVE_SELECT
***************
*** 195,201 ****
              if (tccan(TCCLEAREOD))
                  tcout(TCCLEAREOD);
              else
!                 cleareol = 1;   /* set */
          if (t0 > -1)
              olnct = t0;
          if (isset(SINGLELINEZLE) || termok != TERM_OK)
--- 194,200 ----
              if (tccan(TCCLEAREOD))
                  tcout(TCCLEAREOD);
              else
!                 cleareol = 1;   /* request: clear to end of line */
          if (t0 > -1)
              olnct = t0;
          if (isset(SINGLELINEZLE) || termok != TERM_OK)
***************
*** 204,211 ****
              fwrite(lpptbuf, lpptlen, 1, shout);
  	    fflush(shout);
  	}
! 	if (clearflag)
! 	    putc('\r', shout), vcs = 0, moveto(0, pptw);
  	clearf = clearflag;
      } else if (winw != columns)
  	resetvideo();
--- 203,213 ----
              fwrite(lpptbuf, lpptlen, 1, shout);
  	    fflush(shout);
  	}
! 	if (clearflag) {
! 	    putc('\r', shout);
! 	    vcs = 0;
! 	    moveto(0, pptw);
! 	}
  	clearf = clearflag;
      } else if (winw != columns)
  	resetvideo();
***************
*** 407,419 ****
  
      /* if we have a new list showing, note it; if part of the list has been
      overwritten, redisplay it. */
!     if(showinglist == -2 || (showinglist > 0 && showinglist < nlnct)) {
  	inlist = 1;
  	listmatches();
  	inlist = 0;
  	refresh();
      }
!     if(showinglist == -1)
  	showinglist = nlnct;
  }
  
--- 409,421 ----
  
      /* if we have a new list showing, note it; if part of the list has been
      overwritten, redisplay it. */
!     if (showinglist == -2 || (showinglist > 0 && showinglist < nlnct)) {
  	inlist = 1;
  	listmatches();
  	inlist = 0;
  	refresh();
      }
!     if (showinglist == -1)
  	showinglist = nlnct;
  }
  
***************
*** 437,442 ****
--- 439,445 ----
  	i, j,			/* tmp					 */
  	nllen, ollen;		/* new and old line buffer lengths	 */
  
+ /* 0: setup */
      nl = nbuf[ln];
      nllen = nl ? strlen(nl) : 0;
      ol = obuf[ln] ? obuf[ln] : "";
***************
*** 445,459 ****
  /* 1: pad out the new buffer with spaces to contain _all_ of the characters
        which need to be written. do this now to allow some pre-processing */
  
!     if (cleareol ||		/* request to clear to end of line */
! 	!nllen ||		/* no line buffer given */
! 	(ln == 0 && (put_rpmpt != oput_rpmpt))) {	/* prompt changed */
  	p1 = halloc(winw + 1);
  	if (nllen)
  	    strncpy(p1, nl, nllen);
  	memset(p1 + nllen, ' ', winw - nllen);
  	p1[winw] = '\0';
! 	nl = p1;
  	nllen = winw;
      } else if (ollen > nllen) { /* make new line at least as long as old */
  	p1 = halloc(ollen + 1);
--- 448,465 ----
  /* 1: pad out the new buffer with spaces to contain _all_ of the characters
        which need to be written. do this now to allow some pre-processing */
  
!     if (cleareol 		/* request to clear to end of line */
! 	|| !nllen 		/* no line buffer given */
! 	|| (ln == 0 && (put_rpmpt != oput_rpmpt))) {	/* prompt changed */
  	p1 = halloc(winw + 1);
  	if (nllen)
  	    strncpy(p1, nl, nllen);
  	memset(p1 + nllen, ' ', winw - nllen);
  	p1[winw] = '\0';
! 	if (nbuf[ln])
! 	    strncpy(nl, p1, winw + 1);	/* next time obuf will be up-to-date */
! 	else
! 	    nl = p1;		/* shouldn't happen */
  	nllen = winw;
      } else if (ollen > nllen) { /* make new line at least as long as old */
  	p1 = halloc(ollen + 1);
***************
*** 469,507 ****
     With automatic margins, we shouldn't do it if there is another line, in
     case it messes up cut and paste. */
  
!     col_cleareol = -1;
!     if (tccan(TCCLEAREOL) && (!hasam || ln == nlnct - 1) && 
! 	(nllen == winw ||	/* new buffer goes to the end of the line */
! 	put_rpmpt != oput_rpmpt)) {
! 	for (i = nllen; i && nl[i - 1] == ' '; i--);
! 	for (j = ollen; j && ol[j - 1] == ' '; j--);
! 	if ((j > i + tclen[TCCLEAREOL]) || /* new buf's spaces early enough */
! 	    (nllen == winw && nl[winw - 1] == ' '))
! 	    col_cleareol = i;
!     }
! 
! /* 3: set character for first column, in case automargin stuff needs doing:
!    to begin with, this is the first char of the old screen line, if any. */
!     am_char = *ol ? *ol : *nl;
  
! /* 4: main display loop - write out the buffer using whatever tricks we can */
  
      for (;;) {
      /* skip past all matching characters */
  	for (; *nl && (*nl == *ol); nl++, ol++, ccs++) ;
  
  	if (!*nl) {
! 	    if ((char_ins <= 0)	|| (ccs >= winw))  /* written everything */
  		return;
  	    else		/* we've got junk on the right yet to clear */
! 		if (tccan(TCCLEAREOL) && (char_ins >= tclen[TCCLEAREOL]))
  		    col_cleareol = 0;	/* force a clear to end of line */
  	}
  
  	moveto(ln, ccs);	/* move to where we do all output from */
  
      /* if we can finish quickly, do so */
! 	if ((col_cleareol != -1) && (ccs >= col_cleareol)) {
  	    tcout(TCCLEAREOL);
  	    SELECT_ADD_COST(tclen[TCCLEAREOL]);
  	    return;
--- 475,512 ----
     With automatic margins, we shouldn't do it if there is another line, in
     case it messes up cut and paste. */
  
!     if (hasam && ln < nlnct - 1)
! 	col_cleareol = -2;	/* clearing eol would be evil so don't */
!     else {
! 	col_cleareol = -1;
! 	if (tccan(TCCLEAREOL) && (nllen == winw || put_rpmpt != oput_rpmpt)) {
! 	    for (i = nllen; i && nl[i - 1] == ' '; i--);
! 	    for (j = ollen; j && ol[j - 1] == ' '; j--);
! 	    if ((j > i + tclen[TCCLEAREOL])	/* new buf has enough spaces */
! 		|| (nllen == winw && nl[winw - 1] == ' '))
! 		col_cleareol = i;
! 	}
!     }
  
! /* 3: main display loop - write out the buffer using whatever tricks we can */
  
      for (;;) {
      /* skip past all matching characters */
  	for (; *nl && (*nl == *ol); nl++, ol++, ccs++) ;
  
  	if (!*nl) {
! 	    if ((char_ins <= 0)	|| (ccs >= winw))    /* written everything */
  		return;
  	    else		/* we've got junk on the right yet to clear */
! 		if (tccan(TCCLEAREOL) && (char_ins >= tclen[TCCLEAREOL])
! 	    	    && col_cleareol != -2)
  		    col_cleareol = 0;	/* force a clear to end of line */
  	}
  
  	moveto(ln, ccs);	/* move to where we do all output from */
  
      /* if we can finish quickly, do so */
! 	if ((col_cleareol >= 0) && (ccs >= col_cleareol)) {
  	    tcout(TCCLEAREOL);
  	    SELECT_ADD_COST(tclen[TCCLEAREOL]);
  	    return;
***************
*** 524,535 ****
      /* if we've reached the end of the old buffer, then there are few tricks
         we can do, so we just dump out what we must and clear if we can */
  	if (!*ol) {
! 	    i = (col_cleareol != -1) ? col_cleareol : nllen;
  	    i -= ccs;
  	    fwrite(nl, i, 1, shout);
  	    SELECT_ADD_COST(i);
  	    vcs += i;
! 	    if (col_cleareol != -1) {
  		tcout(TCCLEAREOL);
  		SELECT_ADD_COST(tclen[TCCLEAREOL]);
  	    }
--- 529,540 ----
      /* if we've reached the end of the old buffer, then there are few tricks
         we can do, so we just dump out what we must and clear if we can */
  	if (!*ol) {
! 	    i = (col_cleareol >= 0) ? col_cleareol : nllen;
  	    i -= ccs;
  	    fwrite(nl, i, 1, shout);
  	    SELECT_ADD_COST(i);
  	    vcs += i;
! 	    if (col_cleareol >= 0) {
  		tcout(TCCLEAREOL);
  		SELECT_ADD_COST(tclen[TCCLEAREOL]);
  	    }
***************
*** 593,614 ****
  void
  moveto(int ln, int cl)
  {
-     if (ln == vln && cl == vcs)
- 	return;
- 
      if (vcs == winw) {
  	if (!hasam) {
  	    putc('\r', shout);
  	    putc('\n', shout);
- 	    SELECT_ADD_COST(2);
  	} else {
! 	    putc(am_char, shout);
! 	    tcout(TCLEFT);
! 	    SELECT_ADD_COST(1 + tclen[TCLEFT]);
  	}
! 	vln++, vcs = 0;
      }
!     am_char = ' ';
  
  /* move up */
      if (ln < vln) {
--- 598,620 ----
  void
  moveto(int ln, int cl)
  {
      if (vcs == winw) {
+ 	vln++, vcs = 0;
  	if (!hasam) {
  	    putc('\r', shout);
  	    putc('\n', shout);
  	} else {
! 	    if ((vln < nlnct) && nbuf[vln] && *nbuf[vln])
! 		putc(*nbuf[vln], shout);
! 	    else
! 		putc(' ', shout);
! 	    putc('\r', shout);
  	}
! 	SELECT_ADD_COST(2);
      }
! 
!     if (ln == vln && cl == vcs)
! 	return;
  
  /* move up */
      if (ln < vln) {
***************
*** 638,643 ****
--- 644,653 ----
  	    vln++;
  	}
      }
+ 
+     if (cl == vcs)
+ 	return;
+ 
  /* choose cheapest movements for ttys without multiple movement capabilities -
     do this now because it's easier (to code) */
      if (cl <= vcs / 2) {

                  
 


-- 
Mason [G.C.W]  mason@xxxxxxxxxxxxxxxxxx    "Hurt...Agony...Pain...LOVE-IT"




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