Home | History | Annotate | Line # | Download | only in libedit
refresh.c revision 1.57
      1 /*	$NetBSD: refresh.c,v 1.57 2020/03/30 06:54:37 ryo Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1992, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * This code is derived from software contributed to Berkeley by
      8  * Christos Zoulas of Cornell University.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. Neither the name of the University nor the names of its contributors
     19  *    may be used to endorse or promote products derived from this software
     20  *    without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  */
     34 
     35 #include "config.h"
     36 #if !defined(lint) && !defined(SCCSID)
     37 #if 0
     38 static char sccsid[] = "@(#)refresh.c	8.1 (Berkeley) 6/4/93";
     39 #else
     40 __RCSID("$NetBSD: refresh.c,v 1.57 2020/03/30 06:54:37 ryo Exp $");
     41 #endif
     42 #endif /* not lint && not SCCSID */
     43 
     44 /*
     45  * refresh.c: Lower level screen refreshing functions
     46  */
     47 #include <stdio.h>
     48 #include <stdlib.h>
     49 #include <string.h>
     50 #include <unistd.h>
     51 
     52 #include "el.h"
     53 
     54 static void	re_nextline(EditLine *);
     55 static void	re_addc(EditLine *, wint_t);
     56 static void	re_update_line(EditLine *, wchar_t *, wchar_t *, int);
     57 static void	re_insert (EditLine *, wchar_t *, int, int, wchar_t *, int);
     58 static void	re_delete(EditLine *, wchar_t *, int, int, int);
     59 static void	re_fastputc(EditLine *, wint_t);
     60 static void	re_clear_eol(EditLine *, int, int, int);
     61 static void	re__strncopy(wchar_t *, wchar_t *, size_t);
     62 static void	re__copy_and_pad(wchar_t *, const wchar_t *, size_t);
     63 
     64 #ifdef DEBUG_REFRESH
     65 static void	re_printstr(EditLine *, const char *, wchar_t *, wchar_t *);
     66 #define	__F el->el_errfile
     67 #define	ELRE_ASSERT(a, b, c)	do				\
     68 				    if (/*CONSTCOND*/ a) {	\
     69 					(void) fprintf b;	\
     70 					c;			\
     71 				    }				\
     72 				while (/*CONSTCOND*/0)
     73 #define	ELRE_DEBUG(a, b)	ELRE_ASSERT(a,b,;)
     74 
     75 /* re_printstr():
     76  *	Print a string on the debugging pty
     77  */
     78 static void
     79 re_printstr(EditLine *el, const char *str, wchar_t *f, wchar_t *t)
     80 {
     81 
     82 	ELRE_DEBUG(1, (__F, "%s:\"", str));
     83 	while (f < t)
     84 		ELRE_DEBUG(1, (__F, "%c", *f++ & 0177));
     85 	ELRE_DEBUG(1, (__F, "\"\r\n"));
     86 }
     87 #else
     88 #define	ELRE_ASSERT(a, b, c)
     89 #define	ELRE_DEBUG(a, b)
     90 #endif
     91 
     92 /* re_nextline():
     93  *	Move to the next line or scroll
     94  */
     95 static void
     96 re_nextline(EditLine *el)
     97 {
     98 	el->el_refresh.r_cursor.h = 0;	/* reset it. */
     99 
    100 	/*
    101 	 * If we would overflow (input is longer than terminal size),
    102 	 * emulate scroll by dropping first line and shuffling the rest.
    103 	 * We do this via pointer shuffling - it's safe in this case
    104 	 * and we avoid memcpy().
    105 	 */
    106 	if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) {
    107 		int i, lins = el->el_terminal.t_size.v;
    108 		wchar_t *firstline = el->el_vdisplay[0];
    109 
    110 		for(i = 1; i < lins; i++)
    111 			el->el_vdisplay[i - 1] = el->el_vdisplay[i];
    112 
    113 		firstline[0] = '\0';		/* empty the string */
    114 		el->el_vdisplay[i - 1] = firstline;
    115 	} else
    116 		el->el_refresh.r_cursor.v++;
    117 
    118 	ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_terminal.t_size.v,
    119 	    (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
    120 	    el->el_refresh.r_cursor.v, el->el_terminal.t_size.v),
    121 	    abort());
    122 }
    123 
    124 /* re_addc():
    125  *	Draw c, expanding tabs, control chars etc.
    126  */
    127 static void
    128 re_addc(EditLine *el, wint_t c)
    129 {
    130 	switch (ct_chr_class(c)) {
    131 	case CHTYPE_TAB:        /* expand the tab */
    132 		for (;;) {
    133 			re_putc(el, ' ', 1);
    134 			if ((el->el_refresh.r_cursor.h & 07) == 0)
    135 				break;			/* go until tab stop */
    136 		}
    137 		break;
    138 	case CHTYPE_NL: {
    139 		int oldv = el->el_refresh.r_cursor.v;
    140 		re_putc(el, '\0', 0);			/* assure end of line */
    141 		if (oldv == el->el_refresh.r_cursor.v)	/* XXX */
    142 			re_nextline(el);
    143 		break;
    144 	}
    145 	case CHTYPE_PRINT:
    146 		re_putc(el, c, 1);
    147 		break;
    148 	default: {
    149 		wchar_t visbuf[VISUAL_WIDTH_MAX];
    150 		ssize_t i, n =
    151 		    ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
    152 		for (i = 0; n-- > 0; ++i)
    153 		    re_putc(el, visbuf[i], 1);
    154 		break;
    155 	}
    156 	}
    157 }
    158 
    159 /* re_putliteral():
    160  *	Place the literal string given
    161  */
    162 libedit_private void
    163 re_putliteral(EditLine *el, const wchar_t *begin, const wchar_t *end)
    164 {
    165 	coord_t *cur = &el->el_refresh.r_cursor;
    166 	wint_t c;
    167 	int sizeh = el->el_terminal.t_size.h;
    168 	int i, w;
    169 
    170 	c = literal_add(el, begin, end, &w);
    171 	if (c == 0 || w <= 0)
    172 		return;
    173 	el->el_vdisplay[cur->v][cur->h] = c;
    174 
    175 	i = w;
    176 	if (i > sizeh - cur->h)		/* avoid overflow */
    177 		i = sizeh - cur->h;
    178 	while (--i > 0)
    179 		el->el_vdisplay[cur->v][cur->h + i] = MB_FILL_CHAR;
    180 
    181 	cur->h += w;
    182 	if (cur->h >= sizeh) {
    183 		/* assure end of line */
    184 		el->el_vdisplay[cur->v][sizeh] = '\0';
    185 		re_nextline(el);
    186 	}
    187 }
    188 
    189 /* re_putc():
    190  *	Draw the character given
    191  */
    192 libedit_private void
    193 re_putc(EditLine *el, wint_t c, int shift)
    194 {
    195 	coord_t *cur = &el->el_refresh.r_cursor;
    196 	int i, w = wcwidth(c);
    197 	int sizeh = el->el_terminal.t_size.h;
    198 
    199 	ELRE_DEBUG(1, (__F, "printing %5x '%lc'\r\n", c, c));
    200 	if (w == -1)
    201 		w = 0;
    202 
    203 	while (shift && (cur->h + w > sizeh))
    204 	    re_putc(el, ' ', 1);
    205 
    206 	el->el_vdisplay[cur->v][cur->h] = c;
    207 	/* assumes !shift is only used for single-column chars */
    208 	i = w;
    209 	while (--i > 0)
    210 		el->el_vdisplay[cur->v][cur->h + i] = MB_FILL_CHAR;
    211 
    212 	if (!shift)
    213 		return;
    214 
    215 	cur->h += w;	/* advance to next place */
    216 	if (cur->h >= sizeh) {
    217 		/* assure end of line */
    218 		el->el_vdisplay[cur->v][sizeh] = '\0';
    219 		re_nextline(el);
    220 	}
    221 }
    222 
    223 
    224 /* re_refresh():
    225  *	draws the new virtual screen image from the current input
    226  *	line, then goes line-by-line changing the real image to the new
    227  *	virtual image. The routine to re-draw a line can be replaced
    228  *	easily in hopes of a smarter one being placed there.
    229  */
    230 libedit_private void
    231 re_refresh(EditLine *el)
    232 {
    233 	int i, rhdiff;
    234 	wchar_t *cp, *st;
    235 	coord_t cur;
    236 #ifdef notyet
    237 	size_t termsz;
    238 #endif
    239 
    240 	ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%ls:\r\n",
    241 	    el->el_line.buffer));
    242 
    243 	literal_clear(el);
    244 	/* reset the Drawing cursor */
    245 	el->el_refresh.r_cursor.h = 0;
    246 	el->el_refresh.r_cursor.v = 0;
    247 
    248 	terminal_move_to_char(el, 0);
    249 
    250 	/* temporarily draw rprompt to calculate its size */
    251 	prompt_print(el, EL_RPROMPT);
    252 
    253 	/* reset the Drawing cursor */
    254 	el->el_refresh.r_cursor.h = 0;
    255 	el->el_refresh.r_cursor.v = 0;
    256 
    257 	if (el->el_line.cursor >= el->el_line.lastchar) {
    258 		if (el->el_map.current == el->el_map.alt
    259 		    && el->el_line.lastchar != el->el_line.buffer)
    260 			el->el_line.cursor = el->el_line.lastchar - 1;
    261 		else
    262 			el->el_line.cursor = el->el_line.lastchar;
    263 	}
    264 
    265 	cur.h = -1;		/* set flag in case I'm not set */
    266 	cur.v = 0;
    267 
    268 	prompt_print(el, EL_PROMPT);
    269 
    270 	/* draw the current input buffer */
    271 #if notyet
    272 	termsz = el->el_terminal.t_size.h * el->el_terminal.t_size.v;
    273 	if (el->el_line.lastchar - el->el_line.buffer > termsz) {
    274 		/*
    275 		 * If line is longer than terminal, process only part
    276 		 * of line which would influence display.
    277 		 */
    278 		size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz;
    279 
    280 		st = el->el_line.lastchar - rem
    281 			- (termsz - (((rem / el->el_terminal.t_size.v) - 1)
    282 					* el->el_terminal.t_size.v));
    283 	} else
    284 #endif
    285 		st = el->el_line.buffer;
    286 
    287 	for (cp = st; cp < el->el_line.lastchar; cp++) {
    288 		if (cp == el->el_line.cursor) {
    289                         int w = wcwidth(*cp);
    290 			/* save for later */
    291 			cur.h = el->el_refresh.r_cursor.h;
    292 			cur.v = el->el_refresh.r_cursor.v;
    293                         /* handle being at a linebroken doublewidth char */
    294                         if (w > 1 && el->el_refresh.r_cursor.h + w >
    295 			    el->el_terminal.t_size.h) {
    296 				cur.h = 0;
    297 				cur.v++;
    298                         }
    299 		}
    300 		re_addc(el, *cp);
    301 	}
    302 
    303 	if (cur.h == -1) {	/* if I haven't been set yet, I'm at the end */
    304 		cur.h = el->el_refresh.r_cursor.h;
    305 		cur.v = el->el_refresh.r_cursor.v;
    306 	}
    307 	rhdiff = el->el_terminal.t_size.h - el->el_refresh.r_cursor.h -
    308 	    el->el_rprompt.p_pos.h;
    309 	if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v &&
    310 	    !el->el_refresh.r_cursor.v && rhdiff > 1) {
    311 		/*
    312 		 * have a right-hand side prompt that will fit
    313 		 * on the end of the first line with at least
    314 		 * one character gap to the input buffer.
    315 		 */
    316 		while (--rhdiff > 0)	/* pad out with spaces */
    317 			re_putc(el, ' ', 1);
    318 		prompt_print(el, EL_RPROMPT);
    319 	} else {
    320 		el->el_rprompt.p_pos.h = 0;	/* flag "not using rprompt" */
    321 		el->el_rprompt.p_pos.v = 0;
    322 	}
    323 
    324 	re_putc(el, '\0', 0);	/* make line ended with NUL, no cursor shift */
    325 
    326 	el->el_refresh.r_newcv = el->el_refresh.r_cursor.v;
    327 
    328 	ELRE_DEBUG(1, (__F,
    329 		"term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
    330 		el->el_terminal.t_size.h, el->el_refresh.r_cursor.h,
    331 		el->el_refresh.r_cursor.v, ct_encode_string(el->el_vdisplay[0],
    332 		&el->el_scratch)));
    333 
    334 	ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
    335 	for (i = 0; i <= el->el_refresh.r_newcv; i++) {
    336 		/* NOTE THAT re_update_line MAY CHANGE el_display[i] */
    337 		re_update_line(el, el->el_display[i], el->el_vdisplay[i], i);
    338 
    339 		/*
    340 		 * Copy the new line to be the current one, and pad out with
    341 		 * spaces to the full width of the terminal so that if we try
    342 		 * moving the cursor by writing the character that is at the
    343 		 * end of the screen line, it won't be a NUL or some old
    344 		 * leftover stuff.
    345 		 */
    346 		re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
    347 		    (size_t) el->el_terminal.t_size.h);
    348 	}
    349 	ELRE_DEBUG(1, (__F,
    350 	"\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
    351 	    el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i));
    352 
    353 	if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
    354 		for (; i <= el->el_refresh.r_oldcv; i++) {
    355 			terminal_move_to_line(el, i);
    356 			terminal_move_to_char(el, 0);
    357                         /* This wcslen should be safe even with MB_FILL_CHARs */
    358 			terminal_clear_EOL(el, (int) wcslen(el->el_display[i]));
    359 #ifdef DEBUG_REFRESH
    360 			terminal_overwrite(el, L"C\b", 2);
    361 #endif /* DEBUG_REFRESH */
    362 			el->el_display[i][0] = '\0';
    363 		}
    364 
    365 	el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */
    366 	ELRE_DEBUG(1, (__F,
    367 	    "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
    368 	    el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
    369 	    cur.h, cur.v));
    370 	terminal_move_to_line(el, cur.v);	/* go to where the cursor is */
    371 	terminal_move_to_char(el, cur.h);
    372 }
    373 
    374 
    375 /* re_goto_bottom():
    376  *	 used to go to last used screen line
    377  */
    378 libedit_private void
    379 re_goto_bottom(EditLine *el)
    380 {
    381 
    382 	terminal_move_to_line(el, el->el_refresh.r_oldcv);
    383 	terminal__putc(el, '\n');
    384 	re_clear_display(el);
    385 	terminal__flush(el);
    386 }
    387 
    388 
    389 /* re_insert():
    390  *	insert num characters of s into d (in front of the character)
    391  *	at dat, maximum length of d is dlen
    392  */
    393 static void
    394 /*ARGSUSED*/
    395 re_insert(EditLine *el __attribute__((__unused__)),
    396     wchar_t *d, int dat, int dlen, wchar_t *s, int num)
    397 {
    398 	wchar_t *a, *b;
    399 
    400 	if (num <= 0)
    401 		return;
    402 	if (num > dlen - dat)
    403 		num = dlen - dat;
    404 
    405 	ELRE_DEBUG(1,
    406 	    (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
    407 	    num, dat, dlen, ct_encode_string(d, &el->el_scratch)));
    408 	ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s,
    409 	    &el->el_scratch)));
    410 
    411 	/* open up the space for num chars */
    412 	if (num > 0) {
    413 		b = d + dlen - 1;
    414 		a = b - num;
    415 		while (a >= &d[dat])
    416 			*b-- = *a--;
    417 		d[dlen] = '\0';	/* just in case */
    418 	}
    419 
    420 	ELRE_DEBUG(1, (__F,
    421 		"re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
    422 		num, dat, dlen, ct_encode_string(d, &el->el_scratch)));
    423 	ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s,
    424 		&el->el_scratch)));
    425 
    426 	/* copy the characters */
    427 	for (a = d + dat; (a < d + dlen) && (num > 0); num--)
    428 		*a++ = *s++;
    429 
    430 #ifdef notyet
    431         /* ct_encode_string() uses a static buffer, so we can't conveniently
    432          * encode both d & s here */
    433 	ELRE_DEBUG(1,
    434 	    (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
    435 	    num, dat, dlen, d, s));
    436 	ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
    437 #endif
    438 }
    439 
    440 
    441 /* re_delete():
    442  *	delete num characters d at dat, maximum length of d is dlen
    443  */
    444 static void
    445 /*ARGSUSED*/
    446 re_delete(EditLine *el __attribute__((__unused__)),
    447     wchar_t *d, int dat, int dlen, int num)
    448 {
    449 	wchar_t *a, *b;
    450 
    451 	if (num <= 0)
    452 		return;
    453 	if (dat + num >= dlen) {
    454 		d[dat] = '\0';
    455 		return;
    456 	}
    457 	ELRE_DEBUG(1,
    458 	    (__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
    459 	    num, dat, dlen, ct_encode_string(d, &el->el_scratch)));
    460 
    461 	/* open up the space for num chars */
    462 	if (num > 0) {
    463 		b = d + dat;
    464 		a = b + num;
    465 		while (a < &d[dlen])
    466 			*b++ = *a++;
    467 		d[dlen] = '\0';	/* just in case */
    468 	}
    469 	ELRE_DEBUG(1,
    470 	    (__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
    471 	    num, dat, dlen, ct_encode_string(d, &el->el_scratch)));
    472 }
    473 
    474 
    475 /* re__strncopy():
    476  *	Like strncpy without padding.
    477  */
    478 static void
    479 re__strncopy(wchar_t *a, wchar_t *b, size_t n)
    480 {
    481 
    482 	while (n-- && *b)
    483 		*a++ = *b++;
    484 }
    485 
    486 /* re_clear_eol():
    487  *	Find the number of characters we need to clear till the end of line
    488  *	in order to make sure that we have cleared the previous contents of
    489  *	the line. fx and sx is the number of characters inserted or deleted
    490  *	in the first or second diff, diff is the difference between the
    491  *	number of characters between the new and old line.
    492  */
    493 static void
    494 re_clear_eol(EditLine *el, int fx, int sx, int diff)
    495 {
    496 
    497 	ELRE_DEBUG(1, (__F, "re_clear_eol sx %d, fx %d, diff %d\n",
    498 	    sx, fx, diff));
    499 
    500 	if (fx < 0)
    501 		fx = -fx;
    502 	if (sx < 0)
    503 		sx = -sx;
    504 	if (fx > diff)
    505 		diff = fx;
    506 	if (sx > diff)
    507 		diff = sx;
    508 
    509 	ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff));
    510 	terminal_clear_EOL(el, diff);
    511 }
    512 
    513 /*****************************************************************
    514     re_update_line() is based on finding the middle difference of each line
    515     on the screen; vis:
    516 
    517 			     /old first difference
    518 	/beginning of line   |              /old last same       /old EOL
    519 	v		     v              v                    v
    520 old:	eddie> Oh, my little gruntle-buggy is to me, as lurgid as
    521 new:	eddie> Oh, my little buggy says to me, as lurgid as
    522 	^		     ^        ^			   ^
    523 	\beginning of line   |        \new last same	   \new end of line
    524 			     \new first difference
    525 
    526     all are character pointers for the sake of speed.  Special cases for
    527     no differences, as well as for end of line additions must be handled.
    528 **************************************************************** */
    529 
    530 /* Minimum at which doing an insert it "worth it".  This should be about
    531  * half the "cost" of going into insert mode, inserting a character, and
    532  * going back out.  This should really be calculated from the termcap
    533  * data...  For the moment, a good number for ANSI terminals.
    534  */
    535 #define	MIN_END_KEEP	4
    536 
    537 static void
    538 re_update_line(EditLine *el, wchar_t *old, wchar_t *new, int i)
    539 {
    540 	wchar_t *o, *n, *p, c;
    541 	wchar_t *ofd, *ols, *oe, *nfd, *nls, *ne;
    542 	wchar_t *osb, *ose, *nsb, *nse;
    543 	int fx, sx;
    544 	size_t len;
    545 
    546 	/*
    547          * find first diff
    548          */
    549 	for (o = old, n = new; *o && (*o == *n); o++, n++)
    550 		continue;
    551 	ofd = o;
    552 	nfd = n;
    553 
    554 	/*
    555          * Find the end of both old and new
    556          */
    557 	while (*o)
    558 		o++;
    559 	/*
    560          * Remove any trailing blanks off of the end, being careful not to
    561          * back up past the beginning.
    562          */
    563 	while (ofd < o) {
    564 		if (o[-1] != ' ')
    565 			break;
    566 		o--;
    567 	}
    568 	oe = o;
    569 	*oe = '\0';
    570 
    571 	while (*n)
    572 		n++;
    573 
    574 	/* remove blanks from end of new */
    575 	while (nfd < n) {
    576 		if (n[-1] != ' ')
    577 			break;
    578 		n--;
    579 	}
    580 	ne = n;
    581 	*ne = '\0';
    582 
    583 	/*
    584          * if no diff, continue to next line of redraw
    585          */
    586 	if (*ofd == '\0' && *nfd == '\0') {
    587 		ELRE_DEBUG(1, (__F, "no difference.\r\n"));
    588 		return;
    589 	}
    590 	/*
    591          * find last same pointer
    592          */
    593 	while ((o > ofd) && (n > nfd) && (*--o == *--n))
    594 		continue;
    595 	ols = ++o;
    596 	nls = ++n;
    597 
    598 	/*
    599          * find same beginning and same end
    600          */
    601 	osb = ols;
    602 	nsb = nls;
    603 	ose = ols;
    604 	nse = nls;
    605 
    606 	/*
    607          * case 1: insert: scan from nfd to nls looking for *ofd
    608          */
    609 	if (*ofd) {
    610 		for (c = *ofd, n = nfd; n < nls; n++) {
    611 			if (c == *n) {
    612 				for (o = ofd, p = n;
    613 				    p < nls && o < ols && *o == *p;
    614 				    o++, p++)
    615 					continue;
    616 				/*
    617 				 * if the new match is longer and it's worth
    618 				 * keeping, then we take it
    619 				 */
    620 				if (((nse - nsb) < (p - n)) &&
    621 				    (2 * (p - n) > n - nfd)) {
    622 					nsb = n;
    623 					nse = p;
    624 					osb = ofd;
    625 					ose = o;
    626 				}
    627 			}
    628 		}
    629 	}
    630 	/*
    631          * case 2: delete: scan from ofd to ols looking for *nfd
    632          */
    633 	if (*nfd) {
    634 		for (c = *nfd, o = ofd; o < ols; o++) {
    635 			if (c == *o) {
    636 				for (n = nfd, p = o;
    637 				    p < ols && n < nls && *p == *n;
    638 				    p++, n++)
    639 					continue;
    640 				/*
    641 				 * if the new match is longer and it's worth
    642 				 * keeping, then we take it
    643 				 */
    644 				if (((ose - osb) < (p - o)) &&
    645 				    (2 * (p - o) > o - ofd)) {
    646 					nsb = nfd;
    647 					nse = n;
    648 					osb = o;
    649 					ose = p;
    650 				}
    651 			}
    652 		}
    653 	}
    654 	/*
    655          * Pragmatics I: If old trailing whitespace or not enough characters to
    656          * save to be worth it, then don't save the last same info.
    657          */
    658 	if ((oe - ols) < MIN_END_KEEP) {
    659 		ols = oe;
    660 		nls = ne;
    661 	}
    662 	/*
    663          * Pragmatics II: if the terminal isn't smart enough, make the data
    664          * dumber so the smart update doesn't try anything fancy
    665          */
    666 
    667 	/*
    668          * fx is the number of characters we need to insert/delete: in the
    669          * beginning to bring the two same begins together
    670          */
    671 	fx = (int)((nsb - nfd) - (osb - ofd));
    672 	/*
    673          * sx is the number of characters we need to insert/delete: in the
    674          * end to bring the two same last parts together
    675          */
    676 	sx = (int)((nls - nse) - (ols - ose));
    677 
    678 	if (!EL_CAN_INSERT) {
    679 		if (fx > 0) {
    680 			osb = ols;
    681 			ose = ols;
    682 			nsb = nls;
    683 			nse = nls;
    684 		}
    685 		if (sx > 0) {
    686 			ols = oe;
    687 			nls = ne;
    688 		}
    689 		if ((ols - ofd) < (nls - nfd)) {
    690 			ols = oe;
    691 			nls = ne;
    692 		}
    693 	}
    694 	if (!EL_CAN_DELETE) {
    695 		if (fx < 0) {
    696 			osb = ols;
    697 			ose = ols;
    698 			nsb = nls;
    699 			nse = nls;
    700 		}
    701 		if (sx < 0) {
    702 			ols = oe;
    703 			nls = ne;
    704 		}
    705 		if ((ols - ofd) > (nls - nfd)) {
    706 			ols = oe;
    707 			nls = ne;
    708 		}
    709 	}
    710 	/*
    711          * Pragmatics III: make sure the middle shifted pointers are correct if
    712          * they don't point to anything (we may have moved ols or nls).
    713          */
    714 	/* if the change isn't worth it, don't bother */
    715 	/* was: if (osb == ose) */
    716 	if ((ose - osb) < MIN_END_KEEP) {
    717 		osb = ols;
    718 		ose = ols;
    719 		nsb = nls;
    720 		nse = nls;
    721 	}
    722 	/*
    723          * Now that we are done with pragmatics we recompute fx, sx
    724          */
    725 	fx = (int)((nsb - nfd) - (osb - ofd));
    726 	sx = (int)((nls - nse) - (ols - ose));
    727 
    728 	ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx));
    729 	ELRE_DEBUG(1, (__F, "ofd %td, osb %td, ose %td, ols %td, oe %td\n",
    730 		ofd - old, osb - old, ose - old, ols - old, oe - old));
    731 	ELRE_DEBUG(1, (__F, "nfd %td, nsb %td, nse %td, nls %td, ne %td\n",
    732 		nfd - new, nsb - new, nse - new, nls - new, ne - new));
    733 	ELRE_DEBUG(1, (__F,
    734 		"xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"));
    735 	ELRE_DEBUG(1, (__F,
    736 		"xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"));
    737 #ifdef DEBUG_REFRESH
    738 	re_printstr(el, "old- oe", old, oe);
    739 	re_printstr(el, "new- ne", new, ne);
    740 	re_printstr(el, "old-ofd", old, ofd);
    741 	re_printstr(el, "new-nfd", new, nfd);
    742 	re_printstr(el, "ofd-osb", ofd, osb);
    743 	re_printstr(el, "nfd-nsb", nfd, nsb);
    744 	re_printstr(el, "osb-ose", osb, ose);
    745 	re_printstr(el, "nsb-nse", nsb, nse);
    746 	re_printstr(el, "ose-ols", ose, ols);
    747 	re_printstr(el, "nse-nls", nse, nls);
    748 	re_printstr(el, "ols- oe", ols, oe);
    749 	re_printstr(el, "nls- ne", nls, ne);
    750 #endif /* DEBUG_REFRESH */
    751 
    752 	/*
    753          * el_cursor.v to this line i MUST be in this routine so that if we
    754          * don't have to change the line, we don't move to it. el_cursor.h to
    755          * first diff char
    756          */
    757 	terminal_move_to_line(el, i);
    758 
    759 	/*
    760          * at this point we have something like this:
    761          *
    762          * /old                  /ofd    /osb               /ose    /ols     /oe
    763          * v.....................v       v..................v       v........v
    764          * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as
    765          * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as
    766          * ^.....................^     ^..................^       ^........^
    767          * \new                  \nfd  \nsb               \nse     \nls    \ne
    768          *
    769          * fx is the difference in length between the chars between nfd and
    770          * nsb, and the chars between ofd and osb, and is thus the number of
    771          * characters to delete if < 0 (new is shorter than old, as above),
    772          * or insert (new is longer than short).
    773          *
    774          * sx is the same for the second differences.
    775          */
    776 
    777 	/*
    778          * if we have a net insert on the first difference, AND inserting the
    779          * net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful
    780          * character (which is ne if nls != ne, otherwise is nse) off the edge
    781 	 * of the screen (el->el_terminal.t_size.h) else we do the deletes first
    782 	 * so that we keep everything we need to.
    783          */
    784 
    785 	/*
    786          * if the last same is the same like the end, there is no last same
    787          * part, otherwise we want to keep the last same part set p to the
    788          * last useful old character
    789          */
    790 	p = (ols != oe) ? oe : ose;
    791 
    792 	/*
    793          * if (There is a diffence in the beginning) && (we need to insert
    794          *   characters) && (the number of characters to insert is less than
    795          *   the term width)
    796 	 *	We need to do an insert!
    797 	 * else if (we need to delete characters)
    798 	 *	We need to delete characters!
    799 	 * else
    800 	 *	No insert or delete
    801          */
    802 	if ((nsb != nfd) && fx > 0 &&
    803 	    ((p - old) + fx <= el->el_terminal.t_size.h)) {
    804 		ELRE_DEBUG(1,
    805 		    (__F, "first diff insert at %td...\r\n", nfd - new));
    806 		/*
    807 		 * Move to the first char to insert, where the first diff is.
    808 		 */
    809 		terminal_move_to_char(el, (int)(nfd - new));
    810 		/*
    811 		 * Check if we have stuff to keep at end
    812 		 */
    813 		if (nsb != ne) {
    814 			ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
    815 			/*
    816 		         * insert fx chars of new starting at nfd
    817 		         */
    818 			if (fx > 0) {
    819 				ELRE_DEBUG(!EL_CAN_INSERT, (__F,
    820 				"ERROR: cannot insert in early first diff\n"));
    821 				terminal_insertwrite(el, nfd, fx);
    822 				re_insert(el, old, (int)(ofd - old),
    823 				    el->el_terminal.t_size.h, nfd, fx);
    824 			}
    825 			/*
    826 		         * write (nsb-nfd) - fx chars of new starting at
    827 		         * (nfd + fx)
    828 			 */
    829 			len = (size_t) ((nsb - nfd) - fx);
    830 			terminal_overwrite(el, (nfd + fx), len);
    831 			re__strncopy(ofd + fx, nfd + fx, len);
    832 		} else {
    833 			ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
    834 			len = (size_t)(nsb - nfd);
    835 			terminal_overwrite(el, nfd, len);
    836 			re__strncopy(ofd, nfd, len);
    837 			/*
    838 		         * Done
    839 		         */
    840 			return;
    841 		}
    842 	} else if (fx < 0) {
    843 		ELRE_DEBUG(1,
    844 		    (__F, "first diff delete at %td...\r\n", ofd - old));
    845 		/*
    846 		 * move to the first char to delete where the first diff is
    847 		 */
    848 		terminal_move_to_char(el, (int)(ofd - old));
    849 		/*
    850 		 * Check if we have stuff to save
    851 		 */
    852 		if (osb != oe) {
    853 			ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n"));
    854 			/*
    855 		         * fx is less than zero *always* here but we check
    856 		         * for code symmetry
    857 		         */
    858 			if (fx < 0) {
    859 				ELRE_DEBUG(!EL_CAN_DELETE, (__F,
    860 				    "ERROR: cannot delete in first diff\n"));
    861 				terminal_deletechars(el, -fx);
    862 				re_delete(el, old, (int)(ofd - old),
    863 				    el->el_terminal.t_size.h, -fx);
    864 			}
    865 			/*
    866 		         * write (nsb-nfd) chars of new starting at nfd
    867 		         */
    868 			len = (size_t) (nsb - nfd);
    869 			terminal_overwrite(el, nfd, len);
    870 			re__strncopy(ofd, nfd, len);
    871 
    872 		} else {
    873 			ELRE_DEBUG(1, (__F,
    874 			    "but with nothing left to save\r\n"));
    875 			/*
    876 		         * write (nsb-nfd) chars of new starting at nfd
    877 		         */
    878 			terminal_overwrite(el, nfd, (size_t)(nsb - nfd));
    879 			re_clear_eol(el, fx, sx,
    880 			    (int)((oe - old) - (ne - new)));
    881 			/*
    882 		         * Done
    883 		         */
    884 			return;
    885 		}
    886 	} else
    887 		fx = 0;
    888 
    889 	if (sx < 0 && (ose - old) + fx < el->el_terminal.t_size.h) {
    890 		ELRE_DEBUG(1, (__F,
    891 		    "second diff delete at %td...\r\n", (ose - old) + fx));
    892 		/*
    893 		 * Check if we have stuff to delete
    894 		 */
    895 		/*
    896 		 * fx is the number of characters inserted (+) or deleted (-)
    897 		 */
    898 
    899 		terminal_move_to_char(el, (int)((ose - old) + fx));
    900 		/*
    901 		 * Check if we have stuff to save
    902 		 */
    903 		if (ols != oe) {
    904 			ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n"));
    905 			/*
    906 		         * Again a duplicate test.
    907 		         */
    908 			if (sx < 0) {
    909 				ELRE_DEBUG(!EL_CAN_DELETE, (__F,
    910 				    "ERROR: cannot delete in second diff\n"));
    911 				terminal_deletechars(el, -sx);
    912 			}
    913 			/*
    914 		         * write (nls-nse) chars of new starting at nse
    915 		         */
    916 			terminal_overwrite(el, nse, (size_t)(nls - nse));
    917 		} else {
    918 			ELRE_DEBUG(1, (__F,
    919 			    "but with nothing left to save\r\n"));
    920 			terminal_overwrite(el, nse, (size_t)(nls - nse));
    921 			re_clear_eol(el, fx, sx,
    922 			    (int)((oe - old) - (ne - new)));
    923 		}
    924 	}
    925 	/*
    926          * if we have a first insert AND WE HAVEN'T ALREADY DONE IT...
    927          */
    928 	if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) {
    929 		ELRE_DEBUG(1, (__F, "late first diff insert at %td...\r\n",
    930 		    nfd - new));
    931 
    932 		terminal_move_to_char(el, (int)(nfd - new));
    933 		/*
    934 		 * Check if we have stuff to keep at the end
    935 		 */
    936 		if (nsb != ne) {
    937 			ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
    938 			/*
    939 		         * We have to recalculate fx here because we set it
    940 		         * to zero above as a flag saying that we hadn't done
    941 		         * an early first insert.
    942 		         */
    943 			fx = (int)((nsb - nfd) - (osb - ofd));
    944 			if (fx > 0) {
    945 				/*
    946 				 * insert fx chars of new starting at nfd
    947 				 */
    948 				ELRE_DEBUG(!EL_CAN_INSERT, (__F,
    949 				 "ERROR: cannot insert in late first diff\n"));
    950 				terminal_insertwrite(el, nfd, fx);
    951 				re_insert(el, old, (int)(ofd - old),
    952 				    el->el_terminal.t_size.h, nfd, fx);
    953 			}
    954 			/*
    955 		         * write (nsb-nfd) - fx chars of new starting at
    956 		         * (nfd + fx)
    957 			 */
    958 			len = (size_t) ((nsb - nfd) - fx);
    959 			terminal_overwrite(el, (nfd + fx), len);
    960 			re__strncopy(ofd + fx, nfd + fx, len);
    961 		} else {
    962 			ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
    963 			len = (size_t) (nsb - nfd);
    964 			terminal_overwrite(el, nfd, len);
    965 			re__strncopy(ofd, nfd, len);
    966 		}
    967 	}
    968 	/*
    969          * line is now NEW up to nse
    970          */
    971 	if (sx >= 0) {
    972 		ELRE_DEBUG(1, (__F,
    973 		    "second diff insert at %d...\r\n", (int)(nse - new)));
    974 		terminal_move_to_char(el, (int)(nse - new));
    975 		if (ols != oe) {
    976 			ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
    977 			if (sx > 0) {
    978 				/* insert sx chars of new starting at nse */
    979 				ELRE_DEBUG(!EL_CAN_INSERT, (__F,
    980 				    "ERROR: cannot insert in second diff\n"));
    981 				terminal_insertwrite(el, nse, sx);
    982 			}
    983 			/*
    984 		         * write (nls-nse) - sx chars of new starting at
    985 			 * (nse + sx)
    986 		         */
    987 			terminal_overwrite(el, (nse + sx),
    988 			    (size_t)((nls - nse) - sx));
    989 		} else {
    990 			ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
    991 			terminal_overwrite(el, nse, (size_t)(nls - nse));
    992 
    993 			/*
    994 	                 * No need to do a clear-to-end here because we were
    995 	                 * doing a second insert, so we will have over
    996 	                 * written all of the old string.
    997 		         */
    998 		}
    999 	}
   1000 	ELRE_DEBUG(1, (__F, "done.\r\n"));
   1001 }
   1002 
   1003 
   1004 /* re__copy_and_pad():
   1005  *	Copy string and pad with spaces
   1006  */
   1007 static void
   1008 re__copy_and_pad(wchar_t *dst, const wchar_t *src, size_t width)
   1009 {
   1010 	size_t i;
   1011 
   1012 	for (i = 0; i < width; i++) {
   1013 		if (*src == '\0')
   1014 			break;
   1015 		*dst++ = *src++;
   1016 	}
   1017 
   1018 	for (; i < width; i++)
   1019 		*dst++ = ' ';
   1020 
   1021 	*dst = '\0';
   1022 }
   1023 
   1024 
   1025 /* re_refresh_cursor():
   1026  *	Move to the new cursor position
   1027  */
   1028 libedit_private void
   1029 re_refresh_cursor(EditLine *el)
   1030 {
   1031 	wchar_t *cp;
   1032 	int h, v, th, w;
   1033 
   1034 	if (el->el_line.cursor >= el->el_line.lastchar) {
   1035 		if (el->el_map.current == el->el_map.alt
   1036 		    && el->el_line.lastchar != el->el_line.buffer)
   1037 			el->el_line.cursor = el->el_line.lastchar - 1;
   1038 		else
   1039 			el->el_line.cursor = el->el_line.lastchar;
   1040 	}
   1041 
   1042 	/* first we must find where the cursor is... */
   1043 	h = el->el_prompt.p_pos.h;
   1044 	v = el->el_prompt.p_pos.v;
   1045 	th = el->el_terminal.t_size.h;	/* optimize for speed */
   1046 
   1047 	/* do input buffer to el->el_line.cursor */
   1048 	for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
   1049                 switch (ct_chr_class(*cp)) {
   1050 		case CHTYPE_NL:  /* handle newline in data part too */
   1051 			h = 0;
   1052 			v++;
   1053 			break;
   1054 		case CHTYPE_TAB: /* if a tab, to next tab stop */
   1055 			while (++h & 07)
   1056 				continue;
   1057 			break;
   1058 		default:
   1059 			w = wcwidth(*cp);
   1060 			if (w > 1 && h + w > th) { /* won't fit on line */
   1061 				h = 0;
   1062 				v++;
   1063 			}
   1064 			h += ct_visual_width(*cp);
   1065 			break;
   1066                 }
   1067 
   1068 		if (h >= th) {	/* check, extra long tabs picked up here also */
   1069 			h -= th;
   1070 			v++;
   1071 		}
   1072 	}
   1073         /* if we have a next character, and it's a doublewidth one, we need to
   1074          * check whether we need to linebreak for it to fit */
   1075         if (cp < el->el_line.lastchar && (w = wcwidth(*cp)) > 1)
   1076                 if (h + w > th) {
   1077                     h = 0;
   1078                     v++;
   1079                 }
   1080 
   1081 	/* now go there */
   1082 	terminal_move_to_line(el, v);
   1083 	terminal_move_to_char(el, h);
   1084 	terminal__flush(el);
   1085 }
   1086 
   1087 
   1088 /* re_fastputc():
   1089  *	Add a character fast.
   1090  */
   1091 static void
   1092 re_fastputc(EditLine *el, wint_t c)
   1093 {
   1094 	wchar_t *lastline;
   1095 	int w;
   1096 
   1097 	w = wcwidth(c);
   1098 	while (w > 1 && el->el_cursor.h + w > el->el_terminal.t_size.h)
   1099 	    re_fastputc(el, ' ');
   1100 
   1101 	terminal__putc(el, c);
   1102 	el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
   1103 	while (--w > 0)
   1104 		el->el_display[el->el_cursor.v][el->el_cursor.h++]
   1105 			= MB_FILL_CHAR;
   1106 
   1107 	if (el->el_cursor.h >= el->el_terminal.t_size.h) {
   1108 		/* if we must overflow */
   1109 		el->el_cursor.h = 0;
   1110 
   1111 		/*
   1112 		 * If we would overflow (input is longer than terminal size),
   1113 		 * emulate scroll by dropping first line and shuffling the rest.
   1114 		 * We do this via pointer shuffling - it's safe in this case
   1115 		 * and we avoid memcpy().
   1116 		 */
   1117 		if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) {
   1118 			int i, lins = el->el_terminal.t_size.v;
   1119 
   1120 			lastline = el->el_display[0];
   1121 			for(i = 1; i < lins; i++)
   1122 				el->el_display[i - 1] = el->el_display[i];
   1123 
   1124 			el->el_display[i - 1] = lastline;
   1125 		} else {
   1126 			el->el_cursor.v++;
   1127 			lastline = el->el_display[++el->el_refresh.r_oldcv];
   1128 		}
   1129 		re__copy_and_pad(lastline, L"", (size_t)el->el_terminal.t_size.h);
   1130 
   1131 		if (EL_HAS_AUTO_MARGINS) {
   1132 			if (EL_HAS_MAGIC_MARGINS) {
   1133 				terminal__putc(el, ' ');
   1134 				terminal__putc(el, '\b');
   1135 			}
   1136 		} else {
   1137 			terminal__putc(el, '\r');
   1138 			terminal__putc(el, '\n');
   1139 		}
   1140 	}
   1141 }
   1142 
   1143 
   1144 /* re_fastaddc():
   1145  *	we added just one char, handle it fast.
   1146  *	Assumes that screen cursor == real cursor
   1147  */
   1148 libedit_private void
   1149 re_fastaddc(EditLine *el)
   1150 {
   1151 	wchar_t c;
   1152 	int rhdiff;
   1153 
   1154 	c = el->el_line.cursor[-1];
   1155 
   1156 	if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) {
   1157 		re_refresh(el);	/* too hard to handle */
   1158 		return;
   1159 	}
   1160 	rhdiff = el->el_terminal.t_size.h - el->el_cursor.h -
   1161 	    el->el_rprompt.p_pos.h;
   1162 	if (el->el_rprompt.p_pos.h && rhdiff < 3) {
   1163 		re_refresh(el);	/* clear out rprompt if less than 1 char gap */
   1164 		return;
   1165 	}			/* else (only do at end of line, no TAB) */
   1166 	switch (ct_chr_class(c)) {
   1167 	case CHTYPE_TAB: /* already handled, should never happen here */
   1168 		break;
   1169 	case CHTYPE_NL:
   1170 	case CHTYPE_PRINT:
   1171 		re_fastputc(el, c);
   1172 		break;
   1173 	case CHTYPE_ASCIICTL:
   1174 	case CHTYPE_NONPRINT: {
   1175 		wchar_t visbuf[VISUAL_WIDTH_MAX];
   1176 		ssize_t i, n =
   1177 		    ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
   1178 		for (i = 0; n-- > 0; ++i)
   1179 			re_fastputc(el, visbuf[i]);
   1180 		break;
   1181 	}
   1182 	}
   1183 	terminal__flush(el);
   1184 }
   1185 
   1186 
   1187 /* re_clear_display():
   1188  *	clear the screen buffers so that new new prompt starts fresh.
   1189  */
   1190 libedit_private void
   1191 re_clear_display(EditLine *el)
   1192 {
   1193 	int i;
   1194 
   1195 	el->el_cursor.v = 0;
   1196 	el->el_cursor.h = 0;
   1197 	for (i = 0; i < el->el_terminal.t_size.v; i++)
   1198 		el->el_display[i][0] = '\0';
   1199 	el->el_refresh.r_oldcv = 0;
   1200 }
   1201 
   1202 
   1203 /* re_clear_lines():
   1204  *	Make sure all lines are *really* blank
   1205  */
   1206 libedit_private void
   1207 re_clear_lines(EditLine *el)
   1208 {
   1209 
   1210 	if (EL_CAN_CEOL) {
   1211 		int i;
   1212 		for (i = el->el_refresh.r_oldcv; i >= 0; i--) {
   1213 			/* for each line on the screen */
   1214 			terminal_move_to_line(el, i);
   1215 			terminal_move_to_char(el, 0);
   1216 			terminal_clear_EOL(el, el->el_terminal.t_size.h);
   1217 		}
   1218 	} else {
   1219 		terminal_move_to_line(el, el->el_refresh.r_oldcv);
   1220 					/* go to last line */
   1221 		terminal__putc(el, '\r');	/* go to BOL */
   1222 		terminal__putc(el, '\n');	/* go to new line */
   1223 	}
   1224 }
   1225