xref: /csrg-svn/lib/libedit/refresh.c (revision 61275)
154229Sbostic /*-
2*61275Sbostic  * Copyright (c) 1992, 1993
3*61275Sbostic  *	The Regents of the University of California.  All rights reserved.
454229Sbostic  *
554229Sbostic  * This code is derived from software contributed to Berkeley by
654229Sbostic  * Christos Zoulas of Cornell University.
754229Sbostic  *
854229Sbostic  * %sccs.include.redist.c%
954229Sbostic  */
1054229Sbostic 
1154624Schristos #if !defined(lint) && !defined(SCCSID)
12*61275Sbostic static char sccsid[] = "@(#)refresh.c	8.1 (Berkeley) 06/04/93";
1354624Schristos #endif /* not lint && not SCCSID */
1454229Sbostic 
1554229Sbostic /*
1654624Schristos  * refresh.c: Lower level screen refreshing functions
1754229Sbostic  */
1854229Sbostic #include "sys.h"
1954229Sbostic #include <stdio.h>
2054229Sbostic #include <ctype.h>
2154229Sbostic #include <unistd.h>
2254229Sbostic #include <string.h>
2354229Sbostic 
2454229Sbostic #include "el.h"
2554229Sbostic 
2654229Sbostic private	void	re_addc 		__P((EditLine *, int));
2754229Sbostic private	void	re_update_line 		__P((EditLine *, char *, char *, int));
2854229Sbostic private	void	re_insert		__P((EditLine *, char *, int, int,
2954229Sbostic 					     char *, int));
3054229Sbostic private	void	re_delete		__P((EditLine *, char *, int, int,
3154229Sbostic 					     int));
3254229Sbostic private	void	re_fastputc		__P((EditLine *, int));
3354229Sbostic 
3454229Sbostic private	void	re__strncopy		__P((char *, char *, size_t));
3554229Sbostic private	void	re__copy_and_pad	__P((char *, char *, size_t));
3654229Sbostic 
3754229Sbostic #ifdef DEBUG_REFRESH
3854229Sbostic private	void	re_printstr		__P((EditLine *, char *, char *,
3954229Sbostic 					     char *));
4054229Sbostic # define __F el->el_errfile
4154229Sbostic # define RE_DEBUG(a, b, c)	do 				\
4254229Sbostic 				    if (a) {			\
4354229Sbostic 					(void) fprintf b;	\
4454229Sbostic 					c;			\
4554229Sbostic 				    }				\
4654229Sbostic 				while (0)
4754229Sbostic /* re_printstr():
4854229Sbostic  *	Print a string on the debugging pty
4954229Sbostic  */
5054229Sbostic private void
re_printstr(el,str,f,t)5154229Sbostic re_printstr(el, str, f, t)
5254229Sbostic     EditLine *el;
5354229Sbostic     char *str;
5454229Sbostic     char *f, *t;
5554229Sbostic {
5654229Sbostic     RE_DEBUG(1,(__F, "%s:\"", str),);
5754229Sbostic     while (f < t)
5854229Sbostic 	RE_DEBUG(1,(__F, "%c", *f++ & 0177),);
5954229Sbostic     RE_DEBUG(1,(__F, "\"\r\n"),);
6054229Sbostic }
6154229Sbostic #else
6254229Sbostic # define RE_DEBUG(a, b, c)
6354229Sbostic #endif
6454229Sbostic 
6554229Sbostic 
6654229Sbostic /* re_addc():
6754229Sbostic  *	Draw c, expanding tabs, control chars etc.
6854229Sbostic  */
6954229Sbostic private void
re_addc(el,c)7054229Sbostic re_addc(el, c)
7154229Sbostic     EditLine *el;
7254229Sbostic     int c;
7354229Sbostic {
7454229Sbostic     if (isprint(c)) {
7554229Sbostic 	re_putc(el, c);
7654229Sbostic 	return;
7754229Sbostic     }
7854229Sbostic     if (c == '\n') {			/* expand the newline	 */
7954229Sbostic 	re_putc(el, '\0');		/* assure end of line	 */
8054229Sbostic 	el->el_refresh.r_cursor.h = 0;	/* reset cursor pos	 */
8154229Sbostic 	el->el_refresh.r_cursor.v++;
8254229Sbostic 	return;
8354229Sbostic     }
8454229Sbostic     if (c == '\t') {		/* expand the tab 	 */
8554229Sbostic 	for (;;) {
8654229Sbostic 	    re_putc(el, ' ');
8754229Sbostic 	    if ((el->el_refresh.r_cursor.h & 07) == 0)
8854229Sbostic 		break;		/* go until tab stop	 */
8954229Sbostic 	}
9054229Sbostic     }
9154229Sbostic     else if (iscntrl(c)) {
9254229Sbostic 	re_putc(el, '^');
9354229Sbostic 	if (c == '\177')
9454229Sbostic 	    re_putc(el, '?');
9554229Sbostic 	else
9654229Sbostic 	    /* uncontrolify it; works only for iso8859-1 like sets */
9754229Sbostic 	    re_putc(el, (c | 0100));
9854229Sbostic     }
9954229Sbostic     else {
10054229Sbostic 	re_putc(el, '\\');
10154229Sbostic 	re_putc(el, ((c >> 6) & 07) + '0');
10254229Sbostic 	re_putc(el, ((c >> 3) & 07) + '0');
10354229Sbostic 	re_putc(el, (c & 07) + '0');
10454229Sbostic     }
10554229Sbostic } /* end re_addc */
10654229Sbostic 
10754229Sbostic 
10854229Sbostic /* re_putc():
10954229Sbostic  *	Draw the character given
11054229Sbostic  */
11154229Sbostic protected void
re_putc(el,c)11254229Sbostic re_putc(el, c)
11354229Sbostic     EditLine *el;
11454229Sbostic     int c;
11554229Sbostic {
11654229Sbostic     RE_DEBUG(1,(__F, "printing %3.3o '%c'\r\n", c, c),);
11754229Sbostic 
11854229Sbostic     el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c;
11954229Sbostic     el->el_refresh.r_cursor.h++;				/* advance to next place */
12054229Sbostic     if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) {
12154229Sbostic 	el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0';
12254229Sbostic 						/* assure end of line */
12354229Sbostic 	el->el_refresh.r_cursor.h = 0;				/* reset it. */
12454229Sbostic 	el->el_refresh.r_cursor.v++;
12554229Sbostic 	RE_DEBUG(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
12654229Sbostic 		 (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
12754229Sbostic 		  el->el_refresh.r_cursor.v, el->el_term.t_size.v), abort());
12854229Sbostic     }
12954229Sbostic } /* end re_putc */
13054229Sbostic 
13154229Sbostic 
13254229Sbostic /* re_refresh():
13354229Sbostic  *	draws the new virtual screen image from the current input
13454229Sbostic  *  	line, then goes line-by-line changing the real image to the new
13554229Sbostic  *	virtual image. The routine to re-draw a line can be replaced
13654229Sbostic  *	easily in hopes of a smarter one being placed there.
13754229Sbostic  */
13854229Sbostic protected void
re_refresh(el)13954229Sbostic re_refresh(el)
14054229Sbostic     EditLine *el;
14154229Sbostic {
14254229Sbostic     int i;
14354229Sbostic     char *cp;
14454229Sbostic     coord_t     cur;
14554229Sbostic 
14654229Sbostic     RE_DEBUG(1,(__F, "el->el_line.buffer = :%s:\r\n", el->el_line.buffer),);
14754229Sbostic 
14854229Sbostic     /* reset the Drawing cursor */
14954229Sbostic     el->el_refresh.r_cursor.h = 0;
15054229Sbostic     el->el_refresh.r_cursor.v = 0;
15154229Sbostic 
15254229Sbostic     cur.h = -1;			/* set flag in case I'm not set */
15354229Sbostic     cur.v = 0;
15454229Sbostic 
15554229Sbostic     prompt_print(el);
15654229Sbostic 
15754229Sbostic     /* draw the current input buffer */
15854229Sbostic     for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) {
15954229Sbostic 	if (cp == el->el_line.cursor) {
16054229Sbostic 	    cur.h = el->el_refresh.r_cursor.h;	/* save for later */
16154229Sbostic 	    cur.v = el->el_refresh.r_cursor.v;
16254229Sbostic 	}
16354229Sbostic 	re_addc(el, *cp);
16454229Sbostic     }
16554229Sbostic 
16654229Sbostic     if (cur.h == -1) {		/* if I haven't been set yet, I'm at the end */
16754229Sbostic 	cur.h = el->el_refresh.r_cursor.h;
16854229Sbostic 	cur.v = el->el_refresh.r_cursor.v;
16954229Sbostic     }
17054229Sbostic     /* must be done BEFORE the NUL is written */
17154229Sbostic     el->el_refresh.r_newcv = el->el_refresh.r_cursor.v;
17254229Sbostic     re_putc(el, '\0');		/* put NUL on end */
17354229Sbostic 
17454229Sbostic     RE_DEBUG(1,(__F,
17554229Sbostic 	     "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
17654229Sbostic 	     el->el_term.t_size.h, el->el_refresh.r_cursor.h,
17754229Sbostic 	     el->el_refresh.r_cursor.v, el->el_vdisplay[0]),);
17854229Sbostic 
17954229Sbostic     RE_DEBUG(1,(__F, "updating %d lines.\r\n", el->el_refresh.r_newcv),);
18054229Sbostic     for (i = 0; i <= el->el_refresh.r_newcv; i++) {
18154229Sbostic 	/* NOTE THAT re_update_line MAY CHANGE el_display[i] */
18254229Sbostic 	re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);
18354229Sbostic 
18454229Sbostic 	/*
18554229Sbostic 	 * Copy the new line to be the current one, and pad out with spaces
18654229Sbostic 	 * to the full width of the terminal so that if we try moving the
18754229Sbostic 	 * cursor by writing the character that is at the end of the
18854229Sbostic 	 * screen line, it won't be a NUL or some old leftover stuff.
18954229Sbostic 	 */
19054229Sbostic 	re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
19154229Sbostic 			el->el_term.t_size.h);
19254229Sbostic     }
19354229Sbostic     RE_DEBUG(1,(__F,
19454229Sbostic 	 "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
19554229Sbostic 	 el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i),);
19654229Sbostic 
19754229Sbostic     if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
19854229Sbostic 	for (; i <= el->el_refresh.r_oldcv; i++) {
19954229Sbostic 	    term_move_to_line(el, i);
20054229Sbostic 	    term_move_to_char(el, 0);
20154229Sbostic 	    term_clear_EOL(el, strlen(el->el_display[i]));
20254229Sbostic #ifdef DEBUG_REFRESH
20354229Sbostic 	    term_overwrite(el, "C\b", 2);
20454229Sbostic #endif /* DEBUG_REFRESH */
20554229Sbostic 	    *el->el_display[i] = '\0';
20654229Sbostic 	}
20754229Sbostic 
20854229Sbostic     el->el_refresh.r_oldcv = el->el_refresh.r_newcv;	/* set for next time */
20954229Sbostic     RE_DEBUG(1,(__F,
21054229Sbostic 		"\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
21154229Sbostic 		el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
21254229Sbostic 		cur.h, cur.v),);
21354229Sbostic     term_move_to_line(el, cur.v);		/* go to where the cursor is */
21454229Sbostic     term_move_to_char(el, cur.h);
21554229Sbostic } /* end re_refresh */
21654229Sbostic 
21754229Sbostic 
21854229Sbostic /* re_goto_bottom():
21954229Sbostic  *	 used to go to last used screen line
22054229Sbostic  */
22154229Sbostic protected void
re_goto_bottom(el)22254229Sbostic re_goto_bottom(el)
22354229Sbostic     EditLine *el;
22454229Sbostic {
22554229Sbostic     term_move_to_line(el, el->el_refresh.r_oldcv);
22654229Sbostic     term__putc('\r');
22754229Sbostic     term__putc('\n');
22854229Sbostic     re_clear_display(el);
22954229Sbostic     term__flush();
23054229Sbostic } /* end re_goto_bottom */
23154229Sbostic 
23254229Sbostic 
23354229Sbostic /* re_insert():
23454229Sbostic  *	insert num characters of s into d (in front of the character)
23554229Sbostic  *	at dat, maximum length of d is dlen
23654229Sbostic  */
23754229Sbostic private void
23854229Sbostic /*ARGSUSED*/
re_insert(el,d,dat,dlen,s,num)23954229Sbostic re_insert(el, d, dat, dlen, s, num)
24054229Sbostic     EditLine *el;
24154229Sbostic     char *d;
24254229Sbostic     int dat, dlen;
24354229Sbostic     char *s;
24454229Sbostic     int num;
24554229Sbostic {
24654229Sbostic     char *a, *b;
24754229Sbostic 
24854229Sbostic     if (num <= 0)
24954229Sbostic 	return;
25054229Sbostic     if (num > dlen - dat)
25154229Sbostic 	num = dlen - dat;
25254229Sbostic 
25354229Sbostic     RE_DEBUG(1,(__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
25454229Sbostic 	    num, dat, dlen, d),);
25554229Sbostic     RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
25654229Sbostic 
25754229Sbostic     /* open up the space for num chars */
25854229Sbostic     if (num > 0) {
25954229Sbostic 	b = d + dlen - 1;
26054229Sbostic 	a = b - num;
26154229Sbostic 	while (a >= &d[dat])
26254229Sbostic 	    *b-- = *a--;
26354229Sbostic 	d[dlen] = '\0';		/* just in case */
26454229Sbostic     }
26554229Sbostic     RE_DEBUG(1,(__F,
26654229Sbostic 		"re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
26754229Sbostic 		num, dat, dlen, d),);
26854229Sbostic     RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
26954229Sbostic 
27054229Sbostic     /* copy the characters */
27154229Sbostic     for (a = d + dat; (a < d + dlen) && (num > 0); num--)
27254229Sbostic 	*a++ = *s++;
27354229Sbostic 
27454229Sbostic     RE_DEBUG(1,(__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
27554229Sbostic 	     num, dat, dlen, d, s),);
27654229Sbostic     RE_DEBUG(1,(__F, "s == \"%s\"n", s),);
27754229Sbostic } /* end re_insert */
27854229Sbostic 
27954229Sbostic 
28054229Sbostic /* re_delete():
28154229Sbostic  *	delete num characters d at dat, maximum length of d is dlen
28254229Sbostic  */
28354229Sbostic private void
28454229Sbostic /*ARGSUSED*/
re_delete(el,d,dat,dlen,num)28554229Sbostic re_delete(el, d, dat, dlen, num)
28654229Sbostic     EditLine *el;
28754229Sbostic     char *d;
28854229Sbostic     int dat, dlen, num;
28954229Sbostic {
29054229Sbostic     char *a, *b;
29154229Sbostic 
29254229Sbostic     if (num <= 0)
29354229Sbostic 	return;
29454229Sbostic     if (dat + num >= dlen) {
29554229Sbostic 	d[dat] = '\0';
29654229Sbostic 	return;
29754229Sbostic     }
29854229Sbostic 
29954229Sbostic     RE_DEBUG(1,(__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
30054229Sbostic 	    num, dat, dlen, d),);
30154229Sbostic 
30254229Sbostic     /* open up the space for num chars */
30354229Sbostic     if (num > 0) {
30454229Sbostic 	b = d + dat;
30554229Sbostic 	a = b + num;
30654229Sbostic 	while (a < &d[dlen])
30754229Sbostic 	    *b++ = *a++;
30854229Sbostic 	d[dlen] = '\0';		/* just in case */
30954229Sbostic     }
31054229Sbostic     RE_DEBUG(1,(__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
31154229Sbostic 	    num, dat, dlen, d),);
31254229Sbostic } /* end re_delete */
31354229Sbostic 
31454229Sbostic 
31554229Sbostic /* re__strncopy():
31654229Sbostic  *	Like strncpy without padding.
31754229Sbostic  */
31854229Sbostic private void
re__strncopy(a,b,n)31954229Sbostic re__strncopy(a, b, n)
32054229Sbostic     char *a, *b;
32154229Sbostic     size_t n;
32254229Sbostic {
32354229Sbostic     while (n-- && *b)
32454229Sbostic 	*a++ = *b++;
32554229Sbostic } /* end re__strncopy */
32654229Sbostic 
32754229Sbostic 
32854229Sbostic /* ****************************************************************
32954229Sbostic     re_update_line() is based on finding the middle difference of each line
33054229Sbostic     on the screen; vis:
33154229Sbostic 
33254229Sbostic 			     /old first difference
33354229Sbostic 	/beginning of line   |              /old last same       /old EOL
33454229Sbostic 	v		     v              v                    v
33554229Sbostic old:	eddie> Oh, my little gruntle-buggy is to me, as lurgid as
33654229Sbostic new:	eddie> Oh, my little buggy says to me, as lurgid as
33754229Sbostic 	^		     ^        ^			   ^
33854229Sbostic 	\beginning of line   |        \new last same	   \new end of line
33954229Sbostic 			     \new first difference
34054229Sbostic 
34154229Sbostic     all are character pointers for the sake of speed.  Special cases for
34254229Sbostic     no differences, as well as for end of line additions must be handled.
34354229Sbostic **************************************************************** */
34454229Sbostic 
34554229Sbostic /* Minimum at which doing an insert it "worth it".  This should be about
34654229Sbostic  * half the "cost" of going into insert mode, inserting a character, and
34754229Sbostic  * going back out.  This should really be calculated from the termcap
34854229Sbostic  * data...  For the moment, a good number for ANSI terminals.
34954229Sbostic  */
35054229Sbostic #define MIN_END_KEEP	4
35154229Sbostic 
35254229Sbostic private void
re_update_line(el,old,new,i)35354229Sbostic re_update_line(el, old, new, i)
35454229Sbostic     EditLine *el;
35554229Sbostic     char *old, *new;
35654229Sbostic     int     i;
35754229Sbostic {
35854229Sbostic     char *o, *n, *p, c;
35954229Sbostic     char   *ofd, *ols, *oe, *nfd, *nls, *ne;
36054229Sbostic     char   *osb, *ose, *nsb, *nse;
36154229Sbostic     int     fx, sx;
36254229Sbostic 
36354229Sbostic     /*
36454229Sbostic      * find first diff
36554229Sbostic      */
36654229Sbostic     for (o = old, n = new; *o && (*o == *n); o++, n++)
36754229Sbostic 	continue;
36854229Sbostic     ofd = o;
36954229Sbostic     nfd = n;
37054229Sbostic 
37154229Sbostic     /*
37254229Sbostic      * Find the end of both old and new
37354229Sbostic      */
37454229Sbostic     while (*o)
37554229Sbostic 	o++;
37654229Sbostic     /*
37754229Sbostic      * Remove any trailing blanks off of the end, being careful not to
37854229Sbostic      * back up past the beginning.
37954229Sbostic      */
38054229Sbostic     while (ofd < o) {
38154229Sbostic 	if (o[-1] != ' ')
38254229Sbostic 	    break;
38354229Sbostic 	o--;
38454229Sbostic     }
38554229Sbostic     oe = o;
38654229Sbostic     *oe = '\0';
38754229Sbostic 
38854229Sbostic     while (*n)
38954229Sbostic 	n++;
39054229Sbostic 
39154229Sbostic     /* remove blanks from end of new */
39254229Sbostic     while (nfd < n) {
39354229Sbostic 	if (n[-1] != ' ')
39454229Sbostic 	    break;
39554229Sbostic 	n--;
39654229Sbostic     }
39754229Sbostic     ne = n;
39854229Sbostic     *ne = '\0';
39954229Sbostic 
40054229Sbostic     /*
40154229Sbostic      * if no diff, continue to next line of redraw
40254229Sbostic      */
40354229Sbostic     if (*ofd == '\0' && *nfd == '\0') {
40454229Sbostic 	RE_DEBUG(1,(__F, "no difference.\r\n"),);
40554229Sbostic 	return;
40654229Sbostic     }
40754229Sbostic 
40854229Sbostic     /*
40954229Sbostic      * find last same pointer
41054229Sbostic      */
41154229Sbostic     while ((o > ofd) && (n > nfd) && (*--o == *--n))
41254229Sbostic 	continue;
41354229Sbostic     ols = ++o;
41454229Sbostic     nls = ++n;
41554229Sbostic 
41654229Sbostic     /*
41754229Sbostic      * find same begining and same end
41854229Sbostic      */
41954229Sbostic     osb = ols;
42054229Sbostic     nsb = nls;
42154229Sbostic     ose = ols;
42254229Sbostic     nse = nls;
42354229Sbostic 
42454229Sbostic     /*
42554229Sbostic      * case 1: insert: scan from nfd to nls looking for *ofd
42654229Sbostic      */
42754229Sbostic     if (*ofd) {
42854229Sbostic 	for (c = *ofd, n = nfd; n < nls; n++) {
42954229Sbostic 	    if (c == *n) {
43054229Sbostic 		for (o = ofd, p = n; p < nls && o < ols && *o == *p; o++, p++)
43154229Sbostic 		    continue;
43254229Sbostic 		/*
43354229Sbostic 		 * if the new match is longer and it's worth keeping, then we
43454229Sbostic 		 * take it
43554229Sbostic 		 */
43654229Sbostic 		if (((nse - nsb) < (p - n)) && (2 * (p - n) > n - nfd)) {
43754229Sbostic 		    nsb = n;
43854229Sbostic 		    nse = p;
43954229Sbostic 		    osb = ofd;
44054229Sbostic 		    ose = o;
44154229Sbostic 		}
44254229Sbostic 	    }
44354229Sbostic 	}
44454229Sbostic     }
44554229Sbostic 
44654229Sbostic     /*
44754229Sbostic      * case 2: delete: scan from ofd to ols looking for *nfd
44854229Sbostic      */
44954229Sbostic     if (*nfd) {
45054229Sbostic 	for (c = *nfd, o = ofd; o < ols; o++) {
45154229Sbostic 	    if (c == *o) {
45254229Sbostic 		for (n = nfd, p = o; p < ols && n < nls && *p == *n; p++, n++)
45354229Sbostic 		    continue;
45454229Sbostic 		/*
45554229Sbostic 		 * if the new match is longer and it's worth keeping, then we
45654229Sbostic 		 * take it
45754229Sbostic 		 */
45854229Sbostic 		if (((ose - osb) < (p - o)) && (2 * (p - o) > o - ofd)) {
45954229Sbostic 		    nsb = nfd;
46054229Sbostic 		    nse = n;
46154229Sbostic 		    osb = o;
46254229Sbostic 		    ose = p;
46354229Sbostic 		}
46454229Sbostic 	    }
46554229Sbostic 	}
46654229Sbostic     }
46754229Sbostic 
46854229Sbostic     /*
46954229Sbostic      * Pragmatics I: If old trailing whitespace or not enough characters to
47054229Sbostic      * save to be worth it, then don't save the last same info.
47154229Sbostic      */
47254229Sbostic     if ((oe - ols) < MIN_END_KEEP) {
47354229Sbostic 	ols = oe;
47454229Sbostic 	nls = ne;
47554229Sbostic     }
47654229Sbostic 
47754229Sbostic     /*
47854229Sbostic      * Pragmatics II: if the terminal isn't smart enough, make the data dumber
47954229Sbostic      * so the smart update doesn't try anything fancy
48054229Sbostic      */
48154229Sbostic 
48254229Sbostic     /*
48354229Sbostic      * fx is the number of characters we need to insert/delete: in the
48454229Sbostic      * beginning to bring the two same begins together
48554229Sbostic      */
48654229Sbostic     fx = (nsb - nfd) - (osb - ofd);
48754229Sbostic     /*
48854229Sbostic      * sx is the number of characters we need to insert/delete: in the end to
48954229Sbostic      * bring the two same last parts together
49054229Sbostic      */
49154229Sbostic     sx = (nls - nse) - (ols - ose);
49254229Sbostic 
49354229Sbostic     if (!EL_CAN_INSERT) {
49454229Sbostic 	if (fx > 0) {
49554229Sbostic 	    osb = ols;
49654229Sbostic 	    ose = ols;
49754229Sbostic 	    nsb = nls;
49854229Sbostic 	    nse = nls;
49954229Sbostic 	}
50054229Sbostic 	if (sx > 0) {
50154229Sbostic 	    ols = oe;
50254229Sbostic 	    nls = ne;
50354229Sbostic 	}
50454229Sbostic 	if ((ols - ofd) < (nls - nfd)) {
50554229Sbostic 	    ols = oe;
50654229Sbostic 	    nls = ne;
50754229Sbostic 	}
50854229Sbostic     }
50954229Sbostic     if (!EL_CAN_DELETE) {
51054229Sbostic 	if (fx < 0) {
51154229Sbostic 	    osb = ols;
51254229Sbostic 	    ose = ols;
51354229Sbostic 	    nsb = nls;
51454229Sbostic 	    nse = nls;
51554229Sbostic 	}
51654229Sbostic 	if (sx < 0) {
51754229Sbostic 	    ols = oe;
51854229Sbostic 	    nls = ne;
51954229Sbostic 	}
52054229Sbostic 	if ((ols - ofd) > (nls - nfd)) {
52154229Sbostic 	    ols = oe;
52254229Sbostic 	    nls = ne;
52354229Sbostic 	}
52454229Sbostic     }
52554229Sbostic 
52654229Sbostic     /*
52754229Sbostic      * Pragmatics III: make sure the middle shifted pointers are correct if
52854229Sbostic      * they don't point to anything (we may have moved ols or nls).
52954229Sbostic      */
53054229Sbostic     /* if the change isn't worth it, don't bother */
53154229Sbostic     /* was: if (osb == ose) */
53254229Sbostic     if ((ose - osb) < MIN_END_KEEP) {
53354229Sbostic 	osb = ols;
53454229Sbostic 	ose = ols;
53554229Sbostic 	nsb = nls;
53654229Sbostic 	nse = nls;
53754229Sbostic     }
53854229Sbostic 
53954229Sbostic     /*
54054229Sbostic      * Now that we are done with pragmatics we recompute fx, sx
54154229Sbostic      */
54254229Sbostic     fx = (nsb - nfd) - (osb - ofd);
54354229Sbostic     sx = (nls - nse) - (ols - ose);
54454229Sbostic 
54554229Sbostic     RE_DEBUG(1,(__F, "\n"),);
54654229Sbostic     RE_DEBUG(1,(__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
54754229Sbostic 	    ofd - old, osb - old, ose - old, ols - old, oe - old),);
54854229Sbostic     RE_DEBUG(1,(__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n",
54954229Sbostic 	    nfd - new, nsb - new, nse - new, nls - new, ne - new),);
55054229Sbostic     RE_DEBUG(1,(__F,
55154229Sbostic 		"xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"),);
55254229Sbostic     RE_DEBUG(1,(__F,
55354229Sbostic 		"xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"),);
55454229Sbostic #ifdef DEBUG_REFRESH
55554229Sbostic     re_printstr(el, "old- oe", old, oe);
55654229Sbostic     re_printstr(el, "new- ne", new, ne);
55754229Sbostic     re_printstr(el, "old-ofd", old, ofd);
55854229Sbostic     re_printstr(el, "new-nfd", new, nfd);
55954229Sbostic     re_printstr(el, "ofd-osb", ofd, osb);
56054229Sbostic     re_printstr(el, "nfd-nsb", nfd, nsb);
56154229Sbostic     re_printstr(el, "osb-ose", osb, ose);
56254229Sbostic     re_printstr(el, "nsb-nse", nsb, nse);
56354229Sbostic     re_printstr(el, "ose-ols", ose, ols);
56454229Sbostic     re_printstr(el, "nse-nls", nse, nls);
56554229Sbostic     re_printstr(el, "ols- oe", ols, oe);
56654229Sbostic     re_printstr(el, "nls- ne", nls, ne);
56754229Sbostic #endif /* DEBUG_REFRESH */
56854229Sbostic 
56954229Sbostic     /*
57054229Sbostic      * el_cursor.v to this line i MUST be in this routine so that if we
57154229Sbostic      * don't have to change the line, we don't move to it. el_cursor.h to first
57254229Sbostic      * diff char
57354229Sbostic      */
57454229Sbostic     term_move_to_line(el, i);
57554229Sbostic 
57654229Sbostic     /*
57754229Sbostic      * at this point we have something like this:
57854229Sbostic      *
57954229Sbostic      * /old                  /ofd    /osb               /ose    /ols     /oe
58054229Sbostic      * v.....................v       v..................v       v........v
58154229Sbostic      * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as
58254229Sbostic      * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as
58354229Sbostic      * ^.....................^     ^..................^       ^........^
58454229Sbostic      * \new                  \nfd  \nsb               \nse     \nls    \ne
58554229Sbostic      *
58654229Sbostic      * fx is the difference in length between the the chars between nfd and
58754229Sbostic      * nsb, and the chars between ofd and osb, and is thus the number of
58854229Sbostic      * characters to delete if < 0 (new is shorter than old, as above),
58954229Sbostic      * or insert (new is longer than short).
59054229Sbostic      *
59154229Sbostic      * sx is the same for the second differences.
59254229Sbostic      */
59354229Sbostic 
59454229Sbostic     /*
59554229Sbostic      * if we have a net insert on the first difference, AND inserting the net
59654229Sbostic      * amount ((nsb-nfd) - (osb-ofd)) won't push the last useful character
59754229Sbostic      * (which is ne if nls != ne, otherwise is nse) off the edge of the screen
59854229Sbostic      * (el->el_term.t_size.h) else we do the deletes first so that we keep everything we need
59954229Sbostic      * to.
60054229Sbostic      */
60154229Sbostic 
60254229Sbostic     /*
60354229Sbostic      * if the last same is the same like the end, there is no last same part,
60454229Sbostic      * otherwise we want to keep the last same part set p to the last useful
60554229Sbostic      * old character
60654229Sbostic      */
60754229Sbostic     p = (ols != oe) ? oe : ose;
60854229Sbostic 
60954229Sbostic     /*
61054229Sbostic      * if (There is a diffence in the beginning) && (we need to insert
61154229Sbostic      * characters) && (the number of characters to insert is less than the term
61254229Sbostic      * width) We need to do an insert! else if (we need to delete characters)
61354229Sbostic      * We need to delete characters! else No insert or delete
61454229Sbostic      */
61554229Sbostic     if ((nsb != nfd) && fx > 0 && ((p - old) + fx <= el->el_term.t_size.h)) {
61654229Sbostic 	RE_DEBUG(1,(__F, "first diff insert at %d...\r\n", nfd - new),);
61754229Sbostic 	/*
61854229Sbostic 	 * Move to the first char to insert, where the first diff is.
61954229Sbostic 	 */
62054229Sbostic 	term_move_to_char(el, nfd - new);
62154229Sbostic 	/*
62254229Sbostic 	 * Check if we have stuff to keep at end
62354229Sbostic 	 */
62454229Sbostic 	if (nsb != ne) {
62554229Sbostic 	    RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
62654229Sbostic 	    /*
62754229Sbostic 	     * insert fx chars of new starting at nfd
62854229Sbostic 	     */
62954229Sbostic 	    if (fx > 0) {
63054229Sbostic 		RE_DEBUG(!EL_CAN_INSERT,
63154229Sbostic 			 (__F, "ERROR: cannot insert in early first diff\n"),);
63254229Sbostic 		term_insertwrite(el, nfd, fx);
63354229Sbostic 		re_insert(el, old, ofd - old, el->el_term.t_size.h, nfd, fx);
63454229Sbostic 	    }
63554229Sbostic 	    /*
63654229Sbostic 	     * write (nsb-nfd) - fx chars of new starting at (nfd + fx)
63754229Sbostic 	     */
63854229Sbostic 	    term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
63954229Sbostic 	    re__strncopy(ofd + fx, nfd + fx, (nsb - nfd) - fx);
64054229Sbostic 	}
64154229Sbostic 	else {
64254229Sbostic 	    RE_DEBUG(1,(__F, "without anything to save\r\n"),);
64354229Sbostic 	    term_overwrite(el, nfd, (nsb - nfd));
64454229Sbostic 	    re__strncopy(ofd, nfd, (nsb - nfd));
64554229Sbostic 	    /*
64654229Sbostic 	     * Done
64754229Sbostic 	     */
64854229Sbostic 	    return;
64954229Sbostic 	}
65054229Sbostic     }
65154229Sbostic     else if (fx < 0) {
65254229Sbostic 	RE_DEBUG(1,(__F, "first diff delete at %d...\r\n", ofd - old),);
65354229Sbostic 	/*
65454229Sbostic 	 * move to the first char to delete where the first diff is
65554229Sbostic 	 */
65654229Sbostic 	term_move_to_char(el, ofd - old);
65754229Sbostic 	/*
65854229Sbostic 	 * Check if we have stuff to save
65954229Sbostic 	 */
66054229Sbostic 	if (osb != oe) {
66154229Sbostic 	    RE_DEBUG(1,(__F, "with stuff to save at end\r\n"),);
66254229Sbostic 	    /*
66354229Sbostic 	     * fx is less than zero *always* here but we check for code
66454229Sbostic 	     * symmetry
66554229Sbostic 	     */
66654229Sbostic 	    if (fx < 0) {
66754229Sbostic 		RE_DEBUG(!EL_CAN_DELETE,
66854229Sbostic 			 (__F, "ERROR: cannot delete in first diff\n"),);
66954229Sbostic 		term_deletechars(el, -fx);
67054229Sbostic 		re_delete(el, old, ofd - old, el->el_term.t_size.h, -fx);
67154229Sbostic 	    }
67254229Sbostic 	    /*
67354229Sbostic 	     * write (nsb-nfd) chars of new starting at nfd
67454229Sbostic 	     */
67554229Sbostic 	    term_overwrite(el, nfd, (nsb - nfd));
67654229Sbostic 	    re__strncopy(ofd, nfd, (nsb - nfd));
67754229Sbostic 
67854229Sbostic 	}
67954229Sbostic 	else {
68054229Sbostic 	    RE_DEBUG(1,(__F, "but with nothing left to save\r\n"),);
68154229Sbostic 	    /*
68254229Sbostic 	     * write (nsb-nfd) chars of new starting at nfd
68354229Sbostic 	     */
68454229Sbostic 	    term_overwrite(el, nfd, (nsb - nfd));
68554229Sbostic 	    RE_DEBUG(1,(__F, "cleareol %d\n", (oe - old) - (ne - new)),);
68654229Sbostic 	    term_clear_EOL(el, (oe - old) - (ne - new));
68754229Sbostic 	    /*
68854229Sbostic 	     * Done
68954229Sbostic 	     */
69054229Sbostic 	    return;
69154229Sbostic 	}
69254229Sbostic     }
69354229Sbostic     else
69454229Sbostic 	fx = 0;
69554229Sbostic 
69654229Sbostic     if (sx < 0) {
69754229Sbostic 	RE_DEBUG(1,(__F, "second diff delete at %d...\r\n", (ose - old) + fx),);
69854229Sbostic 	/*
69954229Sbostic 	 * Check if we have stuff to delete
70054229Sbostic 	 */
70154229Sbostic 	/*
70254229Sbostic 	 * fx is the number of characters inserted (+) or deleted (-)
70354229Sbostic 	 */
70454229Sbostic 
70554229Sbostic 	term_move_to_char(el, (ose - old) + fx);
70654229Sbostic 	/*
70754229Sbostic 	 * Check if we have stuff to save
70854229Sbostic 	 */
70954229Sbostic 	if (ols != oe) {
71054229Sbostic 	    RE_DEBUG(1,(__F, "with stuff to save at end\r\n"),);
71154229Sbostic 	    /*
71254229Sbostic 	     * Again a duplicate test.
71354229Sbostic 	     */
71454229Sbostic 	    if (sx < 0) {
71554229Sbostic 		RE_DEBUG(!EL_CAN_DELETE,
71654229Sbostic 			 (__F, "ERROR: cannot delete in second diff\n"),);
71754229Sbostic 		term_deletechars(el, -sx);
71854229Sbostic 	    }
71954229Sbostic 
72054229Sbostic 	    /*
72154229Sbostic 	     * write (nls-nse) chars of new starting at nse
72254229Sbostic 	     */
72354229Sbostic 	    term_overwrite(el, nse, (nls - nse));
72454229Sbostic 	}
72554229Sbostic 	else {
72654229Sbostic 	    RE_DEBUG(1,(__F, "but with nothing left to save\r\n"),);
72754229Sbostic 	    term_overwrite(el, nse, (nls - nse));
72854229Sbostic 	    RE_DEBUG(1,(__F, "cleareol %d\n", (oe - old) - (ne - new)),);
72954229Sbostic 	    term_clear_EOL(el, (oe - old) - (ne - new));
73054229Sbostic 	}
73154229Sbostic     }
73254229Sbostic 
73354229Sbostic     /*
73454229Sbostic      * if we have a first insert AND WE HAVEN'T ALREADY DONE IT...
73554229Sbostic      */
73654229Sbostic     if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) {
73754229Sbostic 	RE_DEBUG(1,(__F, "late first diff insert at %d...\r\n", nfd - new),);
73854229Sbostic 
73954229Sbostic 	term_move_to_char(el, nfd - new);
74054229Sbostic 	/*
74154229Sbostic 	 * Check if we have stuff to keep at the end
74254229Sbostic 	 */
74354229Sbostic 	if (nsb != ne) {
74454229Sbostic 	    RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
74554229Sbostic 	    /*
74654229Sbostic 	     * We have to recalculate fx here because we set it
74754229Sbostic 	     * to zero above as a flag saying that we hadn't done
74854229Sbostic 	     * an early first insert.
74954229Sbostic 	     */
75054229Sbostic 	    fx = (nsb - nfd) - (osb - ofd);
75154229Sbostic 	    if (fx > 0) {
75254229Sbostic 		/*
75354229Sbostic 		 * insert fx chars of new starting at nfd
75454229Sbostic 		 */
75554229Sbostic 		RE_DEBUG(!EL_CAN_INSERT,
75654229Sbostic 			 (__F, "ERROR: cannot insert in late first diff\n"),);
75754229Sbostic 		term_insertwrite(el, nfd, fx);
75854229Sbostic 		re_insert(el, old, ofd - old, el->el_term.t_size.h, nfd, fx);
75954229Sbostic 	    }
76054229Sbostic 
76154229Sbostic 	    /*
76254229Sbostic 	     * write (nsb-nfd) - fx chars of new starting at (nfd + fx)
76354229Sbostic 	     */
76454229Sbostic 	    term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
76554229Sbostic 	    re__strncopy(ofd + fx, nfd + fx, (nsb - nfd) - fx);
76654229Sbostic 	}
76754229Sbostic 	else {
76854229Sbostic 	    RE_DEBUG(1,(__F, "without anything to save\r\n"),);
76954229Sbostic 	    term_overwrite(el, nfd, (nsb - nfd));
77054229Sbostic 	    re__strncopy(ofd, nfd, (nsb - nfd));
77154229Sbostic 	}
77254229Sbostic     }
77354229Sbostic 
77454229Sbostic     /*
77554229Sbostic      * line is now NEW up to nse
77654229Sbostic      */
77754229Sbostic     if (sx >= 0) {
77854229Sbostic 	RE_DEBUG(1,(__F, "second diff insert at %d...\r\n", nse - new),);
77954229Sbostic 	term_move_to_char(el, nse - new);
78054229Sbostic 	if (ols != oe) {
78154229Sbostic 	    RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),);
78254229Sbostic 	    if (sx > 0) {
78354229Sbostic 		/* insert sx chars of new starting at nse */
78454229Sbostic 		RE_DEBUG(!EL_CAN_INSERT,
78554229Sbostic 		         (__F, "ERROR: cannot insert in second diff\n"),);
78654229Sbostic 		term_insertwrite(el, nse, sx);
78754229Sbostic 	    }
78854229Sbostic 
78954229Sbostic 	    /*
79054229Sbostic 	     * write (nls-nse) - sx chars of new starting at (nse + sx)
79154229Sbostic 	     */
79254229Sbostic 	    term_overwrite(el, nse + sx, (nls - nse) - sx);
79354229Sbostic 	}
79454229Sbostic 	else {
79554229Sbostic 	    RE_DEBUG(1,(__F, "without anything to save\r\n"),);
79654229Sbostic 	    term_overwrite(el, nse, (nls - nse));
79754229Sbostic 
79854229Sbostic 	    /*
79954229Sbostic              * No need to do a clear-to-end here because we were doing
80054229Sbostic 	     * a second insert, so we will have over written all of the
80154229Sbostic 	     * old string.
80254229Sbostic 	     */
80354229Sbostic 	}
80454229Sbostic     }
80554229Sbostic     RE_DEBUG(1,(__F, "done.\r\n"),);
80654229Sbostic } /* re_update_line */
80754229Sbostic 
80854229Sbostic 
80954229Sbostic /* re__copy_and_pad():
81054229Sbostic  *	Copy string and pad with spaces
81154229Sbostic  */
81254229Sbostic private void
re__copy_and_pad(dst,src,width)81354229Sbostic re__copy_and_pad(dst, src, width)
81454229Sbostic     char *dst, *src;
81554229Sbostic     size_t width;
81654229Sbostic {
81754229Sbostic     int i;
81854229Sbostic 
81954229Sbostic     for (i = 0; i < width; i++) {
82054229Sbostic 	if (*src == '\0')
82154229Sbostic 	    break;
82254229Sbostic 	*dst++ = *src++;
82354229Sbostic     }
82454229Sbostic 
82554229Sbostic     while (i < width) {
82654229Sbostic 	*dst++ = ' ';
82754229Sbostic 	i++;
82854229Sbostic     }
82954229Sbostic     *dst = '\0';
83054229Sbostic } /* end re__copy_and_pad */
83154229Sbostic 
83254229Sbostic 
83354229Sbostic /* re_refresh_cursor():
83454229Sbostic  *	Move to the new cursor position
83554229Sbostic  */
83654229Sbostic protected void
re_refresh_cursor(el)83754229Sbostic re_refresh_cursor(el)
83854229Sbostic     EditLine *el;
83954229Sbostic {
84054229Sbostic     char *cp, c;
84154229Sbostic     int h, v, th;
84254229Sbostic 
84354229Sbostic     /* first we must find where the cursor is... */
84454229Sbostic     h  = el->el_prompt.p_pos.h;
84554229Sbostic     v  = el->el_prompt.p_pos.v;
84654229Sbostic     th = el->el_term.t_size.h;		/* optimize for speed 		*/
84754229Sbostic 
84854229Sbostic     /* do input buffer to el->el_line.cursor */
84954229Sbostic     for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
85054229Sbostic 	c = *cp;
85154229Sbostic 	h++;			/* all chars at least this long */
85254229Sbostic 
85354229Sbostic 	if (c == '\n') {	/* handle newline in data part too */
85454229Sbostic 	    h = 0;
85554229Sbostic 	    v++;
85654229Sbostic 	}
85754229Sbostic 	else {
85854229Sbostic 	    if (c == '\t') {	/* if a tab, to next tab stop */
85954229Sbostic 		while (h & 07) {
86054229Sbostic 		    h++;
86154229Sbostic 		}
86254229Sbostic 	    }
86354229Sbostic 	    else if (iscntrl(c)) {	/* if control char */
86454229Sbostic 		h++;
86554229Sbostic 		if (h > th) {	/* if overflow, compensate */
86654229Sbostic 		    h = 1;
86754229Sbostic 		    v++;
86854229Sbostic 		}
86954229Sbostic 	    }
87054229Sbostic 	    else if (!isprint(c)) {
87154229Sbostic 		h += 3;
87254229Sbostic 		if (h > th) {	/* if overflow, compensate */
87354229Sbostic 		    h = h - th;
87454229Sbostic 		    v++;
87554229Sbostic 		}
87654229Sbostic 	    }
87754229Sbostic 	}
87854229Sbostic 
87954229Sbostic 	if (h >= th) {		/* check, extra long tabs picked up here also */
88054229Sbostic 	    h = 0;
88154229Sbostic 	    v++;
88254229Sbostic 	}
88354229Sbostic     }
88454229Sbostic 
88554229Sbostic     /* now go there */
88654229Sbostic     term_move_to_line(el, v);
88754229Sbostic     term_move_to_char(el, h);
88854229Sbostic     term__flush();
88954229Sbostic } /* re_refresh_cursor */
89054229Sbostic 
89154229Sbostic 
89254229Sbostic /* re_fastputc():
89354229Sbostic  *	Add a character fast.
89454229Sbostic  */
89554229Sbostic private void
re_fastputc(el,c)89654229Sbostic re_fastputc(el, c)
89754229Sbostic     EditLine *el;
89854229Sbostic     int    c;
89954229Sbostic {
90054229Sbostic     term__putc(c);
90154229Sbostic     el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
90254229Sbostic     if (el->el_cursor.h >= el->el_term.t_size.h) {
90354229Sbostic 	/* if we must overflow */
90454229Sbostic 	el->el_cursor.h = 0;
90554229Sbostic 	el->el_cursor.v++;
90654229Sbostic 	el->el_refresh.r_oldcv++;
90754229Sbostic 	term__putc('\r');
90854229Sbostic 	term__putc('\n');
90954229Sbostic     }
91054229Sbostic } /* end re_fastputc */
91154229Sbostic 
91254229Sbostic 
91354229Sbostic /* re_fastaddc():
91454229Sbostic  *	we added just one char, handle it fast.
91554229Sbostic  *	Assumes that screen cursor == real cursor
91654229Sbostic  */
91754229Sbostic protected void
re_fastaddc(el)91854229Sbostic re_fastaddc(el)
91954229Sbostic     EditLine *el;
92054229Sbostic {
92154229Sbostic     char c;
92254229Sbostic 
92354229Sbostic     c = el->el_line.cursor[-1];
92454229Sbostic 
92554229Sbostic     if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
92654229Sbostic 	re_refresh(el);		/* too hard to handle */
92754229Sbostic 	return;
92854229Sbostic     }				/* else (only do at end of line, no TAB) */
92954229Sbostic 
93054229Sbostic     if (iscntrl(c)) {		/* if control char, do caret */
93154229Sbostic 	char mc = (c == '\177') ? '?' : (c | 0100);
93254229Sbostic 	re_fastputc(el, '^');
93354229Sbostic 	re_fastputc(el, mc);
93454229Sbostic     }
93554229Sbostic     else if (isprint(c)) {	/* normal char */
93654229Sbostic 	re_fastputc(el, c);
93754229Sbostic     }
93854229Sbostic     else {
93954229Sbostic 	re_fastputc(el, '\\');
94054229Sbostic 	re_fastputc(el, ((c >> 6) & 7) + '0');
94154229Sbostic 	re_fastputc(el, ((c >> 3) & 7) + '0');
94254229Sbostic 	re_fastputc(el, (c & 7) + '0');
94354229Sbostic     }
94454229Sbostic     term__flush();
94554229Sbostic } /* end re_fastaddc */
94654229Sbostic 
94754229Sbostic 
94854229Sbostic /* re_clear_display():
94954229Sbostic  *	clear the screen buffers so that new new prompt starts fresh.
95054229Sbostic  */
95154229Sbostic protected void
re_clear_display(el)95254229Sbostic re_clear_display(el)
95354229Sbostic     EditLine *el;
95454229Sbostic {
95554229Sbostic     int i;
95654229Sbostic 
95754229Sbostic     el->el_cursor.v = 0;
95854229Sbostic     el->el_cursor.h = 0;
95954229Sbostic     for (i = 0; i < el->el_term.t_size.v; i++)
96054229Sbostic 	el->el_display[i][0] = '\0';
96154229Sbostic     el->el_refresh.r_oldcv = 0;
96254229Sbostic } /* end re_clear_display */
96354229Sbostic 
96454229Sbostic 
96554229Sbostic /* re_clear_lines():
96654229Sbostic  *	Make sure all lines are *really* blank
96754229Sbostic  */
96854229Sbostic protected void
re_clear_lines(el)96954229Sbostic re_clear_lines(el)
97054229Sbostic     EditLine *el;
97154229Sbostic {
97254229Sbostic     if (EL_CAN_CEOL) {
97354229Sbostic 	int i;
97454229Sbostic 	term_move_to_char(el, 0);
97554229Sbostic 	for (i = 0; i <= el->el_refresh.r_oldcv; i++) {
97654229Sbostic 	    /* for each line on the screen */
97754229Sbostic 	    term_move_to_line(el, i);
97854229Sbostic 	    term_clear_EOL(el, el->el_term.t_size.h);
97954229Sbostic 	}
98054229Sbostic 	term_move_to_line(el, 0);
98154229Sbostic     }
98254229Sbostic     else {
98354229Sbostic 	term_move_to_line(el, el->el_refresh.r_oldcv);	/* go to last line */
98454229Sbostic 	term__putc('\r');				/* go to BOL */
98554229Sbostic 	term__putc('\n');				/* go to new line */
98654229Sbostic     }
98754229Sbostic } /* end re_clear_lines */
988